// Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
//
// MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// fields.js
//
// Fields are divided into 2 types
// 1. Standard fields are loaded with the libarary
// 2. Special fields are loaded with form.compressed.js
//
//
// + wrapper
// + input_area
// + display_area
// ======================================================================================
var no_value_fields = ['Section Break', 'Column Break', 'HTML', 'Table', 'FlexTable', 'Button', 'Image'];
var codeid=0; var code_editors={};
function Field() {
this.with_label = 1;
}
Field.prototype.make_body = function() {
var ischk = (this.df.fieldtype=='Check' ? 1 : 0);
// parent element
this.$wrapper = $('
').appendTo(this.parent);
this.wrapper = this.$wrapper.get(0);
this.label_area = this.label_span = this.$wrapper.find(".control-label").get(0);
this.input_area = this.$wrapper.find(".control-input").get(0);
this.disp_area = this.$wrapper.find(".control-value").get(0);
// set description
this.set_description();
if(this.onmake)this.onmake();
}
Field.prototype.set_max_width = function() {
var no_max = ['Code', 'Text Editor', 'Text', 'Small Text', 'Table', 'HTML']
if(this.wrapper && this.layout_cell && this.layout_cell.parentNode.cells
&& this.layout_cell.parentNode.cells.length==1 && !in_list(no_max, this.df.fieldtype)) {
$y(this.wrapper, {paddingRight:'50%'});
}
}
Field.prototype.set_label = function(label) {
this.label_span.innerHTML = wn._(label || this.df.label);
}
Field.prototype.set_description = function(txt) {
if(txt) {
if(!this.$wrapper.find(".help-box").length) {
$('').appendTo(this.input_area);
}
this.$wrapper.find(".help-box").html(txt);
} else {
this.$wrapper.find(".help-box").empty().toggle(false);
}
}
Field.prototype.get_status = function(explain) {
if(!this.doctype)
return "Write";
return wn.perm.get_field_display_status(this.df,
locals[this.doctype][this.docname], this.perm, explain)
}
Field.prototype.refresh_mandatory = function() {
if(this.in_filter)return;
//this.$wrapper.toggleClass("has-warning", cint(this.df.reqd) ? true : false);
this.refresh_label_icon()
}
Field.prototype.refresh_display = function() {
// from permission
if(!this.current_status || this.current_status!=this.disp_status) { // status changed
if(this.disp_status=='Write') { // write
if(this.make_input&&(!this.input)) { // make input if reqd
this.make_input();
if(this.txt || this.input)
$(this.txt || this.input).addClass("mousetrap");
if(this.onmake_input) this.onmake_input();
}
if(this.show) this.show()
else { $ds(this.wrapper); }
// input or content
if(this.input) { // if there, show it!
$ds(this.input_area);
$dh(this.disp_area);
if(this.input.refresh)
this.input.refresh();
} else { // no widget
$dh(this.input_area);
$ds(this.disp_area);
}
} else if(this.disp_status=='Read') {
// read
if(this.show) this.show()
else { $ds(this.wrapper); }
$dh(this.input_area);
$ds(this.disp_area);
} else {
// None - hide all
if(this.hide) this.hide();
else $dh(this.wrapper);
}
this.current_status = this.disp_status;
}
}
Field.prototype.refresh = function() {
// get status
this.disp_status = this.get_status();
// if there is a special refresh in case of table, then this is not valid
if(this.in_grid
&& this.table_refresh
&& this.disp_status == 'Write')
{ this.table_refresh(); return; }
this.set_label();
this.refresh_display();
if(this.input) {
if(this.input.refresh) this.input.refresh(this.df);
}
// further refresh
if(this.onrefresh)
this.onrefresh(); // called by various fields
if(this.wrapper) {
this.wrapper.fieldobj = this;
$(this.wrapper).trigger('refresh');
}
if(!this.not_in_form)
this.set_input(_f.get_value(this.doctype,this.docname,this.df.fieldname));
this.refresh_mandatory();
this.set_max_width();
}
Field.prototype.refresh_label_icon = function() {
// mandatory
var to_update = false;
if(this.df.reqd && this.get_value && is_null(this.get_value()))
to_update = true;
this.$wrapper.toggleClass("has-error", to_update);
}
Field.prototype.set = function(val) {
// not in form
if(this.not_in_form)
return;
if((!this.docname) && this.grid) {
this.docname = this.grid.add_newrow(); // new row
}
if(this.validate)
val = this.validate(val);
cur_frm.set_value_in_locals(this.doctype, this.docname,
this.df.fieldname, val);
this.value = val; // for return
}
Field.prototype.set_input = function(val) {
this.value = val;
if(this.input && this.input.set_input) {
this.input.set_input(val); // in widget
}
var disp_val = val;
if(val==null)
disp_val = '';
this.set_disp(disp_val); // text
}
Field.prototype.run_trigger = function() {
// update mandatory icon
this.refresh_label_icon();
if(this.not_in_form) {
return;
}
if(cur_frm.cscript[this.df.fieldname])
cur_frm.runclientscript(this.df.fieldname, this.doctype, this.docname);
cur_frm.refresh_dependency();
}
Field.prototype.set_disp_html = function(t) {
if(this.disp_area){
$(this.disp_area).addClass('disp-area');
this.disp_area.innerHTML = (t==null ? '' : t);
if(!t) $(this.disp_area).addClass('disp-area-no-val');
}
}
Field.prototype.set_disp = function(val) {
this.set_disp_html(val);
}
Field.prototype.get_input = function() {
return this.txt || this.input;
}
// for grids (activate against a particular record in the table
Field.prototype.activate = function(docname) {
this.docname = docname;
this.refresh();
if(this.input) {
var v = _f.get_value(this.doctype, this.docname, this.df.fieldname);
this.last_value=v;
// set input value
if(this.input.onchange && this.input.get_value && this.input.get_value() !=v) {
if(this.validate)
this.input.set_value(this.validate(v));
else
this.input.set_value((v==null)?'':v);
if(this.format_input)
this.format_input();
}
if(this.input.focus){
try{this.input.focus();} catch(e){} // IE Fix - Unexpected call???
}
}
if(this.txt) {
try{this.txt.focus();} catch(e){} // IE Fix - Unexpected call???
this.txt.field_object = this;
}
}
function DataField() { } DataField.prototype = new Field();
DataField.prototype.make_input = function() {
var me = this;
this.input = $a_input(this.input_area, this.df.fieldtype=='Password' ? 'password' : 'text');
if(this.df.placeholder) $(this.input).attr("placeholder", this.df.placeholder);
this.get_value= function() {
var v = this.input.value;
if(this.validate)
v = this.validate(v);
return v;
}
this.input.name = this.df.fieldname;
$(this.input).blur(function() {
me.set_value(me.get_value ? me.get_value() : $(this).val());
});
this.set_value = function(val) {
if(!me.last_value) me.last_value=undefined;
if(me.validate) {
val = me.validate(val);
if(me.last_value === val) return;
me.input.value = (val==undefined) ? '' : val;
} else if(me.last_value === val) { return; }
me.set(val);
if(me.format_input)
me.format_input();
if(in_list(['Currency','Float','Int'], me.df.fieldtype)) {
if(flt(me.last_value)==flt(val)) {
me.last_value = val;
return; // do not run trigger
}
}
me.last_value = val;
me.run_trigger();
}
this.input.set_input = function(val) {
if(val==null)val='';
me.input.value = val;
if(me.format_input)me.format_input();
}
}
DataField.prototype.validate = function(v) {
if(this.df.options == 'Phone') {
if(v+''=='')return '';
v1 = ''
// phone may start with + and must only have numbers later, '-' and ' ' are stripped
v = v.replace(/ /g, '').replace(/-/g, '').replace(/\(/g, '').replace(/\)/g, '');
// allow initial +,0,00
if(v && v.substr(0,1)=='+') {
v1 = '+'; v = v.substr(1);
}
if(v && v.substr(0,2)=='00') {
v1 += '00'; v = v.substr(2);
}
if(v && v.substr(0,1)=='0') {
v1 += '0'; v = v.substr(1);
}
v1 += cint(v) + '';
return v1;
} else if(this.df.options == 'Email') {
if(v+''=='')return '';
if(!validate_email(v)) {
msgprint(this.df.label + ': ' + v + ' is not a valid email id');
return '';
} else
return v;
} else {
return v;
}
}
// ======================================================================================
function ReadOnlyField() { }
ReadOnlyField.prototype = new Field();
// ======================================================================================
function HTMLField() {
var me = this;
this.make_body = function() {
me.wrapper = $("