How can I add a jqGrid custom error message? - php

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]
}
});

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)

Jquery Validation Rules for comparing two numbers

I have these two Input boxes
form_open('performances/save/'.$performance_info->prf_id,array('id'=>'performance_form'));
form_input(array(
'class'=>'beg_inv',
'name'=>'beg_inv',
'id'=>'beg_inv',
'value'=>$performance_info->beg_inv);
form_input(array(
'class'=>'end_inv',
'name'=>'end_inv',
'id'=>'end_inv',
'value'=>$performance_info->end_inv);
form_submit(array(
'name'=>'submit',
'id'=>'submit',
'value'=>$this->lang->line('common_submit'),
'class'=>'submit_button float_right')
);
and i am using this jquery validate:
$('#performance_form').validate({
submitHandler:function(form)
{
$('#prf_id').val($('#scan_performance').val());
$(form).ajaxSubmit({
success:function(response)
{
tb_remove();
post_exp_form_submit(response);
},
dataType:'json'
});
},
errorLabelContainer: "#error_message_box",
wrapper: "li",
rules:
{
prod_id:"required",
beg_inv: { greaterThan: "#end_inv" }
},
messages:
{
prod_id:"<?php echo $this->lang->line('performances_product'); ?>",
beg_inv:"<?php echo $this->lang->line('performances_qty_val'); ?>"
}
});
I used the greaterThan as I have seen in this url but that is for dates only I think because my code above does not work. What is the equivalent of the greaterThan for numbers? Or are there any?
EDIT:
adding this worked out, new question: How do I Validate again when I corrected the end_inv without going back to the beg_inv to trigger the rule. If I add a new rule it will create a new error line instead of overwriting the first error message. Fiddle here by Riley
$.validator.addMethod(
"greaterThan",
function (value, element, params)
{
var target = $(params).val();
var isValueNumeric = !isNaN(parseFloat(value)) && isFinite(value);
var isTargetNumeric = !isNaN(parseFloat(target)) && isFinite(target);
if (isValueNumeric && isTargetNumeric) {
return Number(value) > Number(target);
}
if (!/Invalid|NaN/.test(new Date(value))) {
return new Date(value) > new Date(target);
}
return false;
}, 'Must be greater than {0}.');

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
...

Backbone.js model.destroy() not sending DELETE request

I've been trying for days to get this working and I just cannot figure out why when I have my view to destroy a model which belongs to a collection (which properly has a url attribute for the beginning fetch of models' data), only fires the destroy 'event' which is bubbled up to the collection for easy binding by my list view. But it does not ever send an actual DELETE request or any request to the server at all. Everywhere I look, I see everyone using either the collection's url attr, or urlRoot if the model is not connected to a collection. I've even tested before the actual this.model.destroy() to check the model < console.log(this.model.url());
I have not overwritten the destroy nor sync methods for backbone. Also each model does have an id attribute which is populated via the collection's fetch (from database records).
The destroy takes place in the list item view, and the collection's "destroy" event is bound in the list view. All that works well (the event handling), but the problem, again, is there's no request to the server.
I was hoping that backbone.js would do it automatically. That was what the documentation implies, as well as the numerous examples everywhere.
Much thanks to anyone who can give some useful input.
FYI: I'm developing on wampserver PHP 5.3.4.
ListItemView = BaseView.extend({
tagName: "li",
className: "shipment",
initialize: function (options) {
_.bindAll(this);
this.template = listItemTemplate;
this.templateEmpty = listItemTemplateEmpty;
},
events: {
'click .itemTag' : 'toggleData',
'click select option' : 'chkShipper',
'click .update' : 'update',
'click button.delete' : 'removeItem'
},
// ....
removeItem: function() {
debug.log('remove model');
var id = this.model.id;
debug.log(this.model.url());
var options = {
success: function(model, response) {
debug.log('remove success');
//debug.log(model);
debug.log(response);
// this.unbind();
// this.remove();
},
error: function(model, response) {
debug.log('remove error');
debug.log(response);
}
};
this.model.destroy(options);
//model.trigger('destroy', this.model, this.model.collection, options);
}
});
Collection = Backbone.Collection.extend({
model: Model,
url: '?dispatch=get&src=shipments',
url_put : '?dispatch=set&src=shipments',
name: 'Shipments',
initialize: function () {
_.bindAll(this);
this.deferred = new $.Deferred();
/*
this.fetch({
success: this.fetchSuccess,
error: this.fetchError
});
*/
},
fetchSuccess: function (collection, response) {
collection.deferred.resolve();
debug.log(response);
},
fetchError: function (collection, response) {
collection.deferred.reject();
debug.log(response);
throw new Error(this.name + " fetch failed");
},
save: function() {
var that = this;
var proxy = _.extend( new Backbone.Model(),
{
url: this.url_put,
toJSON: function() {
return that.toJSON();
}
});
var newJSON = proxy.toJSON()
proxy.save(
newJSON,
{
success: that.saveSuccess,
error: that.saveError
}
);
},
saveSuccess: function(model, response) {
debug.log('Save successful');
},
saveError: function(model, response) {
var responseText = response.responseText;
throw new Error(this.name + " save failed");
},
updateModels: function(newData) {
//this.reset(newData);
}
});
ListView = BaseView.extend({
tagName: "ul",
className: "shipments adminList",
_viewPointers: {},
initialize: function() {
_.bindAll(this);
var that = this;
this.collection;
this.collection = new collections.ShipmentModel();
this.collection.bind("add", this.addOne);
this.collection.fetch({
success: this.collection.fetchSuccess,
error: this.collection.fetchError
});
this.collection.bind("change", this.save);
this.collection.bind("add", this.addOne);
//this.collection.bind("remove", this.removeModel);
this.collection.bind("destroy", this.removeModel);
this.collection.bind("reset", this.render);
this.collection.deferred.done(function() {
//that.render();
that.options.container.removeClass('hide');
});
debug.log('view pointers');
// debug.log(this._viewPointers['c31']);
// debug.log(this._viewPointers[0]);
},
events: {
},
save: function() {
debug.log('shipments changed');
//this.collection.save();
var that = this;
var proxy = _.extend( new Backbone.Model(),
{
url: that.collection.url_put,
toJSON: function() {
return that.collection.toJSON();
}
});
var newJSON = proxy.toJSON()
proxy.save(
newJSON,
{
success: that.saveSuccess,
error: that.saveError
}
);
},
saveSuccess: function(model, response) {
debug.log('Save successful');
},
saveError: function(model, response) {
var responseText = response.responseText;
throw new Error(this.name + " save failed");
},
addOne: function(model) {
debug.log('added one');
this.renderItem(model);
/*
var view = new SB.Views.TicketSummary({
model: model
});
this._viewPointers[model.cid] = view;
*/
},
removeModel: function(model, response) {
// debug.log(model);
// debug.log('shipment removed from collection');
// remove from server
debug.info('Removing view for ' + model.cid);
debug.info(this._viewPointers[model.cid]);
// this._viewPointers[model.cid].unbind();
// this._viewPointers[model.cid].remove();
debug.info('item removed');
//this.render();
},
add: function() {
var nullModel = new this.collection.model({
"poNum" : null,
"shipper" : null,
"proNum" : null,
"link" : null
});
// var tmpl = emptyItemTmpl;
// debug.log(tmpl);
// this.$el.prepend(tmpl);
this.collection.unshift(nullModel);
this.renderInputItem(nullModel);
},
render: function () {
this.$el.html('');
debug.log('list view render');
var i, len = this.collection.length;
for (i=0; i < len; i++) {
this.renderItem(this.collection.models[i]);
};
$(this.container).find(this.className).remove();
this.$el.prependTo(this.options.container);
return this;
},
renderItem: function (model) {
var item = new listItemView({
"model": model
});
// item.bind('removeItem', this.removeModel);
// this._viewPointers[model.cid] = item;
this._viewPointers[model.cid] = item;
debug.log(this._viewPointers[model.cid]);
item.render().$el.appendTo(this.$el);
},
renderInputItem: function(model) {
var item = new listItemView({
"model": model
});
item.renderEmpty().$el.prependTo(this.$el);
}
});
P.S... Again, there is code that is referenced from elsewhere. But please note: the collection does have a url attribute set. And it does work for the initial fetch as well as when there's a change event fired for saving changes made to the models. But the destroy event in the list-item view, while it does trigger the "destroy" event successfully, it doesn't send the 'DELETE' HTTP request.
Do your models have an ID? If not, the HTTP request won't be sent. –
nikoshr May 14 at 18:03
Thanks so much! Nikoshr's little comment was exactly what I needed. I spent the last 5 hours messing with this. I just had to add an id to the defaults in my model.

Call Dialog.Modal with error

I think I'm missing something here.
in Script:
$('#dialog:ui-dialog').dialog('destroy');
$('#dialog-modal').dialog({ width:150, height:150, resizable:false, draggable:false, autoOpen:true, modal:true });
I use AJAX to call for Data, when the pull detect an error, I want it to pop up an dialog.modal, but it just won't do so. I think I'm missing something here.
in PHP:
case ($amt > $total_storage):
echo "<div id='dialog-modal' class='ui-dialog-content ui-widget-content' title='Error!'><p>Not enough Storage!</p></div>"; (this one don't work)
echo "Test Error"; (this one works)
break;
I tested with echo and it does display "Error" but not the dialog.modal. I just want it to autoOpen when it detects an error.
New Workable Version:
PHP:
case ($amt > $total_storage):
echo ":err:<p>Not enough Storage!</p></div>";
break;
JS:
function CitySell(a){
$.ajax({
beforeSend: function(){ $(".Bags").attr("disabled", "disabled"); },
url: "DataPull.php?get=CitySell&SSIDD="+$('.SDI_'+a).val()+"&SSAmD="+$('.STS_'+a).val(),
success: function(data){
$('#Listing').html(parseScript(data));
if(data.substr(0,5) === ':err:'){
$('<div id="dialog-modal" class="ui-dialog-content ui-widget-content" title="Error!">').html(data.substr(5)).dialog({width:250, height:150, resizable:false, draggable:false, autoOpen:true, modal:true});
$('.Bags').removeAttr("disabled");
} else {
Listing();
CommonUpdates();
}
}
})
}
Wrap you js code into a function
function open_dialog(error_text)
{
$('#dialog:ui-dialog').dialog('destroy');
$('#dialog-modal')
.html(error_text)
.dialog({ width:150, height:150, resizable:false, draggable:false, autoOpen:true, modal:true });
}
and make a function call at the onSuccess method
$.get(url, function(result){ open_dialog(data); })
Though you'll have to distinguish between cases when the response indicates an error and when it's not. You could add some characters to the response to see whether it's an error or not:
case ($amt > $total_storage):
echo ":err:<p>Not enough Storage!</p></div>";
break;
$.get(url, function(result){ if(data.substr(0,5) === ':err:') open_dialog(data); else alert(data); })
You are trying to return the html for the dialog which is what is likely causing problems, since it doesn't exist when you try to initiate the dialog
If you return your data as json it makes it much simpler
echo json_encode( array('status'=>'error', 'message'=>'Your error message') );
Then in success callback of ajax:
$.get( url, function(data){
if( data.status=='error'){
$('<div id="dialog-modal">').html( data.message).dialog( // dialog options)
}
},'json');

Categories