I'm trying to reload the grid after saving a row to be able to get the Id of the row for logging purposes but somehow 'aftersavefunc' and 'successfunc' fires 'reloadGrid('#telephoneGrid')' before saving. It seems that 'aftersavefunc' and 'successfunc' is identical. Now I can't add nor edit any row.
var lastSel;
function onTelephoneSelect(id, status, e) {
if ($(e.target).hasClass('edit')) {
var editParameters = getEditParameters();
if (id && id !== lastSel) {
jQuery('#telephoneGrid').saveRow(lastSel);
}
jQuery("#telephoneGrid").jqGrid('editRow', id, editParameters);
lastSel = id;
}
}
function getEditParameters() {
return {
"keys": true,
"oneditfunc": null,
"successfunc": null,
"url": '#Url.Action("SaveTelephoneEntry","TelephoneEntry")?customerId=' + $('#SelectCompany').val(),
"extraparam": {},
"aftersavefunc": reloadGrid('#telephoneGrid'),
"errorfunc": null,
"afterrestorefunc": null,
"restoreAfterError": true,
"mtype": "POST"
}
}
I'm pretty desperate now and couldn't figure out any working solution.
Could someone please assist me here or has already faced the same issue and figured out a working solution?
Many thanks in advance.
'aftersavefunc' and 'successfunc' are callbacks but it appears you're trying to set the function directly, so they're getting called before you intend.
Using the proper callback signature it should look something like this:
"aftersavefunc": function (rowid, response, options) {
reloadGrid('#telephoneGrid');
},
Not sure why you need getter for EditParameters (instead of just defining the object and using it directly), but have you checked the values for editParameters whether they get set properly, just before firing:
jQuery("#telephoneGrid").jqGrid('editRow', id, editParameters);
Your getter is inside .hasClass('edit') so you might try to use your getter before going to edit-sub, right after function onTelephoneSelect(id, status, e) { To see if it makes any difference. (Just because we do not know where/when you call onTelephoneSelect).
Related
I have a web page in which when a user clicks on a specific element, a javascript function is triggered which uses $.post() (i.e. jquery) to send the user's data to a PHP script which modifies a database.
On success, the PHP page simply prints
<p id='success'>Yay!</p>
On fail, it prints:
<p id='failure'>$some_error_message</p>
The callback part of the $.post then checks which of these exists. On success, it simply shows an existing (currently hidden) element. On failure, I want to grab the $some_error_message bit, and put it on my page.
I've found a way to do this (as below) but it's clunky - I am sure I shouldn't be having to use an ".each" function when I only want to access a single element. Is there a better way of doing this?
$.post('myURL.php', myData, function(retData)
{
if ( $(retData).filter('#success') )
{
$('#mySuccessDiv').show(200);
}
else if ($(retData).filter('#failure') )
{
$(retData).filter('#failure').each(function()
{
$('#myErrorDiv').html($(this).html());
});
}
else
$('#myErrorDiv').html("Unspecified Error");
}, "html");
As I say, the use of .each seems wasteful, but I can't simply use
$('#myErrorDiv').html($(retData).filter('#failure').html());
because .filter returns a series of objects. But equally, I can't work out how to access only element 0 (since I'm filtering on ID, there can only be one match). I tried:
$('#myErrorDiv').html($(retData).filter('#failure')[0].html());
but it didn't like that.
Am I forced to use .each, or am I being really obtuse?
.filter() will return a jQuery object(with or without any element), so it will always be truthy, to see whether it returned any element you need to check the length of the returned jQuery object
$.post('myURL.php', myData, function (retData) {
var $obj = $(retData);
if ($obj.filter('#success').length) {
$('#mySuccessDiv').show(200);
} else if ($obj.filter('#failure').length) {
$('#myErrorDiv').html($obj.html());
} else {
$('#myErrorDiv').html("Unspecified Error");
}
}, "html");
Another solution is to use .is()
$.post('myURL.php', myData, function (retData) {
var $obj = $(retData);
if ($obj.is('#success')) {
$('#mySuccessDiv').show(200);
} else if ($obj.is('#failure')) {
$('#myErrorDiv').html($obj.html());
} else {
$('#myErrorDiv').html("Unspecified Error");
}
}, "html");
For some odd reason, Backbone is trying to put my model object instead of posting it to the server.
The error is an HTTP 500 error because Backbone is trying to put a model with no id (because I have made it undefined):
PUT /api/teams/undefined 500 285ms - 135b
Here's my code:
this.model.id = undefined;
this.model._id = undefined;
teamCollection.add(this.model);
this.model.save(null,
{
success: function (model) {
$('.top-right').notify({
message: {text: ' New team added! '},
type: 'info',
fadeOut: {
delay: 3500
}
}).show();
window.userHomeMainTableView.render();
}
,
error: function (model) {
teamCollection.remove(model);
$('.top-right').notify({
message: {text: ' Error adding team :( '},
type: 'danger',
fadeOut: {
delay: 3500
}
}).show();
}
});
even after "forcing" the model.id and model._id to be undefined, Backbone still tries to do an HTTP PUT. How can this be?
The syncing process internally uses Model#isNew to decide if it should PUT or POST. isNew is very simple minded:
isNew model.isNew()
[...] If the model does not yet have an id, it is considered to be new.
and that check is done using:
!this.has(this.idAttribute)
The has method is just a simple wrapper around attr:
has: function(attr) {
return this.get(attr) != null;
}
so these are irrelevant:
this.model.id = undefined;
this.model._id = undefined;
when Backbone is deciding to PUT or POST, those don't really remove the id attribute, they break your model.
I think you'd be better off copying the model (without the id) and saving the copy:
var data = m.toJSON();
delete data.id;
var copy = new Model(data);
Or better, create a whole new model, populate it with data, and then save the new model instance.
I think you'd need to unset the id attribute and manually remove the id property to make what you're trying to do work.
that's strange it looks like it should do a POST from your code. It looks like you can ovverride it though. From the second answer here
fooModel.save(null, {
type: 'POST'
});
use the following code snippet to set the id to undefined.
this.model.set('id',undefined');
although if it's a new model you don't need to do this. it will be undefined by default.
if you have used the idAttribute for defining the model and say it's value is userId then you need to do something like this.
this.model.set('userId',undefined');
I am building what should be a fairly simple project which is heavily based on Ampersand's starter project (when you first run ampersand). My Add page has a <select> element that should to be populated with data from another collection. I have been comparing this view with the Edit page view because I think they are quite similar but I cannot figure it out.
The form subview has a waitFor attribute but I do not know what type of value it is expecting - I know it should be a string - but what does that string represent?
Below you can see that I am trying to fetch the app.brandCollection and set its value to this.model, is this correct? I will need to modify the output and pass through the data to an ampersand-select-view element with the correct formatting; that is my next problem. If anyone has suggestions for that I would also appreciate it.
var PageView = require('./base');
var templates = require('../templates');
var ProjectForm = require('../forms/addProjectForm');
module.exports = PageView.extend({
pageTitle: 'add project',
template: templates.pages.projectAdd,
initialize: function () {
var self = this;
app.brandCollection.fetch({
success : function(collection, resp) {
console.log('SUCCESS: resp', resp);
self.brands = resp;
},
error: function(collection, resp) {
console.log('ERROR: resp', resp, options);
}
});
},
subviews: {
form: {
container: 'form',
waitFor: 'brands',
prepareView: function (el) {
return new ProjectForm({
el: el,
submitCallback: function (data) {
app.projectCollection.create(data, {
wait: true,
success: function () {
app.navigate('/');
app.projectCollection.fetch();
}
});
}
});
}
}
}
});
This is only the add page view but I think that is all that's needed.
The form subview has a waitFor attribute but I do not know what type of value it is expecting - I know it should be a string - but what does that string represent?
This string represents path in a current object with fixed this context. In your example you've waitFor: 'brands' which is nothing more than PageView.brands here, as PageView is this context. If you'd have model.some.attribute, then it'd mean that this string represents PageView.model.some.attribute. It's just convenient way to traverse through objects.
There's to few informations to answer your latter question. In what form you retrieve your data? What do you want to do with it later on?
It'd be much quicker if you could ping us on https://gitter.im/AmpersandJS/AmpersandJS :)
In Backbone, I need to check if a model record already exists. Right now, I am doing it by fetching the model by id, and seeing if its "created_at" attribute is undefined. This feels brittle to me. Does anyone have any better recommendations?
var dealProgram = new WhiteDeals.Models.DealProgram({id: servant_id});
dealProgram.fetch({
success: function() {
var program = dealProgram.toJSON();
var datecheck = program.created_at
if(typeof datecheck === 'undefined'){
dealPrograms.create({
title: "",
servant_id: servant.servant_id,
servant_name: servant.name,
servant_master: servant.master
},
{
success: function () {
self.manageServants(servants);
}
}); // End of dealPrograms.create
} else if (datecheck !== undefined) {
console.log("is defined, success!")
self.manageServants(servants);
}; // End of if statement for non-existant dealPrograms
} // End of success
}); // End of dealProgram.fetch
You'll obviously have to check by using a request (whatever the form of the request, you'll have a low amount of data anyway). Guess you should still wonder if it wouldn't be worth fetching all your models at once in a collection so you can make the check client-side (or only the id if it'd be too big to fetch everything).
i have this function to retrieve json data from yql query
function link(b){
var jsonURI = "http://query.yahooapis.com/v1/public/yql?q="+encodeURIComponent("select href,alt,content from html where url='"+b+"' and xpath='//a[#id=\"download\"] |//img[#class=\"dvLinkOverlayFill\"] |//meta[#name=\"title\"]'")+"&format=json&diagnostics=true&_maxage=86400&callback=callback&jsoncallback=?";
jQuery.ajaxSetup({cache: true});
jQuery.getJSON(jsonURI,callback);
}
What i want is to check if the data is null or not before passing on to the callback, if its null, it runs again the link() function, if not it passes on, i have tried
if (jQuery.query.results == null){link(b);}
but no luck, any advice or guide?
EDIT: Got it working, part of it, by using
if (o.query.results == null) { link(b); }
inside the callback function
callback(o){
if (o.query.results == null) { link(b); }
However i can't pass the "b" from the link function to the callback function, it's the only thing that is left for this to work, something like callback(o,b) that could be passed on in here jQuery.getJSON(jsonURI,callback);
since this one is sending the "o", how to make it send the "b" aswell? something like
jQuery.getJSON(jsonURI,callback(o,b));
EDIT updated question answer:
function link(b){
var jsonURI = "http://query.yahooapis.com/v1/public/yql?q="+encodeURIComponent("select href,alt,content from html where url='"+b+"' and xpath='//a[#id=\"download\"] |//img[#class=\"dvLinkOverlayFill\"] |//meta[#name=\"title\"]'")+"&format=json&diagnostics=true&_maxage=86400&callback=callback&jsoncallback=?";
jQuery.ajaxSetup({cache: true});
jQuery.getJSON(jsonURI,function(data, status, xhr){
callback(data, status, xhr,b);
});
}
So you got ur b object in arguments[3]
Couldn't you just simplify that?
if (!jQuery.query.results) { link(b); }