From f48bbc904a64cb48cf03a978f38cecf35b87b3d4 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 6 May 2013 12:46:12 +0530 Subject: [PATCH] [form] [scripting] fixes and cleanups for new triggering system --- .../js/legacy/widgets/form/clientscriptAPI.js | 16 +-- public/js/legacy/widgets/form/form.js | 27 ++++ public/js/wn/form/control.js | 31 +++- public/js/wn/form/grid.js | 132 ++++++++++++++---- public/js/wn/form/script_manager.js | 19 +-- public/js/wn/form/toolbar.js | 9 +- public/js/wn/model/model.js | 19 +-- public/js/wn/model/sync.js | 21 ++- 8 files changed, 182 insertions(+), 92 deletions(-) diff --git a/public/js/legacy/widgets/form/clientscriptAPI.js b/public/js/legacy/widgets/form/clientscriptAPI.js index 0048bdac59..058263d75d 100644 --- a/public/js/legacy/widgets/form/clientscriptAPI.js +++ b/public/js/legacy/widgets/form/clientscriptAPI.js @@ -99,21 +99,11 @@ set_field_tip = function(n,txt) { refresh_field = function(n, docname, table_field) { // 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(_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) { cur_frm.refresh_field(n) } diff --git a/public/js/legacy/widgets/form/form.js b/public/js/legacy/widgets/form/form.js index 459b2e55ee..34a94ea693 100644 --- a/public/js/legacy/widgets/form/form.js +++ b/public/js/legacy/widgets/form/form.js @@ -126,6 +126,7 @@ _f.Frm.prototype.setup = function() { this.script_manager = new wn.ui.form.ScriptManager({ frm: this }) + this.watch_model_updates(); this.setup_header(); @@ -134,9 +135,35 @@ _f.Frm.prototype.setup = function() { parent: this.layout_main }) + 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() { var me = this; diff --git a/public/js/wn/form/control.js b/public/js/wn/form/control.js index e6c3be21e2..cc5e72f7ce 100644 --- a/public/js/wn/form/control.js +++ b/public/js/wn/form/control.js @@ -47,8 +47,11 @@ wn.ui.form.Control = Class.extend({ this.validate ? this.validate(value, set) : set(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) { this.$input.val(this.format_for_input(val)); + this.last_value = val; }, get_value: function() { return this.$input.val(); @@ -381,6 +385,7 @@ wn.ui.form.ControlCheck = wn.ui.form.ControlData.extend({ }, set_input: function(value) { 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, // set the default option (displayed) 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()); + } 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.get(0); 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_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) { me.set_model_value(ui.item.value); } @@ -621,7 +642,6 @@ wn.ui.form.ControlLink = wn.ui.form.ControlData.extend({ }, set_fetch_values: function() { var fl = this.frm.fetch_dict[this.df.fieldname].fields; - var changed_fields = []; for(var i=0; i< fl.length; 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) { this.editor.set_input(value); + this.last_value = value; } }); diff --git a/public/js/wn/form/grid.js b/public/js/wn/form/grid.js index aaad95b86e..9453ab4838 100644 --- a/public/js/wn/form/grid.js +++ b/public/js/wn/form/grid.js @@ -39,38 +39,61 @@ wn.ui.form.Grid = Class.extend({ refresh: function() { !this.wrapper && this.make(); 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(); - - $.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 - }); - - // open if last open - if(open_row && d.name===open_row.doc.name) { - open_row.toggle_view(true); - } - }); - + $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); - 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); + 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; + }); + + 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) { var me =this; @@ -102,6 +125,9 @@ wn.ui.form.Grid = Class.extend({ 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({ @@ -118,7 +144,7 @@ wn.ui.form.GridRow = Class.extend({
\
\ Editing Row #\ - \ @@ -181,6 +207,19 @@ wn.ui.form.GridRow = Class.extend({ 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() { var me = this, total_colsize = 1; @@ -205,20 +244,26 @@ wn.ui.form.GridRow = Class.extend({ if(total_colsize > 12) return false; $('
' - + (txt)+ '
') + + txt + '
') .css({ "overflow": "hidden", "text-overflow": "ellipsis", "white-space": "nowrap" }) + .attr("data-fieldname", df.fieldname) + .data("df", df) .appendTo(me.row) } }); }, toggle_view: function(show) { + this.doc = locals[this.doc.doctype][this.doc.name]; // hide other var open_row = $(".grid-row-open").data("grid_row"), me = this; + + this.fields = []; + this.fields_dict = {}; 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 if(me.grid.fieldinfo[df.fieldname]) $.extend(fieldobj, me.grid.fieldinfo[df.fieldname]); + + me.fields.push(fieldobj); + me.fields_dict[df.fieldname] = fieldobj; cnt++; } }); @@ -278,5 +326,27 @@ wn.ui.form.GridRow = Class.extend({ this.wrapper.data({ "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(); + } + }, }); \ No newline at end of file diff --git a/public/js/wn/form/script_manager.js b/public/js/wn/form/script_manager.js index 3fa0b15950..b96859f86d 100644 --- a/public/js/wn/form/script_manager.js +++ b/public/js/wn/form/script_manager.js @@ -1,24 +1,7 @@ wn.ui.form.ScriptManager = Class.extend({ init: function(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) { doctype = doctype || this.frm.doctype; diff --git a/public/js/wn/form/toolbar.js b/public/js/wn/form/toolbar.js index 62eb499a12..90d453a6d9 100644 --- a/public/js/wn/form/toolbar.js +++ b/public/js/wn/form/toolbar.js @@ -13,7 +13,6 @@ wn.ui.form.Toolbar = Class.extend({ this.appframe.clear_buttons(); this.make_file_menu(); this.make_view_menu(); - this.set_title_button(); this.set_title_image(); this.show_title_as_dirty(); }, @@ -127,10 +126,11 @@ wn.ui.form.Toolbar = Class.extend({ var p = this.frm.perm[0]; 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(); } 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() { 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() { 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() { if(this.actions_setup) return; diff --git a/public/js/wn/model/model.js b/public/js/wn/model/model.js index 7aa818a592..328e5d0b56 100644 --- a/public/js/wn/model/model.js +++ b/public/js/wn/model/model.js @@ -191,9 +191,10 @@ $.extend(wn.model, { set_value: function(doctype, name, fieldname, value) { var doc = locals[doctype] && locals[doctype][name] || null; - if(doc) { + if(doc && 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; }, - trigger: function(doctype, name, fieldname, value) { + trigger: function(fieldname, value, doc) { 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 - 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 - 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); }; }; }, diff --git a/public/js/wn/model/sync.js b/public/js/wn/model/sync.js index 82c7a94a46..e8bf9e6bbb 100644 --- a/public/js/wn/model/sync.js +++ b/public/js/wn/model/sync.js @@ -21,37 +21,34 @@ // $.extend(wn.model, { - sync: function(doclist, sync_in) { - if(!sync_in) - sync_in = locals; + sync: function(doclist) { if(doclist._kl) 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) $.each(doclist, function(i, d) { if(!d.name) // get name (local if required) 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(); - + if(cur_frm && cur_frm.doctype==d.doctype && cur_frm.docname==d.name) { cur_frm.doc = d; } if(d.doctype=='DocField') wn.meta.add_field(d); if(d.doctype=='DocType') wn.meta.sync_messages(d); - - + if(d.localname) { wn.model.new_names[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]; } });