MVC - Boorgrid / form control minor additions.

o When row-id isn't specified on a "edit" target, use an empty string
o On form <input> tags support the "type_formatter" attribute, which defines the function to call in order to convert data before sending it to the server. This eases type conversions when needed (e.g. '1' --> 1 using a wrapper which uses parseInt())
o Add support for list type <select> content which offers a sorted list of key,value,selected attributes in addition to the current named array store.

Full example to offer properly typed integers to a backend:

    function form_format_integer(payload)
    {
        if (/^[+-]?[0-9]*$/.test(payload)) {
            return  parseInt(payload);
        } else {
            return payload;
        }
    }

<input type="text" type_formatter="form_format_integer" id="myform.quantity">

Sample data for list type <select> options:

"status":[{"key":null,"value":"-","selected":0},{"key":"PEN","value":"Pending","selected":1}]
This commit is contained in:
Ad Schellevis 2022-10-18 21:49:44 +02:00
parent ac73ab9021
commit 528474372b
2 changed files with 30 additions and 11 deletions

View File

@ -44,13 +44,13 @@ function htmlDecode(value) {
/**
*
* Map input fields from given parent tag to structure of named arrays.
* When a type_formatter attribute exists on the input element, this will be called with the val() content first
*
* @param parent tag id in dom
* @return array
*/
function getFormData(parent) {
var data = {};
let data = {};
$("#"+parent+" input,#"+parent+" select,#"+parent+" textarea" ).each(function() {
if ($(this).prop('id') === undefined || $(this).prop('id') === "") {
// we need an id.
@ -96,8 +96,13 @@ function getFormData(parent) {
// deserialize the field content - used for JS maintained fields
node[keypart] = sourceNode.data('data');
} else {
// regular input type
node[keypart] = sourceNode.val();
// regular input type, might need a parser to convert to the correct format
// (attribute type_formatter as function name)
if (sourceNode.attr('type_formatter') !== undefined && window[sourceNode.attr('type_formatter')] !== undefined) {
node[keypart] = window[sourceNode.attr('type_formatter')](sourceNode.val());
} else {
node[keypart] = sourceNode.val();
}
}
}
});
@ -142,13 +147,27 @@ function setFormData(parent,data) {
targetNode.tokenize2().trigger('tokenize:clear');
}
targetNode.empty(); // flush
$.each(node[keypart],function(indxItem, keyItem){
var opt = $("<option>").val(htmlDecode(indxItem)).text(keyItem["value"]);
if (keyItem["selected"] != "0") {
opt.attr('selected', 'selected');
if (Array.isArray(node[keypart]) && node[keypart][0] !== undefined && node[keypart][0].key !== undefined) {
// key value (sorted) list
// (eg node[keypart][0] = {selected: 0, value: 'my item', key: 'item'})
for (i=0; i < node[keypart].length; ++i) {
let opt = $("<option>").val(htmlDecode(node[keypart][i].key)).text(node[keypart][i].value);
if (String(node[keypart][i].selected) !== "0") {
opt.attr('selected', 'selected');
}
targetNode.append(opt);
}
targetNode.append(opt);
});
} else{
// default "dictionary" type select items
// (eg node[keypart]['item'] = {selected: 0, value: 'my item'})
$.each(node[keypart],function(indxItem, keyItem){
let opt = $("<option>").val(htmlDecode(indxItem)).text(keyItem["value"]);
if (String(keyItem["selected"]) !== "0") {
opt.attr('selected', 'selected');
}
targetNode.append(opt);
});
}
} else if (targetNode.prop("type") === "checkbox") {
// checkbox type
targetNode.prop("checked", node[keypart] != 0);

View File

@ -317,7 +317,7 @@ $.fn.UIBootgrid = function (params) {
event.stopPropagation();
let editDlg = this_grid.attr('data-editDialog');
if (editDlg !== undefined) {
let uuid = $(this).data("row-id");
let uuid = $(this).data("row-id") !== undefined ? $(this).data("row-id") : '';
let saveDlg = $("#btn_"+editDlg+"_save").unbind('click');
this_grid.show_edit_dialog(event, params['get'] + uuid).done(function(){
saveDlg.unbind('click').click(function(){