Not able to save extjs combo using grails controller - combobox

I am a newbie to grails/extjs I am developing a web based config tool for my team .My issue is with comboboxes of extjs I have three remote comboxes(many to one hibernate mappng).I am using hiddenName to submit its value field(which is id primay key of database) instead of its display field which is name which i get by rendering it as json.some how I see that if I select diff index other than which is loaded from db and try updating it.it definitely sends it as params but in save method of grails its not updated.
I want to understand Why?
I have pasted snippetof both combobox and grails method?
{
xtype : 'combo',
id:'cpsServerid',
fieldLabel : 'CpsServer',
name : 'cpsServer',
//hiddenId:'cpsID',
hiddenName:'cpsID',
store: cpsServerStore,
displayField:'NAME',
valueField:'ID',
editable:true,
typeAhead:true,
mode:'remote',
triggerAction:'all',
width:300,
autoScroll:true,
selected:name,
selectOnFocus:true},
GRAILS SAVE
def saveApplicationSubscription = {
println "saveApplicationSubscription, params = $params"
ApplicationSubscription subscription
if (params.id) {
subscription = ApplicationSubscription.get(params.id as int)
subscription.cpsServer = CpsServer.get(params.cpsID as int)
subscription.topic = params.topic
subscription.description = params.description
subscription.subscriberApplication = SubscriberApplication.get(params.subAppID as int)
subscription.outputQueue = OutputQueue.get(params.outputID as int)
bindData(subscription , params)
}
else {
params.id = 0
subscription = new ApplicationSubscription(params)
subscription.id = params.id as int
subscription.cpsServer = CpsServer.get(params.cpsID as int )
subscription.topic = params.topic
subscription.description = params.description
subscription.subscriberApplication = SubscriberApplication.get(params.subAppID as int)
subscription.outputQueue = OutputQueue.get(params.outputID as int)
// subscription.messageFormat = params.messageFormat
}
if (subscription.save()) {
log.info("Saved ApplicationSubscription $subscription")
render([success: true] as JSON)
}
else {
log.info("Failed to save ApplicationSubscription $subscription, errors = ${subscription.errors}")
render([success: false, errors: subscription.errors] as JSON)
}
}
I would really apperciate any help

Have you verified in the Firebug console tab that your POST looks like what you expect? That would confirm whether or not your issue is on the client or server.

Related

ExtJS model raw data is not synced with actual record upon load

