# Create a JS plug-in for the edit page
The New Edit Page JS plugin contains the following extension scenarios:
- Modify the Field component
- Control the form flow
- Interception of business actions
# Modify the Field component
Example: Disable a field
export default {
// 字段判断
entry(context, field) {
return field.api_name == 'field_gq0EF__c'
},
// 渲染
render(context, field, value) {
return '<span>该字段不允许填写内容!!</span>';
}
}
# Control the form flow
Example: Suppose we store special data (serialized by JSON) with multiple lines of text, and the form needs to be JSON parsed when rendering, and then backfilled on other fields.
export default {
// 渲染之前
beforeRender(context) {
const value = context.getData('field_18288__c');
let data = null;
if (value) {
data = JSON.parse(value);
}
if (data) {
context.setData('field_gq0EF__c', data.test);
}
return Promise.resolve();
}
}
# Intercept business information
Example 1: Intercept the click event of the associated field object selection button and execute the customized object selection logic.
export default {
// 绑定点击事件
registerListener() {
this.addFieldClickListeners('field_hlqjV__c.selectObj');
},
// 点击处理
click(context, e) {
if (e.eventTarget === 'selectObj') {
FxUI.objectUIAction.selectObject('AccountObj', {
// ... 选对象参数,见API章节
}).then({
objectList
} => {
context.setData('field_hlqjV__c', objectList[0]._id);
context.setData('field_hlqjV__c__r', objectList[0].name);
});
}
}
}
Example 2: Intercept the click event of the delete button from the object data and decide whether to allow deletion based on the field value.
export default {
//绑定点击事件
registerListener() {
this.addMdClickListeners('object_R9tuj__c.delRow');
},
//点击处理
click(context, e, next) {
if (e.cellData.name !== '不允许删除') {
next();
}
}
}
# Modify the Field component
This type of requirement needs to be implemented through the following APIs:
# entry()
Parameter:
context: Object
: The context of the fieldfield: Object
: Field description information
Usage:
This hook defines which fields need to be re-rendered by the plugin. You can judge by the api_name of the field and the field type.
Example:
// 通过字段api_name判断
export default {
entry(context, field) {
return field.api_name === 'field_bbbb__c';
}
}
// 通过字段类型判断
export default {
entry(context, field) {
return field.type === 'text';
}
}
# render()
Parameter:
context: Object
: The context of the fieldfield: Object
: Field description informationvalue: *
: The value of the fieldwrapper: Object
: The rendered container DOM
Return:
You can return the rendered DOM string or DOM object, or you may not return it.
Usage:
View rendering functions
Example:
// 返回dom字符串
export default {
render(context, field, value) {
return '<span>hello fxiaoke</span>'
}
}
// 返回dom对象
export default {
render(context, field, value) {
var vm = new Vue({
render: h => h('div', 'hello fxiaoke')
}).$mount();
return vm.$el;
}
}
// 不返回结果
export default {
render(context, field, value, wrapper) {
var vm = new Vue({
render: h => h('div', 'hello fxiaoke')
}).$mount();
wrapper.appendChild(vm.$el);
}
}
# Complete example
export default {
entry(context, field) {
return field.api_name === 'field_aaaa__c' || field.api_name === 'field_bbbb__c';
},
render(context, field, value, wrapper) {
if(field.api_name === 'field_aaaa__c') {
return `
<input type="text" value="${value}" />
`
}else if(field.api_name === 'field_bbbb__c') {
const ipt = document.createElement('input');
ipt.value = value;
ipt.setAttribute('type', 'text');
wrapper.appendChild(ipt);
}
}
}
# Control the form flow
This type of requirement needs to be implemented through the following APIs:
# beforeParse()
Parameter:
context: Object
: The context of the fielddata: Object
: The data returned by the form interface, including information such as form layout and form backfill data
Return:
promise: Promise
The value of :p ROMISE is the processed data.
Usage:
beforeParse occurs after the interface is successfully invoked, before the response data is parsed.
export default {
...
beforeParse(context, data) {
output('beforeParse', arguments);
return new Promise(resolve => {
data.objectData.name = '新值';
resolve(data)
});
},
...
}
# beforeRender()
Parameter:
context: Object
: The context of the field
Return:
promise: Promise
: No need to pass data.
Usage:
beforeRender occurs after the data is parsed and before the view is rendered.
export default {
...
beforeRender() {
output('beforeRender', arguments);
return new Promise(resolve => {
resolve()
});
},
...
}
# rendered()
Parameter:
context: Object
: The context of the field
Return:
promise: Promise
: No need to pass data.
Usage:
Rendered occurs after the view is rendered.
export default {
...
rendered() {
output('rendered', arguments);
return new Promise(resolve => {
resolve()
});
},
...
}
# beforeSubmit()
Parameter:
context: Object
: The context of the fieldpostData: Object
: The data that needs to be submitted when the form is saved
Return:
promise: Promise
The value of :p ROMISE is the processed data.
Usage:
beforeSubmit occurs before the data is saved.
export default {
...
beforeSubmit: function(context, postData) {
output('beforeSubmit', arguments);
return new Promise(resolve => {
resolve(postData)
});
},
...
}
# submited()
Parameter:
context: Object
: The context of the fieldres: Object
: The data returned after the form data is saved
Return:
promise: Promise
The value of :p ROMISE is the processed data.
Usage:
Submitted occurs after the data is saved.
export default {
...
submited: function(context, res) {
output('submited', arguments);
return new Promise(resolve => {
resolve(res)
});
},
...
}
# validated(context, result)
Parameter:
context: Object
: The context of the fieldresult: Boolean
: Whether the verification passed
Return:
isPass: Boolean
: Whether the verification passed
Usage:
Validated happens after the built-in validation logic.
export default {
...
validated() {
output('beforeRender', arguments);
return true;
},
...
}
# getTitle(context, data)
Parameter:
context: Object
: The context of the fielddata: Object
:datadata.isEdit: Boolean
: Whether it is an edit or not
Return:
title: String
: The title of the form component.
Usage:
export default {
...
getTitle() {
output('beforeRender', arguments);
return '新标题';
},
...
}
# getMdColumnRenders(context, data)
Return:
rules: Object
: From Object Layout Rule
Usage:
The returned data is relatively complex.
export default {
...
getMdColumnRenders() {
return {
object_adlkjd__c: {
field_dlkjdd__c: {
depend_fields: ['field_aaaaa__c', 'field_bbbbb__c'],
render(val, data) {
return '<div>...</div>'
}
}
}
}
},
...
}
# Intercept business behavior
# registerListener()
Usage:
This method needs to be rewritten after the form is rendered.
export default {
registerListener() {
this.addFieldClickListeners('name');
}
}
# addFormClickListeners()
Parameter:
eventName: String
: Button apiName
Usage:
export default {
registerListener() {
this.addFormClickListeners('button_ccccc__c');
}
}
# addFieldClickListeners()
Parameter:
eventName: String
: Event name, in the format:fieldApiName.[btnName]
options: Object
: Other parametersoptions.selector: String
: Element selector
Usage:
Bind the click event on the field.
export default {
registerListener() {
this.addFieldClickListeners('field_ax3c__c.btnName');
this.addFieldClickListeners('field_ax3c__c', {
selector: '.btn'
});
}
}
Preset btnName:
- selectObj: Find the selection button for the associated field
export default {
registerListener() {
this.addFieldClickListeners('lookup_field__c.selectObj');
}
}
# addMdClickListeners()
Parameter:
eventName: String
: Event name, in the format:detailObjectApiName.[btnName]
Usage:
Bind the click event from the object.
export default {
registerListener() {
this.addMdClickListeners('object_bW95o__c.delRow');
this.addMdClickListeners('object_bW95o__c.singleAdd');
}
}
Preset btnName:
delRow:
Deletes the click event from the Object Data button
export default {
registerListener() {
this.addMdClickListeners('object_bW95o__c.delRow');
}
}
singleAdd:
Add a click event from the Object Data (Single) button
export default {
registerListener() {
this.addMdClickListeners('object_bW95o__c.singleAdd');
}
}
batchAdd:
Add click events from object data buttons (multiple bars) buttons
export default {
registerListener() {
this.addMdClickListeners('object_bW95o__c.batchAdd');
}
}
batchAddConfirm:
Bulk add click events from object data when selecting data to determine buttons
export default {
registerListener() {
this.addMdClickListeners('object_bW95o__c.batchAddConfirm');
}
}
copyRow:
Copies the click event from the object data button
export default {
registerListener() {
this.addMdClickListeners('object_bW95o__c.copyRow');
}
}
rowCell:
Click events for read-only fields
export default {
registerListener() {
this.addMdClickListeners('object_bW95o__c.rowCell');
}
}
# click()
Parameter:
- A handler for binding a form button click event
context: Object
: The context of the fielde: Object
: Event objecteventTarget: String
: button apiNameeventName: String
: Fixed value - clicktype: String
: Fixed value - form_originEvent
: The original event objectnext: Function
: The callback function, which continues the original logic, needs to be called manually
- A handler for binding field click events
context: Object
: The context of the fielde: Object
: Event objectfieldApiName: String
: field apiNamefieldValue: *
: The value of the fieldeventName: String
: Fixed value - clicktype: String
: Fixed value - field_originEvent
: The original event objectnext: Function
: The callback function, which continues the original logic, needs to be called manually
- A handler that binds the click event from the object form
context: Object
: The context of the fielde: Object
: Event objectcellData: Object
: Current dataobjectApiName: String
: From object apiNameeventTarget: String
: The business action performed by the buttoneventName: String
: Fixed value - clicktype: String
: Fixed value - mdnext: Function
: The callback function, which continues the original logic, needs to be called manually
Usage:
This method is called when a click is triggered and needs to be overridden.
export default {
registerListener() {
this.addFieldClickListeners('field_xxxx__c.btnName');
this.addFieldClickListeners('field_yyyy__c', {
selector: '.btn'
});
this.addMdClickListeners('object_bW95o__c.delRow');
this.addMdClickListeners('object_bW95o__c.singleAdd');
},
click(context, e, next) {
console.log(context);
console.log(e);
next(); //该方法可以用来阻塞原有的业务逻辑
}
}
# addFieldChangeListeners()
Parameter:
eventName: String
: Event name, in the format: .fieldApiName
options: Object
: Other parametersoptions.selector: String
: Element selector
Custom fields, you must pass selector to listen to the change event; The pre-made field will listen to the change event of the original input element by default.
Usage:
Bind the change event of the form on the field
export default {
registerListener() {
this.addFieldChangeListeners('field_xxxx__c');
this.addFieldChangeListeners('field_yyyy__c', {
selector: '.btn'
});
}
}
# addFieldValueChangeListeners(eventName)
Parameter:
eventName: String
:Event name, format:fieldApiName
Usage:
The value on the listening field changes.
export default {
registerListener() {
this.addFieldValueChangeListeners('owner');
}
}
Example:
If we want to bring the owner information to the main attribute (name), we need to monitor the change of the owner's value to modify the value of the main attribute in real time.
export default {
//绑定点击事件
registerListener() {
this.addFieldValueChangeListeners('owner');
},
//点击处理
change(context, e, next) {
console.log(arguments);
if (e.fieldApiName === 'owner' || e.type === 'data') {
let nameValue = context.getData('name').name;
if (nameValue){
const ownerValue = e.value;
const employee = FxUI.organization.getEmployeeById(ownerValue[0]);
nameValue = nameValue.replace(/-(.*?)$/, '') + '-' + employee.name;
context.setData('name', nameValue);
}
}
}
}
# change()
parameter:
context: Object
:Context of the fielde: Object
: event objectfieldApiName: String
: field apiNamefieldValue: *
: field valueeventName: String
: fixed value changetype: String
: fixed values field and data_originEvent
: original event object
Usage:
This method will be called when the form input box is out of focus, and you need to rewrite it.
export default {
registerListener() {
this.addFieldChangeListeners('field_xxxx__c');
this.addFieldChangeListeners('field_yyyy__c', {
selector: '.ipt'
});
},
change(context, e) {
console.log(context);
console.log(e);
}
}
# addFieldInputListeners()
parameter:
eventName: String
:Event name, format:fieldApiName
options: Object
:Other parametersoptions.selector: String
:Element Selector
If there is no selector, the input element in the field will be bound by default.
Usage:
The input event of the form on the bound field
export default {
registerListener() {
this.addFieldInputListeners('field_ax3c__c');
this.addFieldInputListeners('field_ax3c__c', {
selector: '.btn'
});
}
}
# input()
parameter:
context: Object
:Context of the fielde: Object
: Event objectfieldApiName: String
: field apiNamefieldValue: *
: The value of the fieldeventName: String
: Fixed value inputtype: String
: Fixed value field_originEvent
: The original event object
Usage:
This method will be called when the form input box is triggered to input characters, and you need to rewrite it.
export default {
registerListener() {
this.addFieldInputListeners('field_xxxx__c');
this.addFieldInputListeners('field_yyyy__c', {
selector: '.ipt'
});
},
input(context, e) {
console.log(context);
console.log(e);
}
}
# Complete example
export default {
registerListener() {
this.addFieldClickListeners('field_0zc2Z__c.selectObj');
this.addFieldChangeListeners('field_5X90M__c');
this.addFieldInputListeners('field_5X90M__c');
// only - class
this.addFieldChangeListeners('field_1G017__c', {
selector: '.ipt'
});
this.addFieldClickListeners('field_1G017__c');
},
click(context, e) {
console.log(context);
console.log(e);
},
change(context, e) {
console.log(context);
console.log(e);
},
input(context, e) {
console.log(context);
console.log(e);
}
}
# context
# getDescribe()
Return:
describe: Object
: The description of the objectapi_name: String
: The apiName of the objectdisplay_name: String
: The name of the objectfields: Object
: All fields of the object
Usage:
The method returns object description information for the current object.
const describe = context.getDescribe();
console.log(describe.api_name);
console.log(describe.fields);
# getFields()
Usage:
Returns all fields under the object.
const fields = context.getFields();
console.log(fields.name);
console.log(fields.owner);
# getDetailDescribeByApiName()
Parameter:
detail_api_name: String
: apiName from the object
Usage:
The method returns object description information from the object.
const describe = context.getDetailDescribeByApiName('detail_api_name');
console.log(describe.api_name);
console.log(describe.fields);
# getAllDetailDescribes()
Usage:
The method returns all the object description information from the object.
const describes = context.getAllDetailDescribes();
describes.forEach(describe => {
console.log(describe);
})
# getData()
Parameter:
fieldApiName: String
: apiName of the field (optional)
Usage:
The method returns the data for the main object.
const data = context.getData();
console.log(data.name);
console.log(data.owner);
const nameValue = context.getData('name');
console.log(nameValue);
# setData()
parameter:
fieldApiName: String | Object
:字段的apiNamevalue: *
:The value of the field
Usage:
Set data.
context.setData('name', 'fxiaoke');
context.setData({
'name': 'fxiaoke',
'owner': [1000]
});
# getDetailDataByApiName()
Parameter:
apiName: String
: The apiName of the objectrecordType: String
: The business type of the object (optional)
Return:
Data from the object under fixed apiName (fixed business type).
Usage:
Gets data from an object of a business type
let data = context.getDetailDataByApiName('object_ad3xs__c');
let data1 = context.getDetailDataByApiName('object_ad3xs__c', 'default__c');
# getAllDetailDatas()
Return:
Get all the data from the object.
Usage:
const data = context.getAllDetailDatas();
console.log(data);
# updateDetailDataByApiName(apiName, list)
Parameter:
apiName: String
: The apiName of the objectlist: Array
: All the data of the object, record_type in the data is required
Usage:
Updating all data from an object, deleting, adding, or updating can be done without triggering calculations and UI events
context.updateDetailDataByApiName(apiName, [{}]);