[form] [controls] finished controls and script manager - 1st cut

This commit is contained in:
Rushabh Mehta 2013-05-03 14:27:29 +05:30
parent 4724006109
commit fe9bc2427b
14 changed files with 409 additions and 183 deletions

View file

@ -31,7 +31,7 @@ cur_frm.cscript.doc_type = function(doc, dt, dn) {
}
cur_frm.cscript.onload = function(doc, dt, dn) {
$('div.grid_tbarlinks').parent().toggle(false);
cur_frm.fields_dict.fields.grid.static_rows = true;
cur_frm.add_fields_help();
}

View file

@ -145,13 +145,13 @@
"lib/public/js/legacy/widgets/form/form_dialog.js",
"lib/public/js/legacy/widgets/form/form_header.js",
"lib/public/js/legacy/widgets/form/form.js",
"lib/public/js/legacy/widgets/form/form_fields.js",
"lib/public/js/legacy/widgets/form/print_format.js",
"lib/public/js/legacy/widgets/form/clientscriptAPI.js",
"lib/public/js/legacy/wn/widgets/form/sidebar.js",
"lib/public/js/wn/form/toolbar.js",
"lib/public/js/wn/form/layout.js",
"lib/public/js/wn/form/script_manager.js",
"lib/public/js/wn/form/control.js",
"lib/public/js/wn/form/editors.js",
"lib/public/js/wn/form/grid.js",
@ -159,7 +159,7 @@
"lib/public/js/wn/form/footer.js",
"lib/public/js/wn/form/comments.js",
"lib/public/js/wn/form/linked_with.js",
"lib/public/js/wn/form/states.js",
"lib/public/js/wn/form/workflow.js",
"lib/public/js/wn/form/assign_to.js",
"lib/public/js/wn/print/print_table.js",
]

View file

