FlexFieldEditor= function( editorOptions ) {
let instance = this;
instance.rootElement = null;
instance.data = editorOptions.data;
instance.dataChanged = false;
instance.onSaved = editorOptions.onSaved;
if( ! instance.onSaved ) {
instance.onSaved = function() {
}
}
instance.onCancelled = editorOptions.onCancelled;
if( ! instance.onCancelled ) {
instance.onCancelled = function() {
}
}
instance.flexType = "standard";
if( editorOptions.flexType ) {
instance.flexType = editorOptions.flexType
}
instance.fieldId = instance.data.fieldId;
let fieldData = $.extend( true, {}, instance.data );
delete fieldData.config;
let fieldConfig = {};
if( instance.data.config ) {
let configSplit = instance.data.config.split(",");
configSplit.forEach( function( co ) {
let avp = co.split( "=" );
fieldConfig[avp[0]] = null;
if( avp.length > 0 ) {
fieldConfig[avp[0]] = avp[1];
}
})
}
instance.rootElement = $("
");
instance.lookupValuesDataGrid = null;
let leftItems = [
{ dataField : "label", editorType : "dxTextBox", isRequired : true },
{
dataField : "sortRank", editorType : "dxNumberBox", isRequired : true, editorOptions : {
width : 40,
showSpinButtons : false,
min : 1, max : 999
}
},
{
dataField : "active", editorType : "dxRadioGroup", editorOptions : {
layout : "horizontal",
items : [
{ text : "Yes", value : "Y" },
{ text : "No", value : "N" }
],
valueExpr : "value"
}
},
{
dataField : "required", editorType : "dxRadioGroup", editorOptions : {
layout : "horizontal",
items : [
{ text : "Yes", value : "Y" },
{ text : "No", value : "N" }
],
valueExpr : "value"
}
},
{
dataField : "searchable",
visible : instance.flexType == "standard" ? true : false,
editorType : "dxRadioGroup",
editorOptions : {
disabled : fieldData.type == "CHECKBOX" || fieldData.type == "SELECT" || fieldData.type == "RADIO" ? false : true,
layout : "horizontal",
items : [
{ text : "Yes", value : "Y" },
{ text : "No", value : "N" }
],
valueExpr : "value"
}
}
];
if( instance.flexType != "standard" ) {
let sourceFieldStore = Fse.Data.newDataSource( { object : "WRK.flexFields", keyField : "fieldId", paginate : false, objectParams : {
domain : instance.data.domain,
category : instance.data.category,
type : "SELECT,RADIO"
} }).store();
let sourceFieldDataSourceConfig = {
store : sourceFieldStore,
paginate : false
}
if( instance.data.fieldId ) {
sourceFieldDataSourceConfig.filter = [ "fieldId", "<>", instance.data.fieldId ];
}
let sourceFieldValueDS = null;
if( instance.data.sourceFieldId ) {
sourceFieldValueDS = Fse.Data.newDataSource( { object : "WRK.flexFieldLookupValues", paginate : false, keyField : "text", objectParams : { domain : instance.data.domain, category : instance.data.category, fieldId : instance.data.sourceFieldId } })
}
console.log( "SourceFieldValueDS", sourceFieldValueDS );
leftItems.push( { itemType : "empty" }, {
itemType : "group",
colCount : 2,
items : [
{
dataField : "sourceFieldId", label : { text : "Conditional Field" }, editorType : "dxSelectBox", editorOptions : {
placeholder : "select field",
showClearButton : true,
dataSource : sourceFieldDataSourceConfig,
displayExpr : "label",
valueExpr : "fieldId"
}
},
{
dataField : "sourceFieldValue", label : { text : "Conditional Value" }, editorType : "dxSelectBox", editorOptions : {
placeholder : "select value",
showClearButton : true,
displayExpr : "text",
valueExpr : "text",
dataSource : sourceFieldValueDS
}
}
]
})
}
let rightItems = [];
if( fieldData.type == "TEXT" || fieldData.type == "TEXTAREA" ) {
rightItems.push( {
dataField : "maxLength", editorType : "dxNumberBox", isRequired : true, editorOptions : {
min : 1, max : 1000, width : 50
}
});
rightItems.push( {
dataField : "format", editorType : "dxSelectBox", editorOptions : {
displayExpr : "format",
valueExpr : "format",
width : 100,
dataSource : { store : { type : "array", data : [ { format : "string"}, { format : "email" }, { format : "url" }, { format : "date" }, { format : "decimal" }, { format : "phone" } ], key : "format" }}
}
});
}
if( fieldData.type == "TEXTAREA" ) {
fieldData.cols = parseInt( fieldConfig.cols );
fieldData.rows = parseInt( fieldConfig.rows );
rightItems.push (
{
dataField : "rows", editorType : "dxNumberBox", isRequired : true, editorOptions : {
min : 1, max : 10, width : 40
}
},
{
dataField : "cols", label : { text : "Columns" }, editorType : "dxNumberBox", isRequired : true, editorOptions : {
min : 1, max : 10, width : 40
}
}
);
} else if ( fieldData.type == "TEXT" ) {
fieldData.size = parseInt( fieldConfig.size );
rightItems.push( {
dataField : "size", label : { text : "Field Width" }, editorType : "dxNumberBox", isRequired : true, editorOptions : {
min : 1, max : 100, width : 40
}
})
}
if( fieldData.type == "RADIO" || fieldData.type == "SELECT" || fieldData.type == "CHECKBOX" ) {
let lookupColumns = [
// these are auto generated now { dataField : "value", caption : "Code", validationRules: [{ type: 'required' }], editorOptions : { maxLength : 75 } },
{ dataField : "text", caption : "Display", validationRules: [{ type: 'required' }], editorOptions : { maxLength : 75 } },
{ dataField : "sortRank", visible : true, caption : "Order", width : 70, dataType : "number", format : "fixedPoint", validationRules: [{ type: 'required' }], editorOptions : { min : 1, max : 999, showSpinControls : false } }
];
if( instance.flexType != "standard" ) {
let sourceFieldStore = Fse.Data.newDataSource( { object : "WRK.flexFields", keyField : "fieldId", paginate : false, objectParams : {
domain : instance.data.domain,
category : instance.data.category,
type : "SELECT,RADIO"
} }).store();
let sourceFieldDataSourceConfig = {
store : sourceFieldStore,
paginate : false
}
if( instance.data.fieldId ) {
sourceFieldDataSourceConfig.filter = [ "fieldId", "<>", instance.data.fieldId ];
}
lookupColumns.push(
{ dataField : "sourceFieldId", caption : "Conditional Field", editorType : "dxSelectBox", lookup : {
dataSource : sourceFieldDataSourceConfig,
displayExpr : "label",
valueExpr : "fieldId",
allowClearing : true
},
editorOptions : {
placeholder : "select field"
},
setCellValue: function(newData, value) {
this.defaultSetCellValue(newData, value);
}
},
{ dataField : "sourceFieldValue", caption : "Conditional Label", editorType : "dxSelectBox",
editorOptions :{
placeholder : "select value",
displayExpr : "text",
valueExpr : "text"
} }
)
}
rightItems.push( {
dataField : "lookupValues", label : { visible : false },
template : function( options ) {
let form = options.component;
let formData = form.option( "formData" );
let lookupValues = formData.lookupValues;
instance.lookupValuesDataGrid = $("
").dxDataGrid( {
height : 200,
scrolling : { mode : "virtual" },
dataSource : { store : { type : "array", data : lookupValues, key : "value" } },
editing : {
allowUpdating : true,
allowAdding : true,
newRowPosition : "last",
allowDeleting : true,
mode : "row",
useIcons : true,
editRowKey : "value",
texts : {
addRow : "Add a possible selection",
deleteRow : "Delete possible selection",
editRow : "Edit possible selection"
}
},
showBorders : true,
rowAlternationEnabled : true,
columns : lookupColumns,
onEditorPreparing : function( e ) {
if( e.dataField == "sourceFieldValue") {
if( e.row.data.sourceFieldId ) {
e.editorOptions.dataSource = Fse.Data.newDataSource( { object : "WRK.flexFieldLookupValues", paginate : false, keyField : "text", objectParams : { domain : instance.data.domain, category : instance.data.category, fieldId : e.row.data.sourceFieldId } })
e.editorOptions.value = e.value;
} else {
e.editorOptions.dataSource = null;
e.editorOptions.value = null;
}
}
console.log( e );
},
onCellClick : function( e ) {
if( e.rowType != "data" ) return;
if( e.column.dataField != "text" ) return;
let ready = $.Deferred();
if( e.component.hasEditData() ) {
e.component.saveEditData().done( function() {
ready.resolve();
})
} else {
ready.resolve();
}
// if( editRowKey ) return; // already editing
ready.done( function() {
e.component.editRow( e.rowIndex );
})
},
onInitNewRow : function( e ) {
// goal is to assign the next sortRank value
let maxSortRank = 0;
let formData = form.option( "formData" );
let formLookupValues = formData.lookupValues;
if( formLookupValues ) {
formLookupValues.forEach( function( lv ) {
if( lv.sortRank > maxSortRank ) {
maxSortRank = lv.sortRank;
}
})
}
let valueSeq = ( new Date() ).getTime();
let newValue = `F${formData.fieldId}_${valueSeq}`;
let newSortRank = maxSortRank;
if( newSortRank == 0 ) {
newSortRank = 10; // start at 10
} else {
// go to the next highest multiple of 10
newSortRank = newSortRank - ( newSortRank % 10 ) + 10;
if( newSortRank == maxSortRank ) {
newSortRank += 10;
}
}
e.data.sortRank = newSortRank;
e.data.value = newValue;
},
onSaved : function( e ) {
let savedKey = e.changes[e.changes.length - 1 ].key;
let items = e.component.getDataSource().items();
form.updateData( { "lookupValues": items } );
let vr = e.component.getVisibleRows();
let currentKey = null;
let nextRow = null;
vr.forEach( function( row ) {
if( !nextRow && currentKey ) {
nextRow = row;
console.log( "next row", row );
}
if( row.key == savedKey ) {
currentKey = savedKey;
}
})
if( nextRow ) {
e.component.editRow( nextRow.rowIndex );
}
},
onRowInserted : function( e ) {
e.component.addRow();
},
onToolbarPreparing : function( e ) {
if( ! e.toolbarOptions.items ) {
e.toolbarOptions.items = [];
}
e.toolbarOptions.items.push( {
location : "before",
template : function() {
return $("
").text( "Possible Selections");
}
})
}
}).dxDataGrid( "instance" );
if( ! lookupValues || lookupValues.length == 0 ) {
let p = instance.lookupValuesDataGrid.addRow();
p.done( function( addRow ) {
console.log( "addRow", addRow );
})
}
return instance.lookupValuesDataGrid.element();
}
},
{
dataField : "lookupValueSortMode",
editorType : "dxRadioGroup",
label : {
text : "Reorder (on save)"
},
editorOptions : {
layout : "horizontal",
valueExpr : "value",
displayExpr : "text",
items : [ { value : "alpha", text : "by Alpha" } , { value : "numeric", text : "by Numeric" }, { value : "manual", text : "using Order" } ]
}
}
)
}
instance.form = $("
").dxForm( {
colCount : 2,
items : [
{
itemType : "group",
items : leftItems
},
{
itemType : "group",
items : rightItems
}
],
formData : fieldData,
onFieldDataChanged : function( e ) {
console.log( e );
if( e.dataField == "sourceFieldId" ) {
let sourceFieldValueEditor = e.component.getEditor( "sourceFieldValue" );
let dataSource = null;
if( e.value ) {
dataSource = Fse.Data.newDataSource( { object : "WRK.flexFieldLookupValues", paginate : false, keyField : "value", objectParams : { domain : instance.data.domain, category : instance.data.category, fieldId : e.value } })
}
sourceFieldValueEditor.option( "dataSource", dataSource );
e.component.updateData( "sourceFieldValue", null );
}
instance.dataChanged = true;
instance.saveButton.option( { disabled : false })
}
}).dxForm( "instance")
instance.saveButton = $("
").dxButton( {
text : "Save Field",
disabled : true,
type : "default",
onClick : function( e ) {
/*
if( instance.lookupValuesDataGrid && instance.lookupValuesDataGrid.hasEditData() ) {
alert( "You must save or cancel the selection you are editing before saving.")
return;
}
*/
let vr = instance.form.validate();
if( ! vr.isValid ) {
return;
}
instance.save();
}
}).dxButton( "instance" );
instance.toolbar = $("
").dxToolbar( {
items : [
{
location : "after",
widget : "dxButton",
options : {
text : "Cancel",
onClick : function( e ) {
instance.onCancelled();
}
}
},
{
location : "after",
template : function() {
return instance.saveButton.element();
}
}
]
}).dxToolbar( "instance" );
instance.rootElement
.append( instance.form.element() )
.append( instance.toolbar.element().css( { "margin-top" : "5px" }) );
}
FlexFieldEditor.prototype.constructor = FlexFieldEditor;
FlexFieldEditor.prototype.element = function() {
return this.rootElement;
}
FlexFieldEditor.prototype.isDirty = function() {
return this.dataChanged;
}
FlexFieldEditor.prototype.save = function() {
let instance = this;
let flexFieldData = instance.form.option( "formData" );
Fse.Ajax.performAction( {
object : "WRK.saveFlexField",
data : flexFieldData
}).done( function() {
instance.dataChanged = false;
instance.saveButton.option( { "disabled" : true } )
Fse.UI.toast( `Field Saved`, "success", 1000 );
instance.onSaved();
})
}