").dxButton( {
text : "Go to",
width : 55,
onClick : function( ee ) {
instance.returnDistributor( options.data.cdr_recordId, "goto" );
}
})
} else {
button = $("
").dxButton( {
width : 55,
text : "Add",
onClick : function( e ) {
instance.initiateAddFrom1FS( options.data );
}
})
}
container.append( button );
}
}
]
}).dxDataGrid( "instance" );
instance.search1FSResultList.element().css( { "margin-top" : "15px" } ).appendTo( content );
return content;
}
NewDistributorProfileDialog.prototype.addDistributorTemplate = function() {
let instance = this;
let crmItems = [
{ dataField : "territoryId", label : { text : "Sales Territory", location : "left" }, isRequired : true,
editorType : "dxSelectBox", editorOptions : {
valueExpr : "TerritoryID",
displayExpr : "territoryName",
// dataSource : Fse.Data.newDataSource( { object : "TER.salesTerritories", keyField : "TerritoryID" }),
dataSource : Fse.Data.getLocalDataSource( "$.salesTerritories" ),
searchEnabled : true,
searchExpr : "territoryName",
searchMode : "contains"
}
},
{ dataField : "salesRepId", label : { text : "Sales Rep", location : "left" },
editorType : "dxSelectBox", editorOptions : {
valueExpr : "fspro_userId",
displayExpr : "fullName",
//dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "CRM.salesRepList", keyField : "fspro_userId", displayExpr : "cmFullName" } ),
dataSource : Fse.Data.getLocalDataSource( "$.salesRepList" ),
searchEnabled : true,
searchExpr : "fullName",
searchMode : "contains",
}
},
{ dataField : "priority", label : { text : "Priority", location : "left" },
editorType : "dxSelectBox", editorOptions : {
dataSource : [
{ text : "A+", value : "*" },
{ text : "A", value : "A" },
{ text : "B", value : "B" },
{ text : "C", value : "C" },
{ text : "D", value : "D" }
],
displayExpr : "text",
valueExpr : "value",
value : "C",
width : 75
}
},
{ dataField : "classificationId", label : { location : "left", text : "Classification" }, editorType : "dxSelectBox",
editorOptions : {
dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "CDR.classifications", keyField : "classificationId" } ),
//dataSource : Fse.Data.getLocalDataSource( "$.distributorList" ),
searchExpr : "name",
searchMode : "contains",
displayExpr : "name",
valueExpr : "classificationName"
}
}
]
let internetItems = [];
let validURLPattern = /^https?:\/\/([-\w\.]+)+(:\d+)?(:\w+)?(@\d+)?(@\w+)?([-\w\.]+)(\/([\w\/_\.]*(\?\S+)?)?)?/i;
let internetLocations = [
{
dataField : "url",
label : "Website", placeholder : "Website URL", maxLength : 150,
type : "url"
},
{
dataField : "companyEmail",
label : "Email", placeholder : "email address", maxLength : 150,
validationRules : [ { type : "email", message : "Invalid Email" } ]
},
{
dataField : "facebook",
label : "Facebook", placeholder : "Facebook URL or ID",
type : "url",
socialMediaPlatform : "facebook"
},
{
dataField : "instagram",
label : "Instagram", placeholder : "Instagram URL or ID",
type : "url",
socialMediaPlatform : "instagram"
},
{
dataField : "twitter",
label : "\"X\"", placeholder : "\"X\" URL or ID (1-15 char)",
type : "url",
socialMediaPlatform : "twitter"
},
{
dataField : "tiktok",
label : "TikTok",placeholder : "TikTok URL or ID",
type : "url",
socialMediaPlatform : "tiktok",
},
{
dataField : "youtube",
label : "YouTube", placeholder : "YouTube URL or ID (10 char)",
type : "url",
socialMediaPlatform : "youtube"
},
{
dataField : "linkedIn",
label : "LinkedIn", placeholder : "LinkedIn URL", maxLength : 150,
type : "url",
socialMediaPlatform : "linkedin"
}
];
internetLocations.forEach( function( il ) {
let item = {
dataField : il.dataField,
label : { text : il.label },
template : function( options, itemElement ) {
let customEditors = options.component.option( "customEditors" );
if( ! customEditors ) {
customEditors = {};
}
let textBoxConfig = {
maxLength : il.maxLength ? il.maxLength : null,
placeholder : il.placeholder ? il.placeholder : null,
onValueChanged : function( e ) {
options.component.updateData( options.dataField, e.value );
}
}
if( il.type == "url" ) {
textBoxConfig.onOptionChanged = function( e ) {
if( e.name == "validationErrors" ) {
let validationErrors = e.value;
if( validationErrors ) {
let errorHandled = false;
validationErrors.forEach( function( ve ) {
if( errorHandled ) return;
if( ve.type == "pattern" ) {
if( ve.socialMediaPlatform ) {
let value = ve.value;
if( ! value.match( validURLPattern ) ) {
value = ve.urlTransform( value );
if( value.match( validURLPattern ) && value.match( ve.pattern ) ) {
errorHandled = true;
setTimeout( function() {
e.component.option( "value", value )
}, 10 );
}
}
} else {
let value = ve.value;
if( ! value.match( /^https+:\/\//i) ) {
value = value.replace( /^.*:/i, '' ).replace( /^\/\//, '' );
value = `https://${value}`
errorHandled = true;
setTimeout( function() {
e.component.option( "value", value )
}, 10 );
}
}
}
})
}
}
}
}
let textBox = $("
").dxTextBox( textBoxConfig ).dxTextBox( "instance" );
let validationRules = il.validationRules ? il.validationRules : null;
if( ! validationRules && il.type == "url" ) {
validationRules = [];
let message = "Invalid URL";
if( il.socialMediaPlatform && Fse.CRM.socialMediaPlatforms[il.socialMediaPlatform] ) {
let pattern = Fse.CRM.socialMediaPlatforms[il.socialMediaPlatform].urlRegEx;
let urlTransform = Fse.CRM.socialMediaPlatforms[il.socialMediaPlatform].urlTransform;
urlTransform ? urlTransform : function( v ) { return v };
message = `Invalid ${il.placeholder}`;
validationRules.push(
{ type : "pattern", socialMediaPlatform : il.socialMediaPlatform, message : message, pattern : pattern, urlTransform : urlTransform }
)
}
validationRules.push(
{ type : "pattern", message : message, pattern : validURLPattern }
);
}
textBox.element().dxValidator( {
validationGroup : options.component.option( "validationGroup" ),
validationRules : validationRules
})
/*
textBox.element().dxValidator( {
validationGroup : options.component.option( "validationGroup" ),
validationRules : il.validationRules ? il.validationRules : null
})
let prefix = null;
if( il.prefix ) {
prefix = $("
").css( { "font-style" : "italic", "display" : "inline-block", "margin-right" : "5px", "width" : "95px", "text-align" : "right" } ).text( il.prefix );
textBox.element().css( { "display" : "inline-block" } );
}
*/
let editorContainer = $("
");
/*
if( prefix ) {
editorContainer.append( prefix );
}
*/
editorContainer.append( textBox.element() );
itemElement.append( editorContainer );
customEditors[il.dataField] = textBox;
options.component.option( "customEditors", customEditors );
}
}
internetItems.push( item );
});
let countyDS = Fse.Data.getLocalDataSource( "$.counties" );
countyDS.filter( [
[ "state", "=", '?' ],
"and",
[ "countryId", "=", 0 ]
] );
let companyItems = [];
companyItems.push(
{ dataField : "dstCompanyType", label : { text : "Company Type", location : "left" }, isRequired : true,
editorType : "dxSelectBox", editorOptions : {
dataSource : [
{ value : "P", text : "Parent Company" },
{ value : "B", text : "Branch Location" },
{ value : "G", text : "Buying Group" },
{ value : "O", text : `Other Direct Ship ${getText( 'DISTRIBUTOR' )}`},
{ value : "R", text : `Re-${getText( 'DISTRIBUTOR' )}`},
{ value : "S", text : "Special Account" },
{ value : "c", text : "Regional Distribution Center" },
{ value : "x", text : "Non-1FS Applicable" },
],
displayExpr : "text",
valueExpr : "value",
value : "C",
width : 150
}
},
{
dataField : "cdr_dstcode", label : { location : "left", text : "Ship to: / Internal ID" }, isRequired : false, editorType : "dxTextBox", editorOptions : {
maxLength : 30,
xwidth : 200,
}
},
{
dataField : "companyName", isRequired : true, editorType : "dxTextBox", editorOptions : {
maxLength : 150,
xwidth : 200
}
},
{
dataField : "address", label : { text : "Address Line 1" }, isRequired : true, editorType : "dxTextBox", editorOptions : {
maxLength : 75,
xwidth : 200
}
}, {
dataField : "address2", label : { location : "left", text : "Address Line 2" },
editorType : "dxTextBox", editorOptions : {
maxLength : 75,
xwidth : 200
}
}
)
if( instance.showCountryField ) {
companyItems.push(
{
dataField : "countryId", label : { text : "Country" },
editorType : "dxSelectBox", editorOptions : {
dataSource : Fse.Data.newDataSource( { object : "UT.countries", keyField : "countryId" } ),
value : instance.defaultCountryId,
displayExpr : "countryAbbrev",
valueExpr : "countryId",
width : 100
}
});
}
companyItems.push(
{ label : { text : "Location", location : "left"},
template : function( options, itemElement ) {
let cityTextBox = $("
").dxTextBox( {
width : 150,
placeholder : "city",
onValueChanged : function( e ) {
options.component.updateData( "city", e.value );
}
}).css( { "display" : "inline-block" } );
cityTextBox.dxValidator( {
validationGroup : options.component.option( "validationGroup" ),
validationRules : [ { type : "required", message : "City is required" } ]
})
let stateSelectBox = $("
").dxSelectBox( {
width : 80,
dataSource : Fse.Data.newDataSource( { object : "UT.states", keyField : "state", objectParams : { countryId : instance.defaultCountryId } } ),
placeholder : "state",
displayExpr : "state",
valueExpr : "state",
searchEnabled : true,
searchExpr : "state",
searchMethod : "startswith",
showClearButton : true,
validationGroup : options.component.option( "validationGroup" ),
onValueChanged : function( e ) {
options.component.updateData( "state", e.value );
}
}).css( { "display" : "inline-block", "margin-left" : "8px" } );
stateSelectBox.dxValidator( {
validationGroup : options.component.option( "validationGroup" ),
validationRules : [ { type : "required", message : "State is required" } ]
})
let zipCodeTextBox = $("
").dxTextBox( {
width : 90,
placeholder : "postal code",
validationGroup : options.component.option( "validationGroup" ),
onValueChanged : function( e ) {
options.component.updateData( "zipCode", e.value );
}
}).css( { "display" : "inline-block", "margin-left" : "8px" } );
zipCodeTextBox.dxValidator( {
validationGroup : options.component.option( "validationGroup" ),
validationRules : [ { type : "required", message : "Zip code is required" } ]
})
// add the editors to the component's options so we can find them later
let customEditors = options.component.option( "customEditors" );
if( ! customEditors ) {
customEditors = {};
}
customEditors.zipCode = zipCodeTextBox.dxTextBox( "instance" );
customEditors.city = cityTextBox.dxTextBox( "instance" );
customEditors.state = stateSelectBox.dxSelectBox( "instance" );
options.component.option( "customEditors", customEditors );
itemElement.append( cityTextBox )
.append( stateSelectBox )
.append( zipCodeTextBox )
}
},
{ dataField : "phone",
label : { text : "Main Phone" },
editorOptions : {
maxLength : 30,
width : 150,
/*
mask: '000-000-0000',
maskChar : ' ',
maskInvalidMessage: 'The phone must have a correct phone format',
useMaskedValue : true,
*/
inputAttr: {
name: "cdr_dstPhone"
},
/*
onValueChanged : function( e ) {
if( e.value ) {
if( e.value.replace( /\s|-/g, '' ) == '' ) {
e.component.option( "value", null );
}
}
}
*/
onValueChanged : function( e ) {
if( e.component.option( "fseReformatted") ) {
e.component.option( "fseReformatted", false );
} else {
let formatted = Fse.UI.reformatPhone( e.value );
if( formatted != e.value ) {
e.component.option( {
"fseReformatted" : true,
value : formatted
} )
}
}
}
},
disabled : instance.coreFieldsDisabled
/*
, validationRules : [
{
type: 'pattern',
pattern: /^\d{3}-\d{3}-\d{4}$/,
message: 'The phone must have a correct phone format',
ignoreEmptyValue : true,
}
]
*/
}
);
/*
let numUnitsItems = [
{
label : { location : "left", text : "Num. Units" },
template : function( options, itemElement ) {
let customEditors = options.component.option( "customEditors" );
if( ! customEditors ) {
customEditors = {};
}
let currentYear = ( new Date() ).getFullYear();
let fieldDefs = [
{ label : currentYear - 1, dataField : "numUnit_LY" },
{ label : currentYear, dataField : "numUnit_TY" },
{ label : currentYear + 1, dataField : "numUnit_NY" },
];
fieldDefs.forEach( function( fd ) {
let editor = $("
").dxTextBox( {
width : 50,
value : 1,
onValueChanged : function( e ) {
options.component.updateData( fd.dataField, e.value );
}
}).dxTextBox( "instance" );
editor.element().dxValidator( {
validationGroup : options.component.option( "validationGroup" ),
validationRules : [
{ type : "required", message : "A number zero or greater is required" },
{ type : "numeric", message : "A number zero or greater is required" },
{ type : "range", message : "A number zero or greater is required", min : 0 }
]
})
let label = $("
").text( fd.label );
label.css( { "padding-right" : "8px" })
editor.element().css( { "display" : "inline-block", "margin-right" : "10px" } )
itemElement.append( label ).append( editor.element() )
customEditors[fd.dataField] = editor;
})
options.component.option( "customEditors", customEditors );
}
}
];
*/
let memberGroupItems = [
/*
{
colSpan : 2,
label : { text : "Food Mgmt. Co" },
dataField : "cmc_distributorId",
editorType : "dxSelectBox",
editorOptions : {
placeholder : "self managed",
dataSource : Fse.Data.newDataSource( { object : "CDR.cmcs", keyField : "distributorId" }),
searchEnabled : true,
searchExpr : "companyName",
searchMode : "contains",
valueExpr : "distributorId",
displayExpr : "companyName",
showClearButton : true,
}
},
{ label : { text : "ID" },
dataField : "cmc_memberNbr",
editorType : "dxTextBox",
editorOptions : {
maxLength : 50,
disabled : true
}
},
{ label : { text : "Since" },
dataField : "cmc_affiliationDate",
editorType : "dxDateBox",
editorOptions : {
disabled : true
}
},
*/
{
colSpan : 2,
label : { text : "Buying Group" },
dataField : "uniqueId",
editorType : "dxSelectBox",
editorOptions : {
placeholder : "none",
dataSource : Fse.Data.newDataSource( { object : "CDR.buyingGroups", keyField : "uniqueId" }),
searchEnabled : true,
searchExpr : "bgName",
searchMode : "contains",
valueExpr : "fslBuyingGroupId",
displayExpr : "bgName",
showClearButton : true,
}
},
/*
{ label : { text : "ID" },
dataField : "gpo_memberNbr",
editorType : "dxTextBox",
editorOptions : {
maxLength : 50,
disabled : true
}
},
{ label : { text : "Since" },
dataField : "gpo_affiliationDate",
editorType : "dxDateBox",
editorOptions : {
disabled : true
}
}
*/
];
let otherItems = [
/*
{ dataField : "oprSegment", label : { location : "left", text : "Segment" }, editorType : "dxSelectBox",
editorOptions : {
showClearButton : true,
dataSource : Fse.Data.newDataSource( { object : "CDR.segments", keyField : "clientSegId" } ),
searchExpr : "segmentPath",
searchMode : "contains",
searchEnabled : true,
displayExpr : "segmentPath",
valueExpr : "clientSegId"
}
},
{ dataField : "cuisineId", label : { location : "left", text : "Cuisine" }, editorType : "dxSelectBox",
editorOptions : {
showClearButton : true,
dataSource : Fse.Data.newDataSource( { object : "CDR.cuisines", keyField : "cuisineId" } ),
searchExpr : "cuisine",
searchEnabled : true,
searchMode : "contains",
displayExpr : "cuisine",
valueExpr : "cuisineId"
}
}
*/
]
let contactItems = instance.addDistributorTemplateContactItems();
instance.addDistributorForm = $("").dxForm( {
validationGroup : "addDistributorForm",
items : [
{
itemType : "tabbed",
tabPanelOptions : { deferRendering : false }, // this is so all of the fields are rendered at the start
tabs : [
{ title : "Company",
items : [
{ itemType : "group",
items : crmItems,
},
{ itemType: "group",
items : companyItems
},
/*
{ itemType : "group",
items : internetItems
},
/*
{ itemType : "group",
colCount : 3,
items : distributionItems
},
{ itemType : "group",
items : numUnitsItems
},
*/
{ itemType : "group",
colCount : 4,
items : memberGroupItems,
},
{ itemType : "group",
items : otherItems,
}
]
},
{ title : "Contact", items : contactItems }
]
}
],
onFieldDataChanged : function( e ) {
let customEditors = e.component.option( "customEditors" );
if( customEditors && customEditors[e.dataField] ) {
// push the data into the custom editor
customEditors[e.dataField].option( "value", e.value );
}
if( e.dataField == "gpo_distributorId" || e.dataField == "cmc_distributorId" ) {
let fieldPrefix = e.dataField.split( "_" )[0];
let memberNbrEditor = e.component.getEditor( `${fieldPrefix}_memberNbr` );
let affiliationDateEditor = e.component.getEditor( `${fieldPrefix}_affiliationDate` );
let editorOptions = {
disabled : e.value ? false : true
}
if( editorOptions.disabled ) {
editorOptions.value = null;
}
memberNbrEditor.option( editorOptions );
affiliationDateEditor.option( editorOptions );
}
if( e.dataField == "zipCode" && e.value ) {
let territoryId = e.component.option( "formData").territoryId;
if( ! territoryId ) {
let salesTerritoryDS = Fse.Data.newDataSource( { object : "TER.salesTerritories", keyField : "territoryId", objectParams : { byZipCode : e.value } });
salesTerritoryDS.load().done( function( data ) {
if( data.length == 1 ) {
e.component.updateData( { territoryId : data[0].TerritoryID } );
}
})
}
}
if( e.dataField == "countryId" ) {
let editor = null;
let customEditors = e.component.option( "customEditors" );
if( customEditors ) {
editor = customEditors.state;
}
if( editor ) {
let countryId = e.value;
if( ! countryId ) {
countryId = 0;
}
let stateDataSource = Fse.Data.newDataSource( { object : "UT.states", keyField : "state", objectParams : { countryId : countryId } } );
let placeholder = "state";
if( countryId == 5 ) {
placeholder = "prov";
}
editor.option( { dataSource : stateDataSource, "value" : null, placeholder : placeholder } );
editor.repaint();
}
}
if( e.dataField == "state" ) {
let editor = e.component.getEditor( "county" );
if( editor ) {
let formData = e.component.option( "formData" );
let countyDataSource = editor.getDataSource();
let countyFilter = [];
if( formData.countryId ) {
countyFilter.push( [ "countryId", "=", formData.countryId ] )
} else {
countyFilter.push( [ "countryId", "=", 0 ] )
}
countyFilter.push( "and" );
if( formData.state ) {
countyFilter.push( [ "state", "=", formData.state ] );
} else {
countyFilter.push( ["state", "=", "?" ]);
}
countyDataSource.filter( countyFilter );
editor.option( "value", null );
}
}
/*
if( e.dataField.substring( 0, 8 ) == "contact." ) {
let editor = customEditors["contact.jobFunction"];
editor = e.component.getEditor( "contact.jobFunction" );
let validator = editor.element().dxValidator( "instance" );
console.log( validator );
console.log( "Contact Field Changed" );
}
*/
if( e.dataField == "contact.countryId" ) {
let stateEditor = e.component.getEditor( "contact.state" );
if( stateEditor ) {
let countryId = e.value;
if( ! countryId ) {
countryId = 0;
}
let placeholder = "state";
if( countryId == 5 ) {
placeholder = "prov";
}
let stateDataSource = Fse.Data.newDataSource( { object : "UT.states", keyField : "state", objectParams : { countryId : countryId } } );
stateEditor.option( { dataSource : stateDataSource, value : null, placeholder : placeholder });
stateEditor.repaint();
}
}
if( e.dataField == "contact.officeAddrSame" ) {
let disabled = e.value ? true : false;
["contact.address1","contact.address2","contact.countryId","contact.city","contact.state","contact.zipCode"].forEach( function( f ) {
let contactAddressEditor = e.component.getEditor( f );
if( contactAddressEditor ) {
contactAddressEditor.option( "disabled", disabled );
}
})
}
e.component.getEditor( "")
}
}).dxForm( "instance" );
return instance.addDistributorForm.element();
}
NewDistributorProfileDialog.prototype.contactFieldValidationCallback = function( v ) {
let instance = this;
let valid = true;
let isRequired = false;
let formData = instance.addDistributorForm.option( "formData" );
for( contactField in formData.contact ) {
if( formData.contact[contactField] ) {
if( instance.contactDefaults[contactField] && instance.contactDefaults[contactField] === formData.contact[contactField] )
continue;
isRequired = true;
break;
}
}
if( isRequired && ! v.value ) {
valid = false;
}
return valid;
}
NewDistributorProfileDialog.prototype.addDistributorTemplateContactItems = function() {
let instance = this;
let contactItems = [];
// the addContact value is determined by the presence of data
// contactItems.push( { label : { text : "Add Contact" }, dataField : "addContact", editorType : "dxCheckBox" });
contactItems.push ( {
label : { text : "Contact Name" },
template : function( options, itemElement ) {
/*
let salutationSelectBox = $("
").dxSelectBox( {
width : 90,
showClearButton : true,
hint : "salutation",
placeholder : null,
dataSource: [
{ text : "Mr." },
{ text : "Ms." },
{ text : "Miss" },
{ text : "Dr." },
{ text : "Chef" }
],
displayExpr: "text",
valueExpr : "text",
onValueChanged : function( e ) {
options.component.updateData( { "contact.salutation" : e.value } );
}
}).dxSelectBox("instance" )
salutationSelectBox.element().dxValidator( {
validationGroup : options.component.option( "validationGroup" )
})
*/
let firstNameTextBox = $("
").dxTextBox( {
width : 150,
//maxLength : 50,
placeholder : "first name",
onValueChanged : function( e ) {
options.component.updateData( { "contact.firstName" : e.value } );
}
}).dxTextBox( "instance");
firstNameTextBox.element().dxValidator( {
validationGroup : options.component.option( "validationGroup" ),
validationRules : [
{ type : "custom", reevaluate : true, message : "First Name is required",
validationCallback : function( v ) {
return instance.contactFieldValidationCallback( v );
}
}
]
})
let lastNameTextBox = $("
").dxTextBox( {
width : 150,
//maxLength : 50,
placeholder : "last name",
onValueChanged : function( e ) {
options.component.updateData( { "contact.lastName" : e.value } );
}
}).dxTextBox( "instance" )
lastNameTextBox.element().dxValidator( {
validationGroup : options.component.option( "validationGroup" )
})
let primaryContactCheckBox = $("
").dxCheckBox( {
text: "Check here to make this the primary contact",
//value: isPrimaryContact,
name: "primaryContactId",
value : true,
onValueChanged: function (e) {
//const previousValue = e.previousValue;
//const newValue = e.value;
options.component.updateData( "contact.primaryContactId", e.value );
}
}); //.css( { "display" : "block", "margin-left" : "8px" } );
let decisionMakerCheckBox = $("
").dxCheckBox( {
text: "Decision Maker",
onValueChanged: function (e) {
options.component.updateData( "contact.contactDecisionMaker", e.value );
}
}).dxCheckBox( "instance" )
itemElement
// .append( salutationSelectBox.element().css( { "display" : "inline-block" } ))
.append( firstNameTextBox.element().css( { "display" : "inline-block" } ))
.append( lastNameTextBox.element().css( { "display" : "inline-block", "margin-left" : "8px" } ))
.append(primaryContactCheckBox)
.append( $("
").append( decisionMakerCheckBox.element() ))
let customEditors = options.component.option( "customEditors" );
if( ! customEditors ) {
customEditors = {};
}
customEditors["contact.firstName"] = firstNameTextBox;
customEditors["contact.lastName"] = lastNameTextBox;
//customEditors["contact.primaryContactId"] = primaryContactCheckBox;
customEditors["contact.contactDecisionMaker"] = decisionMakerCheckBox;
options.component.option( "customEditors", customEditors );
}
})
contactItems.push(
{
dataField : "contact.caRelationshipRank",
label : { text : "Relationship Rank" },
editorType : "dxSelectBox",
editorOptions : {
dataSource : Fse.Data.newDataSource( { object : "CRM.contactRelationshipRanks", keyField : "caRelationshipRank" } ),
//dataSource : Fse.Data.getLocalDataSource( "$.contactRelationshipRanks"),
displayExpr : "caRelationshipRankText",
valueExpr : "caRelationshipRank",
searchEnabled : true,
searchExpr : "caRelationshipRankText",
searchMethod : "startswith",
showClearButton : true,
width : 150
}
}
);
contactItems.push(
{ dataField: "contact.email", label : { text : "Contact Email" }, editorType : "dxTextBox",
editorOptions : {
maxLength : 75,
width : 200
},
validationRules : [
{ type : "email" }
]
},
{ dataField: "contact.title", label : { text : "Contact Title" }, editorType : "dxTextBox",
editorOptions : {
maxLength : 75,
width : 200,
}
},
{
dataField : "contact.jobFunction",
label : { text : "Job Function" },
visible : Fse.Portal.getConfiguration( "CRM.CDR.hasJobFunctions" ),
editorType : "dxSelectBox",
editorOptions : {
dataSource : Fse.Data.newDataSource( { object : "CRM.contactJobFunctions", keyField : "caJobFunction", objectParams : { partnerTypes : "CDR" } } ),
//dataSource : Fse.Data.getLocalDataSource( "$.distributorContactJobFunctions"),
displayExpr : "caJobFunctionText",
valueExpr : "caJobFunction",
searchEnabled : true,
searchExpr : "caJobFunctionText",
searchMethod : "startswith",
showClearButton : true,
width : 150
},
validationRules : [
{ type : "custom", reevaluate : true, message : "Job Function is required",
validationCallback : function( v ) {
if( ! Fse.Portal.getConfiguration( "CRM.CDR.hasJobFunctions" ) ) {
return true;
}
return instance.contactFieldValidationCallback( v );
}
}
]
},
{ dataField : "contact.preferredCommunication",
label : { text : "Communication Pref." },
editorType: 'dxSelectBox',
editorOptions: {
width : 150,
dataSource: [
{ "dispValue": "Text" , "value": "T"},
{ "dispValue": "Email" ,"value": "E"},
{ "dispValue": "Phone", "value": "P"},
{ "dispValue": "Cell", "value": "C"}
],
showClearButton : true,
displayExpr: "dispValue",
valueExpr : "value",
placeholder : "no preference",
searchEnabled: true
}
},
{ label : { text : "Contact Phone" },
template : function( options, itemElement ) {
let phoneTextBox = $("
").dxTextBox( {
width : 150,
maxLength : 30,
/*
mask: '000-000-0000',
maskChar : ' ',
onValueChanged : function( e ) {
options.component.updateData( "contact.phone", e.value );
}
*/
onValueChanged : function( e ) {
if( e.component.option( "fseReformatted") ) {
e.component.option( "fseReformatted", false );
} else {
let formatted = Fse.UI.reformatPhone( e.value );
if( formatted != e.value ) {
e.component.option( {
"fseReformatted" : true,
value : formatted
} )
}else {
options.component.updateData( "contact.phone", e.value );
}
}
}
}).dxTextBox( "instance");
let phoneExtTextBox = $("
").dxTextBox( {
width : 60,
maxLength : 10,
onValueChanged : function( e ) {
options.component.updateData( "contact.phoneExt", e.value );
}
}).dxTextBox( "instance" );
itemElement
.append( phoneTextBox.element().css( { "display" : "inline-block" } ) )
.append( $("
").text( "Ext." ).css( { "padding-left" : "8px", "padding-right" : "8px" }) )
.append( phoneExtTextBox.element().css( { "display" : "inline-block" } ) );
let customEditors = options.component.option( "customEditors" );
if( ! customEditors ) {
customEditors = {};
}
customEditors["contact.phone"] = phoneTextBox;
customEditors["contact.phoneExt"] = phoneExtTextBox;
options.component.option( "customEditors", customEditors );
}
},
{ dataField: "contact.cell", label : { text : "Contact Mobile" }, editorType : "dxTextBox",
editorOptions : {
maxLength : 30,
width : 150,
//mask: '000-000-0000', maskChar : ' '
//, useMaskedValue : true
onValueChanged : function( e ) {
if( e.component.option( "fseReformatted") ) {
e.component.option( "fseReformatted", false );
} else {
let formatted = Fse.UI.reformatPhone( e.value );
if( formatted != e.value ) {
e.component.option( {
"fseReformatted" : true,
value : formatted
} )
}
}
}
}
},
)
let validURLPattern = /^https?:\/\/([-\w\.]+)+(:\d+)?(:\w+)?(@\d+)?(@\w+)?([-\w\.]+)(\/([\w\/_\.]*(\?\S+)?)?)?/i;
let internetLocations = [
{
dataField : "contact.linkedIn",
label : "LinkedIn", placeholder : "LinkedIn URL", maxLength : 150, width : 300,
type : "url",
socialMediaPlatform : "linkedin"
},
{
dataField : "contact.facebook",
label : "Facebook", placeholder : "Facebook URL or ID",
type : "url",
socialMediaPlatform : "facebook"
},
{
dataField : "contact.instagram",
label : "Instagram", placeholder : "Instagram URL or ID",
type : "url",
socialMediaPlatform : "instagram"
},
{
dataField : "contact.twitter",
label : "\"X\"", placeholder : "\"X\" URL or ID (1-15 char)",
type : "url",
socialMediaPlatform : "twitter"
},
{
dataField : "contact.tiktok",
label : "TikTok",placeholder : "TikTok URL or ID",
type : "url",
socialMediaPlatform : "tiktok",
},
{
dataField : "contact.youtube",
label : "YouTube", placeholder : "YouTube URL or ID (10 char)",
type : "url",
socialMediaPlatform : "youtube"
},
];
/*
let internetLocations = [
{ type : "url", dataField : "contact.linkedIn", label : "LinkedIn", maxLength : 150, width : 300, placeholder : "url", validationRules : [ { type : "pattern", message : "Invalid URL", pattern : validURLPattern }] },
{ dataField : "contact.facebook", label : "Facebook", prefix : "facebook.com/" },
{ dataField : "contact.instagram", label : "Instagram", prefix : "instagram.com/" },
{ dataField : "contact.twitter", label : "Twitter (X)", prefix : "twitter.com/" },
{ dataField : "contact.tiktok", label : "TikTok", prefix : "tiktok.com/@" },
{ dataField : "contact.youtube", label : "YouTube", prefix : "youtube.com/@" }
];
*/
internetLocations.forEach( function( il ) {
let item = {
dataField : il.dataField,
label : { text : il.label },
template : function( options, itemElement ) {
let customEditors = options.component.option( "customEditors" );
if( ! customEditors ) {
customEditors = {};
}
let textBoxConfig = {
maxLength : il.maxLength ? il.maxLength : null,
placeholder : il.placeholder ? il.placeholder : null,
width : il.width ? il.width : null,
onValueChanged : function( e ) {
options.component.updateData( options.dataField, e.value );
}
};
if( il.type == "url" ) {
textBoxConfig.onOptionChanged = function( e ) {
if( e.name == "validationErrors" ) {
let validationErrors = e.value;
if( validationErrors ) {
let errorHandled = false;
validationErrors.forEach( function( ve ) {
if( errorHandled ) return;
if( ve.type == "pattern" ) {
if( ve.socialMediaPlatform ) {
let value = ve.value;
if( ! value.match( validURLPattern ) ) {
value = ve.urlTransform( value );
if( value.match( validURLPattern ) && value.match( ve.pattern ) ) {
errorHandled = true;
setTimeout( function() {
e.component.option( "value", value )
}, 10 );
}
}
} else {
let value = ve.value;
if( ! value.match( /^https+:\/\//i) ) {
value = value.replace( /^.*:/i, '' ).replace( /^\/\//, '' );
value = `https://${value}`
errorHandled = true;
setTimeout( function() {
e.component.option( "value", value )
}, 10 );
}
}
}
})
}
}
/*
if( e.name == "validationErrors" ) {
let validationErrors = e.value;
if( validationErrors ) {
validationErrors.forEach( function( ve ) {
if( ve.type == "pattern" ) {
let value = ve.value;
if( ! value.match( /^https+:\/\//i) ) {
value = value.replace( /^.*:/i, '' ).replace( /^\/\//, '' );
value = `https://${value}`
console.log( `revised value ${value}` )
setTimeout( function() {
e.component.option( "value", value )
}, 10 );
}
}
})
}
}
*/
}
}
let textBox = $("").dxTextBox( textBoxConfig ).dxTextBox( "instance" );
let validationRules = il.validationRules ? il.validationRules : null;
if( ! validationRules && il.type == "url" ) {
validationRules = [];
let message = "Invalid URL";
if( il.socialMediaPlatform && Fse.CRM.socialMediaPlatforms[il.socialMediaPlatform] ) {
let pattern = Fse.CRM.socialMediaPlatforms[il.socialMediaPlatform].urlRegEx;
let urlTransform = Fse.CRM.socialMediaPlatforms[il.socialMediaPlatform].urlTransform;
urlTransform ? urlTransform : function( v ) { return v };
message = `Invalid ${il.placeholder}`;
validationRules.push(
{ type : "pattern", socialMediaPlatform : il.socialMediaPlatform, message : message, pattern : pattern, urlTransform : urlTransform }
)
}
validationRules.push(
{ type : "pattern", message : message, pattern : validURLPattern }
);
}
textBox.element().dxValidator( {
validationGroup : options.component.option( "validationGroup" ),
validationRules : validationRules
})
/*
textBox.element().dxValidator( {
validationGroup : options.component.option( "validationGroup" ),
validationRules : il.validationRules ? il.validationRules : null
})
*/
/*
let prefix = null;
if( il.prefix ) {
prefix = $("
").css( { "font-style" : "italic", "display" : "inline-block", "margin-right" : "5px", "width" : "95px", "text-align" : "right" } ).text( il.prefix );
textBox.element().css( { "display" : "inline-block" } );
}
*/
let editorContainer = $("
");
/*
if( prefix ) {
editorContainer.append( prefix );
}
*/
editorContainer.append( textBox.element() );
itemElement.append( editorContainer );
customEditors[il.dataField] = textBox;
options.component.option( "customEditors", customEditors );
}
}
contactItems.push( item );
});
contactItems.push(
{ dataField : "contact.preferredLanguage",
label : { text : "Preferred Language" },
editorType: 'dxSelectBox',
editorOptions: {
width : 150,
// dataSource : Fse.Data.newDataSource( { object : "CRM.languages", keyField : "languageCode" } ),
dataSource : Fse.Data.getLocalDataSource( "$.languages"),
displayExpr : "languageName",
valueExpr : "languageCode",
searchEnabled : true,
searchExpr : "languageName",
searchMethod : "startswith",
showClearButton : true,
placeholder : ""
}
}
)
contactItems.push(
{
dataField : "contact.officeAddrSame",
label : { text : "Location" },
editorType : "dxCheckBox",
editorOptions : {
text : "same as Company",
onValueChanged : function( e ) {
if( e.value ) {
} else {
}
}
}
},
{
dataField : "contact.address1", label : { text : "Address" }, isRequired : true, editorOptions : { maxLength : 75, xwidth : 150, disabled : true }
},
{
dataField : "contact.address2", label : { text : "Line 2" }, editorOptions : { maxLength : 75, xwidth : 150, disabled : true }
}
)
if( instance.showCountryField ) {
contactItems.push(
{
dataField : "contact.countryId", label : { text : "Country" },
editorType : "dxSelectBox", editorOptions : {
disabled : true,
dataSource : Fse.Data.newDataSource( { object : "UT.countries", keyField : "countryId" } ),
value : instance.defaultCountryId,
displayExpr : "countryAbbrev",
valueExpr : "countryId",
width : 100
}
}
);
}
contactItems.push(
{
dataField : "contact.city", label : { text : "City" }, isRequired : true, editorOptions : { maxLength : 75, xwidth : 100, disabled : true }
},
{
dataField : "contact.state", label : { text : instance.defaultStateLabel }, isRequired : true, editorType : "dxSelectBox",
editorOptions : {
disabled : true,
width : 80,
dataSource : Fse.Data.newDataSource( { object : "UT.states", keyField : "state", objectParams : { countryId : instance.defaultCountryId } } ),
placeholder : instance.defaultStatePlaceholder,
displayExpr : "state",
valueExpr : "state",
searchEnabled : true,
searchExpr : "state",
searchMethod : "startswith",
showClearButton : true
}
},
{
dataField : "contact.zipCode", label : { text : "Postal Code" }, isRequired : true, editorOptions : { maxLength : 10, width : 80, disabled : true }
}
)
return contactItems;
}
NewDistributorProfileDialog.prototype.matchedDistributorTemplate = function() {
let instance = this;
let content = $("
");
content.append( $("
" ).css( "font-size", "larger" ).text( "The distributor profile you are attempting to add already exists. Below is a brief view of the existing distributor profile." ));
instance.matchedDistributorForm = $("
").dxForm( {
readOnly : true,
items : [
"territoryName",
{ itemType : "group", colCount : 3,
items : [
{ dataField : "accountOwnerFullName", label : { text : "Account Owner "} },
{ dataField : "accountOwnerTitle", label : { text : "Title" }},
{ dataField : "accountOwnerEmail", label : { text : "Email"}}
],
},
"companyName", "address", "address2", "city", "state", "zipCode",
{ dataField : "recordSource", label : { text : "Source" } }
]
}).dxForm( "instance" );
content.append( instance.matchedDistributorForm.element() );
content.append( $("
").css( "font-size", "larger" ).text( "You can either use the existing distributor, revised your profile and try again, or add your distributor as a duplicate." ));
instance.dupActionForm = $("
").dxForm( {
items : [
{ dataField : "dupAction", label : { text : "Duplicate Action" }, isRequired : true, editorType : "dxSelectBox", editorOptions : {
placeholder : "select action",
dataSource : [
{ text : "Use Existing & Go to Distributor", value : "useThisOne" },
{ text : "Revise and try again", value : "revise" },
{ text : "Add as a duplicate", value : "allowDup" }
],
displayExpr : "text",
valueExpr : "value"
}
},
{
dataField : "allowDupReason", label : { text : "Reason for Duplicate" }, isRequired : true, editorType : "dxTextBox", editorOptions : {
maxLength : 200,
disabled : true
}
}
],
onFieldDataChanged : function( e ) {
if( e.dataField == "dupAction" ) {
let reasonOptions = {
disabled : true
}
if( e.value == "allowDup" ) {
reasonOptions.disabled = false;
reasonOptions.value = null;
}
e.component.getEditor( "allowDupReason" ).option( reasonOptions );
if( e.value == "revise" ) {
instance.backToDistributorAdd();
}
}
}
}).dxForm( "instance" );
content.append( instance.dupActionForm.element() )
return content;
}