@@ -99,21 +99,11 @@ set_field_tip = function(n,txt) { | |||||
refresh_field = function(n, docname, table_field) { | refresh_field = function(n, docname, table_field) { | ||||
// multiple | // multiple | ||||
if(typeof n==typeof []) refresh_many(n, docname, table_field); | |||||
if(typeof n==typeof []) | |||||
refresh_many(n, docname, table_field); | |||||
if(table_field) { // for table | if(table_field) { // for table | ||||
if(_f.frm_dialog && _f.frm_dialog.display) { | |||||
_f.frm_dialog.cur_frm.refresh_field(n); | |||||
} else { | |||||
var g = _f.cur_grid_cell; | |||||
if(g) var hc = g.grid.head_row.cells[g.cellIndex]; | |||||
if(g && hc && hc.fieldname==n && g.row.docname==docname) { | |||||
hc.template.refresh(); // if active | |||||
} else if (cur_frm.fields_dict[table_field]) { | |||||
cur_frm.fields_dict[table_field].grid.refresh(); | |||||
} | |||||
} | |||||
cur_frm.fields_dict[table_field].grid.grid_rows_by_docname[docname].refresh_field(n); | |||||
} else if(cur_frm) { | } else if(cur_frm) { | ||||
cur_frm.refresh_field(n) | cur_frm.refresh_field(n) | ||||
} | } | ||||
@@ -126,6 +126,7 @@ _f.Frm.prototype.setup = function() { | |||||
this.script_manager = new wn.ui.form.ScriptManager({ | this.script_manager = new wn.ui.form.ScriptManager({ | ||||
frm: this | frm: this | ||||
}) | }) | ||||
this.watch_model_updates(); | |||||
this.setup_header(); | this.setup_header(); | ||||
@@ -134,9 +135,35 @@ _f.Frm.prototype.setup = function() { | |||||
parent: this.layout_main | parent: this.layout_main | ||||
}) | }) | ||||
this.setup_done = true; | this.setup_done = true; | ||||
} | } | ||||
_f.Frm.prototype.watch_model_updates = function() { | |||||
// watch model updates | |||||
var me = this; | |||||
// on main doc | |||||
wn.model.on(me.doctype, "*", function(fieldname, value, doc) { | |||||
// set input | |||||
if(doc.name===me.docname) { | |||||
me.fields_dict[fieldname] | |||||
&& me.fields_dict[fieldname].set_input(value); | |||||
me.script_manager.trigger(fieldname, doc.doctype, doc.name); | |||||
} | |||||
}) | |||||
// on table fields | |||||
$.each(wn.model.get("DocField", {fieldtype:"Table", parent: me.doctype}), function(i, df) { | |||||
wn.model.on(df.options, "*", function(fieldname, value, doc) { | |||||
if(doc.parent===me.docname) { | |||||
me.fields_dict[df.fieldname].grid.set_value(fieldname, value, doc); | |||||
me.script_manager.trigger(fieldname, doc.doctype, doc.name); | |||||
} | |||||
}) | |||||
}) | |||||
} | |||||
_f.Frm.prototype.setup_print_layout = function() { | _f.Frm.prototype.setup_print_layout = function() { | ||||
var me = this; | var me = this; | ||||
@@ -47,8 +47,11 @@ wn.ui.form.Control = Class.extend({ | |||||
this.validate ? this.validate(value, set) : set(value); | this.validate ? this.validate(value, set) : set(value); | ||||
}, | }, | ||||
set_model_value: function(value) { | set_model_value: function(value) { | ||||
wn.model.set_value(this.doctype, this.docname, this.df.fieldname, value); | |||||
this.frm && this.frm.dirty(); | |||||
if(this.last_value!==value) { | |||||
wn.model.set_value(this.doctype, this.docname, this.df.fieldname, value); | |||||
this.frm && this.frm.dirty(); | |||||
this.last_value = value; | |||||
} | |||||
}, | }, | ||||
}); | }); | ||||
@@ -207,6 +210,7 @@ wn.ui.form.ControlData = wn.ui.form.ControlInput.extend({ | |||||
}, | }, | ||||
set_input: function(val) { | set_input: function(val) { | ||||
this.$input.val(this.format_for_input(val)); | this.$input.val(this.format_for_input(val)); | ||||
this.last_value = val; | |||||
}, | }, | ||||
get_value: function() { | get_value: function() { | ||||
return this.$input.val(); | return this.$input.val(); | ||||
@@ -381,6 +385,7 @@ wn.ui.form.ControlCheck = wn.ui.form.ControlData.extend({ | |||||
}, | }, | ||||
set_input: function(value) { | set_input: function(value) { | ||||
this.input.checked = value ? 1 : 0; | this.input.checked = value ? 1 : 0; | ||||
this.last_value = value; | |||||
} | } | ||||
}); | }); | ||||
@@ -427,8 +432,10 @@ wn.ui.form.ControlSelect = wn.ui.form.ControlData.extend({ | |||||
// model value is not an option, | // model value is not an option, | ||||
// set the default option (displayed) | // set the default option (displayed) | ||||
var model_value = wn.model.get_value(this.doctype, this.docname, this.df.fieldname); | var model_value = wn.model.get_value(this.doctype, this.docname, this.df.fieldname); | ||||
if(this.$input.val() != model_value) { | |||||
if(this.$input.val() != (model_value || "")) { | |||||
this.set_model_value(this.$input.val()); | this.set_model_value(this.$input.val()); | ||||
} else { | |||||
this.last_value = value; | |||||
} | } | ||||
} | } | ||||
}, | }, | ||||
@@ -503,7 +510,15 @@ wn.ui.form.ControlLink = wn.ui.form.ControlData.extend({ | |||||
this.$input = this.$input_area.find('input'); | this.$input = this.$input_area.find('input'); | ||||
this.input = this.$input.get(0); | this.input = this.$input.get(0); | ||||
this.has_input = true; | this.has_input = true; | ||||
this.bind_change_event(); | |||||
//this.bind_change_event(); | |||||
var me = this; | |||||
this.$input.on("blur", function() { | |||||
if(me.doctype && me.docname && !me.autocomplete_open) { | |||||
var value = me.get_value(); | |||||
if(value!==me.last_value) { | |||||
me.parse_validate_and_set_in_model(value); | |||||
} | |||||
}}); | |||||
this.setup_buttons(); | this.setup_buttons(); | ||||
this.setup_autocomplete(); | this.setup_autocomplete(); | ||||
}, | }, | ||||
@@ -572,6 +587,12 @@ wn.ui.form.ControlLink = wn.ui.form.ControlData.extend({ | |||||
}, | }, | ||||
}); | }); | ||||
}, | }, | ||||
open: function(event, ui) { | |||||
me.autocomplete_open = true; | |||||
}, | |||||
close: function(event, ui) { | |||||
me.autocomplete_open = false; | |||||
}, | |||||
select: function(event, ui) { | select: function(event, ui) { | ||||
me.set_model_value(ui.item.value); | me.set_model_value(ui.item.value); | ||||
} | } | ||||
@@ -621,7 +642,6 @@ wn.ui.form.ControlLink = wn.ui.form.ControlData.extend({ | |||||
}, | }, | ||||
set_fetch_values: function() { | set_fetch_values: function() { | ||||
var fl = this.frm.fetch_dict[this.df.fieldname].fields; | var fl = this.frm.fetch_dict[this.df.fieldname].fields; | ||||
var changed_fields = []; | |||||
for(var i=0; i< fl.length; i++) { | for(var i=0; i< fl.length; i++) { | ||||
wn.model.set_value(this.doctype, this.docname. fl[i], fetch_values[i]); | wn.model.set_value(this.doctype, this.docname. fl[i], fetch_values[i]); | ||||
} | } | ||||
@@ -647,6 +667,7 @@ wn.ui.form.ControlCode = wn.ui.form.ControlInput.extend({ | |||||
}, | }, | ||||
set_input: function(value) { | set_input: function(value) { | ||||
this.editor.set_input(value); | this.editor.set_input(value); | ||||
this.last_value = value; | |||||
} | } | ||||
}); | }); | ||||
@@ -39,38 +39,61 @@ wn.ui.form.Grid = Class.extend({ | |||||
refresh: function() { | refresh: function() { | ||||
!this.wrapper && this.make(); | !this.wrapper && this.make(); | ||||
var me = this, | var me = this, | ||||
$rows = $(me.parent).find(".rows"); | |||||
var open_row = $(".grid-row-open").data("grid_row"); | |||||
this.wrapper.find(".grid-row").remove(); | |||||
this.make_head(); | |||||
$rows = $(me.parent).find(".rows"), | |||||
data = this.get_data(); | |||||
this.display_status = wn.perm.get_field_display_status(this.df, this.frm.doc, | |||||
this.perm); | |||||
$.each(this.get_data() || [], function(ri, d) { | |||||
var grid_row = new wn.ui.form.GridRow({ | |||||
parent: $rows, | |||||
parent_df: me.df, | |||||
docfields: me.docfields, | |||||
doc: d, | |||||
frm: me.frm, | |||||
grid: me | |||||
if(this.data_rows_are_same(data)) { | |||||
// soft refresh | |||||
$.each(this.grid_rows, function(i, g) { | |||||
g.refresh(); | |||||
}); | |||||
} else { | |||||
// redraw | |||||
this.wrapper.find(".grid-row").remove(); | |||||
this.make_head(); | |||||
this.grid_rows = []; | |||||
this.grid_rows_by_docname = {}; | |||||
$.each(data || [], function(ri, d) { | |||||
var grid_row = new wn.ui.form.GridRow({ | |||||
parent: $rows, | |||||
parent_df: me.df, | |||||
docfields: me.docfields, | |||||
doc: d, | |||||
frm: me.frm, | |||||
grid: me | |||||
}); | |||||
me.grid_rows.push(grid_row) | |||||
me.grid_rows_by_docname[d.name] = grid_row; | |||||
}); | }); | ||||
// open if last open | |||||
if(open_row && d.name===open_row.doc.name) { | |||||
open_row.toggle_view(true); | |||||
} | |||||
}); | |||||
this.display_status = wn.perm.get_field_display_status(this.df, this.frm.doc, | |||||
this.perm); | |||||
this.wrapper.find(".grid-add-row").toggle(this.display_status=="Write" | |||||
&& !this.static_rows); | |||||
if(this.display_status=="Write" && !this.static_rows) { | |||||
this.make_sortable($rows); | |||||
} | |||||
this.wrapper.find(".grid-add-row").toggle(this.display_status=="Write" | |||||
&& !this.static_rows); | |||||
if(this.display_status=="Write" && !this.static_rows) { | |||||
this.make_sortable($rows); | |||||
this.last_display_status = this.display_status; | |||||
this.last_docname = this.frm.docname; | |||||
} | |||||
}, | |||||
refresh_row: function(docname) { | |||||
this.grid_rows_by_docname[docname] && | |||||
this.grid_rows_by_docname[docname].refresh(); | |||||
}, | |||||
data_rows_are_same: function(data) { | |||||
if(this.grid_rows) { | |||||
var same = data.length==this.grid_rows.length | |||||
&& this.display_status==this.last_display_status | |||||
&& this.frm.docname==this.last_docname | |||||
&& !$.map(this.grid_rows, function(g, i) { | |||||
return g.doc.name==data[i].name ? null : true; | |||||
}).length; | |||||
return same; | |||||
} | } | ||||
}, | }, | ||||
make_sortable: function($rows) { | make_sortable: function($rows) { | ||||
var me =this; | var me =this; | ||||
@@ -102,6 +125,9 @@ wn.ui.form.Grid = Class.extend({ | |||||
this.fieldinfo[fieldname] = {} | this.fieldinfo[fieldname] = {} | ||||
return this.fieldinfo[fieldname]; | return this.fieldinfo[fieldname]; | ||||
}, | }, | ||||
set_value: function(fieldname, value, doc) { | |||||
this.grid_rows_by_docname[doc.name].set_value(fieldname, value); | |||||
} | |||||
}); | }); | ||||
wn.ui.form.GridRow = Class.extend({ | wn.ui.form.GridRow = Class.extend({ | ||||
@@ -118,7 +144,7 @@ wn.ui.form.GridRow = Class.extend({ | |||||
<div class="panel-heading">\ | <div class="panel-heading">\ | ||||
<div class="toolbar" style="height: 36px;">\ | <div class="toolbar" style="height: 36px;">\ | ||||
Editing Row #<span class="row-index"></span>\ | Editing Row #<span class="row-index"></span>\ | ||||
<button class="btn pull-right" \ | |||||
<button class="btn btn-success pull-right" \ | |||||
title="'+wn._("Close")+'"\ | title="'+wn._("Close")+'"\ | ||||
style="margin-left: 7px;">\ | style="margin-left: 7px;">\ | ||||
<i class="icon-ok"></i></button>\ | <i class="icon-ok"></i></button>\ | ||||
@@ -181,6 +207,19 @@ wn.ui.form.GridRow = Class.extend({ | |||||
return false; | return false; | ||||
}) | }) | ||||
}, | }, | ||||
refresh: function() { | |||||
this.doc = locals[this.doc.doctype][this.doc.name]; | |||||
// re write columns | |||||
this.make_columns(); | |||||
// refersh form fields | |||||
if(this.show) { | |||||
$.each(this.fields, function(i, f) { | |||||
f.refresh(); | |||||
}); | |||||
} | |||||
}, | |||||
make_columns: function() { | make_columns: function() { | ||||
var me = this, | var me = this, | ||||
total_colsize = 1; | total_colsize = 1; | ||||
@@ -205,20 +244,26 @@ wn.ui.form.GridRow = Class.extend({ | |||||
if(total_colsize > 12) | if(total_colsize > 12) | ||||
return false; | return false; | ||||
$('<div class="col-span-'+colsize+'">' | $('<div class="col-span-'+colsize+'">' | ||||
+ (txt)+ '</div>') | |||||
+ txt + '</div>') | |||||
.css({ | .css({ | ||||
"overflow": "hidden", | "overflow": "hidden", | ||||
"text-overflow": "ellipsis", | "text-overflow": "ellipsis", | ||||
"white-space": "nowrap" | "white-space": "nowrap" | ||||
}) | }) | ||||
.attr("data-fieldname", df.fieldname) | |||||
.data("df", df) | |||||
.appendTo(me.row) | .appendTo(me.row) | ||||
} | } | ||||
}); | }); | ||||
}, | }, | ||||
toggle_view: function(show) { | toggle_view: function(show) { | ||||
this.doc = locals[this.doc.doctype][this.doc.name]; | |||||
// hide other | // hide other | ||||
var open_row = $(".grid-row-open").data("grid_row"), | var open_row = $(".grid-row-open").data("grid_row"), | ||||
me = this; | me = this; | ||||
this.fields = []; | |||||
this.fields_dict = {}; | |||||
open_row && open_row != this && open_row.toggle_view(false); | open_row && open_row != this && open_row.toggle_view(false); | ||||
@@ -265,6 +310,9 @@ wn.ui.form.GridRow = Class.extend({ | |||||
// used for setting custom get queries in links | // used for setting custom get queries in links | ||||
if(me.grid.fieldinfo[df.fieldname]) | if(me.grid.fieldinfo[df.fieldname]) | ||||
$.extend(fieldobj, me.grid.fieldinfo[df.fieldname]); | $.extend(fieldobj, me.grid.fieldinfo[df.fieldname]); | ||||
me.fields.push(fieldobj); | |||||
me.fields_dict[df.fieldname] = fieldobj; | |||||
cnt++; | cnt++; | ||||
} | } | ||||
}); | }); | ||||
@@ -278,5 +326,27 @@ wn.ui.form.GridRow = Class.extend({ | |||||
this.wrapper.data({ | this.wrapper.data({ | ||||
"doc": this.doc | "doc": this.doc | ||||
}) | }) | ||||
} | |||||
}, | |||||
set_value: function(fieldname, value) { | |||||
// in row | |||||
var $col = this.row.find("[data-fieldname='"+fieldname+"']"); | |||||
$col.length && $col.html(wn.format(value, $col.data("df"), null, this.doc)); | |||||
// in form | |||||
if(this.fields_dict && this.fields_dict[fieldname]) { | |||||
this.fields_dict[fieldname].set_input(value); | |||||
} | |||||
}, | |||||
refresh_field: function(fieldname) { | |||||
var $col = this.row.find("[data-fieldname='"+fieldname+"']"); | |||||
if($col.length) { | |||||
var value = wn.model.get_value(this.doc.doctype, this.doc.name, fieldname); | |||||
$col.html(wn.format(value, $col.data("df"), null, this.doc)); | |||||
} | |||||
// in form | |||||
if(this.fields_dict && this.fields_dict[fieldname]) { | |||||
this.fields_dict[fieldname].refresh(); | |||||
} | |||||
}, | |||||
}); | }); |
@@ -1,24 +1,7 @@ | |||||
wn.ui.form.ScriptManager = Class.extend({ | wn.ui.form.ScriptManager = Class.extend({ | ||||
init: function(opts) { | init: function(opts) { | ||||
$.extend(this, opts); | $.extend(this, opts); | ||||
this.setup(); | |||||
var me = this; | |||||
// watch model updates | |||||
// on main doc | |||||
wn.model.on(me.frm.doctype, "*", function(value, doctype, name, fieldname) { | |||||
me.trigger(fieldname, doctype, name); | |||||
}) | |||||
// on table fields | |||||
$.each(wn.model.get("DocField", {fieldtype:"Table", parent: me.frm.doctype}), function(i, df) { | |||||
wn.model.on(df.options, "*", function(value, doctype, name, fieldname) { | |||||
me.trigger(fieldname, doctype, name); | |||||
}) | |||||
}) | |||||
this.setup(); | |||||
}, | }, | ||||
trigger: function(event_name, doctype, name) { | trigger: function(event_name, doctype, name) { | ||||
doctype = doctype || this.frm.doctype; | doctype = doctype || this.frm.doctype; | ||||
@@ -13,7 +13,6 @@ wn.ui.form.Toolbar = Class.extend({ | |||||
this.appframe.clear_buttons(); | this.appframe.clear_buttons(); | ||||
this.make_file_menu(); | this.make_file_menu(); | ||||
this.make_view_menu(); | this.make_view_menu(); | ||||
this.set_title_button(); | |||||
this.set_title_image(); | this.set_title_image(); | ||||
this.show_title_as_dirty(); | this.show_title_as_dirty(); | ||||
}, | }, | ||||
@@ -127,10 +126,11 @@ wn.ui.form.Toolbar = Class.extend({ | |||||
var p = this.frm.perm[0]; | var p = this.frm.perm[0]; | ||||
var has_workflow = wn.model.get("Workflow", {document_type: me.frm.doctype}).length; | var has_workflow = wn.model.get("Workflow", {document_type: me.frm.doctype}).length; | ||||
if(has_workflow && this.frm.doc.__islocal) { | |||||
if(has_workflow && (this.frm.doc.__islocal || this.frm.doc.__unsaved)) { | |||||
this.make_save_button(); | this.make_save_button(); | ||||
} else if(!has_workflow) { | } else if(!has_workflow) { | ||||
if(docstatus==0 && p[SUBMIT] && (!me.frm.doc.__islocal)) { | |||||
if(docstatus==0 && p[SUBMIT] && (!me.frm.doc.__islocal) | |||||
&& (!me.frm.doc.__unsaved)) { | |||||
this.appframe.add_button('Submit', function() { | this.appframe.add_button('Submit', function() { | ||||
me.frm.savesubmit(this);}, 'icon-lock', true).addClass("btn-primary"); | me.frm.savesubmit(this);}, 'icon-lock', true).addClass("btn-primary"); | ||||
} | } | ||||
@@ -169,7 +169,8 @@ wn.ui.form.Toolbar = Class.extend({ | |||||
}, | }, | ||||
show_title_as_dirty: function() { | show_title_as_dirty: function() { | ||||
this.appframe.get_title_area() | this.appframe.get_title_area() | ||||
.toggleClass("text-warning", this.frm.doc.__unsaved); | |||||
.toggleClass("text-warning", this.frm.doc.__unsaved ? true : false); | |||||
this.set_title_button(); | |||||
}, | }, | ||||
make_actions_menu: function() { | make_actions_menu: function() { | ||||
if(this.actions_setup) return; | if(this.actions_setup) return; | ||||
@@ -191,9 +191,10 @@ $.extend(wn.model, { | |||||
set_value: function(doctype, name, fieldname, value) { | set_value: function(doctype, name, fieldname, value) { | ||||
var doc = locals[doctype] && locals[doctype][name] || null; | var doc = locals[doctype] && locals[doctype][name] || null; | ||||
if(doc) { | |||||
if(doc && doc[fieldname] !== value) { | |||||
doc[fieldname] = value; | doc[fieldname] = value; | ||||
wn.model.trigger(doctype, name, fieldname, value); | |||||
console.log([fieldname, value]) | |||||
wn.model.trigger(fieldname, value, doc); | |||||
} | } | ||||
}, | }, | ||||
@@ -202,19 +203,19 @@ $.extend(wn.model, { | |||||
wn.model.events[doctype][fieldname] = fn; | wn.model.events[doctype][fieldname] = fn; | ||||
}, | }, | ||||
trigger: function(doctype, name, fieldname, value) { | |||||
trigger: function(fieldname, value, doc) { | |||||
var run = function(fn) { | var run = function(fn) { | ||||
fn && fn(value, doctype, name, fieldname) | |||||
fn && fn(fieldname, value, doc) | |||||
}; | }; | ||||
if(wn.model.events[doctype]) { | |||||
if(wn.model.events[doc.doctype]) { | |||||
// doctype-level | // doctype-level | ||||
if(wn.model.events[doctype]['*']) { | |||||
wn.model.events[doctype]['*'](value, doctype, name, fieldname); | |||||
if(wn.model.events[doc.doctype]['*']) { | |||||
wn.model.events[doc.doctype]['*'](fieldname, value, doc); | |||||
}; | }; | ||||
// field-level | // field-level | ||||
if(wn.model.events[doctype][fieldname]) { | |||||
wn.model.events[doctype][fieldname](value, doctype, name, fieldname); | |||||
if(wn.model.events[doc.doctype][fieldname]) { | |||||
wn.model.events[doc.doctype][fieldname](fieldname, value, doc); | |||||
}; | }; | ||||
}; | }; | ||||
}, | }, | ||||
@@ -21,37 +21,34 @@ | |||||
// | // | ||||
$.extend(wn.model, { | $.extend(wn.model, { | ||||
sync: function(doclist, sync_in) { | |||||
if(!sync_in) | |||||
sync_in = locals; | |||||
sync: function(doclist) { | |||||
if(doclist._kl) | if(doclist._kl) | ||||
doclist = wn.model.expand(doclist); | doclist = wn.model.expand(doclist); | ||||
if(doclist && doclist.length && sync_in==locals) | |||||
if(doclist && doclist.length) | |||||
wn.model.clear_doclist(doclist[0].doctype, doclist[0].name) | wn.model.clear_doclist(doclist[0].doctype, doclist[0].name) | ||||
$.each(doclist, function(i, d) { | $.each(doclist, function(i, d) { | ||||
if(!d.name) // get name (local if required) | if(!d.name) // get name (local if required) | ||||
d.name = wn.model.get_new_name(d.doctype); | d.name = wn.model.get_new_name(d.doctype); | ||||
if(!sync_in[d.doctype]) | |||||
sync_in[d.doctype] = {}; | |||||
if(!locals[d.doctype]) | |||||
locals[d.doctype] = {}; | |||||
sync_in[d.doctype][d.name] = d; | |||||
locals[d.doctype][d.name] = d; | |||||
d.__last_sync_on = new Date(); | d.__last_sync_on = new Date(); | ||||
if(cur_frm && cur_frm.doctype==d.doctype && cur_frm.docname==d.name) { | if(cur_frm && cur_frm.doctype==d.doctype && cur_frm.docname==d.name) { | ||||
cur_frm.doc = d; | cur_frm.doc = d; | ||||
} | } | ||||
if(d.doctype=='DocField') wn.meta.add_field(d); | if(d.doctype=='DocField') wn.meta.add_field(d); | ||||
if(d.doctype=='DocType') wn.meta.sync_messages(d); | if(d.doctype=='DocType') wn.meta.sync_messages(d); | ||||
if(d.localname) { | if(d.localname) { | ||||
wn.model.new_names[d.localname] = d.name; | wn.model.new_names[d.localname] = d.name; | ||||
$(document).trigger('rename', [d.doctype, d.localname, d.name]); | $(document).trigger('rename', [d.doctype, d.localname, d.name]); | ||||
delete sync_in[d.doctype][d.localname]; | |||||
delete locals[d.doctype][d.localname]; | |||||
} | } | ||||
}); | }); | ||||