Right now, my code allows someone to create an li by submitting a movie title and its rating. A remove button also appears at the end of this li. I want this li to be removed once the remove button is clicked on. I understand how to do this with Javascript, however how do you do this with jQuery? The ways I have attempted this are:
$('li button').click( function(e) {
e.target.closest('.li').remove();
})
$('li').on("click", "button", function() {
$(this).remove()
})
I know there are other ways in Jquery to remove the li, but what is wrong with the above two methods? is it how I selected the items? My entire HTML and JS are below. Thanks in advance!
$('#movieForm').submit(function(event) {
event.preventDefault();
let movieInput = $("#movieTitle").val();
let ratingInput = $("#rating").val();
$('#movieList').append("<li>" + movieInput + " " + ratingInput + "<button>Remove</button></li>");
})
$('li button').click( function(e) {
e.target.closest('.li').remove();
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Movies App!</title>
<link rel="stylesheet"
href="https://unpkg.com/bootstrap/dist/css/bootstrap.css">
</head>
<body>
<h1>Movies App!</h1>
<ul id="movieList">
</ul>
<form id="movieForm">
<input id="movieTitle" placeholder="Movie Title">
<input id="rating" placeholder="Rating">
<input type="submit" id="submit"></button>
</form>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="MoviesApp.js"></script>
</body>
</html>
Your use of on() is almost correct, there's just two flaws. Firstly the primary selector should be the closest parent element to the target which exists in the DOM when the page loads, in this case the ul. You also need to remove the entire li when the event happens, not the button, so use closest(). Try this:
jQuery($ => {
$('#movieForm').submit(e => {
e.preventDefault();
let movieInput = $("#movieTitle").val();
let ratingInput = $("#rating").val();
$('#movieList').append(`<li>${movieInput} ${ratingInput}<button>Remove</button></li>`);
})
$('ul').on("click", "li button", e => $(e.target).closest('li').remove());
});
<link rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.css">
<h1>Movies App!</h1>
<ul id="movieList"></ul>
<form id="movieForm">
<input id="movieTitle" placeholder="Movie Title">
<input id="rating" placeholder="Rating">
<input type="submit" id="submit" />
</form>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
Note that I used arrow functions and template literals in the above example. Neither are relevant to the issue you had, they're just some syntactic sugar to make the logic more succinct.
Related
after months of doing courses, I finally ventured into coding my first project, but the most basic functionality of it isn't working.
I'm doing a simple to do list, and im working on it actually displaying the elements added by the user through the button but they don't appear on the screen after clicking, even if i'm using DOM manipulation commands to create an 'ul' element. Also, the page refreshes after every click on the button.
let addToButton = document.getElementById('addButton');
let inputFieldset = document.getElementById('toDoInput');
let toDoContainer = document.getElementById('toDoList');
addToButton.addEventListener('click', function(){
let toDoStuff = document.createElement('ul')
toDoStuff = inputFieldset.value
toDoContainer.append(toDoStuff);
})
<!DOCTYPE html>
<html lang="en">
<head>
<title>la lista</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="list-style.css"/>
</head>
<body>
<main>
<h1>Ysmael's To-Do List</h1>
<h3>Input your activities</h3>
<form>
Input something<input type="text" required id="toDoInput" placeholder="Input your stuff"/><button id="addButton" type="submit">+</button>
</form>
<div id="toDoList">
</div>
</main>
<script href="todolist.js"></script>
</body>
</html>
Acording to my logic, it should work, but I'm clearly doing one or more things wrong.
to not submit the form, replace the <button> with <input type="button" value="+"> and to create list you want <li> element with the parent <ul>
let addToButton = document.getElementById('addButton');
let inputFieldset = document.getElementById('toDoInput');
let toDoContainer = document.getElementById('toDoList');
addToButton.addEventListener('click', function() {
// show warning if input empty
if (!inputFieldset.reportValidity()) // or use: if (!inputFieldset.value)
return
let toDoStuff = document.createElement('li')
toDoStuff.innerHTML = inputFieldset.value
toDoContainer.append(toDoStuff);
// reset input
inputFieldset.value = '';
})
<h3>Input your activities</h3>
<form>
Input something <input type="text" required id="toDoInput" placeholder="Input your stuff" />
<button id="addButton">+</button>
</form>
<ul id="toDoList">
</ul>
For problem #1:
In line 6 you are creating the let binding toDoStuff which holds a <ul>-element, just to override toDoStuff in line 7 with the current value of the <input>-element. Even if it worked (somehow), I suspect it wouldn't work as you expect, because it would create a completely new list for each todo instead of creating a single list of todos. If I'm right, move the let toDoStuff = document.createElement('ul') line out of your event handler function, create the <ul> right away and .append() it to your toDoContainer (hold a reference to it so that you can append elements to it later).
let toDoContainer = document.getElementById('toDoList');
let toDoStuff = document.createElement('ul');
toDoContainer.append(toDoStuff);
Then, inside the click handler function, create an <li> element that you can append to the <ul>:
addToButton.addEventListener('click', function () {
let toDoListItem = document.createElement('li');
// ... elided
});
The .append() method of an HTMLElement expects to receive another HTMLElement or Node, but you are passing it a String. This means you need to transform that String into a Node before passing it to .append(), and the usual way to do that transformation is via document.createTextNode().
let toDoText = document.createTextNode(inputFieldset.value)
However, you want to insert that Node into a <ul> element and the only child elements of an unordered list should be <li>-elements. This is why we generated the <li> in the previous sections, so all you have to do now is adding the Node to the <li>, then adding the <li> to the <ul>. In code:
addToButton.addEventListener('click', function () {
let toDoListItem = document.createElement('li');
let toDoText = document.createTextNode(inputFieldset.value);
toDoListItem.append(toDoText);
toDoStuff.append(toDoListItem);
});
In regards to the #2 submission problem:
Your button is nested inside a <form> element, so pressing it "naturally" submits the form. What you want to do is to suppress the submission, either via:
calling .preventDefault() on the generated SubmitEvent object of the form
returning false in your event handler function
In favor of a standards way, use .preventDefault(), so we need a reference to the <form> element instead of the <button> as well as changing the event type from 'click' to 'submit':
// ... elided
let addToButton = document.querySelector('form');
// ... elided
addToButton.addEventListener('submit', function (event) { // <-- changed click to submit, added generated event object
event.preventDefault(); // <-- suppress form submission
let toDoListItem = document.createElement('li');
// ... elided, see above
});
Changing the variable names to appropriate ones is left as an excercise ;-)
Example:
let addToButton = document.querySelector('form');
let inputFieldset = document.getElementById('toDoInput');
let toDoContainer = document.getElementById('toDoList');
let toDoStuff = document.createElement('ul');
toDoContainer.append(toDoStuff);
addToButton.addEventListener('submit', function (event) {
event.preventDefault();
let toDoListItem = document.createElement('li');
let toDoText = document.createTextNode(inputFieldset.value);
toDoListItem.append(toDoText);
toDoStuff.append(toDoListItem);
})
<!DOCTYPE html>
<html lang="en">
<head>
<title>la lista</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="list-style.css"/>
</head>
<body>
<main>
<h1>Ysmael's To-Do List</h1>
<h3>Input your activities</h3>
<form>
Input something<input type="text" required id="toDoInput" placeholder="Input your stuff"/><button id="addButton" type="submit">+</button>
</form>
<div id="toDoList">
</div>
</main>
<script href="todolist.js"></script>
</body>
</html>
One of the solutions to prevent reloading the page after submitting the form is to use even.preventDefault() on submit event. In this way you prevent default browser's behavior. Anyway, to do so, you should add submit event listener. You can also add submitted task to the list from there, therefore I replaced your 'click' event handler with submit.
<script> tag shouldn't have href attribute. It should be src instead.
You are creating <ul> element which is a container for the list of unordered elements. You should create <li> element and append it to <ul> or <ol> container. I have replaced tasks container from <div> to <ul>.
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>la lista</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="list-style.css" />
</head>
<body>
<main>
<h1>Ysmael's To-Do List</h1>
<h3>Input your activities</h3>
<form id="toDoForm">
Input something
<input type="text" required id="toDoInput" placeholder="Input your stuff" />
<button id="addButton" type="submit">+</button>
</form>
<ul id="toDoList">
</ul>
</main>
<script src="todolist.js"></script>
</body>
</html>
tasklist.js:
let inputFieldset = document.getElementById('toDoInput');
let toDoContainer = document.getElementById('toDoList');
let toDoForm = document.getElementById('toDoForm');
toDoForm.addEventListener('submit', (event) => {
event.preventDefault();
const task = document.createElement('li');
task.innerText = inputFieldset.value;
toDoContainer.appendChild(task);
inputFieldset.value = '';
})
Change button type to button instead of submit to keep everything from disappearing when it's clicked, and change toDoList element from div to ul and then add tasks as li [list items] rather than ul [a whole unordered list in itself]. Also, you need to change the innerHTML (or innerText) of toDoStuff instead of setting the element itself (so that it remains a li).
let addToButton = document.getElementById('addButton');
let inputFieldset = document.getElementById('toDoInput');
let toDoContainer = document.getElementById('toDoList');
addToButton.addEventListener('click', function(){
let toDoStuff = document.createElement('li');
toDoStuff.innerHTML = inputFieldset.value;
toDoContainer.append(toDoStuff);
inputFieldset.value = "";//clear field
})
//so that "enter" does the same as addToButton instead of submit
inputFieldset.addEventListener("keydown", function(event) {
if (event.key === "Enter") {
event.preventDefault();
addToButton.click();
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>la lista</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="list-style.css"/>
</head>
<body>
<main>
<h1>Ysmael's To-Do List</h1>
<h3>Input your activities</h3>
<form>
Input something<input type="text" required id="toDoInput" placeholder="Input your stuff"/><button id="addButton" type="button">+</button>
</form>
<ul id="toDoList">
</ul>
</main>
<script href="todolist.js"></script>
</body>
</html>
I've also added a line to clear the field [for the next task] after a task has been added, and another event listener to the text input because "enter" key can also register as submit - but now, instead of everything disappearing on enter, it simulates clicking the add button.
I changed your code. The problems are 3 in number.
you have button type submit, this submits the form and the form then requires an action to handle the submit, this is typically used to send data to other pages.(dont quote me on that, i never use it)
you made toDoStuff get the value of the input thus overriding the create element.
you had a div as a container for a created ul when you want to have a ul as container for a created li.
Here is the changed html:
<body>
<main>
<h1>Ysmael's To-Do List</h1>
<h3>Input your activities</h3>
<form>
Input something<input type="text" required id="toDoInput" placeholder="Input your stuff"/><button id="addButton" type="button">+</button>
</form>
<ul id="toDoList">
</ul>
</main>
</body>
And here is the changed Javascript:
let addToButton = document.getElementById('addButton')
let inputFieldset = document.getElementById('toDoInput')
let toDoContainer = document.getElementById('toDoList')
addToButton.addEventListener('click', () => {
let toDoStuff = document.createElement('li')
toDoStuff.innerHTML = inputFieldset.value
toDoContainer.append(toDoStuff)
})
Good luck and happy coding, dont let a setback make you give up!
Bind the <form> to the "submit" event. Details are commented in example.
// Reference <form>
const todo = document.forms.todo;
// Reference <input>
const add = todo.elements.add;
// Reference <ul>
const list = document.querySelector(".list");
/**
* Bind <form> to "submit" event
* Stop <form> from sending data and blanking out the page
* Create <li> which is required in a <ul>
* Add the value of <input> as the text of <li>
* Add <li> to <ul>
* Clear the <form> to prevent accidental clicking
*/
todo.addEventListener('submit', function(event) {
event.preventDefault();
const item = document.createElement('li')
item.textContent = add.value
list.append(item);
this.reset();
});
<main>
<!-- Add #id or [name] to <form> -->
<form id="todo">
<fieldset>
<legend>Ysmael's To-Do List</legend>
<!-- Add <label> and [for="{<input> #id}"] -->
<label for="add">Enter Task: </label>
<input id="add" type="text" required>
<!-- A plain <button> inside a <form> will trigger "submit" -->
<button>+</button>
</fieldset>
</form>
<ul class="list"></ul>
</main>
I am new to javascript programming so am hoping that this is a simple issue... I'm wanting my webpage to allow a user to input a music track name and artist in two separate fields and once you hit 'go' the javascript will run and parse the input into a string. To test I have tried to see if these inputs are being taken and I have tried to print them to console, however nothing is being printed to the console.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Spotify</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="main-container">
<div class="header">
<p>TrackSelector</p>
</div>
<section>
<div class="form">
<form action="">
<input type="textt" class="track" placeholder="Enter track..." />
<input type="texta" class="artist" placeholder="Enter artist..." />
<button type="button" class="submit-btn">GO</button>
</form>
</div>
</section>
</main>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="script.js"></script>
</body>
</html>
Javascript file:
const app = {};
//Allow the user to enter names
app.events = function() {
$('form').on('button', function(e){
e.preventDefault();
let tracks = $('input[type=textt]').val();
let artists = $('input[type=texta]').val();
console.log(tracks);
console.log(artists);
});
};
//
//
app.init = function(){
app.events();
};
$(app.init);
I believe I have specified to take in the correct inputs and specified the correct button reference, have played around to try out other methods but I'm still quite stuck... any ideas?
Replace
$('form').on('button', function(e){
with
$('form .submit-btn').on('click', function(e){
jQuery .on() expects event name as its first argument.
There is no input type type="textt" and texta. There are only predefined types like text, email, password, checkbox and so on... So make type "text" in both inputs and for reference use id: <input id="my_track" type="text">. Then in javascript get value by $('#my_track').val(); To handle submit use $('form').on('submit', func)
I am struglling to add and remove a class in order to hide then show the scroll abr on the body tag. I have the follwoing code so far.
<label class="hamburger" for="sidebarToggler" id="menuToggle"></label>
<input type="checkbox" id="sidebarToggler" name="sidebar" value="">
$("#menuToggle").click(function () {
if ($('#menuToggle').hasClass('close-menu')) {
$('body').removeClass('hide-scroll');
}
else {
$('body').addClass('hide-scroll');
}
});
There are a few things to consider here that could be going wrong.
Ensure you have a proper jQuery Reference and "Ready" Function
You need to ensure that any jQuery code that you are writing actually can access a reference to the jQuery library and that the code itself is wrapped in a "ready" function like the one seen below to ensure it is only called after jQuery is loaded :
<!-- Place your jQuery Reference here (or somewhere above here) -->
<script>
// Document ready function
$(function(){
$("#menuToggle").click(function () {
if ($('#menuToggle').hasClass('.close-menu')) {
$('body').removeClass('hide-scroll');
}
else{
$('body').addClass('hide-scroll');
}
});
});
</script>
Ensure your markup is correct
Currently you are missing a closing > for your <label> element which can cause issues if you are targeting things with jQuery (like causing your click event to not be picked up) :
<label class="hamburger" for="sidebarToggler" id="menuToggle"></label>
or if you wanted to wrap your checkbox within it, simply handle it that way :
<label class="hamburger" for="sidebarToggler" id="menuToggle">
<input type="checkbox" id="sidebarToggler" name="sidebar" value="">
</label>
Simplify your code using the toggleClass() function
Your code could be slightly simplified to toggle the class you are targeting by using the toggleClass() function as follows :
$("#menuToggle").click(function () {
// Explicitly toggle your class on this element
$(this).toggleClass('close-menu');
// Notice that you don't need the leading '.' when using the hasClass
// function
$('body').toggleClass('hide-scroll',$(this).hasClass('close-menu'));
});
So a complete example might look like :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Scroll Hide Testing</title>
</head>
<body>
<label class="hamburger" for="sidebarToggler" id="menuToggle">
<input type="checkbox" id="sidebarToggler" name="sidebar" value="">
</label>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script>
$(function(){
$("#menuToggle").click(function () {
$(this).toggleClass('close-menu');
// Notice that you don't need the leading '.' when using the hasClass
// function
$('body').toggleClass('hide-scroll',$(this).hasClass('close-menu'));
});
});
</script>
</body>
</html>
Yes, i know this is a duplicate, but all the answers i've read didn't help me, i have a side by side working example, from w3school, it works, and mine doesn't, what i am trying to do is show a tooltip warning the user to use numbers only, but instead, it just refreshes the page.
This is my full html page code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
<link rel="stylesheet" media="screen" href="Css/style.css"> /*---not using the bootstrap css because it messes up the form layout, so i copied every tooltip referenced block to my style.css instead.---*/
<script type="text/javascript" src="js/tooltip.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
var previous;
$(document).ready(function(){
$('.btn').tooltip();
});
//Buy Button JS code
$(function () {
$("#searchform").bind('submit', function () {
var str = $('#search-form').val();
if (str.match(/^[0-9]*$/)) {
$('#search-form').tooltip({title="You did good :)"});
}
else
{
$('#search-form').tooltip({title="Please enter numbers ONLY !"});
}
});
});
</script>
</head>
<body>
<div class="box">
<form class="search-form" method="post" id="searchform">
<input type="text" id="search-form" name="textbox" placeholder="Please enter your code" required/>
<button type="submit" name="submit" class="btntxt">Validate</button>
<div id="search_results"></div>
</form>
</div>
</body>
</html>
I didn't put the data-toggle:"tooltip" neither a title:"sometitlehere" in the element's options, because i don't really need it.
There are few mistakes in your code,
//it should be title: and not title=
$('#search-form').tooltip({title:"You did good :)"});
The above line initializes the tooltip once your code excutes.
After that if the tooltip title is updated, the tooltip is needed to be destroyed and re-initialized with new title.
var previous;
//Buy Button JS code
$(function () {
$("#searchform").bind('submit', function () {
var newTooltip="";
var str = $('#search-form').val();
if (str.match(/^[0-9]*$/)) {
newTooltip = "You did good :)";
}
else
{
newTooltip = 'Please enter numbers ONLY !';
}
$('#search-form').attr('title', newTooltip).tooltip('fixTitle').tooltip('setContent').tooltip('show');
setTimeout(function(){
$('#search-form').tooltip('hide').tooltip('destroy');
}, 1500);
});
});
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
/*---not using the bootstrap css because it messes up the form layout, so i copied every tooltip referenced block to my style.css instead.---*/
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<div class="box">
<form class="search-form" method="post" id="searchform">
<input type="text" id="search-form" name="textbox" placeholder="Please enter your code" required/>
<button type="submit" name="submit" class="btntxt">Validate</button>
<div id="search_results"></div>
</form>
</div>
You are using form so you need to return true or false on validate action so your code should be like
if (str.match(/^[0-9]*$/)) {
$('#search-form').tooltip({title="You did good :)"});
return true;
}
else
{
$('#search-form').tooltip({title="Please enter numbers ONLY !"});
return false;
}
are you initialising the tooltip in the js? - tooltips won't show unless you have this in the code:
$(function(){
$("[data-toggle=tooltip]").tooltip();
})
ok - I just looked at your code - you have :
$('.btn').tooltip();
listed in theree, but your button has the class "btntxt" and you are also trying to get a tooltip on the search form - but that has the id of "search-form" - neither of which will be affected by your tooltip declaration. Best to use the one I gave in the is post so that all elements with tooltips can display them. Setting them to individual classes or ids is too restrictive if you forget that your class or id is not the same as the one listed in the js.
you have this order to your scripts:
<script type="text/javascript" src="js/tooltip.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
Does the tooltip.js require jquery? - if so you may need to invert that order
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="js/tooltip.js"></script>
In the following code, how can I move the <div class="move">I was moved to the parent.</div> after the parent of the element I click, when I click Add New.
I have everything right, but I cannot do the part where I need to move it after() the parent.
Can you please help?
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Side bar poll thingy</title>
<script type="text/javascript" src="http://localhost/site/scripts/jQueryCore.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.add').click(function() {
$("#container").find('.flag, .edit, .delete').remove();
$(this).parent("div").after(".move");
});
});
</script>
</head>
<body>
<div id="container">
<div class="h1" data-id="1">Teachers <span class="add" data-id="US01">Add New</span></div>
<div class="h2" data-id="2">Who is your favorite Math teacher? <span class="add" data-id="US02">Add New</span></div>
<br>
<div class="h1" data-id="8">Restaurants <span class="add" data-id="US10">Add New</span></div>
<div class="h2" data-id="9">Which is your favourtie restaurant in town? <span class="add" data-id="US20">Add New</span></div>
<div class="move">I was moved to the parent.</div>
</div>
</body>
</html>
.after() doesn't accept selectors, currently you are inserting .move string after the selected element. You can use .insertAfter() method instead:
$(".move").insertAfter(this.parentNode);
http://jsfiddle.net/RYzpG/
try this fiddle http://jsfiddle.net/QP3MZ/
$(document).ready(function () {
$('.add').click(function () {
$("#container").find('.flag, .edit, .delete').remove();
var $move = $('#container .move');
$(this).parent("div").after($move);
});
});
This code should work.
$(document).ready(function() {
$('.add').click(function(e) {
e.preventDefault();
$("#container").find('.flag, .edit, .delete').remove();
$('.move').insertAfter($(this).parent());
//Or (Note we have to pass a jQuery element inside after, if we pass string then it will copy the string instead)
//$(this).parent('div').after($('.move'));
});
});
Also here is a jsfiddle. The reason why yours wasn't working is you are passing a string inside the .after, which jQuery would treat as an HTML string. You had to pass a jQuery element or DOM element. See it here.