HTML list, Adding JQuery to cross selected item. - javascript

I have a little app that adds items to a list. The items appear with a button next to them, I want to be able to press that button to add a (text-decoration: line-through). I have tried a few different things but nothing seems to work (the Javascript to add items, delete the last item, add classes to the new li elements, etc. All that works fine, my problem is only with the JQuery part, more comments on the code itself).
HTML
<html>
<body>
<h1> Shopping List </h1>
<button id="add"> Add </button>
<input type="text" id="input" placeholder="Enter Items"> </input>
<button id="remove"> Remove Last </button>
<ul id="list">
</ul>
</body>
</html>
Js/Jq:
document.getElementById("add").addEventListener('click', function() {
var check = document.createElement("button");
var input = document.getElementById("input").value;
var newEl = document.createElement("li");
var newText = document.createTextNode(input);
var buttonText = document.createTextNode("Check");
newEl.className = "liEl";
newEl.appendChild(newText);
newEl.appendChild(check);
check.setAttribute("class", "checked");
check.appendChild(buttonText);
/* Problem starts here */
$("button.checked").on('click', function() {
$('li.liEl').css('text-decoration: line-through');
/* It should get the button with the class "checked" and on click, make the li elements with class "liEl" to have that css... */
}
);
var position = document.getElementsByTagName("ul")[0];
position.appendChild(newEl);
document.getElementById("input").value = "";
document.getElementById('input').onkeypress = function(e) {
if (e.keyCode == 13) {
document.getElementById('add').click(); /* adds an event listener to the submit text, keyCode 13 equals the enter key so when it's pressed it presses the add button. */
}
}
});
/* Delete last item function: */
document.getElementById("remove").addEventListener('click', function() {
var els = document.getElementsByTagName("li");
var removeEl = els[els.length - 1]; // <-- fetching last el, If els is an array, it has indices from 0 to els.length - 1. 0 is the first, els.length - 1 is the last index.
var containerEl = removeEl.parentNode;
containerEl.removeChild(removeEl);
});

Use style like $('li.liEl').css('text-decoration','line-through');

