I have a problem with this jQuery code. It doesn't work as expected:
$('#select_dropdown').change ( function(){
$('#form_to_submit').submit( function(event){
$.post("list.php", { name: "John", time: "2pm" },
function(data) {
alert("Data Loaded: " + data);
});
});
});
However, this works:
$('#select_dropdown').change ( function(){
$('#form_to_submit').submit();
});
I wonder why the internal function on submit doesn't work. When a user selects a value from a dropdown, the form must be submitted. The second set of codes work but if I add an inner function to submit, it doesn't.
Basically, I want to do some ajax call after the user select on the dropdown.
According to documentation ( http://api.jquery.com/submit/ ), submit() without parameters will submit your form, but if you include arguments it will bind the submit event to the form, but it wont submit it.
So, the code posted by #Chris Fulstow would be the right way of submitting the form, but as ajax is not synchronous, function will continue without waiting for the answer and then, the alert will not be shown.
You can make it synchronous, but you must use $.ajax instead of $.post, because $.post doesn't include an async option. Anyway, I'm providing a solution for your specific problem, but I'm guess there should be a better way for doing it.
$(function() {
$('#select_dropdown').change(function() {
$('#form_to_submit').submit();
});
$('#form_to_submit').submit(function(event) {
$.ajax(
url: "list.php",
data: { name: "John", time: "2pm" },
success: function(){
alert("Data Loaded: " + data);
},
async:false,
);
});
});
When you call with a callback argument submit( handler(eventObject) ) it will only attach an event handler. To trigger a form submit, call submit() with no arguments:
$(function() {
$('#select_dropdown').change(function() {
$('#form_to_submit').submit();
});
$('#form_to_submit').submit(function(event) {
$.post(
"list.php",
{ name: "John", time: "2pm" },
function(data) {
alert("Data Loaded: " + data);
}
);
});
});
The .submit call in your first example is binding a function to the submit event on the form. From the fine manual:
.submit( handler(eventObject) )
handler(eventObject) A function to execute each time the event is triggered.
You need to bind your submit handler:
$('#form_to_submit').submit(function(event){ /*...*/ })
somewhere else and call submit as in your second example.
So the problem here is that in the first case, you are binding an event handler to the element, and in the second you are triggering it. Let's look at the first case:
$('#form_to_submit').submit(function(evt){ ... });
You're essentially doing something like
document.getElementById('form_to_submit').addEventListener(
'submit',
function(evt){...},
false
);
The second case is you instructing the form to submit, which is why it works. If you wanted the handler to work with your custom code you would need both of them. First bind your event handler, then, onchange instruct the form to submit.
$('#form_to_submit').submit(function(evt){ ... });
$('#select_dropdown').change(function(){
$('#form_to_submit').submit();
});
Keep in mind though, that as other people have already said, if your action is set to go to another location, you may not see the results of the binded event handler so instead of explicitly stating a url for your action, you will have to use something to prevent the form from going anywhere like action="javascript:void(0)" or the like.
To make your code a bit cleaner, you could pull the ajax out of an unnamed function and put it in a named one and call it on change so it looks like this.
var fetchList = function(){
$.ajax(...);
};
$('#form_to_submit').submit(fetchList);
$('#select_dropdown').change(fetchList);
I haven't run this code, please excuse any silly syntax mistakes I've made. But this should get you some of the way there. Good luck! :)
Related
I am using jQuery Address plugin, and all my ajax navigation is based on it, and more precisely on internalChange or externalChange events like that
$(document).ready(function() {
initDeepLinking();
});
function linkClicked(e){
var request = $.ajax({
url: e.path,
data: e.queryString,
type: "GET",
dataType: "json",
});
request.done(handleResponse);
return false;
}
function handleResponse(response, textStatus, jqXHR){
$('#main').html(response.responseText);
};
function initDeepLinking(){
$.address.internalChange(function(event){
linkClicked(event);
});
$.address.externalChange(function(event){
linkClicked(event);
});
}
so when i click on a link leading to the current page, nothing happens.
I would like the page to reload when I do that. Any simple options ?
Thanks !
I am having troubles understanding what your question really is:
you don't know how to attach a handler to the link
you don't know what statement can be used to refresh the current page
In order to set a handler you can use some selector. For example, getting the element by class. More about jquery selectors here.
After you have the element, you can attach an event handler for the 'on click' event and do something like this:
window.location.reload(true);
Trying to find out why this jQuery JS isn't making ajax call though it is being called for execution.
I have this button to make an ajax GET request to a method in the controller, the method will partial render. When I click on the button I don't see any request coming on the console but I see the alert "test" on the browser.
I have the same exact JS with other parameters working for other tupes of ajax calls, so I just copied one of them and changed all required parameters, expecting it shall work right away. Neither I get any errors on the console. My routes and id names are good and verified. What is it that I am missing here?
view - Note: this button is rendered via a different ajax, that part works.
<%= button_tag "Add / Remove", :id => "add_remove_button", :onclick => "javascript:add_remove();" %> #note: this is buried under div tags in a html table
JS-
function add_remove(){
$('#add_remove_button').click(function() {
$.ajax({
type: 'GET',
url: "/item/add_remove",
success:$('#view_item').html(data)
/*function(){ },
data:$('#test').serialize(),
error: function(){ },
success: function(data){ },
complete: function (){ }*/
}); #No ajax call made
/*return false;*/
});
alert('test'); #I get this alert
}
You'll always see that alert() because click() is asynchronous: the code inside the function() passed to click does not get executed until you click, but the rest of add_remove() will get called.
Here's what is actually happening in your code, which explains why the AJAX call doesn't get made:
Using :onclick => ... attaches add_remove() to your button.
You click the button, add_remove() gets called and attaches another click callback to your button. Then add_remove() calls alert(). There is no AJAX call happening here, just adding a new click handler, and sending an alert.
You click the button a second time, and you will attach a third click callback to the button. However since you also attached a click handler the first time you clicked the button, you should see an AJAX request here.
Click it a third time and you'll see two AJAX requests this time, for a total of 3 AJAX requests.
Here's what you actually want to do. Remove the :onclick => ... from the button:
<%= button_tag "Add / Remove", :id => "add_remove_button" %>
Attach a click event to the button when the page first loads:
$(function(){
$('#add_remove_button').click(function() {
$.ajax({
type: 'GET',
url: "/item/add_remove",
success: function(data) { $('#view_item').html(data); },
data: $('#test').serialize(),
error: function(){ },
success: function(data){ },
complete: function (){ }
});
return false;
});
});
You are mixing up the jquery-registering-callbacks style and the old event-handler attributes. So you triggered the registering when calling the add_remove function.
Simply remove the :onclick stuff and function add_remove(){ ... }
Well this has me well and truly stumped. After searching for the last few hours I still cannot seem to work out where I am going wrong.
I am trying to append an AJAX response to a container when it gets clicked. That works fine but I don't want it to append another object when the elements from the AJAX response also gets clicked.... so:
<div id="container">
<!-- AJAX response to get inserted here, for example -->
<span id="ajaxResponse"></span>
</div>
Here is my script:
$('#container').click(function(e) {
var current_el = $(this).get(0);
$.ajax({
url: 'text.html',
success: function(data) {
$(current_el).append(data);
}
});
return false;
});
So it works fine but for some reason the click event on #container also fires when I click on the AJAX response span!?
According to jQuery documentation:
To stop further handlers from
executing after one bound using
.live(), the handler must return
false. Calling .stopPropagation() will
not accomplish this.
But unless I am mistaken, I am calling false? :(
Anyone help me out on this?
UPDATED:
So the only way I can get it to work is by updating my code to this:
$('#container').live('click', function() {
var current_el = $(this).get(0);
$.ajax({
url: 'text.html',
success: function(data) {
$(current_el).append(data);
}
});
});
$('#ajaxResponse').live('click', function(e) {
return false;
});
This seems a little messy though... anyone have a better solution?
Where is live part you mention in the title of the question ?
It is how the event model works.. If you click on element which does not handle the event, the event will travel up the DOM hierarchy until it finds an element that handles the click (and stops its propagation..). Otherwise you would not be able to put an image inside a <a> tag and click on it..
You can bind a canceling handler on the inner element assuming you have someway to target it..
$.ajax({
url: 'text.html',
success: function(data) {
$(current_el).append(data);
// assuming the returned data from ajax are wrapped in tags
$(current_el).children().click(function(){ return false;});
}
});
I think the return false is referring to something else in this case...
you should try calling stopPropagation() - this should stop the "click" function from propagating down to the ajaxResponse span....
One option that you may want to try is switching over to using live(). Essentially, the click event you setup is calling bind(), and the solution you referenced is using live() which is a variation on bind().
For example:
$('#container').live("click", function(e) {
var current_el = $(this).get(0);
$.ajax({
url: 'text.html',
success: function(data) {
$(current_el).append(data);
}
});
return false;
});
HTH
I'm trying to do an ajax post after a button is clicked, and it works in firefox but not in IE the first time the page is loaded. It does work if I refresh the page and try again second time - but not first time and this is crucial.
I've scanned over various web pages - could it be anything to do with the listener? (I've just seen this mentioned mentiond somewhere) Is there something not set correctly to do with ajax and posting when page first loads?
$(document).ready(function() {
$('#btnCont').bind('click',function () {
var itm = $("#txtItm").val();
var qty = $("#txtQty").val();
var msg = $("#txtMessage").val();
var op_id = $("#txtOp_id").val();
//if i alert these values out they alert out no prob
alert(itm+'-'+qty+'-'+msg+'-'+op_id);
$.ajax({
type: "POST",
url: "do_request.php?msg="+msg+"&itm="+itm+"&qty="+qty+"&op_id="+op_id,
success: function (msg) {
document.getElementById('div_main').style.display='none';
document.getElementById('div_success').style.display='block';
var row_id = document.getElementById('txtRow').value;
document.getElementById('row'+row_id).style.backgroundColor='#b4e8aa';
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('Error submitting request.');
}
});
});
I would start debugging the click event. I.e. if you try to put .bind into a a href tag, the tag itself has a click event that may act on an unwanted way. There exist a command that are named something like event.preventDefaults() that avoids the standard feature of click. After All, you try to manipulate the DOM last of all actions (document.load).
$('#btnCont').bind('click',function () { .. }
I would also try to debug the same functionality with adding onClientClick to the tag instead of adding bind to the document load.
I hope that bring some light.
Given so much different options to submit sth to the server, I feel a little confused.
Can someone help me to clear the idea when I should use which and why?
1> $.ajax()
2> $('#myForm').ajaxForm
3> ajaxSubmit
4> $('#myForm').submit
Thank you
I personally prefer creating a function such as submitForm(url,data) that way it can be reused.
Javascript:
function submitForm(t_url,t_data) {
$.ajax({
type: 'POST',
url: t_url,
data: t_data,
success: function(data) {
$('#responseArea').html(data);
}
});
}
HTML:
<form action='javascript: submitForm("whatever.php",$("#whatevervalue").val());' method='POST'> etc etc
edit try this then:
$('#yourForm').submit(function() {
var yourValues = {};
$.each($('#yourForm').serializeArray(), function(i, field) {
yourValues[field.name] = field.value;
});
submitForm('whatever.php',yourvalues);
});
Here is my understanding
$.ajax does the nice ajax way to send data to server without whole page reload and refresh. epically you want to refresh the segment on the page. But it has it's own limitation, it doesn't support file upload. so if you don't have any fileupload, this works OK.
$("#form").submit is the javascript way to submit the form and has same behaviour as the input with "submit" type, but you can do some nice js validation check before you submit, which means you can prevent the submit if client validation failed.
ajaxForm and ajaxSubmit basically are same and does the normal way form submit behaviour with some ajax response. The different between these two has been specified on their website, under FAQ section. I just quote it for some lazy people
What is the difference between ajaxForm and ajaxSubmit?
There are two main differences between these methods:
ajaxSubmit submits the form, ajaxForm does not. When you invoke ajaxSubmit it immediately serializes the form data and sends it to the server. When you invoke ajaxForm it adds the necessary event listeners to the form so that it can detect when the form is submitted by the user. When this occurs ajaxSubmit is called for you.
When using ajaxForm the submitted data will include the name and value of the submitting element (or its click coordinates if the submitting element is an image).
A bit late, but here's my contribution. In my experience, $.ajax is the preferred way to send an AJAX call, including forms, to the server. It has a plethora more options. In order to perform the validation which #vincent mentioned, I add a normal submit button to the form, then bind to $(document).on("submit", "#myForm", .... In that, I prevent the default submit action (e.preventDefault() assuming your event is e), do my validation, and then submit.
A simplified version of this would be as follows:
$(document).on("submit", "#login-form", function(e) {
e.preventDefault(); // don't actually submit
// show applicable progress indicators
$("#login-submit-wrapper").addClass("hide");
$("#login-progress-wrapper").removeClass("hide");
// simple validation of username to avoid extra server calls
if (!new RegExp(/^([A-Za-z0-9._-]){2,64}$/).test($("#login-username").val())) {
// if it is invalid, mark the input and revert submit progress bar
markInputInvalid($("#login-username"), "Invalid Username");
$("#login-submit-wrapper").removeClass("hide");
$("#login-progress-wrapper").addClass("hide");
return false;
}
// additional check could go here
// i like FormData as I can submit files using it. However, a standard {} Object would work
var data = new FormData();
data.append("username", $("#login-username").val());
data.append("password", $("#login-password").val()); // just some examples
data.append("captcha", grecaptcha.getResponse());
$.ajax("handler.php", {
data: data,
processData: false, // prevent weird bugs when submitting files with FormData, optional for normal forms
contentType: false,
method: "POST"
}).done(function(response) {
// do something like redirect, display success, etc
}).fail(function(response) {
var data = JSON.parse(response.responseText); // parse server error
switch (data.error_code) { // do something based on that
case 1:
markInputInvalid($("#login-username"), data.message);
return;
break;
case 2:
markInputInvalid($("#login-password"), data.message);
return;
break;
default:
alert(data.message);
return;
break;
}
}).always(function() { // ALWAYS revert the form to old state, fail or success. .always has the benefit of running, even if .fail throws an error itself (bad JSON parse?)
$("#login-submit-wrapper").removeClass("hide");
$("#login-progress-wrapper").addClass("hide");
});
});