Extjs 5, success and failure function - extjs

I have a problem here, here is the code.
function addProduct () {
var prod_form = Ext.getCmp('productForm');
if(!prod_form.getForm().isValid()) {
Ext.Msg.show({
title:'Warning',
msg: 'Please verify the field(s) marked in <font color="red">red</font>',
icon: Ext.Msg.WARNING,
buttons: Ext.Msg.OK
})
return;
}
prod_form.getForm().submit({
url: 'save',
success: function(prod_form,action) {
console.log('SUCCESS');
Ext.Msg.show({
title: 'Adding the Product Successful',
msg: 'Data has been saved!'
})
},
failure : function(prod_form,action) {
console.log('FAILURE');
Ext.Msg.show({
title: 'Error',
msg: 'Failure in adding the Product',
buttons: Ext.Msg.OK
})
}
})
}
i have a function add product in extjs and it handles the button Add Product whenever it is clicked. then it will load the modal which has the form inside.
it do work but the problem is in the success and failure function.
It returns the failure function, but it does write the data in the database.
Why is this?
thanks!!

Make sure your back end returns success: true in the response payload otherwise all calls to form.submit() will "fail" even though it may have worked.
If you can't change the back end to return the success variable, you could use errorReader property of the form.

So for symfony 2 users, what you need to do is to create a json response,
success: true

Related

How to get value from router request?

