How to get javascript `this` element properties? - javascript

I have been learning javascript to get clear of the jquery that's why I'm gonna show you an example with jquery and how to write same code with js
I have to do list like this:
var addText = document.querySelector("#addText"),
addButton = document.querySelector("#addButton");
addText.addEventListener("keyup", function() {
if (addText.value.trim().length > 0) {
addButton.removeAttribute("disabled", false)
} else {
addButton.setAttribute("disabled", true);
}
});
var ul = document.createElement("ul");
addButton.addEventListener("click", function() {
var textVal = addText.value;
var li = document.createElement("li");
li.innerHTML = textVal + " - <span class='removeTodo' onclick='removeTodo()'>Remove</span>";
ul.appendChild(li);
addText.value = '';
addText.focus();
addButton.setAttribute("disabled", true);
});
document.body.appendChild(ul);
function removeTodo(event) {
//
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<input type="text" name="" id="addText">
<input type="button" value="Add" id="addButton" disabled>
</body>
</html>
and as you see on snippet I have removeTodo() function.. I want to remove li which I clicked but before do this I have to ask how can I get clicked properties (id,class,text,parent,child bla bla) and how can I remove or addClass (for example) ?
it was very simple with jquery like this
$(element).on("click", function() {
$(this).attr("id");
$(this).text();
$(this).remove();
$(this).hide();
$(this).parents().attr("class");
})

With the method you're using - where you expect the event to be passed as an argument to the function - you can use event.target to access the clicked element. Note that you will need to amend the onclick to include the event in the arguments, though.
However, a much better solution would be to use an unobtrusive event handler on the li as you are on all the other elements in your code. Then you can use the this keyword to reference the clicked element, similar to the jQuery example in your second code block. Try this:
var addText = document.querySelector("#addText"),
addButton = document.querySelector("#addButton");
addText.addEventListener("keyup", function() {
addButton.disabled = addText.value.trim().length == 0;
});
addButton.addEventListener("click", function() {
var textVal = addText.value;
var li = document.createElement("li");
li.innerHTML = textVal + ' - <span class="removeTodo">Remove</span>';
li.addEventListener('click', removeTodo);
ul.appendChild(li);
addText.value = '';
addText.focus();
addButton.setAttribute("disabled", true);
});
var ul = document.createElement("ul");
document.body.appendChild(ul);
function removeTodo() {
// read properties here...
console.log(this.innerHTML);
// then remove the element...
this.remove();
}
<input type="text" name="" id="addText">
<input type="button" value="Add" id="addButton" disabled>

Your event object is going to have an event.target field that will hold the DOM object you are looking for.

innerHTML is not the best practice. You should for example add another element for span, addEventListner on it and append span to your li.
var addText = document.querySelector("#addText"),
addButton = document.querySelector("#addButton");
addText.addEventListener("keyup", function() {
if (addText.value.trim().length > 0) {
addButton.removeAttribute("disabled", false)
} else {
addButton.setAttribute("disabled", true);
}
});
var ul = document.createElement("ul");
addButton.addEventListener("click", function() {
var textVal = addText.value;
var li = document.createElement("li");
li.innerText = textVal + ' - ';
var span = document.createElement("span");
span.innerText = 'Remove';
span.className = 'removeTodo'
li.appendChild(span)
ul.appendChild(li);
span.addEventListener('click', removeTodo);
addText.value = '';
addText.focus();
addButton.setAttribute("disabled", true);
});
document.body.appendChild(ul);
function removeTodo(event) {
console.log (event.target) // this is a span
console.log (event.target.parentElement) // this is a li
event.target.parentElement.remove(); // remove li
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<input type="text" name="" id="addText">
<input type="button" value="Add" id="addButton" disabled>
</body>
</html>

Related

Why is my save function not executing in its entirety?

I am trying to create a to-do list in HTML, CSS and pure JS.
const dSubmit = document.getElementById('submit');
const storeData = [];
let typer = document.getElementById('type');
let input = document.getElementById('text');
const list = document.getElementById('listHolder');
dSubmit.addEventListener("click", (e) => {
e.preventDefault();
if (input.value == "") {
typer.innerHTML = "Please enter a task";
} else {
typer.innerHTML = "";
store();
}
});
function store() {
const tData = document.getElementById('text').value;
storeData.push(tData);
updater();
input.value = "";
}
function deleter (index) {
storeData.splice(index, 1);
updater();
}
function updater() {
let htmlCode = "";
storeData.forEach(function(item, index){
htmlCode += "<div class='test'><div id = "+ index +">" + item + "</div><div class='sideBtn'><button type='button' class='edit' onClick= 'editF("+ index +")'>Edit</button><button class='delBtn' onClick= 'deleter("+ index +")'>Delete</button> </div> </div>"
})
list.innerHTML = htmlCode;
}
function editF (index) {
let tempOne = document.getElementById(index);
let tempTwo = "<input id='inputText"+String(index)+"' type='text' name='task' value ='" + String(storeData[index]) + "'><button id='saveText"+String(index)+"' onClick= 'save("+index+")' >Save</button>"
tempOne.innerHTML = tempTwo;
}
function save (index) {
console.log('test1')
let tempOne= document.getElementById('saveText'+String(index));
let tempTwo = document.getElementById('inputText'+String(index));
console.log('test2')
tempOne.addEventListener("click", function foo (){
console.log('test3')
storeData.splice(index,1,tempTwo.value)
updater()
}
)
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8">
<title>To Do List</title>
</head>
<body>
<h1>To-do-list</h1>
<form>
<label for="task">Please enter item:</label>
<input type="text" name="task" id="text">
<button id="submit">Submit</button>
</form>
<div id='type'></div>
<div>List:</div>
<div id="listHolder" class="test"></div>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
I am facing problems with the save function. If I edit an item in the to-do list and click the save button, the function executes up to the point of console.log('test2'). If I click save again the function executes in its entirety.
I would like to ask why the first click results in execution of the save function up to 'test2'?
Additionally would anyone be kind enough to critique my JS? are there things in dire need of improvement? or is there a more practical/efficient method of writing my JS code?
Thank you for your help in advance.
After the 'test2' log, you are adding an event listener, and the rest of the code is inside of the listener block. The code in the listener block is only executed once that listener receives a 'click' event, which is why it works the second time.

Using javascript to add an image to a list and then deleting that list item when the image is clicked

Firstly I know I can make things a lot easier by creating the ul in HTML. I'm not supposed to be doing that.
My HTML:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body id="body">
<form id="form" >
<input id="userInput" placeholder="Enter your list item here">
<button type="button" onclick="inputFunction()">Add</button>
</form>
<script src="A4.js"></script>
</body>
</html>
My Javascript so far:
// Creating Array
var listData = ["Crab","Lobster","Scallops"];
// Creating initial List
function listFunction(){
var ul = document.createElement("ul");
ul.id = 'ulId';
document.getElementById('body').appendChild(ul);
listData.forEach(liFunction);
function liFunction(element){
var li = document.createElement('li');
ul.appendChild(li);
li.innerHTML+=element;
}
}
listFunction();
// Adding user input to the list
function inputFunction() {
var input = document.getElementById("userInput").value;
listData.push(input);
var newLi = document.createElement("li");
document.getElementById('ulId').appendChild(newLi);
newLi.innerHTML=input;
}
var liImg = document.getElementsByTagName('li');
for (var i = 0; i < liImg.length; i++) {
liImg[i].addEventListener('mouseover', handlerFunction, false);
}
function handlerFunction(e) {
var img = document.createElement("img");
img.setAttribute("src","https://cdn1.iconfinder.com/data/icons/nuove/128x128/actions/fileclose.png");
img.setAttribute("height","10");
img.setAttribute("width", "10");
document.getElementsByTagName('li').innerHTML += "img";
}
So what I'm supposed to be doing is first create a list using the listData array, and displaying it on the page. Then I take the user input and add it to the list. This part is working fine
The part I am stuck on is having to create/display an image next to each list item when it is mouseover'ed. Then having to delete that specific list item if the image is clicked. I've created the eventListener, but the img part doesn't seem to be working.
The problem is when you're appending the image to the li element.
Solution:
e.target.appendChild(img);
// Creating Array
var listData = ["Crab", "Lobster", "Scallops"];
// Creating initial List
function listFunction() {
var ul = document.createElement("ul");
ul.id = 'ulId';
document.getElementById('body').appendChild(ul);
listData.forEach(liFunction);
function liFunction(element) {
var li = document.createElement('li');
ul.appendChild(li);
li.innerHTML += element;
}
}
listFunction();
// Adding user input to the list
function inputFunction() {
var input = document.getElementById("userInput").value;
listData.push(input);
var newLi = document.createElement("li");
document.getElementById('ulId').appendChild(newLi);
newLi.innerHTML = input;
}
var liImg = document.getElementsByTagName('li');
for (var i = 0; i < liImg.length; i++) {
liImg[i].addEventListener('mouseover', handlerFunction);
}
function handlerFunction(e) {
var img = document.createElement("img");
img.setAttribute("src", "https://cdn1.iconfinder.com/data/icons/nuove/128x128/actions/fileclose.png");
img.setAttribute("height", "10");
img.setAttribute("width", "10");
e.target.appendChild(img);
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body id="body">
<form id="form">
<input id="userInput" placeholder="Enter your list item here">
<button type="button" onclick="inputFunction()">Add</button>
</form>
<script src="A4.js"></script>
</body>
</html>
Hope this helps!
img is not string, it is a variable, so remove the surrounding double quotes from that. Since img is a node element, instead of using innerHTML you should use appendChild(). You also should use the e.target to refer the specific li element:
Change:
document.getElementsByTagName('li').innerHTML += "img";
To
e.target.appendChild(img);
I will suggest you to use mouseenter instead of mousemove. I think you need to attach the mouseleave event as well. You also have to attach the events to the newly created li elements.
Try the following way:
// Creating Array
var listData = ["Crab","Lobster","Scallops"];
// Creating initial List
function listFunction(){
var ul = document.createElement("ul");
ul.id = 'ulId';
document.getElementById('body').appendChild(ul);
listData.forEach(liFunction);
function liFunction(element){
var li = document.createElement('li');
ul.appendChild(li);
li.innerHTML+=element;
}
}
listFunction();
// Adding user input to the list
function inputFunction() {
var input = document.getElementById("userInput").value;
listData.push(input);
var newLi = document.createElement("li");
newLi.addEventListener('mouseenter', handlerFunction, false);
newLi.addEventListener('mouseleave', removeImage, false);
document.getElementById('ulId').appendChild(newLi);
newLi.insertAdjacentHTML('beforeend', input);
}
var liImg = document.getElementsByTagName('li');
for (let i = 0; i < liImg.length; i++) {
liImg[i].addEventListener('mouseenter', handlerFunction, false);
liImg[i].addEventListener('mouseleave', removeImage, false);
}
function handlerFunction(e) {
var img = document.createElement("img");
img.setAttribute("src","https://cdn1.iconfinder.com/data/icons/nuove/128x128/actions/fileclose.png");
img.setAttribute("height","30");
img.setAttribute("width", "30");
img.addEventListener('click', function(){
this.closest('li').remove();
});
e.target.appendChild(img);
}
function removeImage(e){
e.target.querySelector('img').remove();
}
<body id="body">
<form id="form" >
<input id="userInput" placeholder="Enter your list item here">
<button type="button" onclick="inputFunction()">Add</button>
</form>
<script src="A4.js"></script>
</body>

Remove <li> element from <ul> onclick without refreshing page

At the moment i need to remove an li element created by jQuery when it has been clicked.
(function() {
$(document).ready(function() {
$("#likeform").submit(function(event) {
var input = $(this).children("input[name='thing']")
var thing = $(input).val()
$("#likes").append("<li>" + thing + "</li>")
$(input).val("")
event.preventDefault()
})
})
var li = $('<li/>')
.onclick(function() {
$(this).remove()
})
}())
var listitems = document.getElementsByTagName("li")
for (var i = 0; i < listitems.length; i++) {
listitems[i].onclick = this.parentNode.removeChild((this))
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>My New Pen!</title>
<link rel="stylesheet" href="styles/index.processed.css">
</head>
<body>
<h1>What do you like?</h1>
<form id=likeform>
<input name=thing placeholder="a thing you like" size=30>
<input type=submit>
</form>
<ul id=likes></ul>
<!-- Scripts -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script src="scripts/index.js"></script>
</body>
</html>
Currently this has been successful apart from i need to manually reload the page for the change to take effect
Your problem is right here:
var li = $('<li/>').onclick(function() {
$(this).remove()
});
First of all you don't need the comparison operators (<, >) as JQuery will select elements by their tag names. Also, you can't add event listeners the "normal" way on dynamically created elements.
This is discussed right here.
To fix your problem replace the above with this:
$(document).on("click", "li", function() {
$(this).remove();
});
Working example:
(function() {
$(document).ready(function() {
$("#likeform").submit(function(event) {
var input = $(this).children("input[name='thing']")
var thing = $(input).val()
$("#likes").append("<li>" + thing + "</li>")
$(input).val("")
event.preventDefault()
})
})
var li = $(document).on("click", "li", function() {
$(this).remove();
});
}())
var listitems = document.getElementsByTagName("li")
for (var i = 0; i < listitems.length; i++) {
listitems[i].onclick = this.parentNode.removeChild((this))
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>What do you like?</h1>
<form id=likeform>
<input name=thing placeholder="a thing you like" size=30>
<input type=submit>
</form>
<ul id=likes></ul>
I think this is essentially what you are trying to do:
$('li').each(function (i) {
$(this).click(() => $(this).remove());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<ul>
<li>foo</li>
<li>bar</li>
</ul>
</body>
would you please try following.
(function() {
$(document).ready(function() {
$("#likeform").submit(function(event) {
var input = $(this).children("input[name='thing']")
var thing = $(input).val()
$("#likes").append("<li>" + thing + "</li>")
$(input).val("")
event.preventDefault()
})
})
}())
var listitems = document.getElementsByTagName("li")
for (var i = 0; i < listitems.length; i++) {
listitems[i].onclick = this.parentNode.removeChild((this))
}
$(document).on("click", "#likes li", function(){
$(this).remove();
});

Execute javascript on load

i just want to know how to execute this [JSCODE][1] on page load, I'm a newbie and I cant figure it out. I just want to disregard the form or submit button and execute the script on page load. Thank You in advance!
[1]: http://jsfiddle.net/Noumenon72/9X3yZ/8/
Write your code inside anonymous function given below..
$(function() {
//Write your code here
})
Use jquery $(document).ready like this.
$(document).ready(function(){
//task which you want to perform
});
See you code below. I have mentioned where to call these functions.
$(document).ready(function(){
$('#domain').val('http://yourblog.blogspot.com/');
$('#get_tags').click();
});
function getTagsFromFeed(domain){
var myscript = document.createElement("script");
myscript.src = domain + "feeds/posts/summary?alt=json&max-results=0&callback=cat";
document.getElementsByTagName('head')[0].appendChild(myscript);
}
function cat(json){ //get categories of blog & sort them
var label = json.feed.category;
var lst=[];
for (i=0; i<label.length; i++){
lst[i] = label[i].term;
}
displayList(lst.sort()); //use any sort if you need that
}
function displayList(list) {
var mylist = document.getElementById("mylist");
mylist.innerHTML = "";
for (i=0; i<list.length; i++) {
var li = document.createElement("li");
li.appendChild(document.createTextNode(list[i]));
mylist.appendChild(li);
}
urlifyTagsInList(document.forms.myform.host.value);
}
function urlifyTagsInList(hostname){
var mylist = document.getElementById("mylist");
var newlist = document.createElement("ul");
var elements = mylist.getElementsByTagName("li");
for (j=0; j<elements.length; j++) {
var link = document.createElement("a");
var blah = document.createTextNode("blah");
link.href=hostname + "search/label/" + elements[j].innerHTML;
link.appendChild(elements[j].cloneNode(true));
newlist.appendChild(link);
}
mylist.parentNode.replaceChild(newlist, mylist);
newlist.id = "mylist";
}
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<form id="myform" method="POST" onSubmit="getTagsFromFeed(document.forms.myform.host.value); return false;">
<p> Enter blogspot domain (http://yourblog.blogspot.com/):</p>
<input id="domain" type="text" name="host"></input>
<button id="get_tags" type="submit">Get tags</button>
</form>
<ul id="mylist">
</body>
</html>
If you want to use pure javascript, Document ready with pure JavaScript will help you.
A simple way to submit form onload is like this.
$(document).ready(function(){
$('#myForm').submit();
});

Creating paragraphs based on user input

I'm having trouble, grabbing the user input, and having the onclick operator create additional paragraphs with each click.
Here is my HTML code.
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Add Paragraph </title>
<meta charset='utf-8' >
<script src="../js/addPara.js" type="text/javascript"></script>
</head>
<body>
<div>
<input type='text' id='userParagraph' size='20'>
</div>
<div id="par">
<button id='heading'> Add your paragraph</button>
</div>
</body>
</html>
Here is Javascript code:
window.onload = function() {
document.getElementById("addheading").onclick = pCreate;
};
function pCreate() {
var userPar= document.createElement("p");
var parNew = document.getElementById('userParagraph').value;
userPar.innerHTML = par;
var area = document.getElementById("par");
area.appendChild(userPar);
}
userPar.innerHTML = par;
should be
userPar.innerHTML = parNew;
In your code:
> window.onload = function() {
> document.getElementById("addheading").onclick = pCreate;
> };
Where it is possible (perhaps likely) that an element doesn't exist, best to check before calling methods:
var addButton = document.getElementById("addheading");
if (addButton) {
addButton.onclick = pCreate;
}
Also, there is no element with id "addheading", there is a button with id "heading" though.
> function pCreate() {
> var userPar= document.createElement("p");
> var parNew = document.getElementById('userParagraph').value;
> userPar.innerHTML = par;
I think you mean:
userPar.innerHTML = parNew;
if you don't want users inserting random HTML into your page (perhaps you do), you can treat the input as text:
userPar.appendChild(document.createTextNode(parNew));
.
> var area = document.getElementById("par");
> area.appendChild(userPar);
> }
Your variable names and element ids don't make a lot of sense, you might wish to name them after the data or function they represent.
I did it and it worked.
<html lang='en'>
<head>
<title>Add Paragraph </title>
<meta charset='utf-8' >
<script>
window.onload = function() {
document.getElementById("heading").onclick = pCreate;
}
function pCreate() {
var userPar= document.createElement("p");
var parNew = document.getElementById('userParagraph').value;
userPar.innerHTML = parNew;
var area = document.getElementById("par");
area.appendChild(userPar);
}
</script>
</head>
<body>
<div>
<input type='text' id='userParagraph' size='20'>
</div>
<div id="par">
<button id='heading'> Add your paragraph</button>
</div>
</body>
</html>```

Categories

Resources