Kendo UI > Update Grid > Internal Server Error Generated - php

I've been beating my head against my desk for a few days now… time I asked for help.
I'm trying to update a value within Kendo UI's grid. The grid displays correctly, as does the popup editor. That's where the good times end. Here's the situation:
Click 'Edit' > Popup Opens > Click 'Update' (no change made) > Popup closes. Result = As expected.
Click 'Edit' > Popup Opens > Click 'Cancel' > Popup closes. Result = As expected.
Click 'Edit' > Popup Opens > Update the 'clientName' field > Click 'Update'. Result = Value in the row changes (in the background), popup stays open and a alert is displayed stating 'undefined'. If I then close the popup the change is lost. As part of this process a 500 internal server error is also generated.
Here's my Kendo code:
$(document).ready(function () {
var crudServiceBaseUrl = "assets/data/",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + "data.clients.php",
},
update: {
url: crudServiceBaseUrl + "data.clients.update.php",
},
create: {
url: crudServiceBaseUrl + "data.clients.create.php",
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {models: kendo.stringify(options.models)};
}
}
},
batch: true,
pageSize: 10,
error: function(e) {
alert(e.responseText);
},
schema: {
data: function(result) {
return result.data || result;
},
total: function(result) {
var data = this.data(result);
return data ? data.length : 0;
},
model: {
id: "clientID",
fields: {
clientID: { editable: false, nullable: true },
clientName: { validation: { required: true } },
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
toolbar: ["create"],
columns: [
{ field: "clientID", title: "Client ID" },
{ field: "clientName", title: "Client Name"},
{ command: "edit", title: " ", width: 110 }],
editable: "popup"
});
});
Here's my PHP:
include '../includes/connect.php';
$clientName = mysql_real_escape_string($_POST["clientName"]);
$clientID = mysql_real_escape_string($_POST["clientID"]);
$rs = mysql_query("UPDATE cms_clients SET clientName = '" .$clientName ."' WHERE clientID = " .$clientID);
if ($rs) {
echo json_encode($rs);
}
else {
header("HTTP/1.1 500 Internal Server Error");
echo "Update failed for EmployeeID: " .$clientID;
}
Oh, and I know this code has issues with potential injection. That's step 2.
Any help would be appreciated.
Thanks,
#rrfive

Related

Why echo function print data in console?

