persisting filters in grid panel - extjs

I would like to persist filters applied on gridpanel on page refresh. Can you please guide me in doing this.
Thanks.
Here is the code which send the filter data to webservice
Ext.extend(Ext.ux.AspWebServiceProxy, Ext.data.DataProxy,
{
load: function(params, reader, callback, scope, arg) {
var userContext = {
callback: callback,
reader: reader,
arg: arg,
scope: scope
};
var proxyWrapper = this;
//debugger;
//Handles the response we get back from the web service call
var webServiceCallback = function(response, context, methodName) {
proxyWrapper.loadResponse(response, userContext, methodName);
}
var serviceParams = [];
var filters = {};
//Convert the params into an array of values so that they can be used in the call (note assumes that the properties on the object are in the correct order)
for (var property in params) {
if (property.indexOf("filter[") == 0) {
filters[property] = params[property];
}
else {
serviceParams.push(params[property]);
}
//console.log("Property: ", property, "Value: ", params[property]);
}
serviceParams.push(filters);
//Add the webservice callback handlers
serviceParams.push(webServiceCallback);
serviceParams.push(this.handleErrorResponse);
//Make the actual ASP.Net web service call
this.webServiceProxyMethod.apply(this.webServiceProxy, serviceParams);
},
handleErrorResponse: function(response, userContext, methodName) {
window.location.reload();
// Ext.MessageBox.show({
// title: 'Error',
// msg: response.get_message(),
// buttons: Ext.MessageBox.OK,
// icon: Ext.MessageBox.ERROR
// });
//alert("Error while calling method: " + methodName + "n" + response.get_message());
},
loadResponse: function(response, userContext, methodName) {
var result = userContext.reader.readRecords(response);
userContext.callback.call(userContext.scope, result, userContext.arg, true);
}
});

Turn on the Ext JS state manager globally (where you set Ext.BLANK_IMAGE_URL).
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
User changes to some components will now be stored in a cookie, which will persist across requests. If you need to store additional custom data, you can do that using Ext.state.Manager.set and Ext.state.Manager.get. State is configurable on individual components.
Saki has a good example.

To persist filters on grid you can use cookies, here you can find some help:
proxy: new Ext.data.HttpProxy({
url: (local ? url.local : url.remote),
method: 'GET',
listeners:{
beforeload : function(dataproxy,param) {
if(param.searchConditions != undefined && param.searchConditions != '[]') {
Ext.util.Cookies.set('SearchConditions',param.searchConditions);
}
}
}
})
In above sample you can find that we are setting "searchConditions" JSONArray in cookies.Now let us see how to get back that "searchCondition" whenever you load you Grid.
store.load({
params:{
start:0,
limit: 50,
searchConditions:JSON.parse(Ext.util.Cookies.get('SearchConditions'));
}
});
Here simply you just need to pass your "searchCondition" parameter value as value stored in Cookie. Hope above example is useful.Please comment for any help.

Related

Backbone collection doesn't fetch by ajax if has set localStorage object

I want to use backbone.localStorage.js plugin in my app and here is a code sample:
Module.Vehicles = Backbone.Collection.extend({
initialize : function(options) {
this.customerId = options.customerId;
},
url : function() {
var url = App.Config.RESTPath + '/vehicle';
if(this.customerId) {
url = url + '?customerId='+this.customerId;
}
return url;
},
localStorage: new Backbone.LocalStorage("vehicles"),
model : Module.Vehicle,
parse : function(response) {
this.allVehiclesNumber = response.allVehiclesNumber;
this.customers = response.customers;
return response.vehicles;
}
});
Module.getVehicles = function(customerId) {
var result = new Module.Vehicles({
'customerId' : customerId
});
result.fetch();
return result;
};
Everything works great (collection has proper records) if I add a comment in the line:
localStorage: new Backbone.LocalStorage("vehicles"),
But if it is not commentend there are no recordsfetch.
What I missed?
BR, Tomasz.
If you check Backbone.localStorage source code, you will see that it overrides the way Backbone syncs its data : if you have a localStorage declared in you model/collection, the normal sync is discarded and replaced by a local storage.
You can alter this behavior by providing your own custom Backbone.sync. For example, this will use both versions:
Backbone.sync = function(method, model, options) {
if(model.localStorage || (model.collection && model.collection.localStorage)) {
Backbone.localSync.call(this, method, model, options);
}
return Backbone.ajaxSync.call(this, method, model, options);
};
And a Fiddle to play with http://jsfiddle.net/nikoshr/F7Hkw/

how to check the return status of the store 's sync In Extjs

