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

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.

Related

ExtJs CallParent() not working in initComponent When try to call from Ajax.request Success

I am try to create async Dynamic grid in extjs.but I am not be able to figure out how to call callParent() after ajax call complete.
I am trying to call callParent() in Ajax.request() but it gives me
error: Uncaught TypeError: Cannot read property 'superclass' of undefined.
initComponent: function () {
var me = this;
this.loadData(function (fields, columns, data) {
me.store = {
fields: fields,
data: data
};
me.columns = columns;
console.log('inner');
me.callParent(arguments);
});
console.log('outer');
//this.callParent(arguments); //I have try outside of the ajax request but it will call before ajax request compelte.
}
, loadData: function (parent) {
Ext.Ajax.request({
url: 'Url',
headers: { 'Content-Type': 'application/json; charset=UTF-8' },
//async: false,
success: function (response, opts) {
var obj = Ext.decode(response.responseText);
res = Ext.decode(response.responseText);
...
...
parent.call(this, fields, columns, data);
},
failure: function (response, opts) {
}
});
}
I need to call async call of ajax in InitComponent.
This can't work with callParent this way, use reconfigure instead:
Reconfigures the grid or tree with a new store and/or columns. Stores and columns may also be passed as params.

C# with kendo ui - client send file to server

I'm trying to send a .xlsx file to my REST API using Kendo Ui. But I'm lost.
I was able to call my service, but I can't get the file. I believe I'm sending it wrong.
I don't need to save the file. I only need to read the .xlsx file to import the data to my database.
html (don't have a form):
<div>
<input name="files" id="files" type="file" />
<button id="importButton">Import</button>
</div>
js:
$("#files").kendoUpload({
async: {
autoUpload: true
},
select: onSelect
});
$("#importButton").kendoButton({
click: onImport
});
function onImport() {
var formData = new FormData();
jQuery.each(jQuery('#files')[0].files, function (i, file) {
formData.append('file-' + i, file);
});
$.ajax({
type: "POST",
url: url,
data: formData,
processData: false,
cache: false,
success: function (result) {
alert("Ok");
},
error: function (result) {
alert("Not Ok");
}
});
}
Server-side:
[HttpPost, Route("import")]
public void Import()
{
var streamProvider = new MultipartMemoryStreamProvider();
Request.Content.ReadAsMultipartAsync<MultipartMemoryStreamProvider>(streamProvider).ContinueWith((tsk) =>
{
foreach (HttpContent ctnt in streamProvider.Contents)
{
Stream stream = ctnt.ReadAsStreamAsync().Result;
// do something
}
});
}
Got it!
$("#files").kendoUpload({
async: {
withCredentials: false,
saveUrl: url,
autoUpload: true
},
select: onSelect
});
This answer helped me: Cross domain upload
#Brett was right, implement the kendUpload was the way.
I thought the Import button should do the magic, but I only need to use kendoUpload.
Thanks!!

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','');
}
});

ExtJS4 & Symfony 2

I have to mix up Symfony2 and ExtJS4. All views need to be render with ExtJS, no twig.
All the application is in a secured area, only members will be able to access it.
When an user launch the application, main viewport is displayed with login form. After connecting, the entire app is displayed.
In facts, the / route need to display viewport. It will call an ajax request to check if user is connected.
if yes, launch the app
if not, show the login form
And I don't know how to do that, the / action in my controller wait for response and I only want to launch javascript.
EDIT : the login form must be made with ExtJS.
security.yml
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login$
security: false
secured_area:
pattern: ^/
form_login:
check_path: /login_check
login_path: /login
logout:
path: /logout
target: /
and the loginAction
public function loginAction()
{
if ($this->get('request')->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $this->get('request')->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = $this->get('request')->getSession()->get(SecurityContext::AUTHENTICATION_ERROR);
}
$json = json_encode(array(
'username' => $this->get('request')->getSession()->get(SecurityContext::LAST_USERNAME),
'error' => $error,
));
$response = new Response($json);
$response->headers->set('Content-Type', 'application/json');
return $response;
}
Process should be -
Make an ajax call to login_check
Read the json response into an object and check whatever variable is set to denote success or failure
If the user isn't logged in, show the login window
In the click event of the login button, make another ajax call to log them in
If they authenticate, return a variable to notify via json, and show the app, if not give them a hint as to what went wrong in a message.
-
var login = Ext.create('Ext.window.Window', {
id: 'login',
height: 200,
width: 350,
layout: 'anchor',
modal: true,
title: 'Welcome, Please Login',
items: [
this.username = Ext.create('Ext.form.field.Text', {
fieldLabel: 'Username'
}),
this.password = Ext.create('Ext.form.field.Text', {
fieldLabel: 'Password'
}),
this.submit = Ext.create('Ext.button.Button', {
text: 'Login'
})
]
});
login.submit.on('click', function (btn, e, eOpts) {
Ext.Ajax.request({
scope: this,
params: {
username: login.username.getValue(),
password: login.password.getValue()
},
url: 'yoursite/login',
success: function(response, opts) {
var obj = Ext.decode(response.responseText);
if (obj.logged_in === true) {
//Show App
} else {
//Display error message
}
}
});
});
Ext.Ajax.request({
scope: this,
url: 'yoursite/login_check',
success: function(response, opts) {
var obj = Ext.decode(response.responseText);
if (obj.username === null) {
//Show Login window
login.show();
} else {
//Logic to show app if logged in
}
}
});

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