Alert toggles every time when the input is changed - javascript

I have input and it toggles a function if it's been changed. I also have table that is created dynamically. And each row in table has an addButton. So, the problem is that this alert toggles so many times so I change the input, but I need to toggle it only once. How to deal with it?
$('.inputsearchform').bind('input', function() {
var addButton = $(".fa.fa-plus");
addButton.click(function() {
alert("test");
});
});
I don't need to add click event to this button, but I need to get onclick() event from it. But this code is only working way, that I found. By the way, I need to get this event only if button is clicked, not every time that I change input.
Question How to check onclick event on button, that appears dynmically, when the input changes?
I tried to add onclick event <i class="fa fa-plus" onclick="addButtonF()">
and in js file: function addButtonF(){
alert("test");
}
but I have an error addButtonF is not defined.

A start would be to define click outside of input handler to prevent multiple click handler calls at each click of addButton
So, the problem is that this alert toggles so many times so I change
the input, but I need to toggle it only once.
Not clear from Question which element needs to be toggled once, or which function should only be called once ?
addButton appears only if I write something in input. I need to use
alert only if I click on this button, not every time that I change
input.
Use event delegation to attach event to dynamically created elements having className .fa.fa-plus
$(".inputsearchform").bind("input", function() {
// create dynamic element
$("<table class='fa fa-plus'>")
.html("<tr><td>"
+ $(".fa.fa-plus").length
+ "</td></tr>"
).appendTo("body");
});
$(document).on("click", ".fa.fa-plus", function() {
alert("test");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<input type="text" class="inputsearchform">
Substitute className for class which does not set className of element; use latest version of jQuery
$(".inputsearchform").bind("input", function() {
var div = document.getElementById("div");
var table = document.createElement("table");
div.appendChild(table);
var tr = document.createElement("tr");
table.appendChild(tr);
var td = tr.insertCell(0);
td.innerHTML = "test";
td.className = "try"
});
$(document).on("click", ".try", function() {
alert("test");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<input type="text" class="inputsearchform">
<div id="div"></div>
jsfiddle https://jsfiddle.net/1x8ja6qe/2/

Related

click function triggered from div

I have got a button wrapped inside a div.
The problem is that if I click the button, somehow the click function is triggered from the div instead of the button.
Thats the function I have for the click event:
$('#ButtonDiv').on('click', '.Line1', function () {
var myVariable = this.id;
}
Thats my HTML (after is is created dynamically!!):
<div id="ButtonDiv">
<div class="Line1" id="Line1Software">
<button class="Line1" id="Software">Test</button>
</div>
</div>
So now myVariable from the click function is 'Line1Software' because the event is fired from the div instead of the button.
My click function hast to look like this because I am creating buttons dynamically.
Edit:
This is how I create my buttons and wrapp them inside the div
var c = $("<div class='Line1' id='Line1Software'</div>");
$("#ButtonDiv").append(c);
var r = $("<button class='waves-effect waves-light btn-large btnSearch Line1' id='Software' draggable='true'>Software</button>");
$("#Line1Software").append(r);
You code with the example html actually fires twice, once for each element since the event will bubble up and match both elements (since they are .Line1)
If you are trying to add an event listener to the button you should probably be using $('#Software') instead of $('#ButtonDiv')
The real problem is that neither the div nor the button have an id.
You code with the example html actually fires twice, once for each element since the event will bubble up and match both elements (since they are .Line1)
If you only want it to match the innermost element, then use return false to stop the bubbling.
$('#ButtonDiv').on('click', '.Line1', function () {
var myVariable = this.id;
console.log(myVariable);
return false;
});
var c = $("<div class='Line1' id='Line1Software'></div>");
$("#ButtonDiv").append(c);
var r = $("<button class='waves-effect waves-light btn-large btnSearch Line1' id='Software' draggable='true'>Software</button>");
$("#Line1Software").append(r);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ButtonDiv">
</div>
Your question is a bit odd because you give yourself the answer... Look at your code, you are explicitly using event delegation:
$('#ButtonDiv').on('click', '.Line1', function () {
var myVariable = this.id;
});
This code means that, for each click on a .Line1 element, the event will be delegated to the #ButtonDiv element (thanks to bubbling).
If you do not want this behavior, just do that:
$('.Line1').on('click', function () {
var myVariable = this.id;
});
This is also correct:
$('.Line1').click(function () {
var myVariable = this.id;
});

Jquery: After removing content with a click how do I reset the button with the one I triggered the add function?

So I have this function where I add content on click to a "Favorites page", but when I click the button to remove it from the Favorites tab it removes the content but the button on the main page does not reset, the question is, how do I reset the button to it's original state after clicking the "Unfavorite" button?
https://jsfiddle.net/yjL7L6g7/3/
$(document).ready(function() {
$('button').click(function() {
if ($(this).html() == 'Favorite') {
var $favorited = $(this).parent().parent().parent().clone();
$(this).html('Favorited');
$favorited.find('button').html('Unfavorite');
$($favorited).click(function() {
$(this).remove();
});
$('#favorites').append($favorited);
}
});
});
And my second question related to this code is, how do I add a button to be on the same row with the content that is being added to the "Favorites"? I tried a simple .append(); but it did not suffice as the button got placed in a new row, will .css() suffice?
The questions might be stupid but I am still on my first steps in learning jquery
I'd avoid cloning if possible because there are simpler ways to do what you're trying to do. The code below will create a new button and add it to your favorites page. It will also attach an event to the Remove button to change the text of the Favorited button as well as remove itself after being clicked.
$(document).ready(function () {
$('button').click(function () {
if ($(this).html() == 'Favorite') {
var that = this;
$(this).html('Favorited');
var id = $(this).attr('id');
$('#favorites').append('<button id="' + id + 'Remove" class="ui-btn">Remove</button>');
$('#' + id + 'Remove').click(function () {
$(this).remove();
$(that).html('Favorite');
});
}
});
});
As for your second question, there is CSS that allows elements to live on the same line. For example, if you have two buttons that you want on the same line, it would look something like this:
<button style="display: inline;">Button1</button>
<button style="display: inline;">Button2</button>
Let me know if you have any questions.

How to corectly bind events in a loop

On a page I have couple of divs, that look like this:
<div class="product-input">
<input type="hidden" class="hidden-input">
<input type="text">
<button class="remove">X</button>
</div>
I'm trying to bind an event to that remove button with this code (simplified):
$('.product-input').each(function() {
product = $(this);
product_field = product.find('.hidden-input');
product.on('click', '.remove', function(event) {
product_field.val(null);
});
});
It works perfectly when there is only one "product-input" div. When there is more of them, all remove buttons remove value from the hidden field from the last product-input div.
https://jsfiddle.net/ryzr40yh/
Can somebody help me finding the bug?
You dont need to iterate over the element for binding the same event. you can rather bind the event to all at once:
$('.product-input').on('click', '.remove', function(event) {
$(this).prevAll('.hidden-input').val("");
});
If the remove buttons are not added dynamically, you will not need event delegation:
$('.remove').click(function(event) {
$(this).prevAll('.hidden-input').val("");
});
Working Demo
You need to declare product and product_field as local variables, now they are global variables. So whichever button is clicked inside the click handler product_field will refer to the last input element.
$('.product-input').each(function() {
var product = $(this);
var product_field = product.find('.hidden-input');
product.on('click', '.remove', function(event) {
product_field.val(null);
});
});
Demo: Fiddle
But you can simplify it without using a loop as below using the siblings relationship between the clicked button and the input field
$('.product-input .remove').click(function () {
$(this).siblings('.hidden-input').val('')
})
Demo: Fiddle

how to judge which button has been clicked using there className instead of ID

I have 100 buttons in a table having same class name but different id c-1,c-2,....,c-n <input type="button" class="btn-c" id="c-1" value="ADD">
how will i Know which button has been clicked using their className and whithout using onclick event on the each button
<input type="button" ... onclick="call_function(this);"
for simplicity let say I want to alert(button.id); on the click of any of the 100 buttons
If you have so many buttons, it makes sense to use event delegation:
$('table').on('click', '.btn-c', function() {
alert(this.id); // will get you clicked button id
});
This is optimal approach for performance standpoint as you bind only one event handler to parent element and benefit from child element event bubbling.
UPD. This is pure javascript version of the same code:
document.getElementById('table').addEventListener('click', function(e) {
if (/\bbtn-c\b/.test(e.target.className)) {
alert(e.target.id);
}
}, false);
Demo: http://jsfiddle.net/zn0os4n8/
Using jQuery - attach a click handler to the common class and use the instance of this to get the id of the clicked button
$(".btn-c").click(function() {
alert(this.id); //id of the clicked button
});
You need to attach an event to a parent element and listen for the clicks. You can than use the event object to determine what is being clicked on. You can check if it is the element you want and do whatever you want.
document.body.addEventListener("click", function (e) { //attach to element that is a parent of the buttons
var clickedElem = e.target; //find the element that is clicked on
var isC = (clickedElem.classList.contains("c")); //see if it has the class you are looking for
var outStr = isC ? "Yes" : "No"; //just outputting something to the screen
document.getElementById("out").textContent = outStr + " : " + clickedElem.id;
});
<button class="d" id="b0">x</button>
<button class="c" id="b1">y</button>
<button class="c" id="b2">y</button>
<button class="c" id="b3">y</button>
<button class="d" id="b4">x</button>
<div id="out"></div>
Note: this is not going to work in older IEs without polyfills.

Why doesn't javascript function update DOM on first run

I have a dynamic form in which users can add inputs by clicking a button. This works fine. However when clicking to remove the input the first click does not remove an input. Every click after removes inputs as expected. I can see that it runs the function on first click to remove but nothing is updated in the DOM so the field stays. Here is my HTML:
<button onclick="AddFileField()">Add File</button>
<br />
<br />
<form action="" method="post" enctype="multipart/form-data">
<div id="fileFields"></div>
<br />
<input type="submit" value="Upload" />
</form>
And the associated javascript:
function removeField() {
$('.removeclass').click(function () {
$(this).parent().remove();
});
return false;
}
var FieldCount = 1; //to keep track of text box added
function AddFileField() {
var MaxInputs = 10; //maximum input boxes allowed
var InputsWrapper = $("#fileFields"); //Input boxes wrapper ID
var x = $("#fileFields > div").length + 1; //current text box count
if (x <= MaxInputs) //max input box allowed
{
$(InputsWrapper).append('<div class="fileInp"><label for="file' + FieldCount + '">File:</label><input type="file" name="files" class="inpinl" id="file' + FieldCount + '" />×</div>');
FieldCount++;
}
return false;
}
A fiddle showing issue. To duplicate add a couple fields then click an x. The first click does nothing, then proceeding clicks removes fields. How can I get the first click to remove the field as well?
It's because you are registering your event handler inside of another event handler.
http://jsfiddle.net/3e1ajtvo/11/
I removed your event handler and now, you pass the clicked element as elem into the function itself.
As a matter of fact you don't even really need the function, as long as jquery is exposed (it is in your case).
http://jsfiddle.net/3e1ajtvo/12/
A working fiddle is here
The issue lies in the function:
function removeField() {
$('.removeclass').click(function () {
$(this).parent().remove();
});
return false;
}
When you click the X, this function is called, which adds a click event handler to the X to remove it; however, this event handler is not called until the next time you click it. (This is why clicking X twice works).
In the updated fiddle, you simply pass this to removeField as such:
//HTML
×</div>
//JS
function removeField(me) {
$(me).parent().remove();
return false;
}
The reason for this is because you are using onclick="removeField()".
Lets take a look at your function. When you click on the remove button the following script will run. This script then creates a click handler, that will activate on next click, because when you first clicked on remove the handler was not created
function removeField() {
$('.removeclass').click(function () {
$(this).parent().remove();
});
return false;
}
So you will need to replace this is another function. Since you are using jQuery you can learn to use .on() for dynamically generated elements.
$(document).on('click', '.removeclass', function () {
$(this).parent().remove();
});
http://jsfiddle.net/Spokey/3e1ajtvo/16/
I made your code a bit more modular and changed it to use jQuery more than you were. This is just another way to do it, the other answers are also valid.
http://jsfiddle.net/3e1ajtvo/19/
var fields = {
btnAdd: $('#addField'),
inputWrapper: $('#fileFields'),
maxInputs: 10,
fieldCount: 1,
init: function(){
this.inputWrapper.on('click', '.removeclass', this.removeInput);
this.btnAdd.on('click', this.appendField);
},
removeInput: function(){
//this will refer to the html element you clicked on
$(this).parent().remove();
},
appendField: function(){
//this will refer to the html element you clicked on
if ( fields.inputWrapper.children('div').length <= fields.maxInputs ){
fields.inputWrapper.append('<div class="fileInp"><label for="file' + fields.fieldCount + '">File:</label><input type="file" name="files" class="inpinl" id="file' + fields.fieldCount + '" />×</div>');
fields.fieldCount++;
}
}
};
fields.init();
You're not executing the code to remove the row on the first click, you're just adding the click handler to the link. It works after that because the $('.removeclass').click(... then fires as expected.

Categories