I use the the
store.sync({
success:function(){},
failure:function(){}
});
to sync with the server; when the server return {success:false} or {success:true};
how I check the json from the server in the store.sync.
I have knew that:success is called by The function to be called upon successful completion of the sync ,even if return {sucess :false} ,not only the {success:true};
You need to change the reader's successProperty to false in the store's proxy.
store.proxy.reader.successProperty = false;
or
var store = Ext.create('Ext.data.Store', {
(...)
proxy : {
type : 'ajax',
(...)
reader : {
successProperty : false,
(...)
}
}
});
and then you can use this:
store.sync({
callback : function (batch, options) {
var operations = batch.operations;
for (var x in operations) {
var operation = operations[x];
if (operation.request) {
console.log('operation.request ---> ', operation.request);
}
if (operation.response) {
console.log('operation.response ---> ', operation.response);
var object = Ext.decode(operation.response.responseText, false);
console.log('success --->', object.success);
}
}
}
});

Backbone.js - model.save() not firing a PUT request

I have a basic application using Backbone.js that is not making PUT calls (updating model). From the front-end, I calling a models save function doesn't make a PUT call; however, if I replace it with destroy, it does make a DELETE call to the back-end. Anyone have any idea what might be the issue? The function that is not firing a PUT request is the saveTask function.
App.Views.Task = Backbone.View.extend({
template: _.template("<label>ID:</label><input type='text' id='taskId' name='id' value='<%= _id %>' disabled /><br><label>Title:</label><input type='text' id='title' name='title' value='<%= title %>' required/><br><label>Content:</label><input type='text' id='content' name='content' value='<%= content %>'/><br><button class='save'>Save</button>"),
events: {
"change input":"change",
"click .save":"saveTask"
},
render: function(eventName){
$(this.el).html(this.template(this.model.toJSON()));
//console.log(this.generateTemplate());
return this;
},
change: function(event){
var target = event.target;
console.log('changing ' + target.id + ' from: ' + target.defaultValue + ' to: ' + target.value);
change[target.name] = target.value;
this.model.set(change);*/
},
saveTask: function(){
this.model.set({
title:$("#title").val(),
content:$("#content").val()
});
if(this.model.isNew()){
App.taskList.create(this.model);
} else {
this.model.save({});
}
}
});
If your model is new, then at the time you save it it will fire a post method.
If your model however is not new and you are updating it, it will fire a PUT.
if this is not working for you it may be because your model does not have an id property, in case you are using an id with a different name, for example taskID, then in your model you have to set the idAttribute to taskID so backbone uses this property as the Id and everything will be normal.
like this:
var Task= Backbone.Model.extend({
idAttribute: "taskId"
});
here is the link to the documentation on Idattibute
http://backbonejs.org/#Model-idAttribute
also another problem could be the {} in your save call
try just
this.model.save();
instead of
this.model.save({});
I believe model is always expecting options parameter and also probably the callbacks
this.model.save(null, {
success: function (model, response) {
//
},
error: function () {
//
}
});
If you look at Backbone src, you will notice that too...
======
// Set a hash of model attributes, and sync the model to the server.
// If the server returns an attributes hash that differs, the model's
// state will be `set` again.
save: function (key, val, options) {
var attrs, method, xhr, attributes = this.attributes;
// Handle both `"key", value` and `{key: value}` -style arguments.
if (key == null || typeof key === 'object') {
attrs = key;
options = val;
} else {
(attrs = {})[key] = val;
}
options = _.extend({
validate: true
}, options);
// If we're not waiting and attributes exist, save acts as
// `set(attr).save(null, opts)` with validation. Otherwise, check if
// the model will be valid when the attributes, if any, are set.
if (attrs && !options.wait) {
if (!this.set(attrs, options)) return false;
} else {
if (!this._validate(attrs, options)) return false;
}
// Set temporary attributes if `{wait: true}`.
if (attrs && options.wait) {
this.attributes = _.extend({}, attributes, attrs);
}
// After a successful server-side save, the client is (optionally)
// updated with the server-side state.
if (options.parse === void 0) options.parse = true;
var model = this;
var success = options.success;
options.success = function (resp) {
// Ensure attributes are restored during synchronous saves.
model.attributes = attributes;
var serverAttrs = model.parse(resp, options);
if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
return false;
}
if (success) success(model, resp, options);
model.trigger('sync', model, resp, options);
};
wrapError(this, options);
method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
if (method === 'patch') options.attrs = attrs;
xhr = this.sync(method, this, options);
// Restore attributes.
if (attrs && options.wait) this.attributes = attributes;
return xhr;
},
In my case it fails due to validations.As i save the model it validates all the attributes of the model and the collection which i am using for listing interface doesn't required all the attributes of the model.
I was facing the same issues and search in Google and found your question and read the solution and comments.Than i realize that in updated backbone specifications it is mentioned that when model.save() executes before model requests,it first call validate and if validate succeeds than it will go ahead other wise fails, and that is the reason why it doesn't showing any network request in chrome debugger network tab.
I have write the solution for the case which i am facing,other might be facing different issues.
Backbone's sync function is what I wound up using. You have to pass in 'update' as the first parameter (the 'method' parameter).

