Skip to content

Commit

Permalink
Merge pull request #19 from carfup/anycompositefields
Browse files Browse the repository at this point in the history
v1.3.0.0 : AnyCompositefields
  • Loading branch information
carfup authored May 19, 2020
2 parents a3b829f + 9028cf3 commit 386ef14
Show file tree
Hide file tree
Showing 17 changed files with 6,624 additions and 3 deletions.
14 changes: 14 additions & 0 deletions AnyCompositeFields/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules

# generated directory
**/generated

# output directory
/out

# msbuild output directories
/bin
/obj
60 changes: 60 additions & 0 deletions AnyCompositeFields/AnyCompositeFIelds/ControlManifest.Input.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<control namespace="Carfup" constructor="AnyCompositeFIelds" version="0.0.61" display-name-key="Carfup.AnyCompositeFIelds" description-key="AnyCompositeFIelds will allow you to display any stack of fields as composite rendering." control-type="standard" preview-image="img/preview.png">
<!-- property node identifies a specific, configurable piece of data that the control expects from CDS -->
<property name="FieldToAttachControl" display-name-key="FieldToAttachControl" description-key="Field to attach the control to" of-type-group="strings" usage="bound" required="true" />
<property name="separator" display-name-key="Values separator" description-key="Separator to split the mapped values (for a space, put %20)" of-type="SingleLine.Text" usage="input" required="true" default-value="%20" />
<property name="returnCompositeValue" display-name-key="Return the composite value ?" description-key="Do you want to retrieve the composite value ?" of-type="Enum" usage="input" required="true" default-value="true">
<value name="true" display-name-key="True" description-key="true">true</value>
<value name="false" display-name-key="False" description-key="false">false</value>
</property>
<property name="field1" display-name-key="Field 1" description-key="Field 1 to be used" of-type-group="strings" usage="bound" required="true" />
<property name="field2" display-name-key="Field 2" description-key="Field 2 to be used" of-type-group="strings" usage="bound" required="true" />
<property name="field3" display-name-key="Field 3" description-key="Field 3 to be used" of-type-group="strings" usage="bound" required="false" />
<property name="field4" display-name-key="Field 4" description-key="Field 4 to be used" of-type-group="strings" usage="bound" required="false" />
<property name="field5" display-name-key="Field 5" description-key="Field 5 to be used" of-type-group="strings" usage="bound" required="false" />
<property name="field6" display-name-key="Field 6" description-key="Field 6 to be used" of-type-group="strings" usage="bound" required="false" />
<property name="field7" display-name-key="Field 7" description-key="Field 7 to be used" of-type-group="strings" usage="bound" required="false" />
<property name="field8" display-name-key="Field 8" description-key="Field 8 to be used" of-type-group="strings" usage="bound" required="false" />
<type-group name="strings">
<type>SingleLine.Email</type>
<type>SingleLine.Text</type>
<type>SingleLine.Phone</type>
</type-group>
<!--
Property node's of-type attribute can be of-type-group attribute.
Example:
<type-group name="numbers">
<type>Whole.None</type>
<type>Currency</type>
<type>FP</type>
<type>Decimal</type>
</type-group>
<property name="sampleProperty" display-name-key="Property_Display_Key" description-key="Property_Desc_Key" of-type-group="numbers" usage="bound" required="true" />
-->
<resources>
<code path="index.ts" order="1" />
<resx path="strings/AnyCompositeFIelds.1033.resx" version="1.0.0" />
<resx path="strings/AnyCompositeFIelds.1036.resx" version="1.0.0" />
<!-- UNCOMMENT TO ADD MORE RESOURCES
<css path="css/AnyCompositeFIelds.css" order="1" />
<resx path="strings/AnyCompositeFIelds.1033.resx" version="1.0.0" />
-->
</resources>
<feature-usage>
<uses-feature name="WebAPI" required="true" />
</feature-usage>
<!-- UNCOMMENT TO ENABLE THE SPECIFIED API
<feature-usage>
<uses-feature name="Device.captureAudio" required="true" />
<uses-feature name="Device.captureImage" required="true" />
<uses-feature name="Device.captureVideo" required="true" />
<uses-feature name="Device.getBarcodeValue" required="true" />
<uses-feature name="Device.getCurrentPosition" required="true" />
<uses-feature name="Device.pickFile" required="true" />
<uses-feature name="Utility" required="true" />
<uses-feature name="WebAPI" required="true" />
</feature-usage>
-->
</control>
</manifest>
13 changes: 13 additions & 0 deletions AnyCompositeFields/AnyCompositeFIelds/EntitiesDefinition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export class CompositeValue{
public separator : string;
public returnCompositeValue : boolean;
public fullValue : string;
public fieldValue1? : any;
public fieldValue2? : any;
public fieldValue3? : any;
public fieldValue4? : any;
public fieldValue5? : any;
public fieldValue6? : any;
public fieldValue7? : any;
public fieldValue8? : any;
}
160 changes: 160 additions & 0 deletions AnyCompositeFields/AnyCompositeFIelds/components/CompositeControl.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import * as React from 'react';
import { Callout, Stack, TextField, DefaultButton, BaseButton, Button, IStackStyles, ITextFieldStyles, ICalloutContentStyles, DirectionalHint } from 'office-ui-fabric-react';
import { CompositeValue } from '../EntitiesDefinition';

