This repository has been archived by the owner on Jun 2, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
99b929d
commit 5d3439c
Showing
14 changed files
with
6,881 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
|
||
# generated directory | ||
**/generated | ||
|
||
# output directory | ||
/out | ||
|
||
#object folder | ||
/obj | ||
|
||
#vs folder | ||
/.vs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<manifest> | ||
<control namespace="AB" constructor="CompositeAddress" version="0.0.21" display-name-key="Composite Address Control" description-key="Use this control to minimize the size of address section on the form and format it the way you want" control-type="standard"> | ||
<property name="value" display-name-key="Full Address" description-key="Full Address" of-type="SingleLine.Text" usage="bound" required="true" /> | ||
<property name="format" display-name-key="Address Formatting" description-key="Provide pattern to format Full Address" of-type="SingleLine.Text" usage="input" required="true" /> | ||
<property name="street1" display-name-key="Street 1" description-key="Street 1" of-type="SingleLine.Text" usage="bound" required="true" /> | ||
<property name="street2" display-name-key="Street 2" description-key="Street 2" of-type="SingleLine.Text" usage="bound" required="false" /> | ||
<property name="street2visible" usage="input" of-type="Enum" display-name-key="Street 2 is Visible" description-key="Select if Street 2 field is visible" required="true"> | ||
<value name="yes" display-name-key="Yes" description-key="Yes, Street 2 is visible" default="true">yes</value> | ||
<value name="no" display-name-key="No" description-key="No, Street 2 is not visible">no</value> | ||
</property> | ||
<property name="street3" display-name-key="Street 3" description-key="Street 3" of-type="SingleLine.Text" usage="bound" required="false" /> | ||
<property name="street3visible" usage="input" of-type="Enum" display-name-key="Street 3 is Visible" description-key="Select if Street 3 field is visible" required="true"> | ||
<value name="yes" display-name-key="Yes" description-key="Yes, Street 3 is visible" default="true">yes</value> | ||
<value name="no" display-name-key="No" description-key="No, Street 3 is not visible">no</value> | ||
</property> | ||
<property name="city" display-name-key="City" description-key="City" of-type="SingleLine.Text" usage="bound" required="true" /> | ||
<property name="county" display-name-key="County" description-key="County" of-type="SingleLine.Text" usage="bound" required="false" /> | ||
<property name="countyvisible" usage="input" of-type="Enum" display-name-key="County is Visible" description-key="Select if County field is visible" required="true"> | ||
<value name="yes" display-name-key="Yes" description-key="Yes, County is visible" default="true">yes</value> | ||
<value name="no" display-name-key="No" description-key="No, County is not visible">no</value> | ||
</property> | ||
<type-group name="StringOrOptionset"> | ||
<type>SingleLine.Text</type> | ||
<type>OptionSet</type> | ||
</type-group> | ||
<property name="state" display-name-key="State/Province" description-key="State/Province" of-type-group="StringOrOptionset" usage="bound" required="false" /> | ||
<property name="statevisible" usage="input" of-type="Enum" display-name-key="State/Province is Visible" description-key="Select if State/Province field is visible" required="true"> | ||
<value name="yes" display-name-key="Yes" description-key="Yes, State/Province is visible" default="true">yes</value> | ||
<value name="no" display-name-key="No" description-key="No, State/Province is not visible">no</value> | ||
</property> | ||
<property name="zipcode" display-name-key="Zip Code" description-key="Zip Code" of-type="SingleLine.Text" usage="bound" required="true" /> | ||
<property name="country" display-name-key="Country" description-key="Country" of-type-group="StringOrOptionset" usage="bound" required="false" /> | ||
<property name="countryvisible" usage="input" of-type="Enum" display-name-key="Country is Visible" description-key="Select if Country field is visible" required="true"> | ||
<value name="yes" display-name-key="Yes" description-key="Yes, Country is visible" default="true">yes</value> | ||
<value name="no" display-name-key="No" description-key="No, Country is not visible">no</value> | ||
</property> | ||
<resources> | ||
<code path="index.ts" order="1"/> | ||
<css path="../node_modules/bootstrap/dist/css/bootstrap.min.css" order="1" /> | ||
<css path="css/CompositeAddress.css" order="2" /> | ||
</resources> | ||
</control> | ||
</manifest> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
.compositeAddress { | ||
background: transparent; | ||
border-style: none; | ||
color: #000000; | ||
font-size: 1.0rem; | ||
font-weight: 600; | ||
height: 2.5rem; | ||
line-height: 2.5rem; | ||
width: 98%; | ||
padding-left: 0.5em; | ||
padding-right: 0.5em; | ||
outline: 0 !important; | ||
} | ||
|
||
.compositeAddressFocused { | ||
background: transparent; | ||
border-width: 1px; | ||
border-color: #000000; | ||
color: #000000; | ||
font-size: 1.0rem; | ||
height: 2.5rem; | ||
line-height: 2.5rem; | ||
width: 98%; | ||
padding-left: 0.5em; | ||
padding-right: 0.5em; | ||
outline: 0 !important; | ||
} | ||
|
||
.d365StyleInput { | ||
background: transparent; | ||
border-width: 1px; | ||
border-color: #000000; | ||
color: #000000; | ||
font-size: 1.0rem; | ||
height: 2.5rem; | ||
line-height: 2.5rem; | ||
padding-left: 0.5em; | ||
padding-right: 0.5em; | ||
outline: 0 !important; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
import { IInputs, IOutputs } from "./generated/ManifestTypes"; | ||
import * as $ from "jquery"; | ||
import * as Bootstrap from "bootstrap"; | ||
|
||
export class CompositeAddress implements ComponentFramework.StandardControl<IInputs, IOutputs> { | ||
|
||
private notifyOutputChanged: () => void; | ||
private mainAddressField: HTMLInputElement; | ||
private fullAddressFormat: string; | ||
private currentValues: any = new Object(); | ||
private currentLabels: any = new Object(); | ||
private allControls: any = new Object(); | ||
|
||
constructor() { | ||
|
||
} | ||
|
||
public init(context: ComponentFramework.Context<IInputs>, | ||
notifyOutputChanged: () => void, | ||
state: ComponentFramework.Dictionary, | ||
container: HTMLDivElement) { | ||
Bootstrap.hasOwnProperty("test"); | ||
|
||
this.notifyOutputChanged = notifyOutputChanged; | ||
|
||
this.fullAddressFormat = context.parameters.format.raw; | ||
|
||
this.mainAddressField = document.createElement("input"); | ||
this.mainAddressField.className = "compositeAddress"; | ||
this.mainAddressField.readOnly = true; | ||
|
||
if (context.parameters.value.raw !== null) { | ||
this.mainAddressField.value = context.parameters.value.raw.replace(/\n/gm, ', '); | ||
} else { | ||
this.mainAddressField.value = "---"; | ||
} | ||
|
||
this.mainAddressField.addEventListener("mouseenter", () => { | ||
this.mainAddressField.className = "compositeAddressFocused"; | ||
}); | ||
this.mainAddressField.addEventListener("mouseleave", () => { | ||
this.mainAddressField.className = "compositeAddress"; | ||
}); | ||
|
||
container.appendChild(this.mainAddressField); | ||
|
||
let popupDiv = document.createElement("div"); | ||
|
||
this.addControltoPopup(context.parameters.street1, popupDiv, "street1"); | ||
|
||
if (context.parameters.street2visible.raw === "yes") { | ||
this.addControltoPopup(context.parameters.street2, popupDiv, "street2"); | ||
} | ||
|
||
if (context.parameters.street3visible.raw === "yes") { | ||
this.addControltoPopup(context.parameters.street3, popupDiv, "street3"); | ||
} | ||
|
||
this.addControltoPopup(context.parameters.city, popupDiv, "city"); | ||
|
||
if (context.parameters.countyvisible.raw === "yes") { | ||
this.addControltoPopup(context.parameters.county, popupDiv, "county"); | ||
} | ||
|
||
if (context.parameters.statevisible.raw === "yes") { | ||
this.addControltoPopup(context.parameters.state, popupDiv, "state"); | ||
} | ||
|
||
this.addControltoPopup(context.parameters.zipcode, popupDiv, "zipcode"); | ||
|
||
if (context.parameters.countryvisible.raw === "yes") { | ||
this.addControltoPopup(context.parameters.country, popupDiv, "country"); | ||
} | ||
|
||
$(this.mainAddressField).popover({ | ||
content: popupDiv, | ||
html: true, | ||
placement: "bottom" | ||
}); | ||
} | ||
|
||
private addControltoPopup(addressProperty: ComponentFramework.PropertyTypes.Property, | ||
container: HTMLDivElement, | ||
controlId: string): void { | ||
let rowDiv = document.createElement("div"); | ||
rowDiv.className = "form-group"; | ||
container.appendChild(rowDiv); | ||
|
||
if (addressProperty.type === "SingleLine.Text") { | ||
let stringAddressProperty = addressProperty as ComponentFramework.PropertyTypes.StringProperty; | ||
|
||
let fieldLabel = document.createElement("label"); | ||
fieldLabel.innerText = stringAddressProperty.attributes === undefined ? "" : stringAddressProperty.attributes.DisplayName; | ||
rowDiv.appendChild(fieldLabel); | ||
|
||
let inputControl = document.createElement("input"); | ||
inputControl.id = controlId; | ||
inputControl.className = "form-control d365StyleInput"; | ||
inputControl.setAttribute("placeholder", "---"); | ||
inputControl.value = stringAddressProperty.raw; | ||
inputControl.addEventListener("change", () => { | ||
let currentText = inputControl.value; | ||
|
||
this.currentValues[controlId] = currentText; | ||
this.currentLabels[controlId] = currentText === null ? "" : currentText; | ||
|
||
this.formatAddress(); | ||
|
||
this.notifyOutputChanged(); | ||
}); | ||
|
||
this.currentValues[controlId] = stringAddressProperty.raw; | ||
this.currentLabels[controlId] = stringAddressProperty.formatted; | ||
this.allControls[controlId] = inputControl; | ||
|
||
rowDiv.appendChild(inputControl); | ||
} else if (addressProperty.type === "OptionSet") { | ||
let optionsetAddressProperty = addressProperty as ComponentFramework.PropertyTypes.OptionSetProperty; | ||
|
||
let fieldLabel = document.createElement("label"); | ||
fieldLabel.innerText = optionsetAddressProperty.attributes === undefined | ||
? "" | ||
: optionsetAddressProperty.attributes.DisplayName; | ||
rowDiv.appendChild(fieldLabel); | ||
|
||
let selectControl = document.createElement("select"); | ||
selectControl.id = controlId; | ||
selectControl.className = "form-control d365StyleInput"; | ||
|
||
let option: HTMLOptionElement = document.createElement("option"); | ||
option.innerHTML = "---Select---"; | ||
selectControl.add(option); | ||
|
||
if (optionsetAddressProperty.attributes !== undefined) { | ||
optionsetAddressProperty.attributes.Options.forEach(optionRecord => { | ||
option = document.createElement("option"); | ||
option.innerHTML = optionRecord.Label; | ||
option.value = optionRecord.Value.toString(); | ||
|
||
if (optionsetAddressProperty.raw === optionRecord.Value) { | ||
option.selected = true; | ||
} | ||
|
||
selectControl.add(option); | ||
}); | ||
} | ||
|
||
selectControl.addEventListener("change", () => { | ||
if (selectControl.value === "") { | ||
this.currentValues[controlId] = null; | ||
this.currentLabels[controlId] = ""; | ||
} else { | ||
this.currentValues[controlId] = parseInt(selectControl.value); | ||
this.currentLabels[controlId] = selectControl.options[selectControl.selectedIndex].label; | ||
} | ||
|
||
this.formatAddress(); | ||
|
||
this.notifyOutputChanged(); | ||
}); | ||
|
||
this.currentValues[controlId] = optionsetAddressProperty.raw; | ||
this.currentLabels[controlId] = optionsetAddressProperty.formatted; | ||
this.allControls[controlId] = selectControl; | ||
|
||
rowDiv.appendChild(selectControl); | ||
} else { | ||
throw new Error(`Composite Address: can't render control for ${addressProperty.type} type of field`); | ||
} | ||
} | ||
|
||
private formatAddress(): void { | ||
let formattedAddress = this.fullAddressFormat; | ||
|
||
formattedAddress = formattedAddress.replace(/\\n/gm, '\n'); | ||
|
||
for (let propName in this.currentLabels) { | ||
let propertyValue = this.currentLabels[propName] === null ? "" : this.currentLabels[propName]; | ||
|
||
formattedAddress = formattedAddress.replace(`{${propName}}`, propertyValue); | ||
} | ||
|
||
this.currentValues.value = formattedAddress; | ||
this.mainAddressField.value = formattedAddress.replace(/\n/gm, ', '); | ||
} | ||
|
||
public updateView(context: ComponentFramework.Context<IInputs>): void { | ||
let formatChanged: boolean = false; | ||
|
||
context.updatedProperties.forEach(updatedProperty => { | ||
if (!context.parameters.hasOwnProperty(updatedProperty)) { | ||
return ; | ||
} | ||
|
||
formatChanged = true; | ||
|
||
let updatedPropertyObject = (context.parameters as any)[updatedProperty]; | ||
|
||
if (this.allControls.hasOwnProperty(updatedProperty)) { | ||
$(this.allControls[updatedProperty]).val(updatedPropertyObject.raw); | ||
} | ||
|
||
this.currentValues[updatedProperty] = updatedPropertyObject.raw; | ||
this.currentLabels[updatedProperty] = updatedPropertyObject.formatted; | ||
}); | ||
|
||
if (formatChanged) { | ||
this.formatAddress(); | ||
this.notifyOutputChanged(); | ||
} | ||
} | ||
|
||
public getOutputs(): IOutputs { | ||
return this.currentValues as IOutputs; | ||
} | ||
|
||
public destroy(): void { | ||
// Add code to cleanup control if necessary | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/bin | ||
/obj |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<PropertyGroup> | ||
<PowerAppsTargetsPath>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps</PowerAppsTargetsPath> | ||
</PropertyGroup> | ||
|
||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" /> | ||
<Import Project="$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Solution.props" Condition="Exists('$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Solution.props')" /> | ||
|
||
<PropertyGroup> | ||
<ProjectGuid>3ecce81b-4fc4-4969-8051-d95b273ab784</ProjectGuid> | ||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion> | ||
<!--Remove TargetFramework when this is available in 16.1--> | ||
<TargetFramework>net462</TargetFramework> | ||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle> | ||
</PropertyGroup> | ||
|
||
<!-- Solution Packager overrides, un-comment to use: SolutionPackagerType (Managed, Unmanaged, Both) | ||
<PropertyGroup> | ||
<SolutionPackageType>Managed</SolutionPackageType> | ||
</PropertyGroup> | ||
--> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.PowerApps.MSBuild.Solution" Version="0.*" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\.gitignore" /> | ||
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\bin\**" /> | ||
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\obj\**" /> | ||
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\*.cdsproj" /> | ||
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\*.cdsproj.user" /> | ||
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\*.sln" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Include="$(MSBuildThisFileDirectory)\**" Exclude="@(ExcludeDirectories)" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\CompositeAddress_PCF.pcfproj" /> | ||
</ItemGroup> | ||
|
||
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" /> | ||
<Import Project="$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Solution.targets" Condition="Exists('$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Solution.targets')" /> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<ImportExportXml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | ||
<Entities /> | ||
<Roles /> | ||
<Workflows /> | ||
<FieldSecurityProfiles /> | ||
<Templates /> | ||
<EntityMaps /> | ||
<EntityRelationships /> | ||
<OrganizationSettings /> | ||
<optionsets /> | ||
<CustomControls /> | ||
<EntityDataProviders /> | ||
<Languages> | ||
<Language>1033</Language> | ||
</Languages> | ||
</ImportExportXml> |
Oops, something went wrong.