I am using Jquery and Ajax for performing the action, I need after loading complete page, a code click on the every button automatically.
I used the following javascript code for click all the buttons in the end of my page. but it is not working.
<script type='text/javascript'>
document.getElementByClassName('sub').click();
</script>
Structure of my Page code
[JQuery]
[PHP]
[HTML]
[Javascript]
I set all the buttons type as "BUTTON", When I set
type="submit"
The Autoclick code only work on the first button, but with the "button" type it is not working with any of them.
If I click manually on that buttons they are working properly.
Please give any suggestion. Thank You.
Youre using the wrong function. Elements is plural in that method.
document.getElementsByClassName('sub');
Additionally, calling click on this NodeList will not work. You need to loop through and call the event on each index.
Also, you say you're using jQuery. To ensure your call happens after DOM ready, wrap your JS with $().ready().
Last, use the tools you've provided yourself, in this case jQuery, and select your element that way.
$(document).ready(function(){
$(".sub").click()
});
In jQuery you can trigger the click like
$( ".sub" ).trigger( "click" );
Because you retrieve a NodeList(as pointed out in the comments) :
$(document).ready(function () {
var butEl = document.getElementsByClassName('sub'),
count = butEl.length;
for (i = 0; i < count; i++){
butEl[i].click();
}
});
Also is getElementsByClassName
If you're trying to click on multiple different form submit buttons, it makes sense that the browser will POST for only one of them - one page can't simultaneously navigate to multiple different URLs.
Similarly, when you change type to button, none of the forms will be submitted, even though you're clicking on the buttons.
If you know what you're doing, you could always add submit event handlers to all of your forms, and submit them via ajax requests instead - which should allow multiple of them to be processed. Note you may need to work out some extra logic for displaying success/failure for each form to the user since the browser won't navigate you to any of the existing "submitted" pages.
$(document).on('submit', 'form', function() {
$.ajax({
url: $(this).attr('action'),
type: $(this).attr('method'),
dataType: 'json',
data: $(this).serialize(),
success: function(data) {
// Add logic here for handling success for each form, if required
},
error: function(xhr, err) {
// Add logic here for handling errors for each form, if required
}
});
return false; // To stop the browser processing this form
});
With this method, your first attempt with type="submit" buttons should work - however I would encourage you to be as specific as possible with your element selectors for both the forms and the buttons you're trying to target.
Related
I'm facing a sort of dummy problem.
On my site there is an order form (simple html form) and I noticed that I get double commands from time to time.
I realized that if I clicked repeatedly few times the submit button (before the action page is loaded) I got as many commands as I have clicked.
So I wonder if there are simple solution to make form submission asyncronous?
Thanks
P.S. I added JQuery UI dialog on submit "wait please..." but I get still double commands.
UPDATE
As GeoffAtkins proposed I will:
disable submit after dialog is shown
make use of unique form's token (as it is already added by Symfony) Do not use Symfony token as unique form token as it is always the same for current session. Use just random or something like that.
I would consider doing this (jQuery since you said you used that)
$(function() {
$("#formId").on("submit",function() {
$("#submitBut").hide();
$("#pleaseWait").show();
});
});
if you submit the form and reload the page.
If you Ajax the order, then do
$(function() {
$("#formId").on("submit",function(e) {
e.preventDefault();
var $theForm = $(this);
$("#submitBut").hide();
$("#pleaseWait").show();
$.post($(this).attr("action"),$(this).serialize(),function() {
$theForm.reset();
$("#submitBut").show(); // assuming you want the user to order more stuff
$("#pleaseWait").hide();
});
});
});
NOTE that disabling the submit button on click of the submit button may stop the submission all together (at least in Chrome): https://jsfiddle.net/mplungjan/xc6uc46m/
Just disable the button on click, something like:
$("#my-button-id").on("click", function() {
$(this).attr("disabled", "disabled");
});
var bool = true;
function onclick()
{
if(bool)
{
//do stuff
bool = false;
}
else
{
//ignore
}
}
You could disable the button on the form when it is clicked, and then continue to perform the action. You would probably change the text to say "loading..." or some such.
You may also want to re-enable the button on fail or complete of the ajax request.
I've done this many times similar to this: https://stackoverflow.com/a/19220576/89211
For example, there is an input field. Every time a user types a key into that field, it sends an AJAX request with whatever text is currently in that input, and does something with it. I've looked into the change and keyup functions in Jquery, but when I try them in Jsfiddle they don't do anything. Is there a standard way of doing this type of operation? I know its common for validations and stuff.
<form>
<input id="test" type='text' >
<input type="submit" value="asdf">
</form>
$('input').on("change",(function(e){
alert("Hello");
});
The effect I am going for is like this game www.sporcle.com/games/g/nflteams#
You can type in any text and if its within the set of correct answers then the table will update to show that answer. You never have to submit. How do you suppose they achieved this effect?
It seemed to me like they must be querying the database every time a user enters a key, to see if it is a correct answer. If it is they update the table to display the answer. What are other ways to do this?
sending a request on each change is just bad, delay the ajax on the last change
var changeTimer = false;
$("your inputs").on("your change event",function(){
if(changeTimer !== false) clearTimeout(changeTimer);
changeTimer = setTimeout(function(){
/* your ajax here */
changeTimer = false;
},300);
});
I'd probably do something similar to this.
you'd have to add some extra code to handle dropdowns, but the idea is the same.
$('form input').keyup(function () {
$.ajax({
type: "POST",
url: url,
data: data,
success: success,
dataType: dataType
});
});
Just make an $.ajax() call every time the change event is fired! Like so:
$(document).on('keydown','input',function(){
$.ajax({
// options here
});
});
Whilst the above will help achieve what you want, I must advise that it is not great practice to fire off constant AJAX requests as this can put a huge load on the server if you have a lot of traffic. You would be better off either validating every n seconds, or validating client side, or validating on submission...
UPDATE
It appears you do not want to catch the change event, you would like to know when anything is entered. Resultantly, I have changed my code to catch the keydown event. This will fire whenever a key is pressed down whilst focused on an input.
$('#yourInputId').keyup (function () {
$.post('http://yoururl.com', { value: $(this).val() }).done(function (data) {
$('#feedbackDivId').html(data);
});
});
So let me describe standard situation: there's a form with multiple inputs (about 60-70). Each inputs needs to be validated. If its not valid it returns false. I need to protect form from multiclicking(multisubmitting) to prevent multiple AJAX requests with graphical feedback.
My solution is to invoke custom document event before AJAX request is sent which instantly creates div with width and height 100%, z-index 9998 which contains loading gif and some message. And on completion of AJAX request invoke another, which simply removes that element from DOM.
My question is: is that a valid solution? I mean, its a lot of form inputs and validation may be slower on older computers, which means it can take some time, before shield div is appended to the body and protects form from submitting. Can I simply listen to function and detect whether it returns something or not? In case of deffer my understanding that I need to resolve every time before it returns a value, which means 60-70 new lines of code, which is messy and undesirable.
Is there someone, who faced this problem before and resolve it with 100% accuracy and grace?
Don't rely on a "shielding div" to prevent muliple submits. Just hook into the submit event of the form check before submitting:
$('#myForm').submit(function() {
if (!stillValidating())
//submit form
else
//handle however you deem necessary.
});
you first need to stop default behaviour on form submit then u have to check whether form input is valid , if yes then it goes to ajax call .
$('#form').submit( function(e){
e.preventDefault();
var $form = $(this);
// check if the input is valid
if(! $form.valid()) return false;
$.ajax({
type: 'POST',
url: 'add.php',
data: $('#form').serialize(),
success: function(response) {
$("#answers").html(response);
}
});
});
I'm trying to create a simple file upload form for my website. I'm using a hidden iFrame to do it "ajax" style so I can have a user upload files one after another using the same form.
Right now I have a form with an <input type="file" />. What I have happening is when the input field changes(user selects a file) it should submit the form with the target set to the iFrame which loads a php script and then reset the input field to allow the user to upload again. What seems to happen is the form gets submitted based on the amount of times the form was submitted. e.g if you press the button when the page loads it will submit one time, however if you press the button again(without reloading the page) it will submit two times, and when you press the button for a third time it will submit the form three times and so on.
Here is my javascript for when the input changes
newupload is the id of the input
newimgform is the id of the form
postframe is the id of the iframe
$("#newupload").change(function() {
var max = 5242880, iframe = $("#postframe"), iframeContents;
$('#newimgform').attr("action", "uploadPicture.php")
$('#newimgform').attr("method", "post")
$('#newimgform').attr("MAX_FILE_SIZE", max)
$('#newimgform').attr("enctype", "multipart/form-data")
$('#newimgform').attr("encoding", "multipart/form-data")
$('#newimgform').attr("target", "postframe")
$('#newimgform').submit();
$("#postframe").load(function() {
iframeContents = jQuery.parseJSON($(this.contentDocument).find('body').html());
alert(iframeContents.filename);
$("#newimgform")[0].reset();
});
});
I looked for anyone else trying this and I've seen some answers on here that talk about the submit is being bound multiple times and I need to use unbind like $('#newimgform').unbind("submit").submit(); but that doesn't seem to do anything. I can't use any flash uploaders or anything so this has to be pure html/javascript/php.
You can move out the iframe load handler because it need not be added every time you upload a file. And also you can optimize your code like this.
$("#newupload").change(function() {
$('#newimgform').attr({
action: "uploadPicture.php",
method: "post",
MAX_FILE_SIZE: 5242880,
enctype: "multipart/form-data",
encoding: "multipart/form-data",
target: "postframe",
}).submit();
});
$("#postframe").load(function() {
var iframeContents = jQuery.parseJSON($(this.contentDocument).find('body').html());
alert(iframeContents.filename);
$("#newimgform")[0].reset();
});
Bind the load event handler outside the change event handler. As it is, everytime you change the value of #newupload, a new event handler is bound to the #postframe element:
$("#postframe").load(function() {
var iframeContents = jQuery.parseJSON($(this.contentDocument).find('body').html());
alert(iframeContents.filename);
$("#newimgform")[0].reset();
});
$("#newupload").change(function() {
$(this).attr("action", "uploadPicture.php")
.attr("method", "post")
.attr("MAX_FILE_SIZE", 5242880)
.attr("enctype", "multipart/form-data")
.attr("encoding", "multipart/form-data")
.attr("target", "postframe")
.submit();
});
You could alternatively unbind the load event handler each time it runs, but this seems unnecessary in your case. $(this).unbind('load'); is all you would have to add to the load event handler.
Also you can optimize this, a lot. You are using the same selector over and over, when in jQuery we chain function calls.
I'm using buttons to submit data via Ajax. I'm using jQuery to disable and enable the buttons. This is to prevent "button-mashing," where a user can fire multiple requests either maliciously or unwittingly.
Is there an "element-agnostic" way to prevent this behavior in jQuery? For example, say I wanted to use anchors instead of buttons to submit the data. A button I can disable; but as far as I know you can not disable anchors.
Here is how I'm doing this now: (note I've removed some of the unnecessary code to make it shorter)
$('.fav .button').click(function() {
$.ajax({
context: this,
dataType: 'json',
beforeSend: function() {
// Toggle state; disable button to prevent button mashing
$(".fav").toggleClass("fav-state-1");
$(".fav .button").attr("disabled", true);
},
error: function() {
// Rollback state and re-enable button on error
$(".fav").toggleClass("fav-state-1");
$(".fav .button").attr("disabled", false);
},
success: function(response) {
if (response.result == "success") {
$(".fav .button").attr("disabled", false);
}
else {
// Rollback state; re-enable button
$(".fav").toggleClass("fav-state-1");
$(".fav .button").attr("disabled", false);
}
}
});
return false;
});
HTML:
<input class="button" type="button" value="">
Of course, the best way to do this would be to handle it gracefully on the server side.
That said, you could use the data storage methods in jQuery to store a value to indicate it has already been clicked, and use that to determine if the user has already clicked/pressed the button. The values get stored per selector, so you can set it on anything.
$("a").click(function(e) {
e.preventDefault();
if (!$(this).data('isClicked')) {
var link = $(this);
// Your code on successful click
// Set the isClicked value and set a timer to reset in 3s
link.data('isClicked', true);
setTimeout(function() {
link.removeData('isClicked')
}, 3000);
} else {
// Anything you want to say 'Bad user!'
}
});
The benefit is that you're not stopping the user from clicking anything else, as it's a per element solution. In your case, you might want to do the link.removeData in the success function.
Example of it working: http://jsfiddle.net/jonathon/ke8Az/ (Note that if you try to click again within the 3s, you get the 'Please wait' but you can still click the rest)
Note: This is a client side solution only. And only if they have JavaScript installed. Unless you handle it on the server side, the user can maliciously send multiple requests. This just helps with the 'unwittingly' part.
Before the ajax call you could unbind the click event on the clicked object, then in the success / error method you could rebind the click event.
That way they can mash the button as much as they want but it wont have the click wired up until the call has finished.
You could do the following:
setup a variable clickedWithinLastSecond.
in the method that fires the request, check if it is true, if it is then don't send the request
If it is not send the request and set the variable to true. Setup a method that fires after a second with setTimeout that changes the variable back to false.
you will have to customize variable name to your needs, and you will need to find a way to keep the variable in the correct scopes, but that is not difficult.
The best and only way to stop the behavior you are describing is on the server side.
You can also use debounce to register only one click. Both underscore.js and lodash.js provide this handy method.
Here's a fiddle to demo the concept. With lazyClick, you can double/triple click on the link yet the event handler is fired only once.
var lazyClick = _.debounce(onclickHandler, 500);
function onclickHandler(e){
e.preventDefault();
console.log('clicked');
}
$(function(){
// uncomment this and you will see double clicks are being registered.
//$('#btn').click(onclickHandler);
// with debounce, only one click will be registered
$('#btn').click(lazyClick);
});