jquery create and delete input fields - javascript

I wrote this code here:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"> </script>
</head>
<body>
<button id="add_field">Noch ein Inputfeld</button>
<hr>
<div class="input_fields">
</div>
<script>
$(function(){
var number = 1;
$("#add_field").click(function(){
if(number < 11){
var name = "input";
name = name + number;
$(".input_fields").append('<a>'+ number +':</a><input type="text" name="' + name + '" />entfernen<br>');
number++;
}
else{
alert("10 ist Max");
}
});
$(".remove_field").click(function(){
$(this).parent('input').remove();
x--;
});
});
</script>
</body>
I can create input fields, but if i press on the loeschen Button, nothing happens. So i think here is a mistake in this function:
$(".remove_field").click(function(){
$(this).parent('input').remove();
x--;
});

Try something like this:
$('.input_fields').on('click', '.remove_field', function(){
$(this).parent('input').remove();
x--;
});
You need to use the delegate pattern for the event handler.
You might also be interested in:
Your fiddle fixed (note that you need to re-do the logic for displaying numbers if you want them to handle inputs getting removed from the middle)
https://developer.chrome.com/devtools/docs/javascript-debugging
JQuery event handlers not firing
https://api.jquery.com/on/

You need to use event delegation for attaching events to dynamically added elements:
$("body").on("click",".remove_field",function(){
$(this).parent('input').remove();
number--;
});
Working Demo

Related

Jquery checkbox to hide or display an element