I'm creating page in PHP but when I use AJAX to send data, echo function start to printing data in console instead in DOM elements.
I want to add Quagga barcode reader to my page. Quagga is write in JS but my page is in php. So I have to use Ajax to send barcode result to my php code. And there is a problem. After sending data (POST) and using echo to display that on the screen, every data that echo should display are showing up in console. Not only data I send but whole page html code too. Even header('Location: ') doesn't work correctly. Because I'm sending readed code to barcodereaded.php where I put POST data inside SESSION var, and I try to echo that on the screen in different file barcoderesult.php but everytime data is printed in console log in barcode.php (which code is below). On every other subpage php echo and header functions works fine, only this one case causing troubles.
<div id="scanner-container"></div>
<input type="button" id="btn" value="Start/Stop" />
<script src="js/quagga.min.js"></script>
<script>
var _scannerIsRunning = false;
function startScanner() {
var barcode = {};
Quagga.init({
inputStream: {
name: "Live",
type: "LiveStream",
numOfWorkers: navigator.hardwareConcurrency,
target: document.querySelector('#scanner-container'),
constraints: {
size: 1920,
width: 200,
height: 480,
facingMode: "environment"
},
},
config: {
frequency: 5,
},
locator: {
patchSize: "x-large",
},
decoder: {
readers: [
"code_128_reader",
"ean_reader",
"ean_8_reader",
"code_39_reader",
"code_39_vin_reader",
"codabar_reader",
"upc_reader",
"upc_e_reader",
"i2of5_reader"
],
debug: {
showCanvas: true,
showPatches: true,
showFoundPatches: true,
showSkeleton: true,
showLabels: true,
showPatchLabels: true,
showRemainingPatchLabels: true,
boxFromPatches: {
showTransformed: true,
showTransformedBox: true,
showBB: true
}
}
},
}, function (err) {
if (err) {
console.log(err);
return
}
console.log("Initialization finished. Ready to start");
Quagga.start();
// Set flag to is running
_scannerIsRunning = true;
});
Quagga.onProcessed(function (result) {
var drawingCtx = Quagga.canvas.ctx.overlay,
drawingCanvas = Quagga.canvas.dom.overlay;
if (result) {
if (result.boxes) {
drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
result.boxes.filter(function (box) {
return box !== result.box;
}).forEach(function (box) {
Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, { color: "green", lineWidth: 2 });
});
}
if (result.box) {
Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, { color: "#00F", lineWidth: 2 });
}
if (result.codeResult && result.codeResult.code) {
Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: 'red', lineWidth: 3 });
}
}
});
Quagga.onDetected(function (result) {
Quagga.stop();
barcode.code = result.codeResult.code;
$.ajax({
url: "barcodereaded.php",
method: "POST",
data: barcode,
success: function(res){
console.log(res);
}
});
});
}
// Start/stop scanner
document.getElementById("btn").addEventListener("click", function () {
if (_scannerIsRunning) {
Quagga.stop();
_scannerIsRunning = false;
} else {
startScanner();
}
}, false);
</script>
I just want to send readed barcode to other file to convert it into data I want to add to database (quantity of elements on the pallet, production date, etc.)
Look at this part of your code :
$.ajax({
url: "barcodereaded.php",
method: "POST",
data: barcode,
success: function(res){
console.log(res);
}
});
The success method tells what to do with the result of your ajax code.
And here you specifically tell to log the response (res) to the console.
Instead you can use the content of res to append it to your dom via your preferred Javascript solution (vanilla, jQuery,...).
With jQuery you could (if the result from your php code is some text):
$('#my-return-container').text(res)

Kendo subgrid deletion (with php)

I use example like this:Tutorial for Kendo and PHP
And I use code in subgrid as in grid:
subDS = new kendo.data.DataSource({
transport: {
read: "data/channelName.php?acc="+e.data.userId,
destroy: {
url: "data/chMove.php",
type: "DELETE",
complete: function (e) {
$("#grid").data("kendoGrid").dataSource.read();
}
}
},
error: function(e) {
alert(e.responseText);
},
schema: {
data: "results",
model: {
id: "channelId"
}
}
});
detailRow.find(".subgrid").kendoGrid({
dataSource: subDS,
columns: [
{
title: "Channel Name", field: "channelname"
},
{
command: ["destroy"], title: " ", width: "100px"
}]
});
However, the code isn't fired in server side of PHP code,
I not sure it is client side code wrong or server side?
The read is return:
{"results":[{"channelname":"test"},{"channelname":"5413trret"},{"channelname":"d453"},{"channelname":"test3"},{"channelname":"ter"},{"channelname":"test5"}]}
and userId is in the read of the grid.
The server side(chMove.php) I try to test if it is fired use alert like:
<?php
// determine the request type
$verb = $_SERVER["REQUEST_METHOD"];
echo "<script>alert('"."123"."');</script>";
?>
But the alert never be fired, needless to say I want to get the parse_str(file_get_contents('php://input'), $request );
later and parse the $request.
The final goal is delete what user click in the "Delete" button and the server side can delete it in database.
Any idea about my code?
Or is there any other method to do deletion of subgrid?
Any advice appreciate.
OK, I have alternate method.
I look the manual : Below show how to fired remove function
And the code is like:
var detailRow = e.detailRow;
subDS = new kendo.data.DataSource({
transport: {
read: "data/channelName.php?acc="+e.data.userId
},
error: function(e) {
alert(e.responseText);
},
schema: {
data: "results",
model: {
id: "channelid",
fields: {
channelname:{ editable: false}
}
}
}
});
// create a subgrid for the current detail row, getting territory data for this employee
detailRow.find(".subgrid").kendoGrid({
columns: [
{ title: "Channel Name", field: "channelname"},
{ command: "destroy", title: " ", width: "100px" }
],
dataSource: subDS,
editable: true,
remove: function(e) {
//alert("Removing:" + e.model.channelid);
var xmlhttp2;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp2=new XMLHttpRequest();
} else {
xmlhttp2=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp2.open("POST","data/chMove.php",true);
xmlhttp2.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp2.send("channel="+e.model.channelid);
}
});
The most important is set your subgrid to be editable( I don't set the attribute before),
and the model of id can let you use in your data("results").
And I also show my trick to connect to PHP side :)
Then you can handle the server side as usual:
(in chMove.php)
$channel=mysql_real_escape_string($_POST["channel"]);
It takes me a lot of time to deal with it, I hope it is helpful.

