In latest free from from github posting images from form edit sends image key two times.
For example using testcase below post data contains:
------WebKitFormBoundaryHjeY1fJPAaaXE56n
Content-Disposition: form-data; name="Pilt"; filename="eeva.bmp"
Content-Type: image/bmp
------WebKitFormBoundaryHjeY1fJPAaaXE56n
Content-Disposition: form-data; name="_image_Pilt"
------WebKitFormBoundaryHjeY1fJPAaaXE56n
Content-Disposition: form-data; name="Pilt"
Note that name="Pilt"
appears in tow times.
To reproduce, open code below in Chrome, select row, start form edit, select some image, active chrome developer tools and press submit button. Request payload shows that duplicate Pilt keys are posted.
How to fix this so that there are no duplicate keys on post like in earlier version ?
Testcase:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>http://stackoverflow.com/q/33628065/315935</title>
<meta name="author" content="Oleg Kiriljuk">
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/redmond/jquery-ui.css">
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<!--<link rel="stylesheet" href="jqGrid/css/ui.jqgrid.css">-->
<link rel="stylesheet" href="http://rawgit.com/free-jqgrid/jqGrid/master/css/ui.jqgrid.css">
<style>
html, body { font-size: 75%; }
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="http://malsup.github.io/jquery.form.js"></script>
<script>
$.jgrid = $.jgrid || {};
$.jgrid.no_legacy_api = true;
$.jgrid.useJSON = true;
</script>
<!--<script src="jqGrid/js/jquery.jqGrid.src.js"></script>-->
<script src="http://rawgit.com/free-jqgrid/jqGrid/master/js/jquery.jqgrid.src.js"></script>
<script>
//<![CDATA[
/*global $ */
/*jslint browser: true */
$(function () {
"use strict";
/*global $ */
/*jslint plusplus: true, browser: true, eqeq: true */
$(function () {
"use strict";
var mydata = [
{ id: "10", _image_Pilt: null, invdate: "2013-11-01", name: "'", note: "note", amount: "200.00", tax: "10.00", closed: true, ship_via: "TN", total: "210.00" }
],
editSettings = {
url: null,
useDataProxy: true,
dataProxy: function (opt, args) { dataProxyAjax(opt, args, 'Artpilt'); },
checkOnUpdate: true,
reloadAfterSubmit: false,
closeOnEscape: true,
savekey: [true, 13],
closeAfterEdit: true
},
addSettings = {
checkOnUpdate: true,
reloadAfterSubmit: false,
savekey: [true, 13],
closeOnEscape: true,
closeAfterAdd: true
},
delSettings = {
},
initDateEdit = function (elem) {
setTimeout(function () {
$(elem).datepicker({
dateFormat: "dd-M-yy",
showOn: "button",
changeYear: true,
changeMonth: true,
showButtonPanel: true,
showWeek: true
});
}, 50);
},
initDateSearch = function (elem) {
setTimeout(function () {
$(elem).datepicker({
dateFormat: "dd-M-yy",
changeYear: true,
changeMonth: true,
showButtonPanel: true,
showWeek: true
});
}, 50);
},
removeTheOptionAll = function (elem) {
},
dataProxyAjax = function (opts, act, entity) {
//opts.url = $grid.jqGrid('getGridParam', 'url');
if (opts.data._oper === "edit") {
opts.url = 'http://httpbin.org/status/200';
}
else {
opts.url = 'http://httpbin.org/status/201';
}
opts.iframe = true;
var $form = $('#FrmGrid_' + $grid.jqGrid('getGridParam', 'id')),
ele;
//use normal ajax-call when no files to upload
// if ($form.find(':file[value!=""]').size() == 0) {
// $.ajax(opts);
// return;
// }
//Prevent non-file inputs double serialization
ele = $form.find('INPUT,TEXTAREA,SELECT').not(':file');
ele.each(function () {
$(this).data('name', $(this).attr('name'));
$(this).removeAttr('name');
});
//Send only previously generated data + files
$form.ajaxSubmit(opts);
//Set names back after form being submitted
setTimeout(function () {
ele.each(function () {
$(this).attr('name', $(this).data('name'));
});
}, 200);
},
$grid= $("#list")
;
$("#list").jqGrid({
useDataproxy: true,
dataProxy: function (opt, args) { dataProxyAjax(opt, args, 'Artpilt'); },
datatype: "local",
data: mydata,
colNames: ["", "Image","Select image", "Client", "Date", "Amount", "Tax", "Total", "Closed", "Shipped via", "Notes"],
colModel: [
{name: "act", template: "actions"},
{ "label": "Pilt", "name": "_image_Pilt", "edittype": "image", "editoptions": {
"src": ""
}, "editable": true, "formatter": function (cell, options, row) {
return '<img src=\"https://placehold.it/100x100\" />';
}
, "search": false, "title": "", "width": 54
}, { "edittype": "file", "label": "", "name": "Pilt", "search": false, "title": "", "width": 54, "hidden": true, "editrules": { "edithidden": true }, "editable": true },
{ name: "name", width: 60, editrules: { required: true } },
{name: "invdate", width: 80, align: "center", sorttype: "date",
formatter: "date", formatoptions: {newformat: "d-M-Y", reformatAfterEdit: true},
editoptions: {dataInit: initDateEdit, size: 14},
searchoptions: {dataInit: initDateSearch}},
{
name: "amount", width: 62, template: "number",
formatter: "number", formatoptions: { decimalSeparator: ",", thousandsSeparator: " ", decimalPlaces: 2, defaultValue: '0,00' },
editoptions: {
maxlength: 7,
type: "number",
max: "9999",
dataEvents: [
{
type: "blur",
fn: function (e) {
if (e.target.checkValidity()) {
$(e.target).removeClass("ui-state-error");
} else {
$(e.target).addClass("ui-state-error");
alert(e.target.validationMessage);
$(e.target).focus();
}
}
}
]
}
},
//{ name: "amount", width: 70, formatter: "number", align: "right" },
{ name: "tax", width: 50, formatter: "number", align: "right" },
{name: "total", width: 60, formatter: "number", align: "right"},
{name: "closed", width: 70, align: "center", formatter: "checkbox",
edittype: "checkbox", editoptions: {value: "Yes:No", defaultValue: "Yes"},
stype: "select",
searchoptions: {
sopt: ["eq", "ne"],
value: ":All;true:Yes;false:No",
dataInit: removeTheOptionAll
}},
{name: "ship_via", width: 100, align: "center", formatter: "select",
edittype: "select", editoptions: {value: "FE:FedEx;TN:TNT;IN:Intim", defaultValue: "TN"},
stype: "select",
searchoptions: {
sopt: ["eq", "ne"],
value: ":All;FE:FedEx;TN:TNT;IN:Intim",
dataInit: removeTheOptionAll
}},
{name: "note", width: 60, sortable: false, edittype: "textarea"}
],
cmTemplate: {editable: true, searchoptions: {clearSearch: false }},
rowNum: 10,
rowList: [5, 10, 20],
pager: true,
gridview: true,
rownumbers: true,
autoencode: true,
ignoreCase: true,
sortname: "invdate",
viewrecords: true,
sortorder: "desc",
caption: "Demonstrates implementating of local form editing",
height: "100%",
editurl: "http://httpbin.org/status/200",
//editurl: "clientArray",
}).jqGrid("navGrid", {}, editSettings, addSettings, delSettings, {
multipleSearch: true,
overlay: false,
onClose: function () {
// if we close the search dialog during the datapicker are opened
// the datepicker will stay opened. To fix this we have to hide
// the div used by datepicker
$("div#ui-datepicker-div.ui-datepicker").hide();
}
}).jqGrid("filterToolbar", { defaultSearch: "cn" });
});
});
//]]>
</script>
</head>
<body>
<div id="outerDiv" style="margin: 5px;">
<table id="list"></table>
</div>
</body>
</html>
You use useDataproxy
option. Thus jqGrid don't send any data at all. If some problems exists than it should be probably in the code of dataProxyAjax
or the code of jquery.form.js
. jqGrid just prepare the data in postdata
object. The object contains only one property with Pilt
name. Thus any problems with "duplicate form key post" could be not a bug in free jqGrid.
If you want that free jqGrid use the same encoding of output characters as before, then you need just include autoEncodeOnEdit: true
jqGrid option. Moreover you can use any custom encoding by usage of serializeEditData
.
UPDATED: The problem was in the usage of jQuery.val()
for filling of all fields of Add/Edit form. The changes was introduced to allow support of HTML5 input elements with new type values (number
, color
, range
and so on). As the side effect jqGrid filled the fields which had the type image
and file
. It was the origin of the reported problem.
The problem should be fixed after posting the commit.