I have created an angular app. In this app, I want to add a search. for this, I have a textbox and a button. Textbox name is name="search"
I have a get method in API.
router.get('/allActivities', (req, res) => {
Activity.find({ name: req.body.search }, (err, activities) => {
if(err) {
res.json({success: false, message: err});
} else {
if(!activities) {
res.json({success: false, message: 'No recent activities found'});
} else {
res.json({success: true, activities: activities});
}
}
})
});
This is the get request. In this, I'm trying to get the text box value from angular front end
Activity.find({ name: req.body.search }, (err, activities) =>
This is MongoDB
But I'm not getting any output. The matter here is I'm not getting a value for this "req.body.search" which I used to get text box value. can anybody tell me how to do this?
if I put
Activity.find({ name: 'Roshini' }, (err, activities) =>
like this, I'm getting the output. So pretty sure that I'm not getting textbox value to this get method correctly, :/
Html side
<input ng-model="search">
Angular Controller
$http({
method: 'GET',
url: '/allActivities?search='+$scope.search
}).then(function (response) {
$scope.activities = response.data || response
}, function (response) {
alert(response)
}
);
and on backend access it by req.query.search or req.params.search rather than req.body.search

ExtJS MessageBox does not block like alert(..) does

ExtJS MessageBox does not seem to block like Javascript alert(..) does. I want to show a popup, and then call and AJAX call, upon which it will close the window.
If I call the show method like this then...
//Alert Box :
var alertBox = Ext.create('Ext.window.MessageBox');
var config = {
title : 'Title',
closable: true,
msg: 'Message',
buttons: Ext.Msg.OK,
buttonText: { ok: EML.lang.buttons.ok },
modal: true
};
alertBox.show(config);
//callback
Ext.Ajax.request({
url: someURL,
method: 'POST',
callback: function (options, success, response) {
//do some stuff
self.up('window').destroy();
}
})
..no popup is shown, however the parent window is closes.
If I use a standard Javascript alert then the alert will block. After clicking the OK button, then the callback is executed after which the window closes.
//Alert Box :
alert('asdf')
//callback
Ext.Ajax.request({
url: someURL,
method: 'POST',
callback: function (options, success, response) {
//do some stuff
self.up('window').destroy();
}
})
why does MessageBox not block?
what can I do to get around this problem?
does the MessageBox somehow need to know about the parent window to block?
It does not block because blocks are not supported in custom javascript code. As chrome console tells us,
window.alert
function alert() { [native code] }
and native code can block execution.
In ExtJS, you would write a callback for a message box like this:
//Alert Box :
var alertBox = Ext.create('Ext.window.MessageBox');
var config = {
title : 'Title',
closable: true,
msg: 'Message',
buttons: Ext.Msg.OK,
buttonText: { ok: EML.lang.buttons.ok },
modal: true,
callback:function(btn) {
//callback
Ext.Ajax.request({
url: someURL,
method: 'POST',
callback: function (options, success, response) {
//do some stuff
self.up('window').destroy();
}
})
}
};
alertBox.show(config);
If such callbacks are deeply nested, I tend to flatten the callbacks like this:
var store = me.down('grid').getStore();
var callback3 = function(btn) {
if(btn=="yes") store.sync();
};
var callback2 = function() {
Ext.Msg.prompt('A','Third', callback3);
};
var callback1 = function() {
Ext.Msg.alert('A','Second', callback2);
};
Ext.Msg.alert('A','First', callback1);
In newer versions of ExtJS, you can check out Ext.Promise, but not in ExtJS 4.1.

Optimistic Updates Using Flux (async)

I am trying to add optimistic updates to my Flux model. I am smushing the UI action dispatch and the server action dispatch into one action. My code in the action creator looks like this:
deleteItem: function(itemId) {
// optimistic update
WebshipDispatcher.handleServerAction({
type: ActionTypes.DELETE_ITEM,
deleteStatus: 'success',
itemId: itemId
});
// now let's actually check if that was the correct result
AppAjaxUtil.get('/deleteItem', {itemId: itemId}, function(result) {
WebshipDispatcher.handleServerAction({
type: ActionTypes.DELETE_ITEM,
deleteStatus: result.status, // 'success' or 'failure'
itemId: itemId
});
}, function(error) {
WebshipDispatcher.handleServerAction({
type: ActionTypes.DELETE_ITEM,
error: error
});
});
}
Is this an appropriate way to allow for optimistic updates or am I thinking about this piece incorrectly?
#fisherwebdev is right. The true logic would happen in your store. For example how would you handle the logic when an item does fail to delete? That becomes a beast on it's own. You don't really want to remove the item from your store unless you have confirmation from the server. A library like Ext marks the record as dirty while it waits for a successful response from the server. So the update is still happening optimistically, but the user and the record are notified if the server fails.
So you could have a collection of dirty records in your store that are removed when your server responds with success. This is rough, but something like the following:
deleteItem: function(itemId) {
// optimistic update
WebshipDispatcher.handleServerAction({
type: ActionTypes.MARK_ITEM_AS_DIRTY,
deleteStatus: 'success',
itemId: itemId
});
// now let's actually check if that was the correct result
AppAjaxUtil.get('/deleteItem', {itemId: itemId}, function(result) {
WebshipDispatcher.handleServerAction({
type: result.status ? ActionTypes.DELETE_ITEM : ActionTypes.DELETE_ITEM_FAIL,
deleteStatus: result.status, // 'success' or 'failure'
itemId: itemId
});
}, function(error) {
WebshipDispatcher.handleServerAction({
type: ActionTypes.DELETE_ITEM_FAIL,
error: error,
itemId: itemId
});
});
}
So basically you remove the dirty record from your store if you your response is successful. Otherwise you have a reference of your dirty records in your store that can try again with your server behind the scenes while your app is still running. So in essence your user does not have to sit and wait for a response.

Need captcha field in registration form using ExtJS

I am using ExtJS 4.2 and I am not able to get the captcha field in my registration form. Can
anybody suggest a solution?
I use google recpatcha. I'll paste my client side code below here. you'll need to do the server side yourself. you need to include the google recaptcha library and have a panel on your form like what is below. then, when you submit, the google values to up and need to be verified.
ExtJS:
{
xtype: 'panel',
border: false,
height: 150,
html: '<div id="recaptcha">Captcha Control From Google. This should be replaced by image by google</div>',
itemId: 'reCaptcha',
margin: '0 0 0 105'
}
JavaScript Submit Click Event
var myMask = new Ext.LoadMask(Ext.getBody(), {msg:"Creating New Account..."});
myMask.show();
localValues.recaptchaChallengeField = Recaptcha.get_challenge();
localValues.recaptchaResponseField =Recaptcha.get_response();
Ext.Ajax.on('requestexception', function (conn, response, options) {
myMask.hide();
if (response.status != 200) {
var errorData = Ext.JSON.decode(response.responseText);
Ext.MessageBox.show({
title: 'Error Message',
msg: errorData.message,
icon: Ext.MessageBox.ERROR,
buttons: Ext.Msg.OK
});
Ext.Msg.alert('Creating User Failed',errorData.message);
}
});
Ext.Ajax.request({
url:'/rpc/Account/CreateUser',
actionMethods:'POST',
scope:this,
params: localValues,
success: function(r, o) {
myMask.hide();
var retData = Ext.JSON.decode(r.responseText);
} else {
tabPanel.setActiveTab(tabPanel.getTabIdByName('AttendeeAfterLoginConf'));
}
},
failure: function(r,o) {
myMask.hide();
// handled in exception now
//debugger;
//Ext.Msg.alert('Creating User Failed','');
}
});

Cancel store.remove after server call in ExtJS 4

I'm using ExtJS 4 and have an Ext.data.Store with an ajax proxy and api:
var gridStore = Ext.create('Ext.data.Store', {
autoSync: true,
proxy: {
type: 'ajax',
api: {
read: 'myurl',
create: 'myurl',
update: 'myurl',
destroy: 'myurl'
},
reader: {
type: 'json',
successProperty: 'success',
root: 'data',
messageProperty: 'message'
},
writer: {
type: 'json',
writeAllFields: false,
root: 'data'
},
listeners: {
exception: function(proxy, response, operation){
Ext.MessageBox.show({
title: 'Server error',
msg: operation.getError(),
icon: Ext.MessageBox.ERROR,
buttons: Ext.Msg.OK
});
}
}
...
When I use the update function and my server returns a json object with success:false (because he entered something wrong) the field in my associated grid is still marked as changed and the user has the option to change his wrong value.
That works fine.
But when I remove a record from the store...
var store = Ext.StoreManager.lookup('gridStore');
store.remove(store.getById(id));
...then ExtJS removes this record from the store first and call the ajax api afterwards. So when the destroy api returns success:false the message is shown as exception like in the update api, thats fine, but my record has been removed from the store! As example the exception from the server says that you cannot remove this record because of whatever but it's already removed in the store.
How to cancel the store removement after the server sync? I want the record to stay in the store if the server returns success:false.
Any idea? Maybe a bug?
UPDATE SOLUTION
Based on Ryan's anwer, I modified the exception listener as following, which works very well:
listeners: {
exception: function(proxy, response, operation){
Ext.MessageBox.show(...);
// get the removed records and insert them where they have been
var removedRecords = gridStore.getRemovedRecords();
for(var i=0; i<removedRecords.length; i++){
var record = removedRecords[i];
gridStore.insert(record.index, record);
}
}
}
The insert technique didn't work for me, the removed record stays marked for removal on the next sync operation. I am using Ext.data.Store.rejectChanges() for this purpose.
Just extending the code you gave, specifically the listeners area:
listeners: {
exception: function(proxy, response, operation){
Ext.MessageBox.show({
title: 'Server error',
msg: operation.getError(),
icon: Ext.MessageBox.ERROR,
buttons: Ext.Msg.OK
});
gridStore.add(gridStore.getRemovedRecords());
}
}
I am useing callback functions 'success','failure' or 'callback' when sync.
I hope this method can help you.
store.remove(records);
store.sync({
success: function (proxy, operations) {
// pop success message
}, failure: function (proxy, operations) {
// resume records
store.rejectChanges();
}
});
I am using model.destroy, this is what i use for deleting singular entries from grid:
text : 'Delete',
itemId : 'delete',
scope : this,
handler : function() {
var selection = grid.getView().getSelectionModel().getSelection()[0];
if(selection) {
selection.destroy({
failure : function() {
console.log('Record could not be deleted.');
},
success : function() {
store.remove(selection);
console.log('Record successfuly removed.');
},
});
}
}

Resources