I have two Ajax calls. I need to make sure that a JS function is executed between these two calls.
Is it possible to trigger the execution of a client-side JS function via the AJAX response? Or how would you do this kind of thing?
EDIT My code, after doing what was suggested by the first answer (onComplete):
^ (html jQuery ajax
callback: [ :text | id := self createNewAnnotation: text ]
value: (self html jQuery: '#annotationText') value;
onComplete: ((JSStream on: 'displayAnnotation("', id, '")'),
(self html jQuery ajax
callback: [ :text | finalText := text ]
value: (self html jQuery: '#text') html)
);
What this is supposed to do: on the first callback, the value of the #annotationText field is passed to createNewAnnotation, which saves the annotation and returns the ID.
Next, I want to pass that ID to the client-side JS function displayAnnotation().
In this example, this can't yet work, as the code around JSStream on: is not in a block and thus has the initial value of id. How can I pass that result of the server-side method as parameter to the client-side function?
In Seaside, you probably would use the jQuery bindings to execute ajax calls. If you want to make sure that two ajax calls are chained and some other JS code is executed in between, the code would follow these lines:
renderContentOn: html
html span
onClick: (html jQuery ajax
callback: [...1st ajax callback...];
onComplete: ((JSStream on: '... some JS code ...'),
(html jQuery ajax callback: [...2nd ajax callback...]));
with: 'Click this to trigger the calls'.
This will render a span that, when clicked, will execute the 1st ajax call. If that one completes, the JS code and the second ajax call will be executed.
EDIT:answer to the additional question:
If you want the 'id' that is passed on to the call of displayAnnotation to be computed by the first callback, you can only generate that call after the first callback has executed. The value can be passed between ajax callbacks via temporary variables or instance variables (because of closures). The following piece of code makes the chaining via onComplete: explicit. Afterwards, I give an example where less ajax calls are made.
^ (html jQuery ajax
callback: [ :text | id := self createNewAnnotation: text ]
value: (html jQuery: #annotationText) value;
onComplete:
(html jQuery ajax
script:[:s | s << ((JSStream on: 'displayAnnotation("', id, '")')]
onComplete:
(html jQuery ajax
callback: [ :text | finalText := text ]
value: (html jQuery: #text) html)))
You can also reduce the number of ajax calls if you understand how Seaside callbacks work. In summary, the block that produces the response of the callback is always invoked last. This allows to group a number of callback blocks in a single call. Such as:
^ (html jQuery ajax
callback: [ :text | id := self createNewAnnotation: text ]
value: (html jQuery: #annotationText) value;
script:[:s | s << ((JSStream on: 'displayAnnotation("', id, '")')];
onComplete:
(html jQuery ajax
callback: [ :text | finalText := text ]
value: (html jQuery: #text) html)))
The XMLHttpRequest object has a onreadystatechange event. When the object reaches a readyState of 4, you can make your second AJAX request by binding an anonymous function to that event. If you want a more detailed response please post what you have tried and some code and the SO community will be more than willing to give you a more detailed answer.
Related
I have an Ajax which call to an action in a controler.
The controller render:
render template:"changePassword", model:[user: user, passwordError: passwordError]
The passwordError is boolean.
In case the passwordError is true I have to perform function in the js.file.
How can I check in the success's Ajax the value of the passwordError?
The code of the Ajax:
$.ajax({
url: changePassword,
type: "post",
data: {
password: $('#password').val(), npassword: $('#npassword').val()
},
success: function(data,textStatus){
$('#changePassSuceess').modal()
}
});
If you dont need to render a template, you can return a json as #Eylen mentioned and then access the flag from json. If you must render a template then you can have a hidden field in your template with value set to the flag passwordError and then you can get the value of flag from this hidden field in your javascript code
See this question for how to find hidden element in jquery ajax response html
If you don't need to show the template that you are returning, then you can change your return from the controller to something like the following
return [passwordChanged:true] as JSON
Ans then in your ajax call you will have access to the JSON object in the data attribute.
console.log(data.passwordChanged);
Maybe you have to tell also in the ajax call that the return type is json.
Normally one posts an ExtJS form to the backend using form.submit({...}). I want to make my form submission synchronous now, so I'm switching to using Ext.Ajax.request({async: false, ...}). The form property of Ext.Ajax.request() usually looks like so:
Ext.Ajax.request({
url: 'formsubmit',
form: 'formid',
method:'POST',
success: function(response, opts) {
alert("successfull");
},
failure:function(res,opt) {
alert("request failed");
}
});
I'm dealing with a bunch of anonymous forms right now. Is there any way around this?
Given a var form = {xtype: 'form', items: [...]}
I've tried replacing 'formid' with form.getEl(), form.getForm(), and form.getForm().getFieldValues() which all don't work.
There's no other way around this other than assigning a generated id to each of my anonymous forms, is there.
Thanks for any input
It looks like you could just do this as an alternative to the form attribute:
var form = this.down('form');
Ext.Ajax.request({
url: 'test.xyz',
params: form.getValues()
// etc...
});
getValues gives you the name/value pairs you need for your submission.
It looks like the ExtJS forms do not actually use form elements in the markup. When the submit function is called on an ExtJS form, an HTML form element is crafted as part of the process, and that's the form that is used for the submission.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.form.action.Submit-method-buildForm
Ideally, you could modify the options that are used in the Ajax request called within the doSubmit function. Since you can't, you might want to consider overriding Ext.form.action.Submit such that you can, then calling the form.submit() function you mentioned in your question.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.form.action.Submit-method-doSubmit
Below is the code snippet which is hitting the url on server and getting the html response.I can see
the response inside firefox debugger but it does not display in div tag.
$.ajax({
url: url,
dataType: 'html',
data: '',
type: 'POST',
success: function(data) {
//in firefox debugger i can see complete html response inside data
$('#displayContent').html(data); // but here, it does not
// append the html inside div displayContent. Instead it makes
// the current page blank
}
});
I don't get what mistake I'm making here Can I not directly assign the ajax html response to an selector(div tag in my case) with $('#displayContent').html(data)?
Instead of using html() method use append i.e.
$('#displayContent').append(data);
Or if you want to assign whole content direct to your element use load method
$(function(){
$('#displayContent').load(url);
});
If you've got a form tag on your page, and you're trying to submit it asynchronously with jQuery, your function will need to return false, to prevent the browser from handling the form.
Example:
$("form").submit(function () {
$.ajax(...);
return false;
});
I have a form in Magento that I build in code, and that works with ajax, which I need to validate.
I would like to be able to use Magento's built-in validation functionality, but I don't know how I would trigger it since the form is not submitted. The data is retrieved via ajax and outputted in a list below the form.
Is there someone who can point me in the right direction?
Thanks in advance.
Edit:
This is the javascript code used to hande the ajax request. Its called by the onclick event of the button.
function advancedtranslateSearch(url){
new Ajax.Request(url, {
method: 'get',
parameters: $('search_form').serialize(),
onSuccess: function(transport) {
json = transport.responseText.evalJSON();
$('result').update('<div class="hor-scroll">'+json.records+'</div>');
}
});
}
You should use form's onsubmit event.
To prevent page from reloading you must return false value from your function.
I have a form that looks like this:
<form name="formi" method="post" action="http://domain.name/folder/UserSignUp?f=111222&postMethod=HTML&m=0&j=MAS2" style="display:none">
...
<button type="submit" class="moreinfo-send moreinfo-button" tabindex="1006">Subscribe</button>
In the script file I have this code segment where I submit the datas, while in a modal box I say thank you for the subscribers after they passed the validation.
function () {
$.ajax({
url: 'data/moreinfo.php',
data: $('#moreinfo-container form').serialize() + '&action=send',
type: 'post',
cache: false,
dataType: 'html',
success: function (data) {
$('#moreinfo-container .moreinfo-loading').fadeOut(200, function () {
$('form[name=formi]').submit();
$('#moreinfo-container .moreinfo-title').html('Thank you!');
msg.html(data).fadeIn(200);
});
},
Unfortunately, after I submit the datas, I'm navigated to the domain given in the form's action. I tried to insert return false; in the code (first into the form tag, then into the js code) but then the datas were not inserted into the database. What do I need to do if I just want to post the data and stay on my site and give my own feedback.
I edited Eric Martin's SimpleModal Contact Form, so if more code would be necessary to solve my problem, you can check the original here: http://www.ericmmartin.com/projects/simplemodal-demos/ (Contact Form)
Usually returning false is enough to prevent form submission, so double check your code. It should be something like this
$('form[name="formi"]').submit(function() {
$.ajax(...); // do your ajax call here
return false; // this prevent form submission
});
Update
Here is the full answer to your comment
I tried this, but it didn't work. I need to submit the data in the succes part, no?
Maybe, it depends from your logic and your exact needs. Normally to do what you asking for I use the jQuery Form Plugin which handle this kind of behavior pretty well.
From your comment I see that you're not submitting the form itself with the $.ajax call, but you retrieve some kind of data from that call, isn't it? Then you have two choices here:
With plain jQuery (no form plugin)
$('form[name="formi"]').submit(function() {
$.ajax(...); // your existing ajax call
// this will post the form using ajax
$.post($(this).attr('action'), { /* pass here form data */ }, function(data) {
// here you have server response from form submission in data
})
// this prevent form submission
return false;
});
With form plugin it's the same, but you don't have to handle form data retrieval (the commented part above) and return false, because the plugin handle this for you. The code would be
$(document).ready(function() {
// bind 'myForm' and provide a simple callback function
$(form[name="formi"]).ajaxForm(function() {
// this call back is executed when the form is submitted with success
$.ajax(...); // your existing ajax call
});
});
That's it. Keep in mind that with the above code your existing ajax call will be executed after the form submission. So if this is a problem for your needs, you should change the code above and use the alternative ajaxForm call which accepts an options object. So the above code could be rewritten as
$(document).ready(function() {
// bind 'myForm' and provide a simple callback function
$(form[name="formi"]).ajaxForm({
beforeSubmit: function() { $.ajax(...); /* your existing ajax call */},
success: function(data) { /* handle form success here if you need that */ }
});
});