how can I update a model with custom idAttribute

in my simple backbone application, I am trying to update a model and every time it send a put request instead of post.
Well, this is my model named categoryModel
define(['Backbone'], function (Backbone) {
var CategoryModel = Backbone.Model.extend({
defaults: {
ID: '',
Name: 'Empty',
TagID: '0',
GID: '0'
},
idAttribute: "ID",
initialize: function () {
if (!this.get('Name')) {
this.set({ 'Name': this.defaults.Name });
}
}
});
return CategoryModel;
});
this is the collection
define(['Backbone','../../models/categories/categoryModel'], function (Backbone, categoryModel) {
var CategoryCollection = Backbone.Collection.extend({
url: '/parentcategory/Actions',
model: categoryModel
});
return new CategoryCollection;
});
here are my methods in the view
on a keychange event
createNewItem: function (e) {
var $this = $(e.currentTarget);
$('#selectedCategoryName').html($this.val());
//it creates a new model
globals.NewCategory = new CategoryModel({ Name: $this.val() });
}
on handleDrop event
handleDropEvent: function (event, ui) {
var draggable = ui.draggable;
//check if name has set
if (!globals.NewCategory) {
alert("Please write a category name");
$('#createNewCategory').focus();
return;
}
//get itemID
var itemID = draggable.attr("id").split('_')[1];
var itemDesc = draggable.attr("id").split('_')[0];
//check items category
if (itemDesc == "Tag") {
//check if tagID already exists
if (globals.NewCategory.TagID) {
alert("you have already specify a tag from this category");
return;
}
globals.NewCategory.set("TagID", itemID);
} else if (itemDesc == "gTag") {
if (globals.NewCategory.GID) {
alert("you have already specify a tag from this category");
return;
}
globals.NewCategory.set("GID", itemID);
}
categoriesCollection.create(globals.NewCategory, {
silent: true,
wait: true,
success: function (model, response) {
model.set("ID", response);
alert(model.id);
}
});
}
The categoriesCollection.create is called twice. Firstly for setting the TagID (on a success request it gets an ID ) and secondly for setting the GID.
Since the ID has been set, shouldn't had sent a POST request instead of PUT on the second call?
What am I doing wrong?
Thanks
The standard behaviour is to send a POST if the model is new ( doesn't have an ID attributed ) and send a PUT if the model id is set.
In your case it's working as designed, if you want it to use POST to send UPDATES you have to override Backbone.sync to work as you need, but I think it's easier for you to make your backend RESTful and create a PUT listener controller method for updates.
Another thing, if I got it right you are using create() to update models in your collection, I would advise you not to do that and instead use the save() directly in the model you want to update, the code will be a lot more readable.
Cheers.

Ext.data.HttpProxy callback on failure

I've the following ExtJS. The listener "write" is called when the response is a success (the response is JSON like: {"success":true,"message":"......"}). But how do I attach a callback when the response is not a success? ({"success":false,"message":"......"})
tableStructure.proxy = new Ext.data.HttpProxy({
api: {
read: '/controller/tables/' + screenName + '/getstructure/' + table,
create: '/controller/tables/' + screenName + '/createcolumn/' + table,
update: '/controller/tables/' + screenName + '/updatecolumn/' + table,
destroy: '/controller/tables/' + screenName + '/destroycolumn/' + table
},
listeners: {
write: tableStructure.onWrite
}
});
You want to catch the HttpProxy's exception event.
listeners: {
write: tableStructure.onWrite
exception: function(proxy, type, action, options, response, arg) {
if(type === 'remote') { // success is false
// do your error handling here
console.log( response ); // the response object sent from the server
}
}
}
You can find the full documentation in the Ext docs for Ext.data.HttpProxy down in the events section.
You should be able to make use of the write event itself. The write event's signature is:
write(dataproxy,action,data,response,record,options).
You can access the success variable from the action object and check if the value is true or false. You should be able to access the success variable as:
action.result.success
You can do:
if(action.result.success != true ) {
// If success is not true
} else {
// If success is true
}
You can also set an exception handler on the Ext.data.Store wrapping the HttpProxy, provided that you send a response code other than 200.
var store = new CQ.Ext.data.Store({
proxy : new CQ.Ext.data.HttpProxy({
method : "GET",
url : '/some_url'
}),
reader : new CQ.Ext.data.JsonReader(),
baseParams : {
param : 'some value'
}
});
store.on("beforeload", function() {
CQ.Ext.getBody().mask("Please wait...", false);
});
store.on("exception", function() {
CQ.Ext.getBody().unmask();
CQ.Ext.Msg.show({
title: 'Error',
msg: '<span style="color:red">Bad request.</span><br/>',
icon: CQ.Ext.Msg.ERROR,
buttons: CQ.Ext.Msg.OK
});
});

Resources