@ -27,7 +27,7 @@ search_fields = {};
function setlinkvalue(name) {
//selector.input.set(name);// in local - this will be set onchange
selector.input.set_input_value(name); // on screen
selector.input.set_input(name); // on screen
selector.hide();
}
@ -99,13 +99,11 @@ function makeselector() {
}
inp.value = '';
if(d.input && d.input.txt.value) {
inp.value = d.input.txt.value;
if(d.input && d.get_value) {
inp.value = d.get_value();
}
try{inp.focus();} catch(e){}
if(d.input) d.input.set_get_query();
// temp function to strip labels from search fields
var get_sf_list = function(dt) {
var l = []; var lf = search_fields[dt];

View file

@ -673,25 +673,15 @@ _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
});
}
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 'percent':var f = new PercentField(); break;
case 'link':var f = new LinkField(); break;
switch(docfield.fieldtype.toLowerCase()) {
// form fields
case 'code':var f = new _f.CodeField(); break;
case 'text editor':var f = new _f.CodeField(); break;

View file

@ -123,7 +123,9 @@ _f.Frm.prototype.setup = function() {
this.setup_std_layout();
// client script must be called after "setup" - there are no fields_dict attached to the frm otherwise
this.setup_client_script();
this.script_manager = new wn.ui.form.ScriptManager({
frm: this
})
this.setup_header();
@ -308,14 +310,6 @@ _f.Frm.prototype.add_fetch = function(link_field, src_field, tar_field) {
this.fetch_dict[link_field].fields.push(tar_field);
}
_f.Frm.prototype.setup_client_script = function() {
// setup client obj
if(this.meta.client_script_core || this.meta.client_script || this.meta.__js) {
this.runclientscript('setup', this.doctype, this.docname);
}
}
_f.Frm.prototype.refresh_print_layout = function() {
$ds(this.print_wrapper);
$dh(this.form_wrapper);
@ -431,9 +425,6 @@ _f.Frm.prototype.refresh = function(docname) {
// do setup
if(!this.setup_done) this.setup();
// set customized permissions for this record
this.runclientscript('set_perm', this.doctype, this.docname);
// load the record for the first time, if not loaded (call 'onload')
cur_frm.cscript.is_onload = false;
@ -460,7 +451,7 @@ _f.Frm.prototype.refresh = function(docname) {
}
// call trigger
this.runclientscript('refresh');
this.script_manager.trigger("refresh");
// trigger global trigger
// to use this
@ -474,7 +465,7 @@ _f.Frm.prototype.refresh = function(docname) {
// call onload post render for callbacks to be fired
if(this.cscript.is_onload) {
this.runclientscript('onload_post_render', this.doctype, this.docname);
this.script_manager.trigger("onload_post_render");
}
// focus on first input
@ -491,7 +482,6 @@ _f.Frm.prototype.refresh = function(docname) {
if(this.print_wrapper) {
this.refresh_print_layout();
}
this.runclientscript('edit_status_changed');
}
$(cur_frm.wrapper).trigger('render_complete');
@ -571,7 +561,7 @@ _f.Frm.prototype.refresh_dependency = function() {
if(f.df.depends_on.substr(0,5)=='eval:') {
f.guardian_has_value = eval(f.df.depends_on.substr(5));
} else if(f.df.depends_on.substr(0,3)=='fn:') {
f.guardian_has_value = me.runclientscript(f.df.depends_on.substr(3), me.doctype, me.docname);
f.guardian_has_value = me.script_manager.trigger(f.df.depends_on.substr(3), me.doctype, me.docname);
} else {
if(!v) {
f.guardian_has_value = false;
@ -613,7 +603,7 @@ _f.Frm.prototype.setnewdoc = function(docname) {
var viewname = this.meta.issingle ? this.doctype : docname;
// Client Script
this.runclientscript('onload', this.doctype, this.docname);
this.script_manager.trigger("onload");
this.last_view_is_edit[docname] = 1;
if(cint(this.meta.read_only_onload)) this.last_view_is_edit[docname] = 0;
@ -661,69 +651,6 @@ _f.Frm.prototype.runscript = function(scriptname, callingfield, onrefresh) {
}
}
_f.Frm.prototype.runclientscript = function(caller, cdt, cdn) {
if(!cdt)cdt = this.doctype;
if(!cdn)cdn = this.docname;
var ret = null;
var doc = locals[cur_frm.doc.doctype][cur_frm.doc.name];
try {
if(this.cscript[caller])
ret = this.cscript[caller](doc, cdt, cdn);
if(this.cscript['custom_'+caller])
ret += this.cscript['custom_'+caller](doc, cdt, cdn);
} catch(e) {
validated = false;
// show error message
this.log_error(caller, e);
}
if(caller && caller.toLowerCase()=='setup') {
this.setup_client_js();
}
return ret;
}
_f.Frm.prototype.setup_client_js = function(caller, cdt, cdn) {
var doctype = wn.model.get_doc('DocType', this.doctype);
// js
var cs = doctype.__js || (doctype.client_script_core + doctype.client_script);
if(cs) {
try {
var tmp = eval(cs);
} catch(e) {
show_alert("Error in Client Script.");
this.log_error(caller || "setup_client_js", e);
}
}
// css
if(doctype.__css) wn.dom.set_style(doctype.__css);
// ---Client String----
if(doctype.client_string) { // split client string
this.cstring = {};
var elist = doctype.client_string.split('---');
for(var i=1;i<elist.length;i=i+2) {
this.cstring[strip(elist[i])] = elist[i+1];
}
}
}
_f.Frm.prototype.log_error = function(caller, e) {
console.group && console.group();
console.log("----- error in client script -----");
console.log("method: " + caller);
console.log(e);
console.log("error message: " + e.message);
console.trace && console.trace();
console.log("----- end of error message -----");
console.group && console.groupEnd();
}
_f.Frm.prototype.copy_doc = function(onload, from_amend) {
if(!this.perm[0][CREATE]) {
msgprint('You are not allowed to create '+this.meta.name);
@ -780,8 +707,6 @@ _f.Frm.prototype.reload_doc = function() {
var me = this;
var onsave = function(r, rtxt) {
// n tweets and last comment
//me.runclientscript('setup', me.doctype, me.docname);
me.refresh();
}
@ -804,7 +729,7 @@ _f.Frm.prototype.save = function(save_action, callback, btn, on_error) {
// validate
if(save_action!="Cancel") {
validated = true;
this.runclientscript('validate');
this.script_manager.trigger("validate");
if(!validated) {
if(on_error)
on_error();
@ -817,9 +742,6 @@ _f.Frm.prototype.save = function(save_action, callback, btn, on_error) {
doclist.save(save_action || "Save", function(r) {
if(!r.exc) {
me.refresh();
if(save_action==="Save") {
me.runclientscript("after_save", me.doctype, me.docname);
}
} else {
if(on_error)
on_error();
@ -834,7 +756,7 @@ _f.Frm.prototype.savesubmit = function(btn, on_error) {
wn.confirm("Permanently Submit "+this.docname+"?", function() {
me.save('Submit', function(r) {
if(!r.exc) {
me.runclientscript('on_submit', me.doctype, me.docname);
me.script_manager.trigger("on_submit");
}
}, btn, on_error);
});
@ -844,7 +766,7 @@ _f.Frm.prototype.savecancel = function(btn, on_error) {
var me = this;
wn.confirm("Permanently Cancel "+this.docname+"?", function() {
validated = true;
me.runclientscript("before_cancel", me.doctype, me.docname);
me.script_manager.trigger("before_cancel");
if(!validated) {
if(on_error)
on_error();
@ -855,7 +777,7 @@ _f.Frm.prototype.savecancel = function(btn, on_error) {
doclist.cancel(function(r) {
if(!r.exc) {
me.refresh();
me.runclientscript("after_cancel", me.doctype, me.docname);
me.script_manager.trigger("after_cancel");
}
}, btn, on_error);
});

View file

@ -47,6 +47,24 @@ wn.ui.form.ControlHTML = wn.ui.form.Control.extend({
}
});
wn.ui.form.ControlImage = wn.ui.form.Control.extend({
make: function() {
this._super();
var me = this;
this.$wrapper.on("refresh", function() {
me.$wrapper.empty();
if(me.df.options && me.frm.doc[me.df.options]) {
$("<img src='"+me.frm.doc[me.df.options]+"' style='max-width: 70%;'>")
.appendTo(me.$wrapper);
} else {
$("<div class='missing-image'><i class='icon-camera'></i></div>")
.appendTo(me.$wrapper)
}
return false;
})
}
});
wn.ui.form.ControlReadOnly = wn.ui.form.Control.extend({
make: function() {
this._super();
@ -61,6 +79,16 @@ wn.ui.form.ControlReadOnly = wn.ui.form.Control.extend({
wn.ui.form.ControlInput = wn.ui.form.Control.extend({
make: function() {
// parent element
this.make_wrapper();
this.wrapper = this.$wrapper.get(0);
this.wrapper.fieldobj = this; // reference for event handlers
this.set_input_areas();
// set description
this.set_max_width();
this.setup_update_on_refresh();
},
make_wrapper: function() {
this.$wrapper = $('<div class="control-group">\
<label class="control-label"></label>\
<div class="controls">\
@ -68,16 +96,11 @@ wn.ui.form.ControlInput = wn.ui.form.Control.extend({
<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);
},
set_input_areas: function() {
this.label_area = this.label_span = this.$wrapper.find("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();
this.disp_area = this.$wrapper.find(".control-value").get(0);
},
set_max_width: function() {
if(['Code', 'Text Editor', 'Text', 'Small Text', 'Table', 'HTML']
@ -116,6 +139,7 @@ wn.ui.form.ControlInput = wn.ui.form.Control.extend({
me.set_description();
me.set_label();
me.set_mandatory();
return false;
}
})
@ -145,7 +169,7 @@ wn.ui.form.ControlInput = wn.ui.form.Control.extend({
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({
@ -164,17 +188,21 @@ wn.ui.form.ControlData = wn.ui.form.ControlInput.extend({
},
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();
this.$input.on("change", this.change || function() {
me.doctype && me.docname && me.get_value
&& me.parse_validate_and_set_in_model(me.get_value()); } );
},
parse_validate_and_set_in_model: function(value) {
var me = this;
this.inside_change_event = true;
if(this.parse) value = this.parse(value);
me.validate ?
me.validate(value, function() { me.set_model_value(value); }) :
me.set_model_value(value);
}
});
var set = function(value) {
me.set_model_value(value);
me.inside_change_event = false;
}
this.validate ? this.validate(value, set) : set(value);
},
set_input: function(val) {
this.$input.val(this.format_for_input(val));
@ -327,6 +355,23 @@ wn.ui.form.ControlSmallText = wn.ui.form.ControlText;
wn.ui.form.ControlCheck = wn.ui.form.ControlData.extend({
input_type: "checkbox",
make_wrapper: function() {
this.$wrapper = $('<div class="checkbox">\
<label class="input-area">\
<span class="disp-area" style="display:none;"></span>\
<span class="label-area"></span>\
</label>\
</div>').appendTo(this.parent)
},
set_input_areas: function() {
this.label_area = this.label_span = this.$wrapper.find(".label-area").get(0);
this.input_area = this.$wrapper.find(".input-area").get(0);
this.disp_area = this.$wrapper.find(".disp-area").get(0);
},
make_input: function() {
this._super();
this.$input.removeClass("col-span-12");
},
parse: function(value) {
return this.input.checked ? 1 : 0;
},
@ -346,7 +391,7 @@ wn.ui.form.ControlButton = wn.ui.form.ControlData.extend({
.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);
me.frm.script_manager.trigger(me.df.fieldname, me.doctype, me.docname);
} else {
me.frm.runscript(me.df.options, me);
}
@ -426,4 +471,205 @@ wn.ui.form.ControlSelect = wn.ui.form.ControlData.extend({
return [""];
}
}
});
});
// special features for link
// buttons
// autocomplete
// link validation
// custom queries
// add_fetches
wn.ui.form.ControlLink = wn.ui.form.ControlData.extend({
make_input: function() {
$('<div class="input-group link-field">\
<input type="text" data-fieldtype="Link">\
<div class="input-group-btn">\
<button class="btn btn-search" title="Search Link">\
<i class="icon-search"></i>\
</button>\
<button class="btn btn-open" title="Open Link">\
<i class="icon-play"></i>\
</button><button class="btn btn-new" title="Make New">\
<i class="icon-plus"></i>\
</button>\
</div>\
</div>').appendTo(this.input_area);
this.$input_area = $(this.input_area);
this.$input = this.$input_area.find('input');
this.input = this.$input.get(0);
this.has_input = true;
this.bind_change_event();
this.setup_buttons();
this.setup_autocomplete();
},
setup_buttons: function() {
var me = this;
// magnifier - search
this.$input_area.find(".btn-search").on("click", function() {
selector.set(me, me.df.options, me.df.label);
selector.show(me.txt);
});
// open
if(wn.model.can_read(me.df.options)) {
this.$input_area.find(".btn-open").on("click", function() {
var value = me.get_value();
if(value && me.df.options) wn.set_route("Form", me.df.options, value);
});
} else {
this.$input_area.find(".btn-open").remove();
}
// new
if(wn.model.can_create(me.df.options)) {
this.$input_area.find(".btn-new").on("click", function() {
new_doc(me.df.options)
});
} else {
this.$input_area.find(".btn-new").remove();
}
},
setup_autocomplete: function() {
var me = this;
// increasing zindex of input to increase zindex of autosuggest
// because of the increase in zindex of dialog_wrapper
if(cur_dialog || me.dialog_wrapper) {
var $dialog_wrapper = $(cur_dialog ? cur_dialog.wrapper : me.dialog_wrapper)
var zindex = cint($dialog_wrapper.css("z-index"));
this.$input.css({"z-index": (zindex >= 10 ? zindex : 10) + 1});
}
this.$input.autocomplete({
source: function(request, response) {
var args = {
'txt': request.term,
'dt': me.df.options,
};
var q = me.get_custom_query();
if (typeof(q)==="string") {
args.query = q;
} else if($.isPlainObject(q)) {
if(q.filters) {
$.each(q.filters, function(key, value) {
q.filters[key] = value===undefined ? null : value;
});
}
$.extend(args, q);
}
wn.call({
method:'webnotes.widgets.search.search_link',
args: args,
callback: function(r) {
response(r.results);
},
});
},
select: function(event, ui) {
me.set_model_value(ui.item.value);
}
}).data('autocomplete')._renderItem = function(ul, item) {
return $('<li></li>')
.data('item.autocomplete', item)
.append(repl('<a><span style="font-weight: bold;">%(label)s</span><br>\
<span style="font-size:10px;">%(info)s</span></a>',
item))
.appendTo(ul);
};
},
get_custom_query: function() {
if(this.get_query && this.doctype) {
return this.get_query(this.frm.doc, this.doctype, this.docname);
}
},
validate: function(value, callback) {
// validate the value just entered
var me = this;
if(this.df.options=="[Select]") {
callback(value);
}
var fetch = '';
if(me.frm.fetch_dict[me.df.fieldname])
fetch = me.frm.fetch_dict[me.df.fieldname].columns.join(', ');
wn.call({
method:'webnotes.widgets.form.utils.validate_link',
args: {
'value': value,
'options':me.df.options,
'fetch': fetch
},
callback: function(r) {
if(r.message=='Ok') {
callback(value);
if(r.fetch_values)
me.set_fetch_values(r.fetch_values);
} else {
callback("")
}
}
});
},
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]);
}
}
});
wn.ui.form.ControlCode = wn.ui.form.ControlInput.extend({
editor_name: "ACE",
make_input: function() {
$(this.input_area).css({"min-height":"360px"});
var me = this;
this.editor = new wn.editors[this.editor_name]({
parent: this.input_area,
change: function(value) {
me.parse_validate_and_set_in_model(value);
},
field: this
});
},
get_value: function() {
this.editor.get_value();
},
set_input: function(value) {
this.editor.set_input(value);
}
});
wn.ui.form.ControlTextEditor = wn.ui.form.ControlCode.extend({
editor_name: "BootstrapWYSIWYG"
});
wn.ui.form.ControlTable = wn.ui.form.Control.extend({
make: function() {
this._super();
this.grid = new wn.ui.form.Grid({
frm: this.frm,
df: this.df,
perm: this.perm,
parent: this.wrapper
})
if(this.frm)
this.frm.grids[this.frm.grids.length] = this;
// description
if(this.df.description) {
$('<p class="text-muted small">' + this.df.description + '</p>')
.appendTo(this.wrapper);
}
var me = this;
this.$wrapper.on("refresh", function() {
me.grid.refresh();
return false;
});
}
})

View file

@ -206,7 +206,7 @@ wn.editors.ACE = Class.extend({
// during field refresh in run trigger, set_input is called
// if called during on_change, setting doesn't make sense
// and causes cursor to shift back to first position
if(this.opts.field.changing_value) return;
if(this.opts.field.inside_change_event) return;
this.setting_value = true;
this.editor.getSession().setValue(value==null ? "" : value);

View file

@ -72,6 +72,9 @@ wn.form.formatters = {
SmallText: function(value) {
return wn.form.formatters.Text(value);
},
Code: function(value) {
return "<pre>" + (value==null ? "" : value) + "</pre>"
},
WorkflowState: function(value) {
workflow_state = wn.model.get("Workflow State", value)[0];
if(workflow_state) {

View file

@ -1,6 +1,7 @@
wn.ui.form.Grid = Class.extend({
init: function(opts) {
$.extend(this, opts);
this.fieldinfo = {};
this.docfields = wn.meta.docfield_list[this.df.options];
this.docfields.sort(function(a, b) { return a.idx > b.idx ? 1 : -1 });
},
@ -57,8 +58,9 @@ wn.ui.form.Grid = Class.extend({
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");
if(this.display_status=="Write") {
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);
}
},
@ -88,7 +90,9 @@ wn.ui.form.Grid = Class.extend({
// return
},
get_field: function(fieldname) {
return {};
if(!this.fieldinfo[fieldname])
this.fieldinfo[fieldname] = {}
return this.fieldinfo[fieldname];
},
});
@ -176,10 +180,10 @@ wn.ui.form.GridRow = Class.extend({
col = $('<div class="col-span-1 row-index">' + (me.doc ? me.doc.idx : "#")+ '</div>')
.appendTo(me.row)
$.each(me.docfields, function(ci, df) {
if(!df.hidden && !df.print_hide && me.grid.perm[df.permlevel][READ]) {
if(!df.hidden && !df.print_hide && me.grid.frm.perm[df.permlevel][READ]) {
var colsize = 2,
txt = me.doc ?
wn.format(me.doc[df.fieldname], df.fieldtype, me.doc) :
wn.format(me.doc[df.fieldname], df, null, me.doc) :
df.label;
switch(df.fieldtype) {
case "Text":
@ -229,29 +233,38 @@ wn.ui.form.GridRow = Class.extend({
},
render_form: function() {
var me = this,
cnt = 0;
cnt = 0,
row = $('<div class="row">').appendTo(me.form_area),
col1 = $('<div class="col-span-6"></div>').appendTo(row),
col2 = $('<div class="col-span-6"></div>').appendTo(row),
len = $.map(me.docfields, function(d) {
return !d.hidden ? true : null }).length;
len = (len + len % 2) / 2;
$.each(me.docfields, function(ci, df) {
if(!df.hidden) {
if(cnt % 2==0)
form_row = $('<div class="row">').appendTo(me.form_area);
var fieldwrapper = $('<div class="col-span-6">')
.appendTo(form_row)
var fieldwrapper = $('<div>')
.appendTo(ci <= len ? col1 : col2)
var fieldobj = make_field(df, me.parent_df.options,
fieldwrapper.get(0), me.frm);
fieldobj.docname = me.doc.name;
fieldobj.refresh();
fieldobj.input &&
$(fieldobj.input).css({"max-height": "60px"});
$(fieldobj.input).css({"max-height": "100px"});
// set field properties
// used for setting custom get queries in links
if(me.grid.fieldinfo[df.fieldname])
$.extend(fieldobj, me.grid.fieldinfo[df.fieldname]);
cnt++;
}
});
if(this.grid.display_status!="Write") {
if(this.grid.display_status!="Write" || this.grid.static_rows) {
this.wrapper.find(".btn-danger, .grid-insert-row").toggle(false);
return;
}
}
},
set_data: function() {
this.wrapper.data({

View file

@ -0,0 +1,66 @@
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);
})
})
},
trigger: function(event_name, doctype, name) {
doctype = doctype || this.frm.doctype;
name = name || this.frm.docname;
try {
if(this.frm.cscript[event_name])
this.frm.cscript[event_name](this.frm.doc, doctype, name);
if(this.frm.cscript["custom_" + event_name])
this.frm.cscript["custom_" + event_name](this.frm.doc, doctype, name);
} catch(e) {
validated = false;
// show error message
this.log_error(event_name, e);
}
},
setup: function() {
var doctype = this.frm.meta;
// js
var cs = doctype.__js;
if(cs) {
try {
var tmp = eval(cs);
} catch(e) {
this.log_error(caller || "setup_client_js", e);
}
}
// css
doctype.__css && wn.dom.set_style(doctype.__css);
},
log_error: function(e) {
show_alert("Error in Client Script.");
console.group && console.group();
console.log("----- error in client script -----");
console.log("method: " + caller);
console.log(e);
console.log("error message: " + e.message);
console.trace && console.trace();
console.log("----- end of error message -----");
console.group && console.groupEnd();
}
})

View file

@ -1,20 +0,0 @@
wn.provide("wn.ui.form");
wn.ui.form.Sidebar = Class.extend({
init: function(opts) {
$.extend(this, opts);
this.make();
},
make: function() {
$('<ul class="nav nav-list">').appendTo(this.frm.sidebar_area);
},
refresh: function() {
},
});
// <ul class="nav nav-list">
// <li class="nav-header">List header</li>
// <li class="active"><a href="#">Home</a></li>
// <li><a href="#">Library</a></li>
// ...
// </ul>

View file

@ -197,18 +197,26 @@ $.extend(wn.model, {
}
},
on: function(doctype, name, fieldname, fn) {
wn.provide("locals." + doctype + "." + name + "." + fieldname);
locals[doctype][name][fieldname] = fn;
on: function(doctype, fieldname, fn) {
wn.provide("wn.model.events." + doctype + "." + fieldname);
wn.model.events[doctype][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];
var run = function(fn) {
fn && fn(value, doctype, name, fieldname)
};
if(wn.model.events[doctype]) {
// doctype-level
if(wn.model.events[doctype]['*']) {
wn.model.events[doctype]['*'](value, doctype, name, fieldname);
};
ev[fieldname] && ev[fieldname](value, doctype, name, fieldname);
ev["*"] && ev["*"](value, doctype, name, fieldname);
}
// field-level
if(wn.model.events[doctype][fieldname]) {
wn.model.events[doctype][fieldname](value, doctype, name, fieldname);
};
};
},
get_doc: function(doctype, name) {

View file

@ -26,8 +26,8 @@ wn.ui.AppFrame = Class.extend({
<img class="title-status-img hidden-phone"\
style="position: absolute; top: 10px; left: 40%; width: 160px; display:none" />\
<div class="title-button-area btn-group pull-right" style="margin-top: 10px;"></div>\
<div class="title-area"><h3 style="display: inline-block">\
<span class="title-icon"></span><span class="title-text"></span></h3></div>\
<div class="title-area"><h2 style="display: inline-block">\
<span class="title-icon"></span><span class="title-text"></span></h2></div>\
<div class="sub-title-area text-muted small" \
style="margin-top: -10px;"></div>\
<div class="btn-group appframe-toolbar" \