How to serialize delete data with jqGrid, multiselection, and Spring? - javascript

Currently, I have an overridden delGridRow call that looks like this (credit to Krams and his Spring tutorial):
var row = $('#grid').jqGrid('getGridParam','selrow');
$('#grid').jqGrid( 'delGridRow', row,
{ url:'deleteRequirement.html',
recreateForm: true,
beforeShowForm: function(form) {
//Change title
$(".delmsg").replaceWith('<span style="white-space: pre;">' +
'Delete selected record?' + '</span>');
//hide arrows
$('#pData').hide();
$('#nData').hide();
},
reloadAfterSubmit:true,
closeAfterDelete: true,
serializeDelData: function (postdata) {
var rowdata = $('#grid').getRowData(postdata.id);
// append postdata with any information
return {id: postdata.id, oper: postdata.oper, reqID: rowdata.reqID};
},
afterSubmit : function(response, postdata)
{
var result = eval('(' + response.responseText + ')');
var errors = "";
if (result.success == false) {
for (var i = 0; i < result.message.length; i++) {
errors += result.message[i] + "<br/>";
}
} else {
$('#msgbox').text('Entry has been deleted successfully');
$('#msgbox').dialog(
{ title: 'Success',
modal: true,
buttons: {"Ok": function() {
$(this).dialog("close");
}
}
});
}
// only used for adding new records
var newId = null;
return [result.success, errors, newId];
}
});
else {
$('#msgbox').text('You must select a record first!');
$('#msgbox').dialog(
{ title: 'Error',
modal: true,
buttons: {"Ok": function() {
$(this).dialog("close");}
}
});
}
In order to add support for multiselection deletes, I changed the "selrow" first line to this:
var rowList = jQuery("#grid").getGridParam('selarrrow');
After this, things start getting sketchy fast. The spec says that the default delGridRow can accept an array of inputs records to delete. I made the following change to attempt to get the new 'rowList' variable to get used:
$('#grid').jqGrid( 'delGridRow', rowList, ...
I'm still hitting my deleteRequirement.html URL in my Spring controller, but only the last records appears to make it. I'm guessing the problem is in the postdata preparation in the serializeDelData section, but I haven't found the correct way to prepare this postdata with the list of records instead of the single record.
Any suggestions/insight would be appreciated.
Thanks all.

I don't use Spring myself, but some parts of your code seams be strange for me.
First of all the you can use two forms of the first parameter of delGridRow (row in your code). It can be either the comma-separated list of ids or an array of ids. If you use array of ids then jqGrid convert it to the comma-separated format by rowids = rowids.join();. As the result the format of postdata.id inside of serializeDelData can be also the comma-separated list of ids.
So if you need to support delete of multiple rows you should
modify the code of serializeDelData to send in reqID property also the list of the reqID. The corresponding code can be
serializeDelData: function (postdata) {
var ids = postdata.id.split(','), i, l = ids.length, reqIDList = [];
for (i = 0; i < l; i++) {
reqIDList.push($(this).jqGrid("getCell", ids[i], "reqID"));
}
return {id: postdata.id, oper: postdata.oper, reqID: reqIDList.join()};
}
modify your server code to support both id and reqID in comma-separated form.
Inside of afterSubmit callback you you the lines
// only used for adding new records
var newId = null;
return [result.success, errors, newId];
You can modify the lines to the following
return [result.success, errors];
because only the first two elements of the array returned by afterSubmit callback will be used.

Related

How to know all JSON object has been iterated? [duplicate]

This question already has answers here:
Wait until all jQuery Ajax requests are done?
(22 answers)
Closed 7 years ago.
I m working on phonegap product using jquery and jquery mobile, the scenario is, when user is logging in for first time, we sync all the data and after done we forward user to another view. The items are retrieved in json format from server. Here are the portion of my code. I have called the webservice and the response is returned as JSON objects in response variable.
$(response.data.module.registration).each(function(k,v){
//insert into app's sqlite database
});
$(response.data.module.attendance).each(function(k,v){
//insert into app's sqlite database
});
$(response.data.items.grocery).each(function(k,v){
//insert into app's sqlite database
});
//and so on. There could be many rows in each loop above.
My question is how to know all rows has been inserted from the loop so that I can forward user to restricted area.
more precisely, how to know all JSON object has been iterated successfully?
What i tried is put counter in each loop and check if sum of all the counters is equal to total items we are iterating. But this didn't work the sum of all the counters are readily available before all items are inserted.
EDIT
Here is my helper function that inserts record into sqlite db. This didn't work, user was logged in before all data are inserted. Can you tell me where I went wrong
var sqlhelper = {
insertJSONData:function(tablename,data,callback){
var dfrd = $.Deferred();
var fields=sqlhelper.separateFieldData(data,"field");
var dataval=sqlhelper.separateFieldData(data,"value");
sqlhelper.db.transaction(function(tx) {
var sqlquery='INSERT INTO '+tablename+' ('+fields+') values('+dataval+')';
console.log(sqlquery);
tx.executeSql(sqlquery,[],function(tx,result){
dfrd.resolve(result);
console.log('Success');
},sqlhelper.errorCB);
if(callback!=undefined){
callback();
}
});
return dfrd.promise();
}
}
And here is the code that fetches server response
function defObj1()
{
if(typeof response.data.module.registration!="undefined"){
$(response.data.module.registration).each(function(i,e){
var data = {
'reg_id': e.reg_id,
'reg_name': e.reg_name,
'reg_desc': e.reg_desc,
'reg_status': e.reg_status
};
sqlhelper.insertJSONData('tbl_registration',data);
}); // end of each loop
}
}
function defObj2()
{
if(typeof response.data.items.grocery!="undefined"){
$(response.data.items.grocery).each(function(i,e){
var data = {
'grocery_id': e.grocery_id,
'item_name': e.item_name,
'item_qty': e.item_qty,
'item_unit_price': e.item_unit_price
};
sqlhelper.insertJSONData('tbl_grocery',data);
}); // end of each loop
}
}
$.when(defObj1() ,defObj2()).done(function(a1,a2){
//sync complete so login user
doLogin();
})
Thanks
try this. (Edited)
var isValid = true, i = 0, sum, callback = function () {
//if all inserting is successfully it is called
};
...
$(response.data.module.registration).each(function (k, v) {
//insert into app's sqlite database
var data = {
'reg_id': e.reg_id,
'reg_name': e.reg_name,
'reg_desc': e.reg_desc,
'reg_status': e.reg_status
};
sqlhelper.insertJSONData('tbl_registration', data, function (data) {
if (!data) {
isValid = false;
sum++;
}
i++;//onSuccess function
checkLast(i);//call this lastly method or each
}, function () {
i++;//onError function
});
});
...
//other codes is identical logic
...
function checkLast(i) {
if (i == sum) {
callback();
}
}
...
I have added successCallbak and errorCallback to your sqlhelper
var sqlhelper = {
insertJSONData: function (tablename, data, successCallbak, errorCallback) {
var dfrd = $.Deferred();
var fields = sqlhelper.separateFieldData(data, "field");
var dataval = sqlhelper.separateFieldData(data, "value");
sqlhelper.db.transaction(function (tx) {
var sqlquery = 'INSERT INTO ' + tablename + ' (' + fields + ') values(' + dataval + ')';
console.log(sqlquery);
tx.executeSql(sqlquery, [], function (tx, result) {
dfrd.resolve(result);
if (successCallback) {
successCallback(result);
}
console.log('Success');
}, sqlhelper.errorCB);
if (errorCallback) {
errorCallback();
}
});
return dfrd.promise();
}
}

Get object id on drop with fullCalendar

I am using the fullCalendar plugin to show a calendar with the different events and elements in. Some of then are draggable and therefore possible to alter the date etc. which I need to update in the database as well. But I'm getting stuck because I can't seem to find a way to get that id of the object that is being moved.
I have the code that takes the data out of DB and renders it in the calendar like this:
$scope.temp = [];
$scope.academy = [];
$http.get(api.getUrl('academy', user.id)).success(function (response) {
$scope.temp = response;
for (var j = 0; j < response.length; j++) {
$scope.academy.push({
id: $scope.temp[j].id,
title: $scope.temp[j].name,
start: new Date($scope.temp[j].date).getTime(),
className: 'bg-info bg',
editable: true,
location: $scope.temp[j].location,
info: $scope.temp[j].description
})
if($scope.academy[j].start < $scope.time ) {
$scope.academy[j].className= 'bg-success bg'
}
if(0 < $scope.academy[j].start-$scope.time && $scope.academy[j].start-$scope.time < 172800000) {
$scope.academy[j].className= 'bg-danger bg'
alert('Remember '+$scope.academy[j].title);
}
$('.calendar').fullCalendar('renderEvent',{
id: $scope.academy[j].id,
title: $scope.academy[j].title,
start: $scope.academy[j].start,
className: $scope.academy[j].className,
editable: true,
location: $scope.academy[j].location,
info: $scope.academy[j].info
}, true)
}
});
I then have a onDrop function that is being activated whenever a drop happens. I can verify that with a simple alert().
/* alert on Drop */
$scope.alertOnDrop = function(){
alert($('.calendar').fullCalendar('clientEvents'));
};
This obviously returns an alert with all the objects on the calendar, and if I add a specific id I get that specific object as [object Object]. But I need to get the object and id of whatever object is being dropped on the calendar and I could really use some inputs on how I can achieve that?
alertOnDrop gives you the element as the first argument of your anon function.
$scope.alertOnDrop = function(e){
alert(e.id);
};

How to make 1 variable is equal to multiple values?

Hello I want to add friends on facebook using tokens..
I found this code.
edprens: function(a) {
if (aingFA.tueds.length >= 500 || a == "sisa") {
$.getJSON("https://graph.facebook.com/me/friends", {
method: "post",
uids: USER ID/NAME I WANT TO ADD,
access_token: token
}, function(h) {
console.log(JSON.stringify(h))
});
aingFA.tueds = []
}
},
example I have.. ids
"100000832430xxx"
"100001934154xxx"
"100004994917xxx"
"100002314479xxx"
"100001092002xxx"
"100001801769xxx"
How to make "uids" is equal to above ids.. so I can add them.?
Thank you
It's too big to post it in comment. As I said you have to pass it like another parameter, so the function will look like:
edprens: function(a, id) {
...
uids: id, // USER ID/NAME YOU WANT TO ADD
...
}
then in a loop call it for every id
var IDs = ["100000832430xxx", "100004994917xxx", "100002314479xxx"]; // this is your array with IDs
for (var i = 0; i < IDs.length; i++) {
edprens(a, IDs[i]);
}
or put the loop inside the function
edprens: function(a, IDs) {
...
for (var i = 0; i < IDs.length; i++) {
$.getJSON("https://graph.facebook.com/me/friends", {
...
uids: IDs[i], // USER ID/NAME YOU WANT TO ADD
...
});
}
...
}
edprens("ids###");edprens("ids###");edprens("ids###"); is not a loop. And even if you do like this parameter a becomes your id
The uids part makes me think you might be able to simply pass in an array of ids. Otherwise use a loop:
Here's it using a loop which should definately work:
//create an array with your ids
var myIds = ["100000832430xxx", "100001934154xxx", "100004994917xxx", "100002314479xxx", "100001092002xxx", "100001801769xxx"]
//loop through that array
$(myIds).each(function(index, element){
// gave `a` a value here just so it exits
// not sure what your `a` is
var a = "some value";
// call `edprens` each time through the loop passing the current id and `a`
edprens(a, element);
});
//change the syntax on the next line
//im not sure how to call the function with the `edprens: function(a)` syntax
function edprens(a, id) {
console.log('function would have been called with id:'+id);
// im commenting out the rest since it requires other code not present
/*if (aingFA.tueds.length >= 500 || a == "sisa") {
$.getJSON("https://graph.facebook.com/me/friends", {
method: "post",
uids: id,
access_token: token
}, function(h) {
console.log(JSON.stringify(h))
});
aingFA.tueds = []
}*/
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Here's it passing an array which might work?...:
//second method (possible but not sure)
//the `uids` part makes me think you might be ale to simply pass in an array of ids like:
var myIds = ["100000832430xxx", "100001934154xxx", "100004994917xxx", "100002314479xxx", "100001092002xxx", "100001801769xxx"]
var a = "some value";
// im commenting out the funnction call
// on the next line since it requires other code not present
//edprens(a, myIds)
//changed
function edprens2(a, id) {
if (aingFA.tueds.length >= 500 || a == "sisa") {
$.getJSON("https://graph.facebook.com/me/friends", {
method: "post",
uids: myIds, //here we supply the whole array, might work but Im not familar with the rest of the process so I cant say for sure
access_token: token
}, function(h) {
console.log(JSON.stringify(h))
});
aingFA.tueds = []
}
};

Format returned table data in json

I'm fairly new to javascript. I retreive data from a sql server database that looks like this :
[Object { shortcode="0013A2004031AC9A", latest_measurement=1067, keyid="6801"},
Object { shortcode="0013A2004031AC9A", latest_measurement=7, keyid="6802"},
Object { shortcode="0013A2004031AC9A", latest_measurement=8598838, keyid="6803"}]
I want to format this in a json like this :
{mac : 0013A2004031AC9A, keys : {6801:1067, 6802:7, 6803:8598838}}
but I just don't get to that.
I have
var jsonDataPerMac = {};
I loop over the json object above and for every new mac I find I do :
jsonDataPerMac[i]={"mac": device.shortcode, "keys":[]};
but how do I get to fill the keys?
Any hints would be appreciated.enter code here
var macs = [];
var jsonDataPerMac = {};
var i = 0;
$.ajax({
url: "/bmmeasurements",
type: "GET",
data: {"unitid" : unitid},
async: false,
success: function (data) {
console.log(data);
initializeTable();
$.each(data, function (index,device) {
//add all distinct macs in an array, to use them as a column header
if($.inArray(device.shortcode, macs) == -1) {
macs.push(device.shortcode);
jsonDataPerMac[i]={"mac": device.shortcode, "keys":[]};
i++;
//create a table cell for each possible key. id = 'mac-key'
createTableGrid(device.shortcode);
}
//add the measurement data to the correct cell in the grid
$('#' + device.shortcode + '-' + device.keyid).html(device.latest_measurement);
});
}});
Here is my proposition. I would rather avoid using jQuery to perform such a simple operations. In this particular example, we use forEach and for..in loop.
//new output array
var newArray = [];
//we traverse the array received from AJAX call
array.forEach(function(el) {
var added = false; // it's false by default
// we check if the mac is already in newArray, if yes - just add the key
for(var i in newArray) {
if(newArray[i].mac == el.shortcode) {
newArray[i].keys.push(el.keyid+":"+el.latest_measurement);
added = true; // tells us whether the key has been added or not
}
}
// if key hasn't been added - create a new entry
if(!added) {
newArray.push({"mac": el.shortcode, "keys":[el.keyid+":"+el.latest_measurement]});
}
});
console.log(newArray);
You can transform above code to a function and then, reuse it in your ajax onSuccess method. Remember to pass the array as an argument and to return newArray.
JSFiddle:
http://jsfiddle.net/2d5Vq/2/
You need to combine the entries first...
var reducedData = {};
$.each(macs, function(index,macitem){
if (reducedData.hasOwnProperty(macitem.shortcode)) {
reducedData[macitem.shortcode].push(macitem.key);
} else {
reducedData[macitem.shortcode] = [ macitem.key ];
}
});
And then map to your desired format inside an array...
var jsonDataPerMac = [],
i = 0;
$.map(reducedData, function(keys,mac){
jsonDataPerMac[i++] = {"mac": mac, "keys": keys};
// your other code goes here
});
Also your usage of jsonDataPerMac suggests that you want it to be an array.

Handling no results in jquery autocomplete

Hey I'm trying to return a message when there are no results for the users current query! i know i need to tap into the keyup event, but it looks like the plugin is using it
This question is really out of date, anyways I'm working with the new jQuery UI 1.8.16, autocomplete is now pretty different:http://jqueryui.com/demos/autocomplete/#default
Anyways if you're trying to the do the same thing as the question asks, there is no more parse function, as far as I know there is no function that is called with the search results.
The way I managed to pull this off is by overriding the autocomplete's filter function - Note: this will affect all your autocompletes
$.ui.autocomplete.filter = function(array, term) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
var aryMatches = $.grep( array, function(value) {
return matcher.test(value.label || value.value || value);
});
if (aryMatches.length == 0){
aryMatches.push({
label: '<span class="info" style="font-style: italic;">no match found</span>',
value: null
});
}
return aryMatches;
};
The function is slightly modified from the source, the grep call is the same, but if there are no results I add an object with a value of null, then I override the select calls to check for a null value.
This gives you an effect where if you keep typing and no matches are found you get the 'no matches found' item in the dropdown, which is pretty cool.
To override the select calls see jQuery UI Autocomplete disable Select & Close events
$(this).data('autocomplete').menu.options.selected = function(oEvent, ui){
if ($(ui.item).data('item.autocomplete').value != null){
//your code here - remember to call close on your autocomplete after
}
};
Since I use this on all my autocompletes on a page, make sure you check if value is null first! Before you try to reference keys that aren't there.
You could try supplying a parse option (function to handle data parsing) and do what you need when no results are returned to parse.
This example assumes you're getting back an array of JSON objects that contain FullName and Address attributes.
$('#search').autocomplete( {
dataType: "json",
parse: function(data) {
var array = new Array();
if (!data || data.length == 0) {
// handle no data case specially
}
else {
for (var i = 0; i < data.length; ++i) {
var datum = data[i];
array[array.length] = {
data: datum,
value: data.FullName + ' ' + data.Address,
result: data.DisplayName
};
}
}
return array;
}
});
I'm using the following code for the same purpose (the message is shown in the autocomplete list):
success: function(data, status, xhr){
if(!data.length){
var result = [
{
label: 'There are no matches for your query: ' + response.term,
value: response.term
}
];
response(result);
}
else{
// normal response
}
}
You can also utilize the "response" event to examine this. Simple but powerful. http://api.jqueryui.com/autocomplete/#event-response
response: function (event, ui) {
if (ui.content.length == 0) {
//Display an alert or something similar since there are no results
}
},

Categories

Resources