[grid] added feature for bluk edit
This commit is contained in:
parent
1884c98fba
commit
d7f7382ec0
14 changed files with 216 additions and 44 deletions
|
|
@ -132,6 +132,7 @@
|
|||
"public/js/frappe/form/save.js",
|
||||
"public/js/frappe/form/script_manager.js",
|
||||
"public/js/frappe/form/grid_form.html",
|
||||
"public/js/frappe/form/grid_body.html",
|
||||
"public/js/frappe/form/grid.js",
|
||||
"public/js/frappe/form/linked_with.js",
|
||||
"public/js/frappe/form/workflow.js",
|
||||
|
|
|
|||
|
|
@ -77,6 +77,9 @@
|
|||
font-size: 120%;
|
||||
border-bottom: 1px solid #d1d8dd;
|
||||
}
|
||||
.grid-footer {
|
||||
background-color: #fff;
|
||||
}
|
||||
.grid-footer-toolbar {
|
||||
padding: 10px 15px;
|
||||
border-top: 1px solid #d1d8dd;
|
||||
|
|
|
|||
|
|
@ -735,7 +735,7 @@ frappe.ui.form.ControlAttach = frappe.ui.form.ControlData.extend({
|
|||
this.frm.attachments.update_attachment(attachment);
|
||||
} else {
|
||||
this.set_input(this.fileobj.filename, this.dataurl);
|
||||
this.refresh();
|
||||
//this.refresh();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,29 +20,16 @@ frappe.ui.form.Grid = Class.extend({
|
|||
make: function() {
|
||||
var me = this;
|
||||
|
||||
this.wrapper = $('<div>\
|
||||
<div class="form-grid">\
|
||||
<div class="grid-heading-row"></div>\
|
||||
<div class="grid-body">\
|
||||
<div class="rows"></div>\
|
||||
<div class="grid-empty text-center hide">'+__("No Data")+'</div>\
|
||||
<div class="small form-clickable-section grid-footer text-center">\
|
||||
<a href="#" class="grid-add-row h6 text-muted" style="margin-left: 10px;">+ '
|
||||
+__("Add new row")+'.</a>\
|
||||
<a href="#" class="grid-add-multiple-rows h6 text-muted hide" style="margin-left: 10px;">+ '
|
||||
+__("Add multiple rows")+'.</a>\
|
||||
<div class="clearfix"></div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>')
|
||||
this.wrapper = $(frappe.render_template("grid_body", {}))
|
||||
.appendTo(this.parent)
|
||||
.attr("data-fieldname", this.df.fieldname);
|
||||
|
||||
$(this.wrapper).find(".grid-add-row").click(function() {
|
||||
me.add_new_row(null, null, true);
|
||||
return false;
|
||||
})
|
||||
});
|
||||
|
||||
this.setup_allow_bulk_edit();
|
||||
|
||||
},
|
||||
make_head: function() {
|
||||
|
|
@ -144,21 +131,6 @@ frappe.ui.form.Grid = Class.extend({
|
|||
me.frm.dirty();
|
||||
}
|
||||
});
|
||||
|
||||
// $rows.sortable({
|
||||
// handle: ".data-row, .grid-form-heading",
|
||||
// helper: 'clone',
|
||||
// update: function(event, ui) {
|
||||
// me.frm.doc[me.df.fieldname] = [];
|
||||
// $rows.find(".grid-row").each(function(i, item) {
|
||||
// var doc = $(item).data("doc");
|
||||
// doc.idx = i + 1;
|
||||
// $(this).find(".row-index").html(i + 1);
|
||||
// me.frm.doc[me.df.fieldname].push(doc);
|
||||
// });
|
||||
// me.frm.dirty();
|
||||
// }
|
||||
// });
|
||||
},
|
||||
get_data: function() {
|
||||
var data = this.frm.doc[this.df.fieldname] || [];
|
||||
|
|
@ -231,6 +203,68 @@ frappe.ui.form.Grid = Class.extend({
|
|||
return false;
|
||||
});
|
||||
this.multiple_set = true;
|
||||
},
|
||||
setup_allow_bulk_edit: function() {
|
||||
var me = this;
|
||||
if(this.frm.get_docfield(this.df.fieldname).allow_bulk_edit) {
|
||||
// download
|
||||
me.setup_download();
|
||||
|
||||
// upload
|
||||
$(this.wrapper).find(".grid-upload").removeClass("hide").on("click", function() {
|
||||
frappe.prompt({fieldtype:"Attach", label:"Upload File"},
|
||||
function(data) {
|
||||
var data = frappe.utils.csv_to_array(frappe.upload.get_string(data.upload_file));
|
||||
// row #2 contains fieldnames;
|
||||
var fieldnames = data[2];
|
||||
|
||||
me.frm.clear_table(me.df.fieldname);
|
||||
$.each(data, function(i, row) {
|
||||
if(i > 4) {
|
||||
var d = me.frm.add_child(me.df.fieldname);
|
||||
$.each(row, function(ci, value) {
|
||||
d[fieldnames[ci]] = value;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
me.frm.refresh_field(me.df.fieldname);
|
||||
|
||||
}, __("Edit via Upload"), __("Update"));
|
||||
return false;
|
||||
});
|
||||
}
|
||||
},
|
||||
setup_download: function() {
|
||||
var me = this;
|
||||
$(this.wrapper).find(".grid-download").removeClass("hide").on("click", function() {
|
||||
var data = [];
|
||||
data.push([__("Bulk Edit {0}", [me.df.label])]);
|
||||
data.push([]);
|
||||
data.push([]);
|
||||
data.push([]);
|
||||
data.push(["------"]);
|
||||
$.each(frappe.get_meta(me.df.options).fields, function(i, df) {
|
||||
if(frappe.model.is_value_type(me.df.fieldtype)) {
|
||||
data[1].push(df.label);
|
||||
data[2].push(df.fieldname);
|
||||
data[3].push(df.description);
|
||||
}
|
||||
});
|
||||
|
||||
// add data
|
||||
$.each(me.frm.doc[me.df.fieldname] || [], function(i, d) {
|
||||
row = [];
|
||||
$.each(data[2], function(i, fieldname) {
|
||||
row.push(d[fieldname] || "");
|
||||
});
|
||||
data.push(row);
|
||||
});
|
||||
|
||||
frappe.tools.downloadify(data, null, me.df.label);
|
||||
return false;
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
28
frappe/public/js/frappe/form/grid_body.html
Normal file
28
frappe/public/js/frappe/form/grid_body.html
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<div>
|
||||
<div class="form-grid">
|
||||
<div class="grid-heading-row"></div>
|
||||
<div class="grid-body">
|
||||
<div class="rows"></div>
|
||||
<div class="grid-empty text-center hide">{%= __("No Data") %}</div>
|
||||
<div class="small form-clickable-section grid-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<a href="#" class="btn btn-xs btn-default grid-add-row">
|
||||
{%= __("Add new row") %}</a>
|
||||
<a href="#" class="grid-add-multiple-rows btn btn-xs btn-default hide"
|
||||
style="margin-left: 10px;">
|
||||
{%= __("Add multiple rows") %}</a>
|
||||
</div>
|
||||
<div class="col-sm-6 text-right">
|
||||
<a href="#" class="grid-download btn btn-xs btn-default hide"
|
||||
style="margin-left: 10px;">
|
||||
{%= __("Download") %}</a>
|
||||
<a href="#" class="grid-upload btn btn-xs btn-default hide"
|
||||
style="margin-left: 10px;">
|
||||
{%= __("Upload") %}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
frappe.provide("frappe.tools");
|
||||
|
||||
frappe.tools.downloadify = function(data, roles, me) {
|
||||
frappe.tools.downloadify = function(data, roles, title) {
|
||||
if(roles && roles.length && !has_common(roles, user_roles)) {
|
||||
msgprint(__("Export not allowed. You need {0} role to export.", [frappe.utils.comma_or(roles)]));
|
||||
return;
|
||||
|
|
@ -14,7 +14,7 @@ frappe.tools.downloadify = function(data, roles, me) {
|
|||
|
||||
var download_from_server = function() {
|
||||
open_url_post("/", {
|
||||
args: { data: data, filename: me.title },
|
||||
args: { data: data, filename: title },
|
||||
cmd: "frappe.utils.csvutils.send_csv_to_client"
|
||||
}, true);
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ frappe.tools.downloadify = function(data, roles, me) {
|
|||
|
||||
Downloadify.create(id ,{
|
||||
filename: function(){
|
||||
return me.title + '.csv';
|
||||
return title + '.csv';
|
||||
},
|
||||
data: _get_data,
|
||||
swf: 'assets/frappe/js/lib/downloadify/downloadify.swf',
|
||||
|
|
|
|||
|
|
@ -320,4 +320,87 @@ frappe.utils = {
|
|||
setTimeout(function() { callback(dataURL); }, 10 );
|
||||
}
|
||||
},
|
||||
|
||||
csv_to_array: function (strData, strDelimiter) {
|
||||
// Check to see if the delimiter is defined. If not,
|
||||
// then default to comma.
|
||||
strDelimiter = (strDelimiter || ",");
|
||||
|
||||
// Create a regular expression to parse the CSV values.
|
||||
var objPattern = new RegExp(
|
||||
(
|
||||
// Delimiters.
|
||||
"(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +
|
||||
|
||||
// Quoted fields.
|
||||
"(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +
|
||||
|
||||
// Standard fields.
|
||||
"([^\"\\" + strDelimiter + "\\r\\n]*))"
|
||||
),
|
||||
"gi"
|
||||
);
|
||||
|
||||
|
||||
// Create an array to hold our data. Give the array
|
||||
// a default empty first row.
|
||||
var arrData = [[]];
|
||||
|
||||
// Create an array to hold our individual pattern
|
||||
// matching groups.
|
||||
var arrMatches = null;
|
||||
|
||||
|
||||
// Keep looping over the regular expression matches
|
||||
// until we can no longer find a match.
|
||||
while (arrMatches = objPattern.exec( strData )){
|
||||
|
||||
// Get the delimiter that was found.
|
||||
var strMatchedDelimiter = arrMatches[ 1 ];
|
||||
|
||||
// Check to see if the given delimiter has a length
|
||||
// (is not the start of string) and if it matches
|
||||
// field delimiter. If id does not, then we know
|
||||
// that this delimiter is a row delimiter.
|
||||
if (
|
||||
strMatchedDelimiter.length &&
|
||||
strMatchedDelimiter !== strDelimiter
|
||||
){
|
||||
|
||||
// Since we have reached a new row of data,
|
||||
// add an empty row to our data array.
|
||||
arrData.push( [] );
|
||||
|
||||
}
|
||||
|
||||
var strMatchedValue;
|
||||
|
||||
// Now that we have our delimiter out of the way,
|
||||
// let's check to see which kind of value we
|
||||
// captured (quoted or unquoted).
|
||||
if (arrMatches[ 2 ]){
|
||||
|
||||
// We found a quoted value. When we capture
|
||||
// this value, unescape any double quotes.
|
||||
strMatchedValue = arrMatches[ 2 ].replace(
|
||||
new RegExp( "\"\"", "g" ),
|
||||
"\""
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
// We found a non-quoted value.
|
||||
strMatchedValue = arrMatches[ 3 ];
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Now that we have our value string, let's add
|
||||
// it to the data array.
|
||||
arrData[ arrData.length - 1 ].push( strMatchedValue );
|
||||
}
|
||||
|
||||
// Return the parsed data.
|
||||
return( arrData );
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ $.extend(frappe.model, {
|
|||
new_names: {},
|
||||
events: {},
|
||||
|
||||
is_value_type: function(fieldtype) {
|
||||
return frappe.model.no_value_type.indexOf(fieldtype)!==-1;
|
||||
},
|
||||
|
||||
get_std_field: function(fieldname) {
|
||||
var docfield = $.map([].concat(frappe.model.std_fields).concat(frappe.model.std_fields_table),
|
||||
function(d) {
|
||||
|
|
|
|||
|
|
@ -34,13 +34,13 @@ frappe.confirm = function(message, ifyes, ifno) {
|
|||
return d;
|
||||
}
|
||||
|
||||
frappe.prompt = function(fields, callback) {
|
||||
frappe.prompt = function(fields, callback, title, primary_label) {
|
||||
if(!$.isArray(fields)) fields = [fields];
|
||||
var d = new frappe.ui.Dialog({
|
||||
fields: fields,
|
||||
title: __("Enter Value"),
|
||||
title: title || __("Enter Value"),
|
||||
})
|
||||
d.set_primary_action(__("Submit"), function() {
|
||||
d.set_primary_action(primary_label || __("Submit"), function() {
|
||||
var values = d.get_values();
|
||||
if(!values) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -116,5 +116,16 @@ frappe.upload = {
|
|||
|
||||
freader.readAsDataURL(fileobj);
|
||||
}
|
||||
},
|
||||
get_string: function(dataURI) {
|
||||
// remove filename
|
||||
var parts = dataURI.split(',');
|
||||
if(parts[0].indexOf(":")===-1) {
|
||||
var a = parts[2];
|
||||
} else {
|
||||
var a = parts[1];
|
||||
}
|
||||
|
||||
return atob(a);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -444,7 +444,7 @@ frappe.views.GridReport = Class.extend({
|
|||
},
|
||||
export: function() {
|
||||
frappe.tools.downloadify(frappe.slickgrid_tools.get_view_data(this.columns, this.dataView),
|
||||
["Report Manager", "System Manager"], this);
|
||||
["Report Manager", "System Manager"], this.title);
|
||||
return false;
|
||||
},
|
||||
apply_filters: function(item) {
|
||||
|
|
@ -915,7 +915,7 @@ frappe.views.TreeGridReport = frappe.views.GridReportWithPlot.extend({
|
|||
return false;
|
||||
});
|
||||
|
||||
frappe.tools.downloadify(data, ["Report Manager", "System Manager"], me);
|
||||
frappe.tools.downloadify(data, ["Report Manager", "System Manager"], me.title);
|
||||
return false;
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -622,7 +622,7 @@ frappe.views.QueryReport = Class.extend({
|
|||
return [row.splice(1)];
|
||||
});
|
||||
this.title = this.report_name;
|
||||
frappe.tools.downloadify(result, null, this);
|
||||
frappe.tools.downloadify(result, null, this.title);
|
||||
return false;
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -146,11 +146,15 @@ _f.Frm.prototype.field_map = function(fnames, fn) {
|
|||
}
|
||||
}
|
||||
|
||||
_f.Frm.prototype.get_docfield = function(fieldname) {
|
||||
return frappe.meta.get_docfield(this.doctype, fieldname, this.docname);
|
||||
}
|
||||
|
||||
_f.Frm.prototype.set_df_property = function(fieldname, property, value) {
|
||||
var field = frappe.meta.get_docfield(cur_frm.doctype, fieldname, cur_frm.docname)
|
||||
var field = this.get_docfield(fieldname);
|
||||
if(field) {
|
||||
field[property] = value;
|
||||
cur_frm.refresh_field(fieldname);
|
||||
this.refresh_field(fieldname);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,10 @@
|
|||
border-bottom: 1px solid @border-color;
|
||||
}
|
||||
|
||||
.grid-footer {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.grid-footer-toolbar {
|
||||
padding: 10px 15px;
|
||||
border-top: 1px solid @border-color;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue