@@ -152,6 +152,7 @@ | |||
"lib/public/js/wn/form/toolbar.js", | |||
"lib/public/js/wn/form/layout.js", | |||
"lib/public/js/wn/form/control.js", | |||
"lib/public/js/wn/form/editors.js", | |||
"lib/public/js/wn/form/grid.js", | |||
"lib/public/js/wn/form/attachments.js", | |||
@@ -18,13 +18,3 @@ | |||
padding-left: 6px; | |||
padding-right: 6px; | |||
} | |||
.disp-area { | |||
background-color: #eee; | |||
padding: 6px; | |||
margin-bottom: 7px; | |||
border-radius: 3px; | |||
} | |||
.disp-area-no-val { | |||
height: 30px; | |||
} |
@@ -56,10 +56,6 @@ div.dialog_frm { | |||
margin: 10px; | |||
} | |||
/*------------------*/ | |||
.top_cell { | |||
height: 50px; | |||
} | |||
@@ -152,6 +152,21 @@ a { | |||
outline: none; | |||
} | |||
/* appframe header */ | |||
.appframe-header { | |||
background-color: #eee; | |||
padding-bottom: 10px; | |||
margin-bottom: 15px; | |||
border-bottom: 1px solid #ddd; | |||
} | |||
/* form */ | |||
textarea[data-fieldtype="Small Text"] { | |||
height: 60px; | |||
} | |||
/* form grid */ | |||
.rows .grid-row .divider { | |||
@@ -179,4 +194,12 @@ a { | |||
border: 1px dashed #ddd; | |||
padding: 15px; | |||
padding-top: 0px; | |||
} | |||
.like-disabled-input { | |||
background-color: #eee; | |||
padding: 6px; | |||
margin-bottom: 7px; | |||
border-radius: 3px; | |||
min-height: 30px; | |||
} |
@@ -69,12 +69,16 @@ function replace_newlines(t) { | |||
} | |||
function cint(v, def) { | |||
if(v===true) return 1; | |||
v=v+''; | |||
if(v===true) | |||
return 1; | |||
if(v===false) | |||
return 0; | |||
v=v+''; | |||
v=lstrip(v, ['0']); | |||
v=parseInt(v); | |||
if(isNaN(v))v=def?def:0; | |||
return v; | |||
return isNaN(v) ? | |||
(def ? def : 0) : | |||
v | |||
} | |||
function validate_email(txt) { | |||
return wn.utils.validate_type(txt, "email"); | |||
@@ -38,11 +38,9 @@ function Field() { | |||
this.with_label = 1; | |||
} | |||
Field.prototype.make_body = function() { | |||
var ischk = (this.df.fieldtype=='Check' ? 1 : 0); | |||
Field.prototype.make_body = function() { | |||
// parent element | |||
this.$wrapper = $('<div class="control-group">\ | |||
this.$wrapper = $('<div class="control-group" style="max-width: 600px;">\ | |||
<label class="control-label"></label>\ | |||
<div class="controls">\ | |||
<div class="control-input"></div>\ | |||
@@ -244,35 +242,6 @@ Field.prototype.get_input = function() { | |||
} | |||
// 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; | |||
@@ -354,11 +323,6 @@ DataField.prototype.validate = function(v) { | |||
// ====================================================================================== | |||
function ReadOnlyField() { } | |||
ReadOnlyField.prototype = new Field(); | |||
// ====================================================================================== | |||
function HTMLField() { | |||
var me = this; | |||
this.make_body = function() { | |||
@@ -377,75 +341,6 @@ function HTMLField() { | |||
} | |||
} | |||
// ====================================================================================== | |||
var datepicker_active = 0; | |||
function get_datepicker_options() { | |||
var datepicker_options = { | |||
dateFormat: (sys_defaults.date_format || 'yy-mm-dd').replace('yyyy','yy'), | |||
altFormat:'yy-mm-dd', | |||
changeYear: true, | |||
yearRange: "-70Y:+10Y", | |||
beforeShow: function(input, inst) { | |||
datepicker_active = 1 | |||
}, | |||
onClose: function(dateText, inst) { | |||
datepicker_active = 0; | |||
if(_f.cur_grid_cell) | |||
_f.cur_grid_cell.grid.cell_deselect(); | |||
}, | |||
} | |||
return datepicker_options; | |||
} | |||
function DateField() { } DateField.prototype = new Field(); | |||
DateField.prototype.make_input = function() { | |||
var me = this; | |||
this.input = $("<input type='text' data-fieldtype='Date'>") | |||
.appendTo(this.input_area).get(0); | |||
$(this.input).datepicker(get_datepicker_options()); | |||
this.setup_input(); | |||
} | |||
DateField.prototype.setup_input = function() { | |||
var me = this; | |||
me.input.onchange = function() { | |||
// input as dd-mm-yyyy | |||
if(this.value==null)this.value=''; | |||
if(!this.not_in_form) | |||
me.set(dateutil.user_to_str(me.input.value)); | |||
me.run_trigger(); | |||
} | |||
me.input.set_input = function(val) { | |||
if(val==null)val=''; | |||
else val=dateutil.str_to_user(val); | |||
me.input.value = val; | |||
} | |||
me.get_value = function() { | |||
if(me.input.value) | |||
return dateutil.user_to_str(me.input.value); | |||
} | |||
} | |||
DateField.prototype.set_disp = function(val) { | |||
var v = dateutil.str_to_user(val); | |||
if(v==null)v = ''; | |||
this.set_disp_html(v); | |||
} | |||
DateField.prototype.validate = function(v) { | |||
var v = wn.datetime.validate(v); | |||
if(!v) { | |||
msgprint (wn._("Date must be in format") + ": " + (sys_defaults.date_format || "yyyy-mm-dd")); | |||
this.input.set_input(''); | |||
return ''; | |||
} | |||
return v; | |||
}; | |||
// reference when a new record is created via link | |||
function LinkField() { } LinkField.prototype = new Field(); | |||
LinkField.prototype.make_input = function() { | |||
@@ -735,464 +630,29 @@ LinkField.prototype.set_disp = function(val) { | |||
this.set_disp_html(t); | |||
} | |||
// ====================================================================================== | |||
function IntField() { } IntField.prototype = new DataField(); | |||
IntField.prototype.validate = function(v) { | |||
if(isNaN(parseInt(v)))return null; | |||
return cint(v); | |||
}; | |||
IntField.prototype.format_input = function() { | |||
if(this.input.value==null) this.input.value=''; | |||
} | |||
// ====================================================================================== | |||
function FloatField() { } FloatField.prototype = new DataField(); | |||
FloatField.prototype.validate = function(v) { | |||
if(isNaN(parseFloat(v))) | |||
return null; | |||
else | |||
v = flt(v); | |||
return v; | |||
}; | |||
FloatField.prototype.format_input = function() { | |||
if(this.input.value==null || this.input.value=='') | |||
this.input.value=''; | |||
else { | |||
var format; | |||
if(this.get_field_currency) { | |||
format = get_number_format(this.get_field_currency()); | |||
this.input.value = | |||
format_number(parseFloat(this.input.value), format); | |||
} else { | |||
var decimals = wn.boot.sysdefaults.float_precision ? | |||
parseInt(wn.boot.sysdefaults.float_precision) : null; | |||
this.input.value = format_number(parseFloat(this.input.value), null, decimals); | |||
} | |||
} | |||
} | |||
FloatField.prototype.onmake_input = function() { | |||
if(!this.input) return; | |||
this.input.onfocus = function() { | |||
this.select(); | |||
} | |||
} | |||
FloatField.prototype.set_disp = function(val) { | |||
this.set_disp_html(wn.format(val, this.df, null, locals[this.doctype][this.name])); | |||
} | |||
function PercentField() { } PercentField.prototype = new FloatField(); | |||
PercentField.prototype.set_disp = function(val) { | |||
this.set_disp_html(wn.format(val, this.df)); | |||
} | |||
function CurrencyField() { } CurrencyField.prototype = new FloatField(); | |||
CurrencyField.prototype.validate = function(v) { | |||
if(v==null || v=='') | |||
return 0; | |||
return flt(v, null, get_number_format(this.get_field_currency())); | |||
} | |||
CurrencyField.prototype.get_field_currency = function() { | |||
var doc = null; | |||
if(this.doctype && this.docname && locals[this.doctype]) | |||
doc = locals[this.doctype][this.docname]; | |||
return wn.meta.get_field_currency(this.df, doc); | |||
}; | |||
CurrencyField.prototype.get_formatted = function(val) { | |||
if(this.not_in_form) | |||
return val; | |||
return format_currency(val, this.get_field_currency()); | |||
} | |||
CurrencyField.prototype.set_disp = function(val) { | |||
this.set_disp_html(this.get_formatted(val)); | |||
} | |||
function CheckField() { } CheckField.prototype = new Field(); | |||
CheckField.prototype.validate = function(v) { | |||
return cint(v); | |||
}; | |||
CheckField.prototype.onmake = function() { | |||
this.checkimg = $("<i class='icon-check'></i>").appendTo(this.disp_area); | |||
} | |||
CheckField.prototype.make_input = function() { var me = this; | |||
this.input = $("<input type='checkbox'>") | |||
.appendTo(this.input_area) | |||
.get(0); | |||
$(this.input).change(function() { | |||
me.set(this.checked ? 1 : 0); | |||
me.run_trigger(); | |||
}) | |||
this.input.set_input = function(v) { | |||
me.input.checked = cint(v) ? true : false; | |||
} | |||
this.get_value= function() { | |||
return this.input.checked ? 1 : 0; | |||
} | |||
} | |||
CheckField.prototype.set_disp = function(val) { | |||
this.checkimg.toggle(cint(val) ? true : false); | |||
} | |||
function TextField() { } TextField.prototype = new Field(); | |||
TextField.prototype.set_disp = function(val) { | |||
this.disp_area.innerHTML = replace_newlines(val); | |||
} | |||
TextField.prototype.make_input = function() { | |||
var me = this; | |||
if(this.in_grid) | |||
return; // do nothing, text dialog will take over | |||
this.input = $a(this.input_area, 'textarea'); | |||
if(this.df.fieldtype=='Small Text') { | |||
$(this.input).css({height: "60px"}); | |||
} else if(this.df.width) { | |||
$(this.input).css({height: cint(this.df.width) + "px"}); | |||
} else { | |||
$(this.input).css({height: "60px"}); | |||
} | |||
this.input.set_input = function(v) { | |||
me.input.value = (v==null ? "" : v); | |||
} | |||
this.input.onchange = function() { | |||
me.set(me.input.value); | |||
me.run_trigger(); | |||
} | |||
this.get_value= function() { | |||
return this.input.value; | |||
} | |||
} | |||
// text dialog | |||
var text_dialog; | |||
function make_text_dialog() { | |||
var d = new Dialog(520,410,'Edit Text'); | |||
d.make_body([ | |||
['Text', 'Enter Text'], | |||
['HTML', 'Description'], | |||
['Button', 'Update'] | |||
]); | |||
d.widgets['Update'].onclick = function() { | |||
var t = this.dialog; | |||
t.field.set(t.widgets['Enter Text'].value); | |||
t.hide(); | |||
} | |||
d.onshow = function() { | |||
this.widgets['Enter Text'].style.height = '300px'; | |||
var v = _f.get_value(this.field.doctype,this.field.docname,this.field.df.fieldname); | |||
this.widgets['Enter Text'].value = v==null?'':v; | |||
this.widgets['Enter Text'].focus(); | |||
this.widgets['Description'].innerHTML = '' | |||
if(this.field.df.description) | |||
$a(this.widgets['Description'], 'div', 'help small', '', this.field.df.description); | |||
} | |||
d.onhide = function() { | |||
if(_f.cur_grid_cell) | |||
_f.cur_grid_cell.grid.cell_deselect(); | |||
} | |||
text_dialog = d; | |||
} | |||
TextField.prototype.table_refresh = function() { | |||
if(!this.text_dialog) | |||
make_text_dialog(); | |||
text_dialog.set_title(wn._('Enter text for')+': "'+ wn._(this.df.label) +'"'); | |||
text_dialog.field = this; | |||
text_dialog.show(); | |||
} | |||
// Select | |||
// ====================================================================================== | |||
function SelectField() { } SelectField.prototype = new Field(); | |||
SelectField.prototype.make_input = function() { | |||
var me = this; | |||
var opt=[]; | |||
if(this.in_filter && (!this.df.single_select)) { | |||
// multiple select | |||
this.input = $a(this.input_area, 'select'); | |||
this.input.multiple = true; | |||
this.input.style.height = '4em'; | |||
this.input.lab = $a(this.input_area, 'div', {fontSize:'9px',color:'#999'}); | |||
this.input.lab.innerHTML = '(Use Ctrl+Click to select multiple or de-select)' | |||
} else { | |||
// Single select | |||
this.input = $a(this.input_area, 'select'); | |||
this.input.onchange = function() { | |||
if(me.validate) | |||
me.validate(); | |||
me.set(sel_val(this)); | |||
me.run_trigger(); | |||
} | |||
if(this.df.options == 'attach_files:') { | |||
this.attach_files = true; | |||
$(this.input).css({"width": "70%"}); | |||
$("<button class='btn' title='Add attachment'\ | |||
style='margin-bottom: 9px; \ | |||
padding-left: 6px; padding-right: 6px; margin-left: 6px;'>\ | |||
<i class='icon-plus'></i></button>") | |||
.click(function() { | |||
cur_frm.attachments.new_attachment(); | |||
}) | |||
.appendTo(this.input_area); | |||
} | |||
} | |||
// set as single (to be called from report builder) | |||
this.set_as_single = function() { | |||
var i = this.input; | |||
i.multiple = false; | |||
i.style.height = null; | |||
if(i.lab)$dh(i.lab) | |||
} | |||
// refresh options list | |||
this.refresh_options = function(options) { | |||
if(options) | |||
me.df.options = options; | |||
if(this.attach_files) | |||
this.set_attach_options(); | |||
if(typeof me.df.options=="object") | |||
me.options_list = me.df.options || [""]; | |||
else | |||
me.options_list = me.df.options?me.df.options.split('\n'):['']; | |||
// add options | |||
if(me.in_filter && me.options_list[0]!='') { | |||
me.options_list = add_lists([''], me.options_list); | |||
} | |||
$(this.input).empty().add_options(me.options_list); | |||
} | |||
// refresh options | |||
this.onrefresh = function() { | |||
this.refresh_options(); | |||
if(this.not_in_form) { | |||
this.input.value = ''; | |||
return; | |||
} | |||
if(_f.get_value) | |||
var v = _f.get_value(this.doctype,this.docname,this.df.fieldname); | |||
else { | |||
if(this.options_list && this.options_list.length) | |||
var v = this.options_list[0]; | |||
else | |||
var v = null; | |||
} | |||
this.input.set_input(v); | |||
} | |||
var _set_value = function(value) { | |||
// use option's value if dict, else use string for comparison and setting | |||
for(var i in (me.options_list || [""])) { | |||
var option = me.options_list[i]; | |||
if($.isPlainObject(option)){ | |||
option = option.value; | |||
} | |||
if(option === value) { | |||
me.input.value = value; | |||
break; | |||
} | |||
} | |||
} | |||
this.input.set_input=function(v) { | |||
if(!v) { | |||
if(!me.input.multiple) { | |||
if(me.docname) { // if called from onload without docname being set on fields | |||
_set_value(v); | |||
me.set(me.get_value()); | |||
} | |||
} | |||
} else { | |||
if(me.options_list) { | |||
if(me.input.multiple) { | |||
for(var i=0; i<me.input.options.length; i++) { | |||
me.input.options[i].selected = 0; | |||
if(me.input.options[i].value && inList(typeof(v)=='string'?v.split(","):v, me.input.options[i].value)) | |||
me.input.options[i].selected = 1; | |||
} | |||
} else { | |||
_set_value(v); | |||
} | |||
} | |||
} | |||
} | |||
this.get_value= function() { | |||
if(me.input.multiple) { | |||
var l = []; | |||
for(var i=0;i<me.input.options.length; i++ ) { | |||
if(me.input.options[i].selected)l[l.length] = me.input.options[i].value; | |||
} | |||
return l; | |||
} else { | |||
if(me.input.options) { | |||
var val = sel_val(me.input); | |||
if(!val && !me.input.selectedIndex) | |||
val = me.input.options[0].value; | |||
return val; | |||
} | |||
return me.input.value; | |||
} | |||
} | |||
this.set_attach_options = function() { | |||
if(!cur_frm) return; | |||
var fl = cur_frm.doc.file_list; | |||
if(fl) { | |||
fl = JSON.parse(fl); | |||
this.df.options = ''; | |||
for(var fname in fl) { | |||
if(fname.substr(0,4)!="http") | |||
fname = "files/" + fname; | |||
this.df.options += '\n' + fname; | |||
} | |||
this.set_description(""); | |||
} else { | |||
this.df.options = '' | |||
this.set_description(wn._("Please attach a file first.")) | |||
} | |||
} | |||
this.refresh(); | |||
} | |||
function TimeField() { } TimeField.prototype = new DataField(); | |||
function import_timepicker() { | |||
wn.require("lib/js/lib/jquery/jquery.ui.slider.min.js"); | |||
wn.require("lib/js/lib/jquery/jquery.ui.sliderAccess.js"); | |||
wn.require("lib/js/lib/jquery/jquery.ui.timepicker-addon.css"); | |||
wn.require("lib/js/lib/jquery/jquery.ui.timepicker-addon.js"); | |||
} | |||
TimeField.prototype.make_input = function() { | |||
import_timepicker(); | |||
var me = this; | |||
this.input = $('<input type="text">') | |||
.appendTo(this.input_area) | |||
.timepicker({ | |||
timeFormat: 'hh:mm:ss', | |||
}).get(0); | |||
this.input.set_input = function(v) { | |||
$(me.input).val(v); | |||
}; | |||
this.input.onchange = function() { | |||
if(!this.not_in_form) | |||
me.set(me.input.value); | |||
me.run_trigger(); | |||
}; | |||
} | |||
function DateTimeField() { } DateTimeField.prototype = new DateField(); | |||
DateTimeField.prototype.make_input = function() { | |||
import_timepicker(); | |||
var me = this; | |||
args = get_datepicker_options(); | |||
args.timeFormat = "hh:mm:ss"; | |||
this.input = $('<input type="text" data-fieldtype="Datetime">') | |||
.appendTo(this.input_area) | |||
.datetimepicker(args).get(0); | |||
this.setup_input(); | |||
} | |||
var tmpid = 0; | |||
_f.ButtonField = function() { }; | |||
_f.ButtonField.prototype = new Field(); | |||
_f.ButtonField.prototype.set_label = function(label) { }; | |||
_f.ButtonField.prototype.make_input = function() { var me = this; | |||
// make a button area for one button | |||
if(!this.button_area) | |||
this.button_area = $a(this.input_area, 'div','',{ | |||
marginBottom:'4px'}); | |||
// make the input | |||
this.input = $btn(this.button_area, | |||
me.df.label, null, | |||
{fontWeight:'bold'}, null, 1) | |||
$(this.input).click(function() { | |||
if(me.not_in_form) return; | |||
if(cur_frm.cscript[me.df.fieldname] && (!me.in_filter)) { | |||
cur_frm.runclientscript(me.df.fieldname, me.doctype, me.docname); | |||
} else { | |||
cur_frm.runscript(me.df.options, me); | |||
} | |||
}); | |||
} | |||
_f.ButtonField.prototype.hide = function() { | |||
$dh(this.button_area); | |||
}; | |||
_f.ButtonField.prototype.show = function() { | |||
$ds(this.button_area); | |||
}; | |||
_f.ButtonField.prototype.set = function(v) { }; // No Setter | |||
_f.ButtonField.prototype.set_disp = function(val) { } // No Disp on readonly | |||
function make_field(docfield, doctype, parent, frm, in_grid, hide_label) { // Factory | |||
if(["Data", "Int", "Float", "Currency", "HTML", "Date", "Time", "DateTime", | |||
"Text", "Small Text", "Long Text", "Check", "Button", "Select", | |||
"Password", "Read Only"].indexOf(docfield.fieldtype)!=-1) { | |||
return new wn.ui.form.make_control({ | |||
df: docfield, | |||
doctype: doctype, | |||
parent: parent, | |||
hide_label: hide_label, | |||
frm: frm | |||
}); | |||
} | |||
switch(docfield.fieldtype.toLowerCase()) { | |||
// general fields | |||
case 'data':var f = new DataField(); break; | |||
case 'password':var f = new DataField(); break; | |||
case 'int':var f = new IntField(); break; | |||
case 'float':var f = new FloatField(); break; | |||
case 'currency':var f = new CurrencyField(); break; | |||
case 'percent':var f = new PercentField(); break; | |||
case 'read only':var f = new ReadOnlyField(); break; | |||
case 'link':var f = new LinkField(); break; | |||
case 'long text': var f = new TextField(); break; | |||
case 'date':var f = new DateField(); break; | |||
case 'datetime':var f = new DateTimeField(); break; | |||
case 'time':var f = new TimeField(); break; | |||
case 'html':var f = new HTMLField(); break; | |||
case 'check':var f = new CheckField(); break; | |||
case 'text':var f = new TextField(); break; | |||
case 'small text':var f = new TextField(); break; | |||
case 'select':var f = new SelectField(); break; | |||
case 'button':var f = new _f.ButtonField(); break; | |||
// form fields | |||
case 'code':var f = new _f.CodeField(); break; | |||
@@ -1200,6 +660,8 @@ function make_field(docfield, doctype, parent, frm, in_grid, hide_label) { // Fa | |||
case 'table':var f = new _f.TableField(); break; | |||
case 'image':var f= new _f.ImageField(); break; | |||
} | |||
if(!f) console.log(docfield.fieldtype) | |||
f.parent = parent; | |||
f.doctype = doctype; | |||
@@ -139,11 +139,10 @@ _f.Frm.prototype.setup = function() { | |||
_f.Frm.prototype.setup_print_layout = function() { | |||
var me = this; | |||
this.print_wrapper = $('<div>\ | |||
<form class="form-inline">\ | |||
<form class="form-inline" style="margin-bottom: 10px;">\ | |||
<select class="col-span-2 preview-select"></select> \ | |||
<button class="btn btn-edit btn-info"><i class="icon-edit"></i> Edit</button>\ | |||
</form>\ | |||
<hr>\ | |||
<div class="print-format-area clear-fix" style="min-height: 400px;"></div>\ | |||
</div>').appendTo(this.layout_main).get(0); | |||
@@ -1,78 +0,0 @@ | |||
// 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. | |||
// | |||
wn.widgets.form.comments = { | |||
n_comments: {}, | |||
comment_list: {}, | |||
sync: function(dt, dn, r) { | |||
var f = wn.widgets.form.comments; | |||
f.n_comments[dn] = r.n_comments; | |||
f.comment_list[dn] = r.comment_list; | |||
}, | |||
add: function(input, dt, dn, callback) { | |||
$c('webnotes.widgets.form.comments.add_comment', wn.widgets.form.comments.get_args(input, dt, dn), | |||
function(r,rt) { | |||
// update the comments | |||
wn.widgets.form.comments.update_comment_list(input, dt, dn); | |||
// clean up the text area | |||
input.value = ''; | |||
callback(input, dt, dn); | |||
} | |||
); | |||
}, | |||
remove: function(dt, dn, comment_id, callback) { | |||
$c('webnotes.widgets.form.comments.remove_comment',{ | |||
id:comment_id, | |||
dt:dt, | |||
dn:dn | |||
}, callback | |||
); | |||
}, | |||
get_args: function(input, dt, dn) { | |||
return { | |||
comment: input.value, | |||
comment_by: user, | |||
comment_by_fullname: user_fullname, | |||
comment_doctype: dt, | |||
comment_docname: dn | |||
} | |||
}, | |||
update_comment_list: function(input, dt, dn) { | |||
var f = wn.widgets.form.comments; | |||
// update no of comments | |||
f.n_comments[dn] = cint(f.n_comments[dn]) + 1; | |||
// update comment list | |||
f.comment_list[dn] = add_lists( | |||
[f.get_args(input, dt, dn)], | |||
f.comment_list[dn] | |||
); | |||
} | |||
} |
@@ -224,7 +224,7 @@ wn.dom.set_box_shadow = function(ele, spread) { | |||
ele.loading_img = $('<img src="lib/images/ui/button-load.gif" \ | |||
style="margin-left: 4px; margin-bottom: -2px; display: inline;" />') | |||
.insertAfter(ele); | |||
} | |||
} | |||
} | |||
$.fn.done_working = function() { | |||
var ele = this.get(0); | |||
@@ -0,0 +1,114 @@ | |||
wn.ui.form.Comments = Class.extend({ | |||
init: function(opts) { | |||
$.extend(this, opts); | |||
this.make(); | |||
}, | |||
make: function() { | |||
var me = this; | |||
this.wrapper =this.parent; | |||
this.row = $("<div class='row'>").appendTo(this.parent); | |||
this.input = $('<div class="col-span-10">\ | |||
<textarea rows="3"></textarea></div>') | |||
.appendTo(this.row) | |||
.find("textarea"); | |||
this.button = $('<div class="col-span-1">\ | |||
<button class="btn btn-go" class="col-span-1">\ | |||
<i class="icon-ok"></i></button>\ | |||
</div>') | |||
.appendTo(this.row) | |||
.find("button") | |||
.click(function() { | |||
me.add_comment(); | |||
}); | |||
this.list = $('<div class="comments" style="margin-top: 15px;"></div>') | |||
.appendTo(this.parent); | |||
}, | |||
refresh: function() { | |||
var me = this; | |||
if(this.frm.doc.__islocal) { | |||
this.wrapper.toggle(false); | |||
return; | |||
} | |||
this.wrapper.toggle(true); | |||
this.list.empty(); | |||
var comments = JSON.parse(this.frm.doc.__comments || "[]"); | |||
$.each(comments, function(i, c) { | |||
if(c.comment_by==user) { | |||
c["delete"] = '<a class="close" href="#">×</a>'; | |||
} | |||
c.image = wn.user_info(c.comment_by).image; | |||
c.comment_on = dateutil.comment_when(c.creation); | |||
c.fullname = wn.user_info(c.comment_by).fullname; | |||
$(repl('<div class="comment alert col-span-10" data-name="%(name)s">\ | |||
<div class="row">\ | |||
<div class="col-span-1">\ | |||
<span class="avatar avatar-small"><img src="%(image)s"></span>\ | |||
</div>\ | |||
<div class="col-span-11">\ | |||
%(comment)s%(delete)s<br>\ | |||
<span class="small text-muted">%(fullname)s / %(comment_on)s</span>\ | |||
</div>\ | |||
</div>\ | |||
</div>', c)) | |||
.appendTo(me.list) | |||
.on("click", ".close", function() { | |||
var name = $(this).parent().attr("data-name"); | |||
me.delete_comment(name); | |||
return false; | |||
}) | |||
}); | |||
}, | |||
add_comment: function() { | |||
var me = this, | |||
txt = me.input.val(); | |||
if(txt) { | |||
var comment = { | |||
doctype: "Comment", | |||
comment_doctype: me.frm.doctype, | |||
comment_docname: me.frm.docname, | |||
comment: txt, | |||
comment_by: user | |||
}; | |||
wn.call({ | |||
method: "webnotes.client.insert", | |||
args: { | |||
doclist:[comment] | |||
}, | |||
callback: function(r) { | |||
if(!r.exc) { | |||
var comments = JSON.parse(me.frm.doc.__comments || "[]"); | |||
me.frm.doc.__comments = JSON.stringify(r.message.concat(comments)); | |||
me.input.val(""); | |||
me.refresh(); | |||
} | |||
} | |||
}); | |||
} | |||
}, | |||
delete_comment: function(name) { | |||
var me = this; | |||
wn.call({ | |||
method: "webnotes.client.delete", | |||
args: { | |||
doctype: "Comment", | |||
name: name | |||
}, | |||
callback: function(r) { | |||
if(!r.exc) { | |||
me.frm.doc.__comments = JSON.stringify( | |||
$.map(JSON.parse(me.frm.doc.__comments || "[]"), | |||
function(v) { | |||
if(v.name==name) return null; | |||
else return v; | |||
} | |||
) | |||
); | |||
me.refresh(); | |||
} | |||
} | |||
}); | |||
} | |||
}) |
@@ -0,0 +1,431 @@ | |||
wn.ui.form.make_control = function(opts) { | |||
var control_class_name = "Control" + opts.df.fieldtype.replace(/ /g, ""); | |||
if(wn.ui.form[control_class_name]) { | |||
return new wn.ui.form[control_class_name](opts); | |||
} else { | |||
console.log("Invalid Control Name: " + opts.df.fieldtype); | |||
} | |||
} | |||
wn.ui.form.Control = Class.extend({ | |||
init: function(opts) { | |||
$.extend(this, opts); | |||
this.make(); | |||
}, | |||
make: function() { | |||
this.$wrapper = $("<div>").appendTo(this.parent); | |||
this.wrapper = this.$wrapper.get(0); | |||
}, | |||
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); | |||
}, | |||
refresh: function() { | |||
this.disp_status = this.get_status(); | |||
this.$wrapper && this.$wrapper.toggle(this.disp_status!="None"); | |||
this.$wrapper && this.$wrapper.trigger("refresh"); | |||
}, | |||
get_doc: function() { | |||
return this.doctype && this.docname | |||
&& locals[this.doctype] && locals[this.doctype][this.docname] || {}; | |||
} | |||
}); | |||
wn.ui.form.ControlHTML = wn.ui.form.Control.extend({ | |||
make: function() { | |||
this._super(); | |||
var me = this; | |||
this.$wrapper.on("refresh", function() { | |||
if(me.df.options) | |||
me.$wrapper.html(me.df.options); | |||
}) | |||
} | |||
}); | |||
wn.ui.form.ControlReadOnly = wn.ui.form.Control.extend({ | |||
make: function() { | |||
this._super(); | |||
var me = this; | |||
this.$wrapper.on("refresh", function() { | |||
var value = wn.model.get_value(me.doctype, me.docname, me.fieldname); | |||
me.$wrapper.html(value); | |||
}) | |||
} | |||
}); | |||
wn.ui.form.ControlInput = wn.ui.form.Control.extend({ | |||
make: function() { | |||
// parent element | |||
this.$wrapper = $('<div class="control-group">\ | |||
<label class="control-label"></label>\ | |||
<div class="controls">\ | |||
<div class="control-input"></div>\ | |||
<div class="control-value like-disabled-input" style="display: none;"></div>\ | |||
</div>\ | |||
</div>').appendTo(this.parent); | |||
this.wrapper = this.$wrapper.get(0); | |||
this.wrapper.fieldobj = this; // reference for event handlers | |||
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_max_width(); | |||
this.setup_update_on_refresh(); | |||
}, | |||
set_max_width: function() { | |||
if(['Code', 'Text Editor', 'Text', 'Small Text', 'Table', 'HTML'] | |||
.indexOf(this.df.fieldtype)==-1) { | |||
this.$wrapper.css({"max-width": "600px"}); | |||
} | |||
}, | |||
// update input value, label, description | |||
// display (show/hide/read-only), | |||
// mandatory style on refresh | |||
setup_update_on_refresh: function() { | |||
var me = this; | |||
this.$wrapper.on("refresh", function() { | |||
if(me.disp_status != "None") { | |||
// refresh value | |||
if(me.docname && me.set_input) { | |||
me.value = wn.model.get_value(me.doctype, me.docname, me.df.fieldname); | |||
if(me.disp_status=="Write") { | |||
$(me.disp_area).toggle(false); | |||
$(me.input_area).toggle(true); | |||
!me.has_input && me.make_input(); | |||
me.set_input(me.value); | |||
} else { | |||
$(me.input_area).toggle(false); | |||
me.disp_area && $(me.disp_area) | |||
.toggle(true) | |||
.html( | |||
wn.format(me.value, me.df, null, locals[me.doctype][me.name]) | |||
); | |||
} | |||
} | |||
me.set_description(); | |||
me.set_label(); | |||
me.set_mandatory(); | |||
} | |||
}) | |||
}, | |||
set_label: function() { | |||
if(this.df.label==this._description) | |||
return; | |||
this.label_span.innerHTML = wn._(this.df.label); | |||
this._label = this.df.label; | |||
}, | |||
set_description: function() { | |||
if(this.df.description==this._description) return; | |||
if(this.df.description) { | |||
if(!this.$wrapper.find(".help-box").length) { | |||
$('<p class="help-box small text-muted"></p>').appendTo(this.input_area); | |||
} | |||
this.$wrapper.find(".help-box").html(this.df.description); | |||
} else { | |||
this.$wrapper.find(".help-box").empty().toggle(false); | |||
} | |||
this._description = this.df.description; | |||
}, | |||
set_mandatory: function() { | |||
this.$wrapper.toggleClass("has-error", (this.df.reqd | |||
&& (this.value==null || this.value=="")) ? true : false); | |||
}, | |||
set_model_value: function(value) { | |||
wn.model.set_value(this.doctype, this.docname, this.df.fieldname, value); | |||
this.frm && this.frm.dirty(); | |||
} | |||
}); | |||
wn.ui.form.ControlData = wn.ui.form.ControlInput.extend({ | |||
html_element: "input", | |||
input_type: "text", | |||
make_input: function() { | |||
this.$input = $("<"+ this.html_element +">") | |||
.attr("type", this.input_type) | |||
.attr("placeholder", this.df.placeholder || "") | |||
.attr("data-fieldtype", this.df.fieldtype) | |||
.addClass("col-span-12") | |||
.prependTo(this.input_area) | |||
this.input = this.$input.get(0); | |||
this.has_input = true; | |||
this.bind_change_event(); | |||
}, | |||
bind_change_event: function() { | |||
var me = this; | |||
this.$input.on("change", this.change || function() { | |||
if(me.doctype && me.docname && me.get_value) { | |||
var value = me.parse ? | |||
me.parse(me.get_value()) : | |||
me.get_value(); | |||
me.validate ? | |||
me.validate(value, function() { me.set_model_value(value); }) : | |||
me.set_model_value(value); | |||
} | |||
}); | |||
}, | |||
set_input: function(val) { | |||
this.$input.val(this.format_for_input(val)); | |||
}, | |||
get_value: function() { | |||
return this.$input.val(); | |||
}, | |||
format_for_input: function(val) { | |||
return val==null ? "" : val; | |||
}, | |||
validate: function(v, callback) { | |||
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) + ''; | |||
callback(v1); | |||
} else if(this.df.options == 'Email') { | |||
if(v+''=='')return ''; | |||
if(!validate_email(v)) { | |||
msgprint(wn._("Invalid Email") + ": " + v); | |||
callback(""); | |||
} else | |||
callback(v); | |||
} else { | |||
callback(v); | |||
} | |||
} | |||
}); | |||
wn.ui.form.ControlPassword = wn.ui.form.ControlData.extend({ | |||
input_type: "password" | |||
}); | |||
wn.ui.form.ControlInt = wn.ui.form.ControlData.extend({ | |||
make_input: function() { | |||
this._super(); | |||
this.$input.css({"text-align": "right"}) | |||
}, | |||
validate: function(value, callback) { | |||
return callback(cint(value, null)); | |||
} | |||
}); | |||
wn.ui.form.ControlFloat = wn.ui.form.ControlInt.extend({ | |||
validate: function(value, callback) { | |||
return callback(isNaN(parseFloat(value)) ? null : flt(value)); | |||
}, | |||
format_for_input: function(value) { | |||
value = format_number(parseFloat(value), | |||
null, cint(wn.boot.sysdefaults.float_precision, null)); | |||
return isNaN(value) ? "" : value; | |||
} | |||
}); | |||
wn.ui.form.ControlCurrency = wn.ui.form.ControlFloat.extend({ | |||
format_for_input: function(value) { | |||
value = format_number(parseFloat(value), | |||
get_number_format(this.get_currency())); | |||
return isNaN(value) ? "" : value; | |||
}, | |||
get_currency: function() { | |||
return wn.meta.get_field_currency(this.df, this.get_doc()); | |||
} | |||
}); | |||
wn.ui.form.ControlPercent = wn.ui.form.ControlFloat; | |||
wn.ui.form.ControlDate = wn.ui.form.ControlData.extend({ | |||
datepicker_options: { | |||
altFormat:'yy-mm-dd', | |||
changeYear: true, | |||
yearRange: "-70Y:+10Y", | |||
}, | |||
make_input: function() { | |||
this._super(); | |||
this.set_datepicker(); | |||
}, | |||
set_datepicker: function() { | |||
this.datepicker_options.dateFormat = | |||
(wn.boot.sysdefaults.date_format || 'yy-mm-dd').replace('yyyy','yy') | |||
this.$input.datepicker(this.datepicker_options); | |||
}, | |||
parse: function(value) { | |||
return dateutil.user_to_str(value); | |||
}, | |||
format_for_input: function(value) { | |||
return dateutil.str_to_user(value); | |||
}, | |||
validate: function(value, callback) { | |||
var value = wn.datetime.validate(value); | |||
if(!value) { | |||
msgprint (wn._("Date must be in format") + ": " + (sys_defaults.date_format || "yyyy-mm-dd")); | |||
callback(""); | |||
} | |||
return callback(value); | |||
} | |||
}) | |||
import_timepicker = function() { | |||
wn.require("lib/js/lib/jquery/jquery.ui.slider.min.js"); | |||
wn.require("lib/js/lib/jquery/jquery.ui.sliderAccess.js"); | |||
wn.require("lib/js/lib/jquery/jquery.ui.timepicker-addon.css"); | |||
wn.require("lib/js/lib/jquery/jquery.ui.timepicker-addon.js"); | |||
} | |||
wn.ui.form.ControlTime = wn.ui.form.ControlData.extend({ | |||
make_input: function() { | |||
import_timepicker(); | |||
this._super(); | |||
this.$input.timepicker({ | |||
timeFormat: 'hh:mm:ss', | |||
}); | |||
} | |||
}); | |||
wn.ui.form.ControlDateTime = wn.ui.form.ControlDate.extend({ | |||
set_datepicker: function() { | |||
this.datepicker_options.dateFormat = | |||
(wn.boot.sysdefaults.date_format || 'yy-mm-dd').replace('yyyy','yy') | |||
this.datepicker_options.timeFormat = "hh:mm:ss"; | |||
this.$input.datetimepicker(this.datepicker_options); | |||
}, | |||
make_input: function() { | |||
import_timepicker(); | |||
this._super(); | |||
}, | |||
}); | |||
wn.ui.form.ControlText = wn.ui.form.ControlData.extend({ | |||
html_element: "textarea" | |||
}); | |||
wn.ui.form.ControlLongText = wn.ui.form.ControlData.extend({ | |||
html_element: "textarea" | |||
}); | |||
wn.ui.form.ControlSmallText = wn.ui.form.ControlText.extend({ | |||
html_element: "textarea" | |||
}); | |||
wn.ui.form.ControlCheck = wn.ui.form.ControlData.extend({ | |||
input_type: "checkbox", | |||
parse: function(value) { | |||
return this.input.checked ? 1 : 0; | |||
}, | |||
validate: function(value, callback) { | |||
return callback(cint(value)); | |||
}, | |||
set_input: function(value) { | |||
this.input.checked = value ? 1 : 0; | |||
} | |||
}); | |||
wn.ui.form.ControlButton = wn.ui.form.ControlData.extend({ | |||
make_input: function() { | |||
var me = this; | |||
this.$input = $('<button class="btn">') | |||
.prependTo(me.input_area) | |||
.on("click", function() { | |||
if(me.frm && me.frm.cscript) { | |||
if(me.frm.cscript[me.df.fieldname]) { | |||
me.frm.runclientscript(me.df.fieldname, me.doctype, me.docname); | |||
} else { | |||
me.frm.runscript(me.df.options, me); | |||
} | |||
} | |||
}); | |||
this.input = this.$input.get(0); | |||
this.has_input = true; | |||
}, | |||
set_label: function() { | |||
this.$input && this.$input.html(this.df.label); | |||
} | |||
}); | |||
wn.ui.form.ControlSelect = wn.ui.form.ControlData.extend({ | |||
html_element: "select", | |||
make_input: function() { | |||
var me = this; | |||
this._super(); | |||
if(this.df.options=="attach_files:") { | |||
this.setup_attachment(); | |||
} | |||
this.set_options(); | |||
this.$wrapper.on("refresh", function() { | |||
me.set_options(); | |||
var value = wn.model.get_value(me.doctype, me.docname, me.fieldname); | |||
if(me.doctype && me.docname) { | |||
// model value is not an option, | |||
// set the default option (displayed) | |||
if(me.$input.val() != value) { | |||
me.set_model_value(me.$input.val()); | |||
} | |||
} | |||
}) | |||
}, | |||
setup_attachment: function() { | |||
var me = this; | |||
$(this.input).css({"width": "70%"}); | |||
$("<button class='btn' title='"+ wn._("Add attachment") + "'\ | |||
style='margin-bottom: 9px; \ | |||
padding-left: 6px; padding-right: 6px; margin-left: 6px;'>\ | |||
<i class='icon-plus'></i></button>") | |||
.click(function() { | |||
me.frm.attachments.new_attachment(); | |||
}) | |||
.appendTo(this.input_area); | |||
}, | |||
set_options: function() { | |||
var options = this.df.options || []; | |||
if(this.df.options=="attach_files:") { | |||
options = this.get_file_attachment_list(); | |||
} else if(typeof this.df.options==="string") { | |||
options = this.df.options.split("\n"); | |||
} | |||
if(this.in_filter && options[0] != "") { | |||
options = add_lists([''], options); | |||
} | |||
this.$input.empty().add_options(options || []); | |||
}, | |||
get_file_attachment_list: function() { | |||
if(!this.frm) return; | |||
var fl = this.frm.doc.file_list; | |||
if(fl) { | |||
this.set_description(""); | |||
var fl = JSON.parse(fl), | |||
options = []; | |||
for(var fname in fl) { | |||
if(fname.substr(0,4)!="http") | |||
fname = "files/" + fname; | |||
options.push(fname); | |||
} | |||
return options; | |||
} else { | |||
this.set_description(wn._("Please attach a file first.")) | |||
return [""]; | |||
} | |||
} | |||
}); |
@@ -0,0 +1,72 @@ | |||
wn.ui.form.Footer = Class.extend({ | |||
init: function(opts) { | |||
var me = this; | |||
$.extend(this, opts); | |||
this.make(); | |||
this.make_attachments(); | |||
this.make_comments(); | |||
// render-complete | |||
$(this.frm.wrapper).on("render_complete", function() { | |||
me.refresh(); | |||
}) | |||
}, | |||
make: function() { | |||
this.wrapper = $('<div class="form-footer row">\ | |||
<!--i class="icon-cut" style="margin-top: -23px; margin-bottom: 23px; \ | |||
display: block; margin-left: 15px; color: #888;"></i-->\ | |||
<div class="col-span-12">\ | |||
<div class="save-area">\ | |||
<button class="btn btn-save btn-primary">\ | |||
<i class="icon-save"></i> Save</button>\ | |||
</div>\ | |||
</div>\ | |||
<div class="col-span-8">\ | |||
<div class="form-comments">\ | |||
<h4><i class="icon-comments"></i> Comments</h4>\ | |||
</div>\ | |||
</div>\ | |||
<div class="col-span-4">\ | |||
<div class="form-attachments">\ | |||
<h5><i class="icon-paper-clip"></i> Attachments</h5>\ | |||
</div>\ | |||
</div>\ | |||
</div>') | |||
.appendTo(this.parent); | |||
this.wrapper.find(".btn-save").click(function() { | |||
me.frm.save('Save', null, this); | |||
}) | |||
}, | |||
make_attachments: function() { | |||
this.frm.attachments = new wn.ui.form.Attachments({ | |||
parent: this.wrapper.find(".form-attachments"), | |||
frm: this.frm | |||
}); | |||
}, | |||
make_comments: function() { | |||
this.frm.comments = new wn.ui.form.Comments({ | |||
parent: this.wrapper.find(".form-comments"), | |||
frm: this.frm | |||
}) | |||
}, | |||
show_save: function() { | |||
this.wrapper.find(".save-area").toggle(true); | |||
}, | |||
hide_save: function() { | |||
this.wrapper.find(".save-area").toggle(false); | |||
}, | |||
refresh: function() { | |||
this.toggle_save(); | |||
this.frm.attachments.refresh(); | |||
this.frm.comments.refresh(); | |||
// show save? | |||
}, | |||
toggle_save: function() { | |||
if(this.frm_head && this.appframe.toolbar | |||
&& this.appframe.buttons.Save && !this.save_disabled | |||
&& (this.fields && this.fields.length > 7)) { | |||
this.show_save(); | |||
} else { | |||
this.hide_save(); | |||
} | |||
} | |||
}); |
@@ -7,11 +7,9 @@ wn.form.formatters = { | |||
return value==null ? "" : value | |||
}, | |||
Float: function(value, docfield) { | |||
var decimals = wn.boot.sysdefaults.float_precision ? | |||
parseInt(wn.boot.sysdefaults.float_precision) : null; | |||
return "<div style='text-align: right'>" + | |||
format_number(value, null, decimals) + "</div>"; | |||
var decimals = cint(wn.boot.sysdefaults.float_precision, null); | |||
return "<div style='text-align: right'>" + format_number(value, null, decimals) | |||
+ "</div>"; | |||
}, | |||
Int: function(value) { | |||
return cint(value); | |||
@@ -64,7 +64,7 @@ wn.ui.form.Layout = Class.extend({ | |||
}, | |||
make_section: function(df) { | |||
if(this.section) { | |||
$("<hr>").appendTo(this.wrapper); | |||
//$("<hr>").appendTo(this.wrapper); | |||
} | |||
this.section = $('<div class="row">').appendTo(this.wrapper); | |||
this.frm.sections.push(this.section); | |||
@@ -45,6 +45,7 @@ $.extend(wn.model, { | |||
], | |||
new_names: {}, | |||
events: {}, | |||
get_std_field: function(fieldname) { | |||
var docfield = $.map([].concat(wn.model.std_fields).concat(wn.model.std_fields_table), | |||
@@ -179,8 +180,35 @@ $.extend(wn.model, { | |||
}, | |||
get_value: function(doctype, filters, fieldname) { | |||
var l = wn.model.get(doctype, filters); | |||
return (l.length && l[0]) ? l[0][fieldname] : null; | |||
if(typeof filters==="string") { | |||
return locals[doctype] && locals[doctype][filters] | |||
&& locals[doctype][filters][fieldname]; | |||
} else { | |||
var l = wn.model.get(doctype, filters); | |||
return (l.length && l[0]) ? l[0][fieldname] : null; | |||
} | |||
}, | |||
set_value: function(doctype, name, fieldname, value) { | |||
var doc = locals[doctype] && locals[doctype][name]; | |||
if(doc) { | |||
doc[fieldname] = value; | |||
wn.model.trigger(doctype, name, fieldname, value); | |||
} | |||
}, | |||
on: function(doctype, name, fieldname, fn) { | |||
wn.provide("locals." + doctype + "." + name + "." + fieldname); | |||
locals[doctype][name][fieldname] = fn; | |||
}, | |||
trigger: function(doctype, name, fieldname, value) { | |||
if(wn.model.events[doctype] && wn.model.events[doctype][name]) { | |||
var ev = wn.model.events[doctype][name]; | |||
ev[fieldname] && ev[fieldname](value, doctype, name, fieldname); | |||
ev["*"] && ev["*"](value, doctype, name, fieldname); | |||
} | |||
}, | |||
get_doc: function(doctype, name) { | |||
@@ -7,8 +7,14 @@ wn.ui.AppFrame = Class.extend({ | |||
init: function(parent, title, module) { | |||
this.set_document_title = true; | |||
this.buttons = {}; | |||
this.$w = $('<div class="col-span-12"></div>').prependTo(parent); | |||
this.$w = $('<div class="col-span-12">\ | |||
<div class="row appframe-header">\ | |||
<div class="col-span-12"></div>\ | |||
</div>\ | |||
</div>') | |||
.prependTo(parent) | |||
.find(".appframe-header div"); | |||
$('<!-- div>\ | |||
<ul class="breadcrumb" style="height: 32px;">\ | |||
<span class="appframe-right pull-right">\ | |||
@@ -26,7 +32,6 @@ wn.ui.AppFrame = Class.extend({ | |||
style="margin-top: -10px;"></div>\ | |||
<div class="btn-group appframe-toolbar" \ | |||
style="display: none; margin-top: 15px;"></div>\ | |||
<hr>\ | |||
').appendTo(this.$w); | |||
this.$w.find('.close').click(function() { | |||