Standard Patterns for Client Side Scripts
This can be implemented using the standard fetch pattern:
cur_frm.add_fetch('customer', 'email_id', 'customer_email');
cur_frm.add_fetch('customer', 'cell_no', 'customer_cell_no');
Standard Form-level Triggers are
Some Examples:
cur_frm.cscript.refresh = function(doc, dt, dn) {
// set contextual help
cur_frm.clear_tip();
if(doc.city && !doc.location) cur_frm.set_tip("Its always a good idea to add location to the city");
}
Every input / field in the Form is an instance of the _f.Field. The reference to the field object can be got using cur_frm.fields_dict property. This is a dictionary that contains reference to all field objects by name or label (in case there is no name).
Properties of the field can be set by setting the df dictionary (which represents the DocField). Example:
var f = cur_frm.fields_dict['first_name']
f.df.hidden = 1;
f.refresh();
Field onchange triggers can be set by declaring a function in the cur_frm.cscript object (namespace). The function will be called when the onchange event will be triggered. The function will be passed 3 parameters
Example:
cur_frm.cscript.first_name(doc, dt, dn) {
if(doc.first_name.length < 3) {
msgprint("First Name should atleast be 3 characters long.")
}
}
If a filter is to be added to validate values that can be set by Link fields, it is necessary to overload the exiting query method. This can be done by setting the get_query method on the Field object. Example:
// standard field
cur_frm.fields_dict['test_link'].get_query = function(doc,dt,dn) {
return "SELECT tabDocType.name FROM tabDocType WHERE IFNULL(tabDocType.issingle,0)=0 AND tabDocType.name LIKE '%s'"
}
// field in a grid
cur_frm.fields_dict['test_grid'].grid.get_field('my_link').get_query = function(doc,dt,dn) {
return "SELECT tabDocType.name FROM tabDocType WHERE IFNULL(tabDocType.issingle,0)=0 AND tabDocType.name LIKE '%s'"
}
Contextual help can be set using the _f.Frm.set_tip(), _f.Frm.append_tip(), _f.Frm.clear_tip() methods. See Examples:
cur_frm.cscript.refresh = function(doc, doctype, docname) {
cur_frm.clear_tip("")
if(doc.status="Draft") {
cur_frm.set_tip("This is a Draft, to publish, please check on 'Published' before saving")
}
if(doc.is_popular="Yes") {
cur_frm.append_tip("This post is popular!")
}
}
Custom UI Objects can be added to forms by using the HTML field. The object can be added in the form wrapper and reset with latest values on the refresh event. Example:
cur_frm.cscript.refresh = function(doc, dt, dn) {
var cs = cur_frm.cscript;
if(!cs.my_object) {
// lets add a listing
cs.my_object = new Listing();
..
..
}
cs.my_object.refresh();
}
Get list of child records for the given parent record where:
Get the field metadata (DocField format) for the given field and given record.
Note: Separate metadata is maintained for each field of each record. This is because metadata can be changed by a script only for one record. For example, a field may be hidden in record A but visible in record B. Hence same metadata cannot be referenced for the two records. Example:
f = get_field(doc.doctype, 'first_name', doc.name);
f.hidden = 1;
refresh_field('first_name');
Update the values in the current record by calling a remote method. Example Client Side:
cur_frm.cscript.contact_person = function(doc, cdt, cdn) {
if(doc.contact_person) {
var arg = {'customer':doc.customer_name,'contact_person':doc.contact_person};
get_server_fields('get_contact_details',docstring(arg),'',doc, cdt, cdn, 1);
}
}
Server side version:
def get_contact_details(self, arg):
arg = eval(arg)
contact = sql("select contact_no, email_id from `tabContact` where contact_name = '%s' and customer_name = '%s'" %(arg['contact_person'],arg['customer']), as_dict = 1)
ret = {
'contact_no' : contact and contact[0]['contact_no'] or '',
'email_id' : contact and contact[0]['email_id'] or ''
}
return str(ret)
Similar to get_server_fields, but no serverside required:
cur_frm.cscript.item_code = function(doc, dt, dn) {
var d = locals[dt][dn];
$c_get_values({
fields:'description,uom' // fields to be updated
,table_field:'sales_bom_items' // [optional] if the fields are in a table
,select:'description,stock_uom' // values to be returned
,from:'tabItem'
,where:'name="'+d.item_code+'"'
}, doc, dt, dn);
}
The standard Form UI Engine can be overridden using the templates. The template is HTML code and can be set in the template field of the DocType. To render fields in the template, Element IDs must be set in a specific pattern. The pattern is
See Example:
<h1>Contact Form</h1>
<table>
<tr>
<td>First Name</td>
<td id="frm_Contact_first_name"></td>
</tr>
<tr>
<td>Last Name</td>
<td id="frm_Contact_last_name"></td>
</tr>
<tr>
<td>Email ID</td>
<td id="frm_Contact_email"></td>
</tr>
<tr>
<td></td>
<td><button onclick="cur_frm.save('Save', function() { loadpage('Thank You'); })">Save</button></td>
</tr>
</table>