EXTJS 4: Editable grid doesn't commit changes to MySQL Database

Dear fellow EXT enthusiasts,
I'm working on a project where I need an admin panel to edit job functions.
The grid is communicating to a MySQL database using Ext.Direct. It loads the data fine.
The grid shows the id and the function name
I added a RowEditing plugin to my grid for editting the function settings.
The problem is, when I try to commit the changes I get a tiny red triangle in the upper left corner of the grid without any error code in the console. The changes don't commit to the MySQL database.
The way my program works and loads the data:
This is my functionStore:
Ext.direct.Manager.addProvider(Ext.app.REMOTING_API);
Ext.define("MCS.store.FunctionStore",
{
extend: "Ext.data.Store",
requires: "MCS.model.Functions",
model: "MCS.model.Functions",
id: "FunctionStore",
proxy:
{
type: "direct",
api:
{
read: QueryDatabase.getFunctions,
create: QueryDatabase.createFunction,
update: QueryDatabase.updateFunction,
destroy: QueryDatabase.removeFunction,
}
},
});
In the controller: when the admin panel is rendered, the store gets loaded with the following function:
loadStore: function()
{
functionStore.load();
}
This is the grid where the functions are displayed:
var rowEditingFunctions = Ext.create("Ext.grid.plugin.RowEditing",
{
clicksToMoveEditor: 1,
autoCancel: false,
listeners: {
edit: function(editor,e,opt)
{
var grid = e.grid;
var record = e.record;
console.log(record.data.functionName);
var editedrecords = grid.getStore().getUpdatedRecords();
console.log(editedrecords);
}
}
});
var functionGrid = Ext.create("Ext.grid.Panel",
{
height: 500,
width: 800,
store: functionStore,
title:"List of Job Functions - double click to edit",
columns: [
{
dataIndex: "id",
width: 50,
text: "ID"
},{
dataIndex: "functionName",
flex: 1,
text: "Function",
field:
{
type: "textfield",
allowBlank: false
}
}],
plugins: [
rowEditingFunctions
],
dockedItems: [
{
xtype: "toolbar",
store: functionStore,
dock: "bottom",
items: [
{
iconCls: "add",
text: "Add",
handler: function()
{
rowEditingFunctions.cancelEdit();
var newRecord = Ext.create("App.model.Functions");
functionStore.insert(0, newRecord);
rowEditingFunctions.startEdit(0, 0);
var sm = functionGrid.getSelectionModel();
functionGrid.on("edit", function() {
var record = sm.getSelection()
functionStore.sync();
functionStore.remove(record);
functionStore.load();
});
}
}, {
iconCls: "delete",
text: "Delete",
handler: function()
{
rowEditingFunctions.cancelEdit();
var sm = functionGrid.getSelectionModel();
Ext.Msg.show(
{
title:"Delete Record?",
msg: "You are deleting a function permanently, this cannot be undone. Proceed?",
buttons: Ext.Msg.YESNO,
icon: Ext.Msg.QUESTION,
fn: function(btn)
{
if(btn === "yes")
{
functionStore.remove(sm.getSelection());
functionStore.sync();
}
}
});
}
}]
}]
});
As u can see I added a listener to the edit event of the RowEditing plugin, this displays the array of the edited record in console like it should.
4. And finally, this is the PHP code that updates the database:
public function updateFunction(stdClass $params)
{
$db = $this->__construct();
if ($stmt = $db->prepare("UPDATE functions SET functionName=? WHERE id=?"))
{
$stmt->bind_param('si', $functionName, $id);
$functionName = $params->functionName;
$id = (int) $params->id;
$stmt->execute();
$stmt->close();
}
return $this;
}
5. The weird part: once I've added one job function, I can edit all the other functions and those changes are committed to the database...
As a side note: I'm just a beginner in EXT, trying to learn it on my own, but I have been breaking my head on this issue for the last few days so I decided to ask you guys.
Thanks for your answers in advance!
I left the bug for what it was for a few weeks and started to look into it again this week.
I found a work around solution.
I've added the following code to my controller that controls the grids:
functionGrid.on('edit', function(editor, e)
{
e.store.sync();
});
Now when I update a record, the tiny red triangle still appears but after the e.store.sync() function is completed it disappears and the database table is updated.
Not a 100% clean solution, but it does the trick
If anyone has a better solution, please let me know

