Saturday, February 26, 2011

Refresh single ExtJs grid row after editing without refreshing grid

Hello,

This is another ExtJs blog. Recently I was working with ExtJs editor grid and I got requirement that after editing data in a row grid should be refreshed and at the same time row should be back to its normal position.

Those who have worked with ExtJs editor grid know that when you edit values in row cells, it will display red mark on top left corner. It states that row data is edited. See the image below.


To remove it, we need to reload grid data and refresh the grid view. Following is the code for it.

myGrid.store.reload();
myGrid.getView().refresh();

Grid will be refreshed and updated data gets loaded from server. Now my requirement was to refresh the only single row, without refreshing the whole grid. When you tab out of edit field or you click outside of the row it will fire afteredit event. Normally in afteredit event there is a Ajax request to send updated data to server and when we get success response we normally reload the grid data store. But in this case its different situation. Following is the code for it.

'afteredit':{
fn : function(e){
Ext.Ajax.request({
url:"savedata.php",
method:'GET',
params:{
param1:value1,
param2:value2
},
success:function(resp,opt){
e.record.set(e.field,gridValue);
e.record.commit();
myGrid.getView().refresh();
},
failure:function(resp,opt){
}
});
}
}

Checkout the code in success function of Ajax request. This does the trick.
e.reocord.set() function set's the value. For example if you have some renderer for columns then this code will set the cell value according to renderer.

e.record.commit() commits the changes and grid row is back to its normal view. It will remove all the red marks from the edited cell.

So using this small trick you have normal row after editing it without refresh the grid data. This trick is useful when you have large number of data in the grid and you want to avoid unnecessary data flow.


Saturday, February 12, 2011

Modified jQuery sortable for horizontal and vertical sorting

Recently I got a requirement to modify jQuery sortable for horizontal and vertical sorting capability. Basically we have to override some functions from jQuery sortable. By default jQuery sortable only provides vertical sorting. But for me requirement was some thing different. See the images below.

Sorting should be something like above. First of all let's see how jQuery sortable does this. If you see the source code there is a function called _rearrange(). This is the function responsible for rearranging the items. This function is called when there is some kind of intersection between items. For example if you want to swap item1 and item2, you have to drag item1 over item2. Code will detect intersection and it will rearrange the items. But in our case there is no intersection as we are dragging item 2 towards right hand side where there are no items.

So how we can do this? First of all we need to give style clear:both and float:left to all the items. When we set this style to any component, it will not allow any floating element on both sides. After setting above styles to all the items we get layout shown in left hand side image. As there is no intersection now we can not use _rearrange() function for changing position. We have to use another function available in jQuery sortable code, that is _mouseStop(). This is the function which is executed when we stop dragging. In this function first of all we need to identify drag direction . Drag direction should be either right top or right bottom. Once the direction is identified we have to set style clear:none for dragged object. Following is the code for it.

var horizontalDistance = Math.abs(this.offset.left - this.currentItem[0].offsetLeft);
var verticalDistance = Math.abs(this.offset.top - this.currentItem[0].offsetTop);
if(horizontalDistance > (this.currentItem[0].clientWidth/2) || verticalDistance > (this.currentItem[0].clientHeight))
{
if(this.offset.left>event.pageX){
this.horizontalDirection = 'left';
}
else{
this.horizontalDirection = 'right';
}
if(this.offset.top>event.pageY){
this.verticalDirection = 'up';
}
else{
this.verticalDirection = 'down';
}
if(this.horizontalDirection == 'right' && this.verticalDirection == 'up'){
this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
this.currentItem[0].style.clear = "none";
this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
}
}

To avoid unnecessary flicker effect, I have removed placeholder.

This is the code which you need to insert in _mouseStop() function at start. I am still working on it and doing some more changes to make it fully functional for all the scenarios so your suggestions are welcome. Please post a comment if you have any suggestion.




Saturday, February 5, 2011

Get JSON data from Asp.Net web service into ExtJs JSON store

In one of my previous project which was based on SOA, we have used Asp.Net web service to get data from Sql Server. The front end was built using ExtJs. As every one no that Asp.Net web service uses soap protocol which is XML based protocol.

For ExtJs front end we have to use JSON store for data as we were getting data from some other source in JSON format. So we need a response from Asp.Net web service in JSON format. Following the code example of how to get JSON data from Asp.Net web service.

First of all you need to enter Script Service Attribute to the web service.

[System.Web.Script.Services.ScriptService]
public class Service : System.Web.Services.WebService
{
//code of service.
}

A web service with ScriptService attribute by default returns data in JSON format. However it might be the case that in web service some methods return data in XML format so for that you need to add ScriptMethod attribute to specific method which should return data in JSON format.Following is an example of it.

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true, XmlSerializeString = false)]
public List GetCustomers()
{
dbDataContext obj= new dbDataContext();
return dc.getCustomers().ToList();
}

So above method when called form ExtJs front end will return data in JSON format. Following is the ExtJs code to call the service.

var storeCustomer = new Ext.data.JsonStore({
proxy: new Ext.data.HttpProxy({
url: 'Service.asmx/GetCustomers',
headers: {
'content-type': 'application/json'
}
}),
root: 'd',
autoLoad : true,
id: 'Customer_Id',
scope : this,
fields: ['Customer_Id', 'CurrentSeller_Id', 'Name']
});

That's it and you have JSON data from Asp.Net web service to your ExtJs front end.