JQuery parent selector and fadeout - javascript

I'm trying to make a simple ToDo list in JQuery and I run into a problem.
I made function 'deleteListItem' and I use it to delete my lists items with:
$(this).parent().remove();
, and then I wanted to add fadeOut effect to my list and so I tried:
$(this).fadeOut(1000, function(){
$(this).parent().remove();
})
, but this fadesOut just my delete button so then I tried
$(this).parent().fadeOut(1000, function(){
$(this).parent().remove();
})
and this fades all of my 'ul' instead of just 'li' element.
Here is mine JSBIN so you better understand what I'm doing: http://jsbin.com/ciyufi/edit?html,js,output

Inside the callback handler, this refers to the <li>.
$(this).parent().fadeOut(1000, function(){
$(this).remove();
})

// This is where I put my functions
// This function adds items on our list
function addListItem() {
var text=$('#newText').val(); // val returns any text thats inside input
$('#todoList').append('<li><input type="checkbox" class="done">'+ text +'<button class="delete">Delete</button></li>');
$('#newText').val(''); // this is added so that our input deletes previous text when add is clicked
};
// This function deletes items on our list
function deleteListItem() {
// In order to delete entire list item we have to use parent method > without parent method we would only delete our delete button
$(this).parent().fadeOut(1000, function(){
$(this).closest("li").remove();
})
};
// This function adds checked remark on our item list
function itemDone() {
// First we check if our element has textDecoration="line-through"
// If it has it second line deletes it
// And our else statement allows as to add it again
if ($(this).parent().css('textDecoration') == 'line-through') {
$(this).parent().css('textDecoration', 'none');
} else {
$(this).parent().css('textDecoration', 'line-through');
}
}
$ (document).ready(function(){
$('#add').on('click', addListItem); // This is for button to add text
// This part enables us to add text on pressing enter key
$( "#newText" ).keypress(function( event ) {
if ( event.which == 13) {
addListItem();
}
});
// $('.delete').on('click', deleteListItem);
// $('.done').on('click', itemDone);
// Lines above don't work because we are adding elements after page loads
// In above lines browser didn't bind functions to our new elements because it didn't see them at the time
// In order to make it work we add document selector > its not the best solution but i'm not good enough for better
// We don't need to do it for #add because its already on page
$(document).on('click', '.delete', deleteListItem);
$(document).on('click', '.done', itemDone);
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>ToDo Lista</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/main.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<section class="container">
<h1>ToDo List</h1>
<ul id="todoList">
<li><input type="checkbox" class="done"> Clean House <button class="delete">Delete</button></li>
<li><input type="checkbox" class="done">Buy Milk <button class="delete">Delete</button></li>
<input id="newText" type="text" placeholder="Write Your Task"><button id="add">Add</button>
</ul>
</section>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="js/main.js"></script>
</body>
</html>
I prefer to use closest. closest Just change 'deleteListItem' function to remove closest li item on delete.
function deleteListItem() {
// In order to delete entire list item we have to use parent method > without parent method we would only delete our delete button
$(this).parent().fadeOut(1000, function(){
$(this).closest("li").remove();
})
};

Related

How to add event with Javascript to an html tag

I've a landingpage with dynamic html tags.
The Problem is, that i can't select directly the tag. Its a link.
the following code is the construct:
<div id="testid"><div><div>Button 1<div><div><div>
Every time someone clicks on the link (a-tag) I want to fire an event like the following code:
Button 1
the question: what is the Javascript code to add the onclick="dataLayer.push({'event': 'button1-click'}) attribute to the a tag.
I tried the following code:
var d = document.getElementById("testid").firstchild;
d.setAttribute("onclick", "dataLayer.push({'event': 'button1-click'})");
but it seems to the code is incorrect. The a tag is also not the first child; there are 2 divs between :(
Use querySelector and addEventListener:
document.addEventListener('DOMContentLoaded', function () {
var dataLayer = [];
var d = document.querySelector("#testid a[name=button1]");
d.addEventListener("click", function () {
dataLayer.push({ 'event': 'button1-click' });
});
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="testid">
<div>
<div>
Button 1
<div>
<div>
<div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="script.js">
</script>
</body>
</html>
There's a few things you were missing from your JS.
Using a more specific selector (#testid a[name=button1] vs. the firstchild of #testid, which was not accurate).
Wrapping all the code in a DOMContentLoaded listener. JS that depends on elements on a page needs to wait for the page to build first, that's what DOMContentLoaded is.
Check out my solution. Hope this helps.
var d = document.querySelector("#testid a");
var dataLayer = []
d.onclick = function () {
dataLayer.push({'event': 'button1-click'})
console.log(dataLayer.length)
}
<div id="testid"><div><div>Button 1<div><div><div>

Where can I add a second on click function that targets the var "giphyImage"?

I have tried: inside the for loop, inside the .done function but outside the for loop, and before and after the button function end. I'm wanting to be able to run a function on the click of the giphyImage.
Below is the code I am trying to insert somewhere to get the second click and test it in the console but nothing displays in the console at all.
$('giphyImage').on('click', function() {
console.log('testclickedimage')
});
Here is my HTML:
<!-- language: lang-html -->
<!DOCTYPE html>
<html>
<head>
<!--Megatags-->
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--Title on browser tab-->
<title>Bradley's Giphy API App</title>
<!--Reset tag-->
<link rel="stylesheet" href="assets/css/reset.css">
<!--Bootstrap tag-->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!--Css tag (after bootstrap)-->
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<div class="container">
<div class="buttons">
<button data-giphy="cat">Cats</button>
<button data-giphy="dog">Dogs</button>
<button data-giphy="bird">Birds</button>
<button data-giphy="horse">Horses</button>
<button data-giphy="parrots">Parrots</button>
<button data-giphy="jason schwartzman">Jason Schwartzman</button>
<button data-giphy="zooey deschanel">Zooey Deschanel</button>
<button data-giphy="michael cera">Michael Cera</button>
<button data-giphy="zach braff">Zach Braff</button>
<button data-giphy="natalie portman">Natalie Portman</button>
<button data-giphy="pizza">Pizza</button>
<button data-giphy="hamburger">Hamburger</button>
<button data-giphy="beer">Beer</button>
<button data-giphy="shrimp">Shimp</button>
<button data-giphy="lobster">Lobster</button>
</div>
<div class="addButtons"></div>
<div class="gifsAppearHere"></div>
</div>
<!--Jquery tag-->
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
<!--Javascript tag-->
<script src="assets/javascript/game.js"></script>
</body>
</html>
Here is my javascript code:
$('button').on('click', function() {
var giphy = $(this).data('giphy');
var queryURL = "http://api.giphy.com/v1/gifs/search?q=" + giphy
+ "&api_key=dc6zaTOxFJmzC&limit=10";
//testing variable
console.log (queryURL);
$.ajax({
url: queryURL,
method: 'GET'
}).done(function(response) { //done function
//console logs results remove when done testing
console.log(response)
//pulls response from data key
var results = response.data
//loops though images randomly
for (var i = 0; i < results.length; i++) {
//creates Div
var giphyDiv = $('<div class="giphyDiv">');
//pulls ratings
var p = $('<p>').text('Ratings: ' + results[i].rating);
//creats images
var giphyImage = $('<img>');
//pulls images from API
giphyImage.attr('src', results[i].images.fixed_height.url);
//appends rating and image
giphyDiv.append(p);
giphyDiv.append(giphyImage);
//prepends to class specified in html
$('.gifsAppearHere').prepend(giphyDiv);
} //end of for loop
}); //end of done function
}); //end of button function
::edit:: was able to fix by targeting 'img' instead of 'giphyImage'
$('img').on('click', function() {
console.log('testclickedimage')
});
now console displays 'testclickedimage'
I think your problem is that giphyImage is a string and not a DOM element. That's why you cannot attach an event listener to it.
Try this:
var giphyImage = document.createElement('img');
giphyImage.setAttribute('src', yourImageSource);
giphyImage.addEventListener('click', yourFunctionHere /* without () */);
giphyDiv.appendChild(giphyImage);
Edit
A better way to achieve the same result is to use event delegation.
In short, instead of attaching one event listener to each image element, you can simply attach a single event listener to a parent element, which will fire for all children matching some criteria (for example, a class name). Even better, it does not matter at all if the child already exists or is added at a later time.
Example using pure JavaScript:
var body = document.querySelector('body');
body.addEventListener('click', function(event) {
if (event.target.tagName === 'IMG')
youFunctionHere();
})

Jquery not working at all but other Javascript code runs

I'm facing a problem with my jquery. I have a table with multiple records and with each record there is delete link. On clicking that link that particular record is deleted. That is fine but what I am trying for is when a record is deleted it simply disappears without any page refresh. For that I have a jquery code which works fine on a stand alone page but when I'm trying to integrate it with my actual code nothing happens at all. I replaced $ with jQuery but still nothing happening. I also checked for other causes but nothing worked. Can someone point out what could possibly be missing or I'm doing wrong. Codes are below:
This is my row code which is inside a foreach so multiple ones are created
<tr class="showdel">
<td class="align"><input type="checkbox" name="instanceids[]" id="checkid" value="<?php echo $instanceid; ?>" /></td>
<td class="align"><?php echo $i++.'.'; ?></td>
<td><?php echo $title; ?></td>
<td>Delete</td>
</tr>
Below is my jquery code which deletes the record and it simply disappears. It is in head section of the page.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript">
jQuery(function()
{
jQuery(".delete").click(function()
{
var element = jQuery(this);
var del_id = element.attr("id");
var info = 'id=' + del_id;
if(confirm("Are you sure you want to delete this?"))
{
jQuery.ajax({
type: "POST",
url: "content_list.php",
data: info,
success: function() {}
});
jQuery(this).parents(".showdel").animate({ backgroundColor: "#003" }, "slow")
.animate({ opacity: "hide" }, "slow");
}
return false;
});
});
</script>
Please point out what am I doing wrong. Thanks in advance.
PS: Here is my whole head section. See if this helps. May be ordering of scripts is wrong.
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title><?php echo $client; ?> Admin</title>
<!-- bootstrap core css -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- custom css -->
<link href="css/sb-admin.css" rel="stylesheet">
<!-- style.css -->
<link href="css/style.css" rel="stylesheet">
<!-- paginng css -->
<link href="css/pagination.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript">
jQuery(".delete").click(function()
{
var element = jQuery(this);
var del_id = element.attr("id");
var info = 'id=' + del_id;
if(confirm("Are you sure you want to delete this?"))
{
jQuery.ajax({
type: "POST",
url: "content_list.php",
data: info,
success: function() {}
});
jQuery(this).parents(".show").animate({ backgroundColor: "#003" }, "slow")
.animate({ opacity: "hide" }, "slow");
}
return false;
});
</script>
<!-- form validation scripts -->
<script type="text/javascript" src="js/validate_category.js"></script>
<script type="text/javascript" src="js/validate_subcategory.js"></script>
<script type="text/javascript" src="js/validate_subsubcategory.js"></script>
<script type="text/javascript" src="js/selectall.js"></script>
<script type="text/javascript" src="js/validate_content.js"></script>
<script type="text/javascript" src="js/validate_resource.js"></script>
<script type="text/javascript" src="js/validate_data.js"></script>
<script type="text/javascript" src="js/ajax_scripts.js"></script>
</head>
Also my table is loaded by ajax call as Alpesh Panchal below pointed out.
Since your data table is loading by an ajax call, your selection of jQuery(".delete") is actually empty when it is trying to set the event handlers before the data is loaded. So, the solution is to set the event handler to the document itself and set a filter for your .delete element. Like this :
jQuery(document).on('click',".delete",(function()
{
//Your code
});
Make sure to check any javascript error using firebug console during page loading. Sometimes javascript errors prevents rest of javascript to execute.
Make sure that your table is not being loading by ajax call. If it is then jQuery's click event won't be binded to it. To bind it, you need to use ajaxStop() event handler to bind delete function.
If ajaxStop() doesn't work then you can create your delete click function separately and call it on "onclick" event of link
e.g.
<td>
Delete
</td>
With the jQuery .animate() method only numeric values can be animated (like "margin:30px"). String values cannot be animated (like "background-color:red").
Read more in jQuery docs.
Instead of animate use the .css() method of jQuery to change color and/or hide elements.

Change URL based on change of dynamic select box

I have a select box populated from a JSON file, I want to reload the URL but pass the value from the select box.
Here is a cut down version of my index.html file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Timetables</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div id="navbar" class="navbar-collapse collapse">
</div>
<!--/.navbar-collapse -->
</div>
</nav>
<!-- Main jumbotron for a primary marketing message or call to action -->
<div class="jumbotron">
<div class="container">
<div id="headerArea">
</div>
</div>
</div>
</body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
var $crs = GetURLParameter('crs');
// Function that uses this variable removed as not relevant
$.getJSON('csr.json', function (data) {
var stationDropdown = '<form class="navbar-form navbar-right" action="">';
stationDropdown += '<select class="form-control" id="stations">';
for (var i in data) {
stationDropdown += '<option value="' + data[i].Code + '">' + data[i].StationName + '</option>';
}
stationDropdown += '</select>';
stationDropdown += '</form>';
$("#navbar").html(stationDropdown);
});
$(function(){
// bind change event to select
$('#stations').bind('change', function () {
var url = $(this).val(); // get selected value
if (url) { // require a URL
window.location = 'index.html?crs='.url; // redirect
}
return false;
});
});
</script>
</html>
and here is a sample of the JSON
[
{
"StationName":"Abbey Wood",
"Code":"ABW"
},
{
"StationName":"Aber",
"Code":"ABE"
}
]
The select box generates fine and is 'injected(?) into the navbar div, but the on change event wont register
Basically if someone was to select Aber, the onchange event will reload index.html?crs=ABE automatically.
Dev tools is not throwing up any errors, its just not doing anything when I change the select box.
I suspect I need to run the on change event as a function that is called exclusively when needed as putting it in at the bottom of the index.html file means its loading before the DOM is ready?
Thanks in advance for any assistance.
You should move all of your HTML building INTO the HTML.
Inside of your getJSON() you can cut that code down to this:
var stations = $( '#stations' );
for (var i in data) {
stations.append( '<option value="' + data[i].Code + '">' + data[i].StationName + '</option>' );
}
Once you do that, everything else should work appropriately. Here's what I changed in your HTML:
<div id="navbar" class="navbar-collapse collapse">
<form class="navbar-form navbar-right" action="">
<select class="form-control" id="stations">
<option>Select One</option>
</select>
</form>
</div>
Also, as a note. jQuery recommends using the on() method instead of the bind() method as of 1.7.
http://api.jquery.com/bind/
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the event binding call.
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.
As you are creating elements dynamically.
You need to use Event Delegation. You have to use .on() using delegated-events approach.
General Syntax
$(document).on(event, selector, eventHandler);
Ideally you should replace document with closest static container.
Example
$("#navbar").on('change', '#stations', function(){
//Your code
});
Always the same question... you initiate your bind event before the dropdown is created, because it depends on an ajax call.
What's wrong with your code :
$.getJSON('csr.json', function (data) { // This is done #1
.......
$("#navbar").html(stationDropdown); // this is done #3 : creating #stations.
});
$('#stations').bind('change', function () { // This is done #2 and won't do anything because #stations doesn't exist yet
........
});
The right way is :
$.getJSON('csr.json', function (data) { // This is done #1
.......
$("#navbar").html(stationDropdown); // this is done #2 : creating #stations.
$('#stations').bind('change', function () { // This is done #3
........})
});
It's because the $.getJSON function is called after the $(function(){
If you move the code in $(function(){, to the end of the $.getJSON function, then it'll work.
You need to use on for dynamic content:
$('#navbar').on('change', '#stations', function () {
^ Static container content is appended to
^ #stations = target element

Adding/removing <li> elements with jQuery

I just started to learn JavaScript/jQuery, and I made a little test website to practice coding.
In one of the tests I made, there is a list that says Milk and Eggs. There is an input field and a button, which you can type something, click the button, and add it to the list. I then added an option where if you click on one of the list items, it removes it. This works, but only on the preset Milk and Eggs items, not any items that you add yourself.
I think it's because the code wasn't loaded for the newly added items, but I'm not sure. Can someone help?
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Practice 3</title>
<link href="index.css" rel="stylesheet" type="text/css">
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
</head>
<body>
<div class="Title" align="center">
<h1>Hello</h1>
<p>This website will use JavaScript to create interactive elements.</p>
</div>
<div class="1">
<h3>Test 1</h3>
<ul id="list">
<li>Milk</li>
<li>Eggs</li>
</ul>
<input id="textbox">
<button id="add">Add to list</button>
</div>
<script>
$('#add').click(function() {
var listvalue = $('#textbox').val();
$("#textbox").val("");
$('ul').append('<li>' + listvalue + '</li>');
});
$('#textbox').keypress(function(event) {
if(event.which === 13) {
var listvalue = $('#textbox').val();
$('#textbox').val("");
$('ul').append('<li>' + listvalue + '</li>');
}
});
$('li').click(function(e) {
$(e.target).remove();
});
</script>
</body>
</html>
Use event delegation
$('#list').on('click', 'li', function(e) {
$(this).remove();
});
Example
You can use on to bind the click even to the document, then specify a selector to specify that it should only trigger for li elements:
$(document).on('click', 'li', function (e) {
$(this).remove();
});
This will still work with newly-added li elements because the event-handler itself is bound to the document itself, not the individual elements. It simply performs a runtime check to ensure that the dispatched event matches the provided selector.
Answered by Gone Coding on stackoverflow:
https://stackoverflow.com/a/34857252/7074256
And here is example how to do it with jquery:
function moveItems(origin, dest) {
$(origin).closest("li").appendTo(dest);
}
$(document).on('click', '.add', function () {
moveItems(this, '#listTwo');
});
$(document).on('click', '.remove', function () {
moveItems(this, '#listOne');
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/r7j3odyy/4/

Categories

Resources