Fancybox form ajax submit, only one ajax request - javascript

I've a question about ajax submitting.
I have a html form
<div style="display:none">
<form id="myform" method="post" action="">
<input type="text" id="name" />
<input type="submit" id="sbmt" />
</form>
</div>
And button to open the fancybox:
<a id="sbtfancybox" href="#myform">
<input type="button" value="Add new"
onClick="defineFancybox();" />
</a>
And i define a fancybox with jquery:
<script type="text/javascript">
function defineFancybox() {
$('#sbtfancybox').fancybox({
//...some json parameters
});
$('#myform').submit(function() {//the main problem is here
//....calling an ajax
return false;
});
}
</script>
My question is that how to do $('#myform').submit(..) that the submit always is called once, not that if i open fancybox the first time, the $('#myform').submit() is called once, if i open the fancybox the second time, the $('#myform').submit() is called twice, if i open the fancybox the third time then $('#myform').submit() is called tree times etc.
Thank you

jQuery event handlers don't override each other, even in the case where you're binding the same function again. Every time you call this code:
$('#myform').submit(function() {//the main problem is here
//....calling an ajax
return false;
});
another event handler gets added. Since that code is in the function that is called when you click on your button, the first click results in one event handler. The second click adds another one, so you now have two. The third click adds another, so you have three...
Since the form doesn't appear to be dynamically created you can just bind the single event handler when the page loads:
$(document).ready(function() {
$('#myform').submit(function() {
//....calling an ajax
return false;
});
});
Then move it out of the defineFancybox() function.
If you absolutely have to keep the event handler binding inside that function, then you can use the .off() (or .unbind() if you're using a version prior to 1.7) function to remove any existing event handlers before binding the new one:
$('#myform').off('submit').submit(function() {
//....calling an ajax
return false;
});

Have you tried with .one() handler:
$('#myform').one('submit', function() {//This will make it submitted once
//....calling an ajax
return false;
});

You can do something like
$('#myform').unbind('submit');
$('#myform').bind('submit',function() {//the main problem is here
//....calling an ajax
return false;
});

You may try the following
$("#myform").each(function(i) {
var handler = i.on("submit", function() {
handler.stop();
// do stuff
});
// other stuff
});

Related

Refresh javascript's function without using Recursion

I'm trying to create a simple form where i can add more text field after current text field.
And also i can add more field from the new field that ive added before (im using Recursion for this).
Problems come when i click the add on the first field, it creates more then 1 new fields (this happens because of recursion)
how do i refresh javascripts function without calling it again and again?
HTML :
<div class="line-input">
<input type='text' class='ipt-txt'>
<input type='submit' class='btn-smt' value="add new">
</div>
JS :
$(document).ready(function(){
callFunction();
});
function callFunction(){
$(".btn-smt").click(function(e){
$(this).parent(".line-input").clone().insertAfter($(this).parent(".line-input"));
callFunction();
});
};
JSFiddle : https://jsfiddle.net/1uofya3k/
Thanks!
Use event delegation:
$(function() {
$(document).on("click", ".btn-smt", function(e) {
$(this).parent(".line-input").clone().insertAfter($(this).parent(".line-input"));
});
});
That sets up an event handler at the document level that responds to clicks on your button class. You only have to add it once, and it'll work for all subsequent elements that are added dynamically.
(You don't really even have to do it in a "ready" handler; you can set it up before the DOM has been completed.)
Add true to the clone() function. From the jQuery API:
withDataAndEvents (default: false) Type: Boolean A Boolean indicating
whether event handlers should be copied along with the elements. As of
jQuery 1.4, element data will be copied as well.
https://api.jquery.com/clone/
$(document).ready(function() {
callFunction();
});
function callFunction() {
$(".btn-smt").click(function(e) {
e.stopPropagation();
$(this).parent(".line-input").clone(true).insertAfter($(this).parent(".line-input"));
});
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="line-input">
<input type='text' class='ipt-txt'>
<input type='submit' class='btn-smt' value="add new">
</div>

Event call multiple time after ajax replace element

I have an problem with Jquery event. Jquery Event was call multiple time after I replace that element with another element but same type and same id.
// 1. ajax call success and replace my block
// 2. This is my event that I want it happen.
$(document).on("click", ".polaroid button.addImage", function(event) {
event.preventDefault();
// trigger browse file to upload
$(event.target).closest("div.polaroid").find("input[type=file]").trigger("click");
});
This code was used to resold event was call after AJAX success. So, why is button.addImage with event click called many times at the same time AJAX is called?
This is html:
<div class="col-md-3 polaroid">
<img src="images/ingredient/default_img.png" title="Main image" />
<input type="file" name="file-image" style="display:none"/>
<button type="button" data-toggle="tooltip" title="Add" class="btn addImage"><i class="glyphicon glyphicon-plus icon-plus"></i></button>
</div>
You most likely are loading this script again or calling a function that adds this event handler again
The best fix is to find where this event handler is being called again.
A workaround would be to namespace the event and always remove the event handler using off() before adding it again
$(document)
.off('click.polaroid')
.on("click.polaroid", ".polaroid button.addImage", function(event) {
// other code
});
use one()
$(document).one("click", ".polaroid button.addImage", function(event) {
Thanks. I found answer. that is use "off" before "on", like this:
I update the answer of Mr.charlietfl.
$(document)
.off('click',".polaroid button.addImage")
.on("click", ".polaroid button.addImage", function(event) {
event.PreventDefault();
// other code
});

Can't detect changed id

When I change the id of a button I cannot find the new id with on.("click"). The function console.log() does detect that it's changed but I cannot detect it with the on() function.
HTML:
<form id="formName" action="" method="post">
<input type="submit" id="submitBtn" value="Submit" />
</form>
<button id="change">Change</button>
JS:
$("#change").on("click", function(){
$("#submitBtn").attr("id", "NewBtn");
});
$("#formName").submit(function(e){
e.preventDefault();
});
$("#NewBtn").on("click", function(){
alert("Hello");
});
So I need it to alert "Hello" after I have clicked on change. It does change the id I checked that with inspect element.
Fiddle: http://jsfiddle.net/WvbXX/
Change
$("#NewBtn").on("click", function(){
to
$(document).on("click", "#NewBtn", function(){
The reason for this is that you're wanting to use the delegate form of .on(). This call is a little different in that it takes a "string" as the second parameter. That string is the selector for your "dynamic" element while the main selector need either be a parent container (not created dynamically) or the document itself.
jsFiddle
you are setting onclick event for newBtn on load of page for the first time but unfortunately newBtn not available that time. hence after changing the id it will not trigger onclick function for newBtn.
you can do one thing to make it work, set onclick event for newBtn inside the same function where you are changing the id like below.
$("#change").on("click", function(){
$("#submitBtn").attr("id", "NewBtn");
// set on click event for new button
$("#NewBtn").on("click", function(){
alert("Hello");
});
});
.attr() function does not have a callback and thus it cannot be checked unless you setup an interval using setInterval but the function itself executes pretty soon so you are not going to need it.
For solving the problem in hand event delegation proposed by tymeJV is the right way to do it.

why jquery detach element will cause a form to submit?

i wonder why in the following example, trying to detach an element (li) causes the form containing it to submit
html
<form id="frmToDo" name="frmToDo">
<p id="lineInput">
...
<input type="submit" id="btnSubmit" value="Add" />
</p>
<ul id="todolist">
<!-- added in ajax -->
</ul>
</form>
JS
$("#frmToDo").submit(function() {
// this runs after: $("#todolist").detach(...)
});
$("#todolist").delegate("li[id^=task-] button", "click", function() {
$("#todolist").detach($($(this).parent()).id());
return false;
});
I guess you just want to remove the li element in which the button was clicked.
So instead of using
$("#todolist").delegate("li[id^=task-] button", "click", function() {
$("#todolist").detach($($(this).parent()).id());
return false;
});
Try using
$("#todolist").delegate("li[id^=task-] button", "click", function() {
$(this).parent().detach();
return false;
});
That's not a button, it's an input element.
$("#todolist").delegate("li[id^=task-] input:submit", "click", function() {
I am not sure if this is the cause of your problem but you are not using the detach function correctly if your intention is to detach an li element. The argument of the detach function is a selector expression that filters the set of matched element in the jQuery element that you are calling the function on. In your code you call detach on $('#todolist'), which means you want to detach the todolist element, if it matches the argument passed.
You should do something like this instead :
$('#todolist li').detach(); //this will detach all the li elements
I am not sure if this can explain the fact that your form is submitting. If it is not : what event triggers the submit event of your form ? Maybe you use a button or input element that is placed inside the form and triggers the submit of the form ?
Unless there's some relevant code missing, you seem to assign a handler to the onclick event outside a $(document).ready() block. That makes it possible to run the assignment before the #todolist is loaded, thus failing to find the buttons and attach handlers.
With no event cancelling, the default behaviur for a button is to submit the form.
Try this:
$(document).ready(function(){
$("#frmToDo").submit(function() {
// this runs after: $("#todolist").detach(...)
});
$("#todolist").delegate("li[id^=task-] button", "click", function() {
$("#todolist").detach($($(this).parent()).id());
return false;
});
});

jQuery ajax defined actions

When I'm loading some content through ajax it returns an jQuery .click event and some elements. But when the ajax content is loaded a couple of times and I click the the button that is bound to the .click event, the action is executed a couple of times.
For example the ajax content is:
<script type="text/javascript">
$('#click').click(function() { alert('test') });
</script>
<input type="button" id="click" value="click here">
If this is refreshed 5 times and I click the button I will get 5 alert boxes.
Is there a workaround for this?
You can use the unbind function just before the click, something like this:
$('#click').unbind('click').click(function() { alert('test') });
That should let only one function associated with the click
The JQuery one method unbinds the handler after it is invoked:
$('#click').one("click",function() { alert('test') });
More info:
http://docs.jquery.com/Events/one

Categories

Resources