PDA

View Full Version : vtype is marking field invalid before ajax returns



hallikpapa
11 Oct 2009, 11:12 AM
I have a custom vtype that looks to make sure emails are unique, and only specific domains are being used; via an ajax call


Ext.apply(Ext.form.VTypes, {
useremail: function (value, field) {
var validfield = false;
Ext.Ajax.request({
url : '../admin/extjs.php?act=UserForm&method=validate',
method: 'POST',
params: {
"task": 'checkuseremail',
'tmpUserEmail': value,
'tmpUserID': Ext.get("user-id").getValue()
},
success: function (response, options) {
var resp = Ext.util.JSON.decode(response.responseText);
if (resp == null) {
field.clearInvalid();
validfield = true;
} else {
validfield = false;
field.markInvalid(resp.errormsg);
// return validfield;
}
return validfield;
},
failure: function () {
Ext.Msg.show({
"title": "Error",
"msg": "Connection Error!"
});
}
});
},


So if f.validate() returns false, it goes into my markInvalid() function. I put breakpoints in both functions, and I see it going into the above ajax call, but THEN it hits the markInvalid() function, and the next breakpoint it hits is the "success" function listed above. the ajax call returns in 116ms, so it doesn't take long at all.

What may be causing it not to wait for the server response before marking it an invalid field?

I see the email field underlined red for a split second when I hit the submit button, but then it is valid again; but it's long enough to not allow me to submit the form because form.isValid() always fails because of that out of order processing I am experiencing.

Animal
11 Oct 2009, 11:30 AM
It's a code read failure. At what TIME do those callback functions execute?

You have to learn to read Javascript in execution time frames.

The useremail function returns before those callbacks are executed.

hallikpapa
11 Oct 2009, 11:44 AM
Not sure exactly what you are getting at. I assumed the callbacks were executed as soon as the response was received, and THEN it would return to here in the ext-all.js


if(this.vtype){
var vt = Ext.form.VTypes;
if(!vt[this.vtype](value, this)){
this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
return false;
}
}
But it seems to hit that markInvalid before the callbacks are executed.

My learning extjs book is coming this friday. :) But still having trouble grasping why it doesn't wait for the callback to execute before marking invalid.

Animal
11 Oct 2009, 11:40 PM
Read the code.

I mean read it line by line, dry running it in your head as if you were the Javascript runtime.

The thoughts that go through your mind should be


Set validfield to false
Send off the request
Return


That is a dry run of your validator.

hallikpapa
12 Oct 2009, 7:44 AM
Seriously, thanks for the replies. But I just don't see why it seems to be marking it invalid before the response comes back. I did move where it returns stuff, I thought that might be the problem. But the problem still remains.


useremail: function (value, field) {
var validfield = false;
Ext.Ajax.request({
url : '../admin/extjs.php?act=UserForm&method=validate',
method: 'POST',
params: {
"task": 'checkuseremail',
'tmpUserEmail': value,
'tmpUserID': Ext.get("user-id").getValue()
},
success: function (response, options) {
var resp = Ext.util.JSON.decode(response.responseText);
if (!resp) {
field.clearInvalid();
validfield = true;
return true;
} else {
validfield = false;
field.markInvalid(resp.errormsg);
return false;
}
},
failure: function () {
Ext.Msg.show({
"title": "Error",
"msg": "Connection Error!"
});
}
});
}

Unless you have any other tips, I am going to abandon the form.isValid() function. I am completely stumped as to why it's invalidating the field before it hits the callback

Animal
12 Oct 2009, 7:50 AM
READ. THE. CODE.

It RETURNS before the response comes back!

The success and failure properties are CALLBACKS.

Callback functions executed in a completely separate execution context at some unspecifiable point in the future.

hallikpapa
12 Oct 2009, 9:54 AM
I removed the return statements, but it is still failing somewhere. For now I am going to try marking the fields valid on submit, and still do my error checking server side, and not try and do client side validation on form submit.

Animal
12 Oct 2009, 10:12 AM
OK, don't think about what I told you.

aw1zard2
12 Oct 2009, 10:35 AM
The way this is coded it will never wait for the ajax to finish.
Your vtype function always returns before ajax is finished.
Think of it this way.


useremail: function (value, field) {
var validfield = false;
Ext.Ajax.request({
url : '../admin/extjs.php?act=UserForm&method=validate',
method: 'POST',
params: {
"task": 'checkuseremail',
'tmpUserEmail': value,
'tmpUserID': Ext.get("user-id").getValue()
},
success: function (response, options) {
var resp = Ext.util.JSON.decode(response.responseText);
if (!resp) {
field.clearInvalid();
validfield = true;
return true;
} else {
validfield = false;
field.markInvalid(resp.errormsg);
return false;
}
},
failure: function () {
Ext.Msg.show({
"title": "Error",
"msg": "Connection Error!"
});
}
});
return; //Even though this isn't there it is acting like it is. Which is normal for a function.
}

mschwartz
12 Oct 2009, 10:59 AM
The Ajax request is asynchronous. It fires an XMLHTTP request to the server and the response comes back seconds later after you code has returned.

You might try:
return true;

at the end so Ext doesn't mark the field(s) invalid.

You seem to be marking them invalid yourself in the success handler of the Ajax request.

Something like this would work if the request were synchronous. Ext doesn't support it native.

You will also have to wait for the Ajax to finish before submitting your form.

hallikpapa
12 Oct 2009, 11:39 AM
OK, don't think about what I told you.

I did. I am. I set the field to true initially, and mark them as false if the ajax call sends back a fail, but return the valuefield outside of the callbacks at the end, so it returns true to the validate() function.

The vtypes seem to be working great except on the form submit. So the interim solution was to mark them as valid off the bat so they pass the form submit validation, and let server side validation double check it, and use the Ajax requests as visual cues to point the user to the incorrect fields if the server comes back with errors.

So if I am still missing something, I should have my extjs book this week.

mschwartz,
Yeah, that's what I had just done and it seems to be working right now.

aw1zard2,
Yeah, I think that is what Animal was getting at, and what I did. But I guess I didn't word my solution correctly initially, and he's a bit fiesty. :)

Thanks everybody!

moegal
25 Mar 2010, 4:12 PM
Hi,

I am using something like this and it works fine until I try to close the window that the form field is in. It only happens when my cursor is still in the field.

field.errorIcon.dom is undefined

I am getting a dom error. I think the ajax response is trying to update a value that no longer exists. I have tried checking for field but I still get the error. Anyone know how I can fix this?



Ext.apply(Ext.form.VTypes, {
BillBoardNumber: function (value, field) {
Ext.Ajax.request({
url: 'includes/remote-validator-BillBoardNumber.asp',
method: 'POST',
params: {
'BillBoardNumber': value
},
success: function (response, options) {
obj = Ext.util.JSON.decode(response.responseText);
if(obj.success == true){
field.clearInvalid();
return true;
}else{
field.markInvalid(obj.error.reason);
return false;
}
},
failure: function () {

}
});
return true;
}
});