jqGrid errorTextFormat function

I´m developing an application using CodeIgniter and JQuery.
I have read here jqgrid error message on delete and here jqGrid error message from server side exception some issues about this problem but the fact is that does not work for me.
In my database I have set some business rules in form of index, checks, etc. I need to customize the "error Status: 'error'. Error code: 500" that the jqGrid returns when I have those types of errors.
I´d appreciate any help.
Here is my jquery grid code.
<script type="text/javascript">
var base_url = 'http://localhost/sp/';
var site_url = 'http://localhost/sp/index.php';
var url = '';
$(document).ready(function() {
var grid = jQuery("#newapi_1351019084").jqGrid({
ajaxGridOptions : {type:"POST"},
jsonReader : {
root:"data",
repeatitems: false
},
ondblClickRow: function(id){
dtgLoadButton1();
return;
},
rowList:[10,20,30],
viewrecords: true
,url:'http://localhost/sp/index.php/assigment/getData'
,editurl:'http://localhost/sp/index.php/assigment/setData'
,datatype:'json'
,rowNum:'13'
,width:'800'
,height:'300'
,pager: '#pnewapi_1351019084'
,caption:'Control de asignaciones'
,colModel:[
{name:'username',index:'username',label:'Usuario' ,align:'left',width:300,editable:false,edittype:'text',editrules:{required:true} }
,{name:'StoreName',index:'StoreName',label:'Tienda' ,align:'center',width:200,editable:false,edittype:'text',editrules:{required:true} }
,{name:'Users_idUsers',index:'Users_idUsers',label:'Usuario' ,align:'center',width:100,hidden:true,editable:true,edittype:'select',editoptions:{value:":Select;5:tienda1;6:tienda2;17:tienda3;18:tienda11",size:10},editrules:{edithidden:true,required:true,integer:true} }
,{name:'Stores_idStores',index:'Stores_idStores',label:'Tienda' ,align:'center',width:100,hidden:true,editable:true,edittype:'select',editoptions:{value:":Select;1:EA001;3:EA003;4:EA005;5:EA006;6:EA007;7:EA008;8:EA009;9:EA010;10:EA011;11:EA012;12:EA013;13:EA015;14:EA017;15:EA018;16:EA019;17:EA020;18:EA021;19:EA022;20:EA002;21:EA000",size:10},editrules:{edithidden:true,required:true,integer:true} }
,{name:'SurrugateTurn',index:'SurrugateTurn',label:'SurrugateTurn' ,align:'center',width:100,key:true,hidden:true,editable:true,edittype:'select',editoptions:{value:":Select;1:1;3:3;2:2",size:10},editrules:{hidden:true} }
] })
jQuery("#newapi_1351019084")
.jqGrid('navGrid',
'#pnewapi_1351019084',
{view:false,
edit:'1',
add:'1',
del:'1',
close:true,
delfunc: null ,
search:''
},
{ recreateForm: true,
width : 400 ,
beforeShowForm : function(form) {
},
closeAfterEdit:true }, // edit options
{ recreateForm: true,
width : 400,
closeAfterAdd : true,
beforeSubmit : function(postdata, formid) {
var mensaje = '';
var resultado = true;
return[resultado,mensaje];
}
}, /*add options*/
{mtype: 'POST'} /*delete options*/,
{sopt: ['eq','cn','ge','le' ] ,
multipleSearch: false ,
showOnLoad : false,
overlay:false,mtype: 'POST'} /*search options*/
).navButtonAdd('#pnewapi_1351019084',
{ caption:'', buttonicon:'ui-icon-extlink', onClickButton:dtgOpenExportdata, position: 'last', title:'Export data', cursor: 'pointer'}
);
;
});
</script>
Best regards and thanks for your time,
Assuming the server returns a user-friendly error message with the HTTP 500 response, you can simply to this:
...
{ recreateForm: true,
width : 400 , //removed the empty beforeShowForm callback
errorTextFormat:function(data){
if (data.status == 500)
return data.responseText; // You may need to do some HTML parsing here
}
closeAfterEdit:true }, // edit options
...

