ParamQuery grid support forum
General Category => Help for ParamQuery Grid (free version) => Topic started by: hyh888 on November 07, 2024, 12:35:14 pm
-
When batch-copying data into select(dropdown) column, the new updated data of select(dropdown) column could not be saved to server.
But if use mouse to click the select element one by one to change the data, the changes can be saved to server.
Maybe there's something wrong for pqgrid.
Would you like to provide a sample for saving select batch-copying data?
When set the width of first column(in https://paramquery.com/pro/demos/pivot) to 500px, after press "edit and run", the width of first column keep unchanged(still 158px).
var colM = [
//extra column to show grouping (for both pivot and row grouping mode, used along with groupModel.titleIndx )
{
title: 'Group', tpHide: true, menuInHide: true,
dataIndx: 'grp',
width:500,//width is changed here , but no expected result.
menuUI: {
tabs: ['hideCols'] //display only hide columns tab in menu.
}
},
-
Dear Paramvir,
Batch-copy for select column could not be saved, this is really a trouble, end-user maybe be unware of the problem and make wrong operation.
Would you like to provide any advice or treat it as a bug?
Pivotable's style control is also a trouble for end-user.
-
Dear Paramvir,
If there is no solution for saving-data of batch-copy of select column, I have to remove the select of pqgrid.
This is really a trouble for me.
-
Batch editing is based on grid getChanges method.
getChanges include the updates due to copy paste in select lists similar to inline editing of individual editing of select lists.
So I don't see any issue there unless you share some technical details.
-
Dear Paramvir,
I changed code of demo in https://paramquery.com/pro/demos/editing_custom , you can copy all code to your demo and press "edit and run".
Firstly batch-copy many "USA"(this should be pre-copied in excel) to first row, secondly press "get change", then you will find than updatelist has no content in the console.
I put screencopy in the attach.
Here is the changed code:
$(function () {
function saveChanges() {
var grid = this;
//attempt to save editing cell.
if (grid.saveEditCell() === false) {
return false;
}
if (grid.isDirty() && grid.isValidChange({ focusInvalid: true }).valid) {
var gridChanges = grid.getChanges({ format: 'byVal' });
//post changes to server
$.ajax({
dataType: "json",
type: "POST",
async: true,
beforeSend: function (jqXHR, settings) {
grid.showLoading();
},
url: "/pro/products/batch", //for ASP.NET, java
//url: '/products.php?pq_batch=1', for PHP
data: {
//JSON.stringify not required for PHP
list: JSON.stringify(gridChanges)
},
success: function (changes) {
//debugger;
grid.commit({ type: 'add', rows: changes.addList });
grid.commit({ type: 'update', rows: changes.updateList });
grid.commit({ type: 'delete', rows: changes.deleteList });
grid.history({ method: 'reset' });
},
complete: function () {
grid.hideLoading();
}
});
}
}
//rename the bootstrap datepicker to avoid conflict with jquery date picker.
if (typeof $.fn.datepicker.noConflict == "function") {
$.fn.bootstrapDatepicker = $.fn.datepicker.noConflict();
}
var books = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
function autoCompleteEditor(source) {
return function (ui) {
ui.$cell.addClass('ui-front');//so that dropdown remains with input.
//initialize the editor
ui.$editor.autocomplete({
//appendTo: ui.$cell, //for grid in maximized state.
source: source,
position: {
collision: 'flipfit',
within: ui.$editor.closest(".pq-grid")
},
selectItem: { on: true }, //custom option
highlightText: { on: true }, //custom option
minLength: 0
}).one('focus', function () {
//open the autocomplete upon focus
$(this).autocomplete("search", "");
});
}
}
function dateEditor(ui) {
//initialize the editor
ui.$cell.find("input")
.attr('readonly', 'readonly')
.datepicker({
changeMonth: true,
changeYear: true,
//convert from excel to jquery ui format
dateFormat: pq.excelToJui(ui.column.format),
showAnim: '',
onSelect: function () {
this.firstOpen = true;
},
beforeShow: function (input, inst) {
setTimeout(function () {
//to fix the issue of datepicker z-index when grid is in maximized state.
$('.ui-datepicker').css('z-index', 999999999999);
});
//return !this.firstOpen; uncomment if don't want to allow datepicker editor to open upon focus in editor after first opening.
},
onClose: function () {
this.focus();
}
});
}
function bootstrapDateEditor(ui) {
//initialize the editor
ui.$cell.find("input")
.bootstrapDatepicker({
format: ui.column.format,
})
.on('changeDate', function (e) {
$(this).focus();
$(this).bootstrapDatepicker('hide');
})
}
var colM = [
{
title: "Ship Country", dataIndx: "ShipCountry", width: 120,
cls: 'pq-drop-icon pq-side-icon',
editor: {
type: "textbox",
attr: "autocomplete='off'",
init: autoCompleteEditor("/pro/demos/getCountries")
},
validations: [
{ type: 'minLen', value: 1, msg: "Required" },
{
type: function (ui) {
var value = ui.value,
_found = false;
//remote validation
//debugger;
$.ajax({
url: "/pro/demos/checkCountry",
data: { 'country': value },
async: false,
success: function (response) {
if (response == "true") {
_found = true;
}
}
});
if (!_found) {
ui.msg = value + " not found in list";
return false;
}
}
}
]
},
{
title: "Books", dataIndx: "books", width: 90,
cls: 'pq-drop-icon pq-side-icon',
editor: {
type: "textbox",
attr: "autocomplete='off'",
init: autoCompleteEditor(books)
},
validations: [
{ type: 'minLen', value: 1, msg: "Required" },
{
type: function (ui) {
var value = ui.value;
if (books.indexOf(value) == -1) {
ui.msg = value + " not found in list";
return false;
}
}, icon: 'ui-icon-info'
}
]
},
{
title: "Fruits", dataIndx: "fruits", width: 140,
//custom editor.
editor: {
options: ['Apple', 'Orange', 'Kiwi', 'Guava', 'Grapes'],
type: 'div',
init: function (ui) {
//debugger;
var options = ui.column.editor.options,
str = options.map(function (option) {
var checked = (option == ui.cellData) ? 'checked = checked' : '';
return "<input type='radio' " + checked + " name='" + ui.dataIndx + "' style='margin-left:5px;' value='" + option + "'> " + option;
}).join("");
//ui.$cell.append("<div class='pq-editor-focus' tabindex='0' style='padding:5px;margin-top:1px;'>" + str + "</div>");
ui.$cell.children('div').css({ padding: '5px' }).html(str);
},
getData: function (ui) {
return ui.$cell.find('input:checked').val();
}
}
},
{
title: "Order ID", width: 100, dataIndx: "OrderID",
editor: {
type: "textbox",
//make it html5 number editor.
attr: "type='number'"
}
},
{
title: "Date jui",
width: "120",
dataIndx: "OrderDate",
dataType: 'date',
format: 'dd-mm-yyyy', //display format.
fmtDateEdit: 'dd-mm-yyyy', //format of date value in editor
cls: 'pq-calendar pq-side-icon',
editor: {
type: 'textbox',
init: dateEditor
},
validations: [
{ type: 'regexp', value: '^[0-9]{4}-[0-9]{2}-[0-9]{2}$', msg: 'Not in yyyy-mm-dd format' }
]
},
{
title: "Date bootstrap",
width: "120",
dataIndx: "OrderDate2",
dataType: 'date',
format: 'yyyy-mm-dd', //display format.
fmtDateEdit: 'yyyy-mm-dd', //format of date value in editor
cls: 'pq-calendar pq-side-icon',
editor: {
type: 'textbox',
init: bootstrapDateEditor,
preventClose: function (ui) {
return $(".datepicker-dropdown").is(":visible");
}
},
validations: [
{ type: 'regexp', value: '^[0-9]{4}-[0-9]{2}-[0-9]{2}$', msg: 'Not in yyyy-mm-dd format' }
]
},
//column with pqselect editor
{
title: "Shipping Via", dataIndx: "ShipVia", width: 110,
cls: 'pq-drop-icon pq-side-icon',
editor: {
type: 'select',
options: [
{ "SE": "Speedy Express" },
{ "UP": "United Package" },
{ "FS": "Federal Shipping" }
],
init: function (ui) {
ui.$cell.find("select").pqSelect();
setTimeout(function () {
ui.$cell.find("select").pqSelect('open');
})
}
},
//render required to display options text corresponding to value stored in the cell.
render: function (ui) {
var option = ui.column.editor.options.find(option => option[ui.cellData] != null);
return option ? option[ui.cellData] : "";
},
validations: [
{ type: 'minLen', value: 1, msg: "Required" },
{
type: function (ui) {
var value = ui.value,
option = ui.column.editor.options.find(option => option[value] != null);
if (!option) {
ui.msg = value + " not found in list";
return false;
}
}, icon: 'ui-icon-info'
}
]
},
{
title: "Shipping Via2", dataIndx: "ShipVia2", width: 110,
cls: 'pq-drop-icon pq-side-icon',
editor: {
type: 'select',
valueIndx: "value",
labelIndx: "text",
options: [
{ value: "", text: "" },
{ value: "SE", text: "Speedy Express" },
{ value: "UP", text: "United Package" },
{ value: "FS", text: "Federal Shipping" }
]
},
//render required to display options text corresponding to value stored in the cell.
render: function (ui) {
var option = ui.column.editor.options.find(option => option.value == ui.cellData );
return option ? option.text : "";
},
validations: [
{ type: 'minLen', value: 1, msg: "Required" },
{
type: function (ui) {
var value = ui.value,
option = ui.column.editor.options.find(option => option.value == value );
if (!option) {
ui.msg = value + " not found in list";
return false;
}
}, icon: 'ui-icon-info'
}
]
},
{
title: "Shipping Address", width: 200, dataIndx: "ShipAddress",
editor: {
style: {
width: "auto"
}
},
editModel: {
saveKey: '' //disable or set it to some other key code to free up use of Enter key for line breaks.
},
validations: [{ type: 'minLen', value: 1, msg: "Required" }]
},
{
title: "Freight", dataIndx: "Freight", dataType: "float", width: 100, format: '$#,###.00',
editor: { select: true },
validations: [{ type: 'gte', value: 1, msg: "should be >= 1" }],
editModel: { keyUpDown: true }
}
];
var dataModel = {
location: "remote",
dataType: "JSON",
method: "GET",
url: "/content/invoice.json",
getData: function (response) {
response.data.forEach(function (rd) {
//convert dates from 'mm/dd/yyyy' to ISO format.
rd.OrderDate = pq.parseDate(rd.OrderDate, 'mm/dd/yyyy');
//make ShipAddress multiline text.
rd.ShipAddress = rd.ShipAddress + "\n" + rd.ShipCity + "\n" + (rd.ShipRegion || "") + "\n" + rd.ShipPostalCode;
})
return response;
}
}
//finally define the grid.
$("div#grid_custom_editing").pqGrid({
toolbar: {
items: [
{
type: 'button', icon: 'ui-icon-plus', label: 'New Product', listener: function () {
//append empty row at the end.
var rowData = { ProductID: 34, UnitPrice: 0.2 }; //empty row
var rowIndx = this.addRow({ rowData: rowData, checkEditable: true });
this.goToPage({ rowIndx: rowIndx });
this.editFirstCellInRow({ rowIndx: rowIndx });
}
},
{ type: 'separator' },
{
type: 'button', icon: 'ui-icon-disk', label: 'Save Changes', cls: 'changes', listener: saveChanges,
options: { disabled: true }
},
{
type: 'button', icon: 'ui-icon-cancel', label: 'Reject Changes', cls: 'changes', listener: function () {
this.rollback();
this.history({ method: 'resetUndo' });
},
options: { disabled: true }
},
{
type: 'button', icon: 'ui-icon-cart', label: 'Get Changes', cls: 'changes', listener: function () {
var changes = this.getChanges({ format: 'byVal' });
if (console && console.log) {
console.log(changes);
}
alert("Please see the log of changes in your browser console.");
},
options: { disabled: true }
},
{ type: 'separator' },
{
type: 'button', icon: 'ui-icon-arrowreturn-1-s', label: 'Undo', cls: 'changes', listener: function () {
this.history({ method: 'undo' });
},
options: { disabled: true }
},
{
type: 'button', icon: 'ui-icon-arrowrefresh-1-s', label: 'Redo', listener: function () {
this.history({ method: 'redo' });
},
options: { disabled: true }
}
]
},
trackModel: { on: true }, //to turn on the track changes.
history: function (evt, ui) {
var $tb = this.toolbar();
if (ui.canUndo != null) {
$("button.changes", $tb).button("option", { disabled: !ui.canUndo });
}
if (ui.canRedo != null) {
$("button:contains('Redo')", $tb).button("option", "disabled", !ui.canRedo);
}
$("button:contains('Undo')", $tb).button("option", { label: 'Undo (' + ui.num_undo + ')' });
$("button:contains('Redo')", $tb).button("option", { label: 'Redo (' + ui.num_redo + ')' });
},
title: "Shipping Orders <b>(Custom editing)</b>",
dataModel: dataModel,
colModel: colM,
//we don't want to allow invalid values while paste of data.
pasteModel: {allowInvalid: false},
//scrollModel: { autoFit: true },
columnTemplate: {
valign: 'center',
width: 150
},
create: function (evt, ui) {
this.widget().pqTooltip();
},
editModel: {
//clicksToEdit: 1,
keyUpDown: false,
onBlur: 'save'
},
numberCell: { show: false },
resizable: true
});
});
-
With your code, getChanges returns empty updateList even for inline editing of any cell.
-
Dear Paramvir,
I also found that there were problem in the code, would you like to correct the code in this code block? or provide a another demo?
Million thanks, this problem has troubled me for a long time.
The "get changes" button changed from disable status to enable status, but I don'nt know why getChanges returns empty updateList after batch-copying to select column(the first column).
-
Dear Team,
To persuade you that this is a bug, you can batch-copy many "United Package"s (this should be prepared in excel) into the 3rd col in https://paramquery.com/demos/edit_select.
Then you will find that the second col is blank, if you use mouse to select "United Package" one by one in 3rd col, "UP" will show in second col.
-
Please check this example: https://paramquery.com/pro/demos/datamap
-
Dear Team,
In https://paramquery.com/pro/demos/datamap, the select col's(the 1st col's) valueIndx and labelIndx are same(in my case they are different), maybe the formula will force the 1st col to be updated when batch-copying.
https://paramquery.com/pro/demos/datamap and https://paramquery.com/demos/edit_select are not same topic.
I wonder why batch-copy could not work well in https://paramquery.com/demos/edit_select, and how to make it work.
It's obviously that if there no extra code to fix bug or add configuration, the select in https://paramquery.com/demos/edit_select could not handle batch-copy smoothly.
-
ShipVia (2nd column) in this example: https://paramquery.com/pro/demos/edit_select has different valueIndx, labelIndx and it works with copy paste.
editor.mapIndices is not designed for copy paste.
Please use formulas instead of editor.mapIndices in case there are any dependencies between different columns.
-
Dear Team,
When batch-copy many "United Package"s (they should be prepared in excel instead in pqgrid) to 2nd col in https://paramquery.com/pro/demos/edit_select, it doesn't work.
I get many selected blank cells, unless I batch-copy many "UP"s(prepared in excel) into the 2nd column, but usually end-user doesn't know key of the options or makes a lot of trouble to make them(key) in excel.
-
Dear Paramvir,
Thank you very much for caring about this post in weekends.
Another problem is if batch-copy one column of "Speedy Express" from pqgrid to excel, you can only get one column of "SE" in excel.
This is not expected for any users.