export interface ICompositeControlProps {
disabled : boolean;
visible: boolean;
compositeValue : CompositeValue;
doneLabel : string;
randNumber: number;
onClickedDone : (compositeValue? : CompositeValue) => void;
}

export interface IBCompositeControlState {
showCallout: boolean,
compositeValue : CompositeValue;
}

const stackStyles: Partial<IStackStyles> = { root: { width: "100%" } };
const textFieldStyles: Partial<ITextFieldStyles> = { root: { width: "100%" } };
const calloutStyles: Partial<ICalloutContentStyles> = { root: { width: "300px" } };

export default class CompositeControl extends React.Component<ICompositeControlProps, IBCompositeControlState> {
constructor(props: ICompositeControlProps) {
super(props);
this.state = {
showCallout : false,
compositeValue : this.props.compositeValue,
};
}



render(){
return (
<Stack horizontal id="acf_compositestack" styles={stackStyles}>
<TextField
value={this.state.compositeValue.fullValue}
readOnly={true}
onClick={() => this.setState({ showCallout : true }) }
styles={textFieldStyles}
id={"acf_compositeFullValue"+this.props.randNumber}
/>
{this.state.showCallout && (
<Callout
target={"#acf_compositeFullValue"+this.props.randNumber}
onDismiss={() => this.setState({ showCallout : false }) }
styles={calloutStyles}
directionalHint={DirectionalHint.topCenter}
>
<Stack style={{margin : "10px"}}>

{this.state.compositeValue.fieldValue1.attributes.LogicalName != undefined && <TextField
value={this.state.compositeValue.fieldValue1.raw!}
label={this.state.compositeValue.fieldValue1.attributes.DisplayName}
id={"acf_fieldValue1"}
onChange={this.onChangeField}
disabled={this.props.disabled || this.state.compositeValue.fieldValue1.disabled!}
styles={textFieldStyles}
/>}
{this.state.compositeValue.fieldValue2.attributes.LogicalName != undefined && <TextField
value={this.state.compositeValue.fieldValue2.raw!}
label={this.state.compositeValue.fieldValue2.attributes.DisplayName}
id={"acf_fieldValue2"}
onChange={this.onChangeField}
disabled={this.props.disabled || this.state.compositeValue.fieldValue2.disabled!}
styles={textFieldStyles}
/>}
{this.state.compositeValue.fieldValue3.attributes.LogicalName != undefined && <TextField
value={this.state.compositeValue.fieldValue3.raw!}
label={this.state.compositeValue.fieldValue3.attributes.DisplayName}
id={"acf_fieldValue3"}
onChange={this.onChangeField}
disabled={this.props.disabled || this.state.compositeValue.fieldValue3.disabled!}
styles={textFieldStyles}
/>}
{this.state.compositeValue.fieldValue4.attributes.LogicalName != undefined && <TextField
value={this.state.compositeValue.fieldValue4.raw!}
label={this.state.compositeValue.fieldValue4.attributes.DisplayName}
id={"acf_fieldValue4"}
onChange={this.onChangeField}
disabled={this.props.disabled || this.state.compositeValue.fieldValue4.disabled!}
styles={textFieldStyles}
/>}
{this.state.compositeValue.fieldValue5.attributes.LogicalName != undefined && <TextField
value={this.state.compositeValue.fieldValue5.raw!}
label={this.state.compositeValue.fieldValue5.attributes.DisplayName}
id={"acf_fieldValue5"}
onChange={this.onChangeField}
disabled={this.props.disabled || this.state.compositeValue.fieldValue5.disabled!}
styles={textFieldStyles}
/>}
{this.state.compositeValue.fieldValue6.attributes.LogicalName != undefined && <TextField
value={this.state.compositeValue.fieldValue6.raw!}
label={this.state.compositeValue.fieldValue6.attributes.DisplayName}
id={"acf_fieldValue6"}
onChange={this.onChangeField}
disabled={this.props.disabled || this.state.compositeValue.fieldValue6.disabled!}
styles={textFieldStyles}
/>}
{this.state.compositeValue.fieldValue7.attributes.LogicalName != undefined && <TextField
value={this.state.compositeValue.fieldValue7.raw!}
label={this.state.compositeValue.fieldValue7.attributes.DisplayName}
id={"acf_fieldValue7"}
onChange={this.onChangeField}
disabled={this.props.disabled || this.state.compositeValue.fieldValue7.disabled!}
styles={textFieldStyles}
/>}
{this.state.compositeValue.fieldValue8.attributes.LogicalName != undefined && <TextField
value={this.state.compositeValue.fieldValue8.raw!}
label={this.state.compositeValue.fieldValue8.attributes.DisplayName}
id={"acf_fieldValue8"}
onChange={this.onChangeField}
disabled={this.props.disabled || this.state.compositeValue.fieldValue8.disabled!}
styles={textFieldStyles}
/>}

<DefaultButton text={this.props.doneLabel} onClick={this.onClick} style={{marginTop:'10px',alignSelf: "flex-end"}}/>
</Stack>

</Callout>
)}
</Stack>
);
}

private onChangeField = (event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string | undefined) : void => {
// @ts-ignore
let target = event.target.id.replace('acf_', '');
const compositeValue = {...this.state}.compositeValue;
// @ts-ignore
compositeValue[target].raw = newValue!;
this.setState({compositeValue : compositeValue});
}

private onClick = (event: React.MouseEvent<HTMLDivElement | HTMLAnchorElement | HTMLButtonElement | BaseButton | Button | HTMLSpanElement, MouseEvent>) : void => {
const compositeValue = {...this.state}.compositeValue;
this.buildFullValue(compositeValue);
this.setState({showCallout : false});
this.props.onClickedDone(this.state.compositeValue);
}

private buildFullValue = (compositeValue : CompositeValue) : void => {
let arrayValues = [];

let i = 1;
for(i ; i<9; i++){
// @ts-ignore
if(compositeValue["fieldValue"+i]!.raw!){
// @ts-ignore
arrayValues.push(compositeValue["fieldValue"+i].raw);
}
}

compositeValue.fullValue = arrayValues.join(compositeValue.separator);

this.setState({compositeValue : compositeValue});
}
};

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 386ef14

Please sign in to comment.