Your jQuery css function is wrong, you need to provide two parameter to set css value (see this: css-property-name-value).
Your selector syntax ($('li.liEl')) is not right, it would return all <li> element, not the one the clicked button is located.
You can use this: $(this).parent().css('text-decoration', 'line-through');.
Your code contain some bug, the last added button would not trigger the function. It is because your click function is added before the new element added to DOM. And it would cause your click function to be triggered multiple time for earlier added button.
Here's the snippet for fixed code. Since you already using jQuery, I change several native java script native element query and event handler whith jquery syntax.
$(function () {
$("#add").click(function(evt) {
var input = $('#input').val();
var check = $('<button class="checked">Check</button>');
var newEl = $('<li class="liEl"></li>');
newEl.append(input);
newEl.append(check);
$(check).click(function(evt) {
$(this).parent().css('text-decoration', 'line-through');
});
$('#list').append(newEl);
$('#input').val('');
});
$('#remove').click(function(evt) {
var lastEl = $('li.liEl').last();
lastEl.remove();
});
$('#input').keypress(function(evt) {
if (evt.keyCode === 13) {
$("#add").click();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<body>
<h1> Shopping List </h1>
<button id="add"> Add </button>
<input type="text" id="input" placeholder="Enter Items" />
<button id="remove"> Remove Last </button>
<ul id="list"></ul>
</body>

Related

Delete element in JS

I was trying to prototype a site for a To-Do List to experiment with something new using JavaScript.
function task() {
//Create checkbox
var x = document.createElement("INPUT");
x.setAttribute("type", "checkbox");
//Create <br>
lineBreak = document.createElement("br");
//Create <p> element
var todo = document.createElement("p");
//Insert in <p> the text in the input box
todo.innerText = document.getElementById("task").value;
//Create the <p>checkbox+text</p><br> on every botton click
return document.body.appendChild(x) + document.body.appendChild(todo) + document.body.appendChild(lineBreak);
document.querySelector('#reset').addEventListener('click', () => {
document.getElementById('reset').clicked
});
}
//Show Reset button on task generated
document.querySelector('#go').addEventListener('click', () => {
document.getElementById("reset").style.visibility = "visible";
});
p {
display: inline;
}
img {
width: 30px;
display: inline;
}
#reset {
visibility: hidden;
}
<h1>To-Do List</h1>
<input type="text" placeholder="Write a Task" id="task"><button id="go" onclick="task()">GO</button>
<hr>
<body>
<section>
<button id="reset">RESET</button>
</section>
</body>
As you can see from the code and the indicated if statement I was able to generate for each click on the go button (defined in HTML) new <p></p>.
It successfully generates a checkbox, next to a text typed in a text box and then wraps with the <br>.
I was trying to eliminate the elements generated by pressing the reset button, but despite having tried several solutions the only one that seems to work is the one that deletes all the contents of the body.
Could you suggest a solution to allow it to work?
Just make the adjustments to your javascript code with the following steps and it should work as your expectation:
Steps to fix the code:
Step 1: AddEventListener should be called before return so it would be called whenever the task() is executed with the click of the Go button.
Step 2: Firstly, remove the className "go-element" from the previously added elements if they exist.
Step 3: Add the class "go-element" to newly added elements so they can be identified easily while resetting them.
Step 4: on reset click, it should remove all the elements with the class "go-element"
Note: If you just want to remove all the elements which are added through the Go button, just skip step 2. Also, to simplify you can wrap your all elements in a div element and just follow all the steps as shown above with the div instead of elements.
function task() {
// Step 2: removing go-element class from previously added elements
const elements = document.getElementsByClassName("go-element");
while(elements.length > 0) {
elements[0].classList.remove("go-element");
}
// Step 3: add the class name to new elements
//Create checkbox
var x = document.createElement("INPUT");
x.setAttribute("type", "checkbox");
x.classList.add("go-element"); // step 3
//Create <br>
lineBreak = document.createElement("br");
lineBreak.classList.add("go-element"); // step 3
//Create <p> element
var todo = document.createElement("p");
todo.classList.add("go-element"); // step 3
//Insert in <p> the text in the input box
todo.innerText = document.getElementById("task").value;
// Step 1: moved this code before return so it will execute
document.querySelector('#reset').addEventListener('click', () => {
// Step 4: removing elements with class name "go-element"
const elements = document.getElementsByClassName("go-element");
while (elements.length > 0) {
elements[0].parentNode.removeChild(elements[0]);
}
});
//Create the <p>checkbox+text</p><br> on every botton click
return document.body.appendChild(x) + document.body.appendChild(todo) + document.body.appendChild(lineBreak);
}
//Show Reset button on task generated
document.querySelector('#go').addEventListener('click', () => {
document.getElementById("reset").style.visibility = "visible";
});

How to delete text box along with button in JavaScript

I have a button when user clicks the button it create the text box along with remove button
but all the text boxes created with same id how we can delete the text box when clicks respective remove button
here My Code:
<body>
<button type="button" id="URLbtn" onclick="Createinput()"> + Add URL</button>
<div id="TextAreaBtn"></div>
<script>
function Createinput() {
var newdiv=document.createElement("div");
newdiv.id="test"
var Inputele=document.createElement("input");
Inputele.type="text";
Inputele.id="URLtxt"
newdiv.appendChild(btnele);
var btnele=document.createElement("button");
btnele.id="rmvbtn"
btnele.type="button"
btnele.innerHTML="-"
btnele.onclick=RemoveUrlBox()
newdiv.appendChild(btnele);
var element = document.getElementById("TextAreaBtn");
element.appendChild(newdiv);
}
function RemoveUrlBox() {}
</script>
</body>
i am getting following output
if user click 2 remove button only remove the second textbox and button
You need to select the wrapping div. Easiest way is to use remove() and use closest. No need to use the id..... You also need to remember ids need to be unique.
function createInput() {
var newDiv = document.createElement("div");
newDiv.className = 'group';
var inputElem = document.createElement("input");
inputElem.type = "text";
newDiv.appendChild(inputElem);
var btnElem = document.createElement("button");
btnElem.type = "button";
btnElem.textContent = "-";
btnElem.addEventListener("click", removeUrlBox);
newDiv.appendChild(btnElem);
var element = document.getElementById("TextAreaBtn");
element.appendChild(newDiv);
}
function removeUrlBox() {
this.closest('.group').remove();
}
<button type="button" id="URLbtn" onclick="createInput()"> + Add URL</button>
<div id="TextAreaBtn"></div>
This should do the trick:
const txtarea=document.getElementById('TextAreaBtn');
document.getElementById('URLbtn').onclick=()=>txtarea.innerHTML+=
'<div><input type="text" class="URLtxt"><button class="rmvbtn">-</button></div>';
txtarea.onclick=ev=>ev.target.className==="rmvbtn"&&ev.target.parentNode.remove()
<button type="button" id="URLbtn"> + Add URL</button>
<div id="TextAreaBtn"></div>
I replaced your id attributes with class attributes, as these don't need to be unique.
I reduced your script by using innerHTML instead of laboriously putting elements together with createElement(). This is a matter of opinion as both methods have their advantages.
I also used delegated event listener attachment for the removal buttons. This way you can get away with a single event listener on div.TextAreaBtn. The attached funcion will only trigger any action if the clicked element has class "rmvbtn".
Change
btnele.onclick=RemoveUrlBox()
to
btnele.addEventListener('click', function (e) {
// `this` is the button that was clicked no matter about the id
// `this.parentNode` is the div you want to remove
const nodeToRemove = this.parentNode;
nodeToRemove.parentNode.removeChild(nodeToRemove);
});

Saving only the first word of a paragraph in a javascript variable

I am trying to store a paragraph in a javascript variable. I have multiple buttons inside a table, each one of the buttons has a different value, the value of each button is a small text paragraph. When i click a button a save the current buttons value in a javascript variable called 'input'.
When a button is clicked i also load an html form called "contactForm" and i display the buttons value inside that form.
The functionality works fine, the problem though is that when i save the value of the button in the ('input') js variable it saves only the first word of the paragraph, is there a way to fix this?
<html>
<div id="contactForm" >
<p><h4><i>First Choose the clients and then the file which will be uploaded in order to proced</i></h4></2>
<hr>
<input type="text" id="someInput" name="someInput"></input>
<hr>
</div>
<script>
var input; //prepare var to save contact name/ PLACE outside document ready
$(function() {
// contact form animations
$('button[id="contactbutton"]').click(function() {
input = $(this).val(); //set var input to value of the pressed button
document.getElementById("someInput").value = input;
$('#contactForm').fadeToggle();
})
$(document).mouseup(function (e) {
var container = $("#contactForm");
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
{
container.fadeOut();
}
});
});
</script>
<html>
It's simple and it works... I just didn't include the additional jQuery that you've written, as for getting the first word from a paragraph, it does do that though.
<div id="contactForm" >
<p>First Choose the clients and then the file which will be uploaded in order to proced</p>
<hr>
<input type="text" id="someInput" name="someInput">
<hr>
</div>
<br>...
<br>
<h4>Demo</h4>
<button id ="contactbutton">Click Me</button>
<script>
/**
* #description the purpose of this function is to demonstrate how to
* get the first word of a paragraph, sentence, etc.
*/
!function() {
var btn = document.querySelector('button[id="contactbutton"]');
btn.addEventListener("click", function(){
// get the paragraph tag text
var para = document.querySelector("#contactForm p").textContent;
console.log(para);
// break the paragraph into an arraywor each word seperated by a space
// index 0 = first element in the array
var word = para.split(" ")[0];
console.log(word);
// another example
var inp = document.querySelector("input#someInput");
var inpVal = inp.value;
console.log(inpVal);
var word2 = inpVal.split(" ")[0];
console.log(word2);
});
}();
</script>

How to make click event work with dynamically generated html elements

When the add more link is clicked, a div is dynamically generated that adds an additional text input and a add more link. This dynamically inserted add more link doesn't respond to click event. Even though each dynamically inserted link has a unique id and the click event uses "delegated" binding through Jquery on() method, yet the dynamically inserted link does not work by adding more fields when clicked. Here is a jsbin and the whole code is below:
The Javascript:
<script type="text/javascript">
$(document).on("ready", function(){
return $(".add_people_filter").on("click", function(event){
event.preventDefault();
var time = new Date().getTime();
var dynamicallyCreatedDiv = document.createElement("div");
dynamicallyCreatedDiv.id = time;
var peopleFilterContainerDiv = $("#people_filter_container");
peopleFilterContainerDiv.append(dynamicallyCreatedDiv);
var getHtmlForDynamicDiv = $(".people_filter").html();
var theNewDiv = $(dynamicallyCreatedDiv);
theNewDiv.append(getHtmlForDynamicDiv);
var AddUniqueIdToLinK = time * 2;
var x = time * 3;
$(this).attr('id', AddUniqueIdToLinK);
theNewDiv.find("a:last").attr('id', x);
return theNewDiv;
});
});
</script>
The html:
<div id="people_filter_container">
<div class="people_filter" >
<input type="text" name="firstname" placeholder="add name" >
add more
<br> <br>
</div>
</div>
Change it for that :
return $("body").on("click",".add_people_filter", function(event)
{
...... YOUR CODE
});

getElement 1 and do1, getElement 2 and do2, getElement 3 and do3

I have this code for smooth scrolling, it works great but only for one "clickme" id, how could i use this code for multiple tabs whit i++
<div class="navbar">
<button type="button" id="clickme1">Scroll to red section!</button>
<button type="button" id="clickme2">Scroll to blue section!</button>
</div>
<div class="second" id="second">Hello</div>
<div class="tab1" id="tab1">The start of the red section!</div>
<div class="tab2" id="tab2">The start of the blue section!</div>
and here is the pure javascript that i want to use, please do not recommend me jQuery and anchor navigation.
document.getElementById('clickme1').addEventListener('click', function() {
var header = document.querySelectorAll('.navbar');
aim = -header[0].clientHeight;
initial = Date.now();
smoothScroll(document.getElementById('tab1'));
});
*******or more simplified, how can i make this code shorter:*******
document.getElementById('clickme1').addEventListener('click', function() {
var header = document.querySelectorAll('.navbar');
aim = -header[0].clientHeight;
initial = Date.now();
smoothScroll(document.getElementById('tab1'));
});
document.getElementById('clickme2').addEventListener('click', function() {
var header = document.querySelectorAll('.navbar');
aim = -header[0].clientHeight;
initial = Date.now();
smoothScroll(document.getElementById('tab2'));
});
here is JSFIDDLE
You can do something like following
// Get buttons
var buttons = document.getElementsByTagName('button');
for (var i = 0; i < buttons.length; i++) {
// Iterate over buttons and add handler
buttons[i].addEventListener('click', clickHandler, false);
}
// Handler function
function clickHandler(){
var counter = this.id.substring(7); // Substring id to get counter
var header = document.querySelectorAll('.navbar');
aim = -header[0].clientHeight;
initial = Date.now();
smoothScroll(document.getElementById('tab'+counter));
}
Note : As you can have some other buttons on your page and do not want to add this handler to them, so, in place of tag name selector, I will suggest you to add a specific class to the button elements and then use class selector to get elements.
You should consider using proper anchor links with progressive enhancement for smooth scrolling. This would involve either changing the buttons to <a> tags or just wrapping them:
<div class="navbar">
<button type="button">Scroll to red section!</button>
<button type="button">Scroll to blue section!</button>
</div>
You can then use event delegation to trap clicks on any anchor link at the document level:
document.addEventListener('click', function (evt) {
var tgt = evt.target;
if (tgt.tagName === 'A' && tgt.getAttribute('href')[0] === '#') {
smoothScroll(document.getElementById(tgt.hash.slice(1)));
}
});
There are numerous benefits to this approach, including:
Ability to hotlink to a section by copy/pasting the URL
Graceful degrading when JavaScript is not present.

Categories

Resources