I have a model
Ext.define('MyCompany.model.Customer', {
extend: 'Ext.data.Model',
fields: [
'id', 'name', 'taxID', 'tradeID', 'vatID', 'email'
]
}
and a store
Ext.define('MyCompany.store.Customers', {
extend: 'MyCompany.lib.base.Store',
model: 'MyCompany.model.Customer',
api: {
read: $["crmModule.CustomerController"].list,
create: $["crmModule.CustomerController"].save
}
});
The problem is that upon calling store.load() (e.g. from the console), the field vatID is not synced. I can see the field in store.data.items[0].raw, but in store.data.items[0].data the field is empty. How can I debug this issue? Where does ExtJS does the conversion from raw data to the actual records?
Look for the method named extractData defined for Ext.data.reader.Reader. There are following lines:
// If the server did not include an id in the response data, the Model constructor will mark the record as phantom.
// We need to set phantom to false here because records created from a server response using a reader by definition are not phantom records.
record.phantom = false;
// Use generated function to extract all fields at once
me.convertRecordData(convertedValues, node, record);
records.push(record);
When you step into the method convertRecordData, you will be presented with the generated temporary code for actual conversion like the following:
return function(dest, source, record) {
value = source["id"];
if (value !== undefined) {
dest["id"] = value;
}
value = source["name"];
if (value === undefined) {
if (me.applyDefaults) {
...

Extjs update for all grid row not working

I am using Extjs 3.2grid.I have 5 Records.I am also stoping user to select multiple rows at a time.In grid i have button say approve.What i want is once user selects one record and clicks on approve the selected row coloumn "showRecord" will become 1 and remaing rows will become with showrecord:0
Here is my code
var proxy_surv = new Ext.data.HttpProxy({
type: 'ajax',
api : {
read : 'test/view.action?test='+testid_para+'&flag='+0,
create : 'test/create.action',
update : 'test/update.action',
destroy : 'test/delete.action'
}
});
var store_surv = new Ext.data.Store({
id : 'store_surv',
proxy : proxy_surv,
reader : reader,
autoSave : false
// <-- false would delay executing create, update, destroy
// requests until specifically told to do so with some [save]
// buton.
});
store_surv.on({
beforeload: {
fn: function (store, options) {
// Altering the proxy API should be done using the public
// method setApi.
store_surv.proxy.setApi('read', 'test/view.action?test='+testid_para+'&flag='+0);
}
}
});
And here is my logic
tbar: [{
iconCls: 'icon-user-add',
text: 'Approve',
handler: function(){
// Server hasn't returned yet for these two lines.
var survgrid=Ext.getCmp('grid_surv');
getstore =survgrid.getStore();
count =getstore.getCount();
var selected = survgrid.getSelectionModel().getSelected();
getstore.each(function(record){
if(parseInt(record.get('id'))==parseInt(selected.get('id')))
{
record.set('showRecord','1');
}
else
{
record.set('showRecord','0');
}
record.commit();
});
store_surv.save();
}
}
My problem is its not saving in database
don't use record.commit() it will say the record that all changes have been changed. it gets automatically called by store.sync(). remove record.commit() and it should work. you could also use 'record.save()' which will sync a single record.

Cant push in Panel after changing table item data

I have an app that allows the user to enter a set of options and then returns the result in a table. When you click the table item it push's in a panel with more detail. The problem i'm having is that it works perfect the first time but when i go to change the set of options the table items become not select-able. I am not getting any errors in the console so don't kn whats going wrong with it. The only thing i can think is it might have something to do with the below code, do i have to clear the details.setData to allow the second search results data to be pushed through?
Ext.define('FirstApp.controller.Details', {
extend: 'Ext.app.Controller',
config: {
refs: {
placesNavView:'placesContainer',
},
control: {
'placesContainer places list':{
itemtap:function(list,index,target,record){
var ref = record.get('reference');
var name = record.get('name');
var address = record.get('vicinity');
console.log(address);
console.log(name);
console.log(ref);
Ext.Viewport.setMasked({xtype:'loadmask', message:'Please Wait...'});
var proxy = {
type:'ajax',
url:'https://maps.googleapis.com/maps/api/place/details/json? reference='+ref+'&sensor=true&key=123...',
reader:{
type:'json',
rootProperty:'result'
}
}
Ext.StoreMgr.get('Details').setProxy(proxy);
Ext.StoreMgr.get('Details').load();
console.log(proxy);
var details = Ext.create('FirstApp.view.Details');
details.setData(record.data);
this.getPlacesNavView().push(details);
Ext.Viewport.setMasked(false);
}
}
}
}
});

Ext js Updating the total count of a paging toolbar on the fly

This should be fairly simple but I haven't found a way to do it yet.
I am using a ExtJs v.3.3.
I have a grid panel that allows record deletion with context menu.
The grid has a paging toolbar that is attached to the panel store.
The deletion process sends an ajax request to the server, on success I remove the record from the store (using the remove method).
The thing is that the paging toolbar does not reflect the change in the store , that is the total amount of records is unchanged until the store is reloaded.
Is there any way to set the total amount of records in the paging toolbar?
Thanks
This works like a charm for ExtJs ver 4.1.3.
gridStore.add(record); //Add the record to the store
gridStore.totalCount = gridStore.count(); //update the totalCount property of Store
pagingToolbar.onLoad(); //Refresh the display message on paging tool bar
Are you not able to return the totalProperty value in the response after the data has been deleted in the DB?
EDIT:
You'll need to get your response constructed properly first. This is how it should look according to the API Docs for the Paging Toolbar.
If using store's autoLoad configuration:
var myStore = new Ext.data.Store({
reader: new Ext.data.JsonReader({
totalProperty: 'results',
...
}),
...
});
var myStore = new Ext.data.Store({
autoLoad: {params:{start: 0, limit: 25}},
...
});
The packet sent back from the server would have this form:
{
"success": true,
"results": 2000,
"rows": [ // *Note: this must be an Array
{ "id": 1, "name": "Bill", "occupation": "Gardener" },
{ "id": 2, "name": "Ben", "occupation": "Horticulturalist" },
...
{ "id": 25, "name": "Sue", "occupation": "Botanist" }
]
}
This worked fine for me:
me.gridStore.add(data);
// Manually update the paging toolbar.
me.gridStore.totalCount = 500;
me.pagingToolbar.onLoad();
I had a similar problem when getting results from a third party api which had a separate url for the item count. I created a new class inheriting from the pagingtoolbar with an additional updatePager() function:
updatePager : function(){
var me = this,
pageData,
currPage,
pageCount,
afterText,
count,
isEmpty;
count = me.store.getCount();
isEmpty = count === 0;
if (!isEmpty) {
pageData = me.getPageData();
currPage = pageData.currentPage;
pageCount = pageData.pageCount;
afterText = Ext.String.format(me.afterPageText, isNaN(pageCount) ? 1 : pageCount);
} else {
currPage = 0;
pageCount = 0;
afterText = Ext.String.format(me.afterPageText, 0);
}
Ext.suspendLayouts();
me.child('#afterTextItem').setText(afterText);
me.child('#inputItem').setDisabled(isEmpty).setValue(currPage);
me.child('#first').setDisabled(currPage === 1 || isEmpty);
me.child('#prev').setDisabled(currPage === 1 || isEmpty);
me.child('#next').setDisabled(currPage === pageCount || isEmpty);
me.child('#last').setDisabled(currPage === pageCount || isEmpty);
me.child('#refresh').enable();
me.updateInfo();
Ext.resumeLayouts(true);
if (me.rendered) {
me.fireEvent('change', me, pageData);
}
}
});
I added an itemId to it when adding to the dock
dockedItems: [{
xtype: 'dynamicpagingtoolbar',
itemId: 'pager_id',
dock: 'bottom',
store: 'CompoundPharmacologyPaginatedStore',
displayInfo: true
}],
I added a setTotalCount() function to the associated store:
setTotalCount: function(count) {
this.totalCount = count;
}
Then when you want to update it call store.setTotalCount(total) and then pager.updatePager(). Remember that you will have get the pager first using something like
pager = grid_view.down('#pager_id');
"The deletion process sends an ajax request to the server, on success I remove the record from the store (using the remove method)..." - this suggest that you got method that handle "delete" action - and if you using Ext.PagingToolbar - just add one more line like this:
(this).YourPagingToolbar.doRefresh()
I put (this) in () because you did not provide any code example so I not sure how you defined it
store.totalLength = store.totalLength - 1;
this would change the number of total rows in the store, but I am not sure if this change would be reflected by the paging toolbar.
I had a similar situation when trying to use multiple paging toolbars (top/bottom of grid). The only place in the paging toolbar that updates the display gets called on store 'load'. So you can fire the event manually (but beware of unintended consequences!). In my case this worked well when run from the beforechange listener of one of my toolbars:
myStore.fireEvent('load', myStore, myStore.data.items, myStore.lastOptions);
Or ... you could override or extend the PagingToolbar to add a public method which would call or override the onLoad function
If you have multiple pages in paging toolbar, and perform insert/remove operation locally from store then use below snippet.
updatePagingToolbar: function (pagingToolbar) {
var store = pagingToolbar.getStore()
, affectedChanges = store.getCount() - store.config.pageSize;
if (pagingToolbar.store.totalCount > store.config.pageSize)
pagingToolbar.store.totalCount += affectedChanges;
else
pagingToolbar.store.totalCount = store.getCount();
pagingToolbar.onLoad();
}

Ext.JsonStore accesing custom property returned by the server in json

I have a EXtJS web application that returns data in json format. The results are presented paged in ExtJS Grid and are handled by pagingToolbar. I'm using slidingPager plugin to select the pages. What i need when the user selects the page with the slider is to show additionaly to the page number the title of the first result of that page.
So in the jason data the server returns additionaly to count and records data etc. i'm adding a property called headers that is actualy an array of the titles of the first result of each page.
What i dont know is how i can access and handle this new property so i can grab for e.g the 10th page the 10th item of the header property in the json data.
Thanks in advance
Andreas
There is a property of the JsonReader called jsonData, which is the raw JSON returned in the response:
http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.JsonReader
You can access it like yourGridObject.getStore().reader.jsonData
Thanks! it worked. I got the source of Ext.ux.SlidingPager and changed to this
Ext.ux.SlidingPagerWithHeaders = Ext.extend(Object, {
init : function(pbar){
var idx = pbar.items.indexOf(pbar.inputItem);
Ext.each(pbar.items.getRange(idx - 2, idx + 2), function(c){
c.hide();
});
var slider = new Ext.Slider({
width: 114,
minValue: 1,
maxValue: 1,
plugins: new Ext.slider.Tip({
getText : function(thumb) {
var header = pbar.store.reader.jsonData.headers[thumb.value-1];
return String.format('Page <b>{0}</b> of <b>{1}</b><br><br>', thumb.value, thumb.slider.maxValue)+header;
}
}),
listeners: {
changecomplete: function(s, v){
pbar.changePage(v);
}
}
});
pbar.insert(idx + 1, slider);
//pb.store.getHeaders = pb.store.createAccessor("headers");
pbar.on({
change: function(pb, data){
slider.setMaxValue(data.pages);
slider.setValue(data.activePage);
}
});
}
});
I'm returning the Json data like this
{ "count": 100,
"records" : [{record 1 ...},{ record 2 ...}, ...],
"headers" : ["Header1", "Header2"]
}
Say that pagesize is 50 so i send two headers.

Resources