How can I add a jqGrid custom error message?

I´m using CodeIgniter and JQuery Grid. I have seen the responses that you have been made here about this topic but I haven't been able to solve my problem with none of them.
The fact is that I have a jqGrid and I need to show the the dialog of insert several types of error that the database server returns.
For example, in one case I have this error:
Duplicate entry '18-2-1-2012-10-25' for key 'user_store_turn_index'
I need to get this and to show a custom message instead of the current:
error Status: 'Internal Server Error'. Error code: 500
I've tried with the aftersubmit event. I've read the docs and seen the available examples but nothing works.
Inside my JavaScript code I have the function that deals with the after submit event for jqGrid:
afterSubmit : function(response, postdata){
test_validate
return false;
},
}
Then, I write the function that should get the responses for the after submit event:
function test_validate(response,postdata) {
alert('test');
if(response.responseText == '') {
success = true;
} else {
success = false;
}
return [success,response.responseText]
}
But nothing happens... Here is the almost complete jquery grid code
$(document).ready(function() {
var grid = jQuery("#newapi_1351189510").jqGrid({
ajaxGridOptions : {type:"POST"},
jsonReader : {
root:"data",
repeatitems: false
},
rowList:[10,20,30],
viewrecords: true
,url:'http://localhost/sp/index.php/turn_open/getData'
,editurl:'http://localhost/sp/index.php/turn_open/setData'
,datatype:'json'
,rowNum:'20'
,width:'600'
,height:'300'
,pager: '#pnewapi_1351189510'
,caption:'Apertura de caja'
,colModel:[
{name:'username',index:'username',label:'Usuario' ,align:'center',width:180,editable:false }
,{name:'TurnName',index:'TurnName',label:'Turno' ,align:'center',width:180,editable:false }
,{name:'date',index:'date',label:'Fecha' ,width:100,editable:true,edittype:'text',editrules:{required:false,date:true} ,editoptions: {size: 10, maxlengh: 10,dataInit: function(element) { $(element).datepicker({dateFormat: 'yy-mm-dd',changeMonth: true,changeYear: true,yearRange: '1982:2022'})}},searchoptions: {size: 10, maxlengh: 10,dataInit: function(element) { $(element).datepicker({dateFormat: 'yy-mm-dd',changeMonth: true,changeYear: true,yearRange: '1982:2022'})}}}
] })
jQuery("#newapi_1351189510")
.jqGrid('navGrid',
'#pnewapi_1351189510',
{view:false,
edit:'1',
add:'1',
del:'1',
close:true,
delfunc: null
},
afterSubmit : function(response, postdata)
{ test_validate
return false;
},
},
{mtype: 'POST'} /*delete options*/,
).navButtonAdd('#pnewapi_1351189510',
{ caption:'', buttonicon:'ui-icon-extlink', onClickButton:dtgOpenExportdata, position: 'last', title:'Export data', cursor: 'pointer'}
);
;
function test_validate(response,postdata){
alert('test');
if(response.responseText == ''){
success = true;
}else{
success = false;
}
return [success,response.responseText]
}
});

Categories