I want to use jquery to always hide an element when it is checked, and show the element when it is unchecked. After doing some research I found the "is" attribute and so I created a simple html file as:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
if($("#s").is(':checked'))
$("#test").hide(); // checked
else
$("#test").show();
});
</script>
</head>
<body>
<h2>This is a heading</h2>
<p id="test">This is a paragraph.</p>
<p id="test">This is another paragraph.</p>
<input type="checkbox" id="s">Click me</input>
</body>
</html>
Now for some reason, the jquery is not functional. Any help would be appreciated please. I also tried:
if(document.getElementById('isAgeSelected').checked) {
$("#txtAge").show();
} else {
$("#txtAge").hide();
}
And this doesn't work either.
This is simple in javascript. Please try the following:
var cb = document.getElementById('isAgeSelected');
var txtAge = document.getElementById('txtAge');
$(document).ready(function(){
cb.change= function(){
if(cb.checked) {
txtAge.style.display ='block';
} else {
txtAge.style.display ='none';
}
};
});
In JQuery, you can do the following:
$(document).ready(function(){
$('#s').on('change', function(){
if($(this).is(":checked")){
$('#txtAge').show();
}
else{
$('#txtAge').hide();
}
});
});
You are only checking the checkbox once after the DOM is ready instead you should do it on its change event
$("#s").change(function(){
if($(this).is(':checked'))
$("#test").hide(); // checked
else
$("#test").show();
});
You can do this using following jQuery onchange event and .checked function
$(document).ready(function(){
$('#s').change(function(){
if(this.checked)
$("#test").hide(); // checked
else
$("#test").show();
});
});
Working URL:: https://jsfiddle.net/qn0ne1uz/
Good question !
now you were almost there.
$(document).ready(function(){ // <= !! you only evaluete the chackbox once (on document ready)
if($("#s").is(':checked'))
$("#test").hide(); // checked
else
$("#test").show();
});
What you want to do is monitor checkbox the whole time, like so:
$('#s').bind('change', function() {
if ($("#s").is(':checked'))
$("#test").hide(); // checked
else
$("#test").show();
});
example on jsfiddle
I'm guessing you are wanting to use the jQuery when the checkbox changes - at the moment you are just changing the hide / show it when the document loads.
Also ids need to be unique or jQuery will only get the first item with that id it comes to when you use the id selector. Change the test id to a class.
If you want the click me to change the state of the checkbox, turn it into a label (think you had it as a button) and target the input (using either for="input-id or wrap the label around the input and the text)
Try the following:
// this is to go in your document ready
$('#s').on('change', function() { // bind to the change event of the chackbox
// inside any change event, this is the js object of the thing that changed (ie the checkbox)
if (this.checked) {
$('.test').hide();
} else {
$('.test').show();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>This is a heading</h2>
<!-- ids need to be unique so change this to a class or your jquery won't work -->
<p class="test">This is a paragraph.</p>
<p class="test">This is another paragraph.</p>
<input type="checkbox" id="s"><label for="s">Click me</label>

Jquery .on() not calling selector

I am trying to make the image of the mole clickable and once clicked will increase the score but the .on() will not work with the class name of the image. It will, however, work if I use the selector "#gamespace", but then clicking anywhere within the game space will get the player points rather than just clicking the mole.
<!DOCTYPE html>
<html>
<head>
<title>Whack-A-Mole (CSCI2447)</title>
<!-- CSS styles: This is for me to worry about; not you. -->
<link href="css/game.css" rel="stylesheet" />
<script src="js/jquery-2.2.1.min.js"></script>
<script type="text/javascript">
var score = 0
var time = 30
var t;
var moleRepeat;
$(document).ready(function(){
$('#start_button').click(function (){
start();
});
$('.mole').on('click' , function () {
counter();
});
});
function getYRandomNumber(){
return Math.floor((Math.random()*300)+0);
};
function getXRandomNumber(){
return Math.floor((Math.random()*600)+0);
};
function counter() {
score++;
$("#score").html(score + ' pts');
};
function start() {
$('#timer').show();
addMole();
decrement();
$('h1').css("color","purple");
$('#gamespace').css("background-color", "green");
};
function decrement() {
time--;
$('#timer').html(time + ' seconds left');
t = setTimeout('decrement()', 1000);
};
function addMole() {
$('#gamespace').append('<img class="mole" src="img/mole.png" onClick="counter()"/>');
moleRepeat = setTimeout('addMole()', 2000);
};
</script>
</head>
<body>
<div id="content">
<h1>Whack-A-Mole</h1>
<p>After clicking "start", you will have 30 seconds to click
as many moles as you can. The moles appear randomly so be ready! </p>
<div id="controls">
<span id="score">0 pts</span>
<button type="button" id="start_button">Start!</button>
</div>
<div id="timer">30 seconds left</div>
<div id="gamespace">
</div>
</div>
</body>
</html>
You are adding click event handler on .mole before it is appended to #gamespace and exist on the page, use event delegation instead
$('#gamespace').on('click','.mole' ,function () {
counter();
});
It looks like your trying to bind to the click event of '.mole' before any exist. Direct bindings only work for elements that already exist in the DOM. You could fix this by doing a delegate binding.
$('#content').on('click', '.mole', function(){ ... });
This will make it listen for the bubbled events from mole elements. Since it works with the bubbled events, it does not matter when they are created.

change the background of an id that is clicked

When one of the element(id) of a form is clicked, i would like to listen to that event, and change the background of that element.
$(document).ready(function(){
$('form').on('click', function(e){
var x = e.target.id;
$(x).css('background-color',color);
return false;
});
}
<form>
<div id="a">Item1</div>
<div id="b">Item2</div>
<div id="c">Item3</div>
</form>
Your code will end up looking for tag names because the selector is
$("b")
If you want to do it the way you have it, you would need to add the missing #.
$("#" + x).css('background-color',color);
But there is no need to look up the element when you already have a reference to is. Use event delegation and this
$('form').on('click', 'div', function(e){
$(this).css('background-color',color);
});
Why bother using e.target? Just update your code to use $(this):
$(function() {
$('form > div').on('click', function(e) {
e.preventDefault();
$(this).css('backgroundColor', color);
});
});
This will work out. Take care of your tags.
$(document).ready(function(){
$('form').on('click', function(e){
var x = e.target.id;
$("#"+x).css('background-color',"red");
return false;
});
});
The thing happening to you is that event.target.id returns a string representing the id of the element, not a selector. So where you use $(x).... you have to use $('#'+x), your actual code does not work because the selector for the background change is not looking for an element with the X value on the Id but for an element called like the value of X (eg. x="a", then it's looking for elements)
Here's my "lowly" try:
<!DOCTYPE html>
<html lang = 'es'>
<head>
<title> My Test </title>
</head>
<body>
<form>
<div id="a"> Item1 </div>
<div id="b"> Item2 </div>
<div id="c"> Item3 </div>
</form>
<script>
function addBackgroundColor(e){
var index = parseInt(Math.random() * 4); // the number of the multiplier has to be equal to the length of the array colorsList.
e.target.style.backgroundColor = colorsList[index];
}
var colorsList = ['blue','red','green','yellow','orange']; //add others colors here if you want.
var divsList = document.getElementsByTagName('div');
for (var i in divsList){
divsList[i].addEventListener('click', addBackgroundColor);
}
</script>
</body>
</html>
No need to go fancy. Just do
$(document).ready(function(){
$('form div').on('click', function(e){
$(this).css('background-color',color);
return false;
});
}

Trying to change the id only works once and I have no idea why?

This is my page which contains both HTML and Javascript code. No matter how I set the initial value of the ID, it only works once. Which I find very strange!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--<meta http-equiv="refresh" content="30" />-->
<title>Relay Trigger</title>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js></script>
</head>
<body>
<div id="button">
<button id="off">OFF</button>
</div>
<script type="text/javascript">
$(document).ready(function(){
$("#on").click(function(){
document.getElementById("on").innerHTML="OFF";
document.getElementById("on").id="off";
alert(document.getElementById("button").innerHTML)
});
$("#off").click(function(){
document.getElementById("off").innerHTML="ON";
document.getElementById("off").id="on";
alert(document.getElementById("button").innerHTML)
});
})
</script>
</body>
</html>
When you use $("#on").click(function(){/*...*/}, there isn't any element with id on.
Then, that event handler isn't attached.
Moreover, when you use $("#off").click(function(){/*...*/}, you add the event handler to the element that, in that moment, has the id off. It doesn't matter if the id changes, the element is still the same and still has the same event handler.
To get the functionality you want, you can use event delegation to an ancestor with a filtering selector:
$("#button")
.on('click', '#on', function(){
document.getElementById("on").innerHTML="OFF";
document.getElementById("on").id="off";
alert(document.getElementById("button").innerHTML)
})
.on('click', '#off', function(){
document.getElementById("off").innerHTML="ON";
document.getElementById("off").id="on";
alert(document.getElementById("button").innerHTML)
});
Note this can be several times slower.
But a better alternative would be using id="myButton" data-state="off", and
$('#myButton').on('click', function() {
var state = $(this).data('state');
$(this).data('state', state==='on' ? 'off' : 'on');
state = state.toUpperCase();
$(this).html(state);
alert(state);
});
Try using a class instead, ID's should not be used like this.
The reason it happens is because when you registered the event handlers - the #on actually did nothing because there was no #on element in the document in that time
You have 2 options here:
set the handler only after you change the id:
<script type="text/javascript">
$(document).ready(function(){
$("#off").click(function(){
document.getElementById("off").innerHTML="ON";
document.getElementById("off").id="on";
alert(document.getElementById("button").innerHTML)
$("#on").click(function(){
document.getElementById("on").innerHTML="OFF";
document.getElementById("on").id="off";
alert(document.getElementById("button").innerHTML)
});
});
})
use "live" behavior:
the live function of jQuery is deprecated - but you can do it by doing:
instead of
$("#on").click(function);
write
$(document).on("click","#on",function);
You're missing a " in your script src.
All you need is
LIVE DEMO
$(function(){ // DOM ready
$("#on, #off").click(function(){
var io = this.io ^= 1; // Toggler used as 1/0 boolean
$(this).text(io?"ON":"OFF").prop('id', io?"on":"off");
});
});
So inside this simple click function if you need to do more stuff depending on the stored io object value you can do:
PLAYGROUND
if(io){
// do additional stuff if "on"
}else{
// do additional stuff if "off"
}

Creating closures in a loop in JavaScript

I have this scenario:
<html>
<head>
<script type="text/javascript" src="jquery-1.4.4.js"></script>
<script type="text/javascript">
var actions = {
'view' : function(){alert("view");},
'history': function(){alert("history");},
'renewal': function(){alert("renewal");}
}
for(var action in actions){
$('.' + action).live('click', function(e){
e.preventDefault();
if(actions[action])
actions[action]();
});
}
</script>
</head>
<body>
<a class="view" href="#">view</a>
<a class="history" href="#">history</a>
<a class="renewal" href="#">renewal</a>
</body>
</html>
I think a closure is created, since clicking a link always alerts "renewal" and I am not able to fix it.
Why dont you try using the classname in the click event?
I'm no jQuery expert, but something like this:
$('.' + action).live('click', function(e)
{
e.preventDefault();
if(actions[this.className])
actions[this.className]();
});
It is indeed. You can replace
for(var action in actions){
$('.' + action).live('click', function(e){
e.preventDefault();
if(actions[action])
actions[action]();
});
}
with
for(var action in actions){
$('.' + action).live('click', function(e){
e.preventDefault();
var currentAction = $(e.target).attr('class');
if(actions[currentAction])
actions[currentAction]();
});
}
By the way, the problem is not that there is a closure. Indeed, if there was not a closure, the value of the variable action would not be rembered at all! The problem is that all the functions in the loop refer to the same variable action, that at the end of the loop will have the value renewal.
There are better ways of doing this, but to make your solution work:
for(var action in actions){
(function(myAction){
$('.' + myAction).live('click', function(e){
e.preventDefault();
if(actions[myAction])
actions[myAction]();
});
})(action);
}
You are going to find out that live is not going to cancel the default action, You are going to want to use delegate
That's not what happens. Instead, your event handler function references the action variable, which will always have the value 'renewal', since that 's the last item in the list after the loop is done. The best way to go about it is to replace the loop with something like that:
for(var action in actions) {
$('.' + action).live('click', function(e){
e.preventDefault();
var action = $(e.currentTarget).attr('class');
if(actions[action]) actions[action]();
});
}

Categories

Resources