I have code here in a todo list that can add and delete tasks. I'm trying to implement code to edit tasks after they are added by double clicking. Right now the code should just log to the console after double clicking the LI element but it's not doing anything.
newTodoInput.addEventListener('keyup', function addTodoController(event){
if ( event.keyCode === 13){
if ( newTodoInput.value !== '' ){
var newTask = todos.addTaskToList(newTodoInput.value.trim(), todos.taskList);
var clone = templateContent.cloneNode(true);
clone.querySelector("label").appendChild(document.createTextNode(newTodoInput.value.trim()));
todoList.appendChild(clone);
newTodoInput.value = '';
deletingTasks();
editingTasks();
}
}
}); // END addEventListener(addTodoController)
function deletingTasks() {
var deleteTaskButtons = document.querySelectorAll('button.destroy');
_.last(deleteTaskButtons).addEventListener('click', function removeLi(){
//console.log(event.target.parentNode.parentNode.parentNode);
event.target.parentNode.parentNode.parentNode.removeChild(event.target.parentNode.parentNode);
todos.deleteTask(_.indexOf(deleteTaskButtons, event.target), todos.taskList);
});
}
function editingTasks(){
var editTask = document.querySelectorAll('li');
_.last(editTask).addEventListener('dblclick', function taskEdit(){
console.log("Edit this task!");
});
}
I'm invoking the editingTasks function every time a task is added just like I did with the deleting tasks function so that the event listeners will be added to each li element as it's added but I'm not getting anything. Any pointers to why this code doesn't work? Here's the HTML if needed:
<ul class="todo-list">
<!-- These are here just to show the structure of the list items -->
<!-- List items should get the class `editing` when editing and `completed` when marked as completed -->
<template id='newtasktemplate'>
<li>
<div class="view">
<input class="toggle" type="checkbox">
<label class="tasking"></label>
<button class="destroy"></button>
</div>
<input class="edit" value="Rule the web">
</li>
</template>
</ul>
It seems likely that your code that does:
var editTask = document.querySelectorAll('li');
_.last(deleteTaskButtons).addEventListener(...)
may not be selecting the right <li> tag. My suggestion is to change your template to add a unique class name to the <li> tag as in:
<li class="myListItem">
And, then change your code to this:
var editTask = document.querySelectorAll('.myListItem');
_.last(deleteTaskButtons).addEventListener(...)
Related
My problem is that I have a website, using javascript I have made it when I click on the About Me it opens, but when I click on Education and Achievements the About me button's content remains open and the Education stuff overlaps it. I want to make it so that when I click on another button the first one closes (its content. The website name is dirieahmed.ml
My code HTML and JS will be linked below ill add CSS later if need be.
<div class="container">
<button id="one" class="click one">About Me</button>
<div class="list-1 sec">
<h1 class="content-header-one content">Dummy text header</h1>
<p class="content-paragraph-one">Dummy text</p>
</div>
<button class="click two">Education and Achivements</button>
<div class="list-2 sec">
<p class="content-paragraph2 content">Dummy text</p>
<ul class="content-list content">
<li>- Achivement #1</li>
<li>- Achivement #2</li>
<li>- Achivement #3</li>
</ul>
</div>
<button class="click three" >Other</button>
<div class="list-3 sec">
<h1 class="content-header-two content">Dummy text header</h1>
<p class="content-paragraph3 content">Dummy text</p>
</div>
<script async>
let one = document.querySelector('.one');
let two = document.querySelector('.two');
let three = document.querySelector('.three');
let list1 = document.querySelector('.list-1');
let list2 = document.querySelector('.list-2');
let list3 = document.querySelector('.list-3');
one.addEventListener("click", ()=>{
list1.classList.toggle('newlist');
});
two.addEventListener("click", ()=>{
list2.classList.toggle('newlist');
lis
})
three.addEventListener("click", ()=>{
list3.classList.toggle('newlist')
});
// please change above
</script>
</div>
To summarize you will need to hide all other ones when there is a click anywhere and then only show the ones based on the link that you clicked
Check the code below
https://codesandbox.io/s/keen-driscoll-igzlwb?file=/index.html:2333-3356
<script async>
// Instanciate List div's
let list1 = document.querySelector(".list-1");
let list2 = document.querySelector(".list-2");
let list3 = document.querySelector(".list-3");
// Reset's all views to the default without .newlist
const resetAllViews = () => {
list1.classList.remove("newlist");
list2.classList.remove("newlist");
list3.classList.remove("newlist");
};
// Checks to see what button is clicked and shows correct list based on input
document.addEventListener(
"click",
function (e) {
e = e || window.event;
var target = e.target;
if (target.classList.contains("one")) {
resetAllViews();
list1.classList.add("newlist");
}
if (target.classList.contains("two")) {
resetAllViews();
list2.classList.add("newlist");
}
if (target.classList.contains("three")) {
resetAllViews();
list3.classList.add("newlist");
}
}, false);
</script>
The document object should be given a click event listener.
Use the contains() function to determine with each click if the clicked element is outside the targeted element.
Hide the original element if the clicked element is outside.
I have divs with same classes where i have got textarea value. there are added in 'li' which is added to body. I want that when i click 'li' show this div text, when i click second div show only second div value and once, not twice. can someone help me please?
here is my code for example:
let value = $('.text').val();
$('.add').text(value);
$('.addNewValue').click(function() {
$('.newValue').text($('.add').text())
})
<textarea class="text" placeholder="value"></textarea>
<ul>
<li class="newValue"></li>
</ul>
<button class="addNewValue">Add</button>
<div class="add"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Here's how to populate a List <ul> with <li> elements having a textarea value - on button click:
// PS: Don't use classes if you don't refer to a reusable parent component
const $text = $("#text");
const $list = $("#list");
const $add = $("#add");
const createLi = () => {
// Get textarea value (trimmed from whitespaces)
const text = $text.val().trim();
// If there's no text, exit the function here using `return`
if (!text) return alert("Please, enter a desired text!");
// else...
$("<li>", {
text: text,
appendTo: $list
});
$text.val(""); // And empty the textarea!
};
$add.on("click", createLi);
<textarea id="text" placeholder="Write something…"></textarea>
<br>
<button id="add" type="button">ADD</button>
<ul id="list"></ul>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I'm trying to append a button into a li item with the .appendChild method, but it doesn't work. I also tried altering the parent's inner HTML.
let inputElement = document.querySelector('#input');
let listItem = document.createElement('li');
listItem.className = 'todo-item'
let checkButton = document.createElement('button');
checkButton.className = 'checkButton'
//? When adding the child element, it is only added after the text content is defined.
listItem.appendChild(checkButton);
listItem.textContent = inputElement.value;
<div class="app">
<div class="list">
<h1> My Todo List </h1>
<ul class="todo-list" id="list">
<div class="list-row">
<li class="todo-item"><button class="checkButton"></button> Test Item </li>
</div>
<div class="list-row">
<li class="todo-item"><button class="checkButton"></button> Test Item </li>
</div>
</ul>
<input id="input" class="list-input" type="text" placeholder="Next I need to...">
</div>
</div>
Here's the current result
If I modify the order in which the child is appended, the button DOES show up but it's not the best result
//? When adding the child element, it is only added after the text content is defined.
listItem.textContent = inputElement.value;
listItem.appendChild(checkButton);
Setting the textContent property will reset the whole li element, thus removes the previously added button, try with insertAdjacentHTML().
The insertAdjacentHTML() method of the Element interface parses the specified text as HTML or XML and inserts the resulting nodes into the DOM tree at a specified position. It does not reparse the element it is being used on, and thus it does not corrupt the existing elements inside that element.
let inputElement = document.querySelector('#input');
let listItem = document.createElement('li');
listItem.className = 'todo-item'
let checkButton = document.createElement('button');
checkButton.className = 'checkButton'
listItem.appendChild(checkButton);
listItem.insertAdjacentHTML('beforeend',inputElement.value);
document.querySelector('#list').appendChild(listItem);
<div class="app">
<div class="list">
<h1> My Todo List </h1>
<ul class="todo-list" id="list">
<div class="list-row">
<li class="todo-item"><button class="checkButton"></button> Test Item </li>
</div>
<div class="list-row">
<li class="todo-item"><button class="checkButton"></button> Test Item </li>
</div>
</ul>
<input id="input" class="list-input" type="text" placeholder="Next I need to...">
</div>
</div>
First do not be so greedy with the ";" signs ;)
This happens cause the whole thing is wrong :)
Look, This would and will work perfectly in plain html:
<ul>
<li><input type="radio" name="gender" value="male"> Male</li>
<li><input type="radio" name="gender" value="female"> Female</li>
<li><input type="radio" name="gender" value="other"> Other </li>
....
</ul>
And now we do exactly the same in Javascript.
var ipb=document.createElement("INPUT") //Not button ! Forget that this
// button tag
// even exists
ipb.setAttribute("id","ibp_0"); //always a good idea
ipb.setAttribute("name","gender"); //if its inside a form you want to use
//and a must have for radio buttons *)'
ipb.setAttribute("type","radio");// or checkbutton or input - what you
// want for a input type
ipb.setAttribute("value","male");
var txt = document.createTextNode("Male");
ipb.appendChild(txt);
// and now you can
LIST.appendChild(ipb); //the formaly created <UL> Node for sure
As you can see its the same thing like writing the html version just in a different syntax. There is no magic thing in behind which will do something for you.
The text node is not a perfect idea. I would use a label for that. Or a additional Label.
A label has a "FOR" attribute which i really suggest to use if you go that way.
But this typing i let up to ou :) Have fun !
*) radio buttons. They know that they belong together by the name.
You've created the element, for listItem but you've never actually added it to the DOM.
You need to append or insert the listItem before you try to add the checkbox.
Aspiring developer and first time posting a question to StackOverflow.
Researched the topic but couldn't find an exact answer to my question.
Background:
Modifying this static shopping cart, to accept dynamically created list item.
https://tutorialzine.com/2014/04/responsive-shopping-cart-layout-twitter-bootstrap-3
Trying to insert a new item to the shopping cart via span tag, span tag information will be dynamically provided by another function.
For testing purpose I'm using a button to insert the new item to the shopping list.
The shopping cart has popover event to "Modify / Delete" individual items lists
Question: I can't figure out the exact JavaScript / jQuery command to attach the popover event. All static items in the list have the popover event automatically attached but the dynamically created items do not.
I tried using the addEventListener(); but the jQuery doesn't get attached properly.
My initial assumption was if the dynamically created list items had the same "class" as the static items that the popoever event would be automatically applied to them as well.
Tried these solutions but didn't work out for me, the popover event doesn't get attached properly.
a. Event binding on dynamically created elements?
Event binding on dynamically created elements?
b. Attach event to dynamically created chosen select using jQuery
Attach event to dynamically created chosen select using jQuery
c. Attaching events after DOM manipulation using JQuery ajax
Attaching events after DOM manipulation using JQuery ajax
Here's the HTML and JavaScript:
var qrcodelist = document.getElementById('qrdemo_list');
function myFunction() {
// HTML for testing when device is not connected: comment out when device is connected
var x = document.getElementsByClassName("decode-value-offline")[0].innerHTML;
// Qty and Price text values
var qty_text = 1;
var price_text = '$150';
// Create li
var entry_li = document.createElement('li');
entry_li.setAttribute("class", "row");
// Create quantity span
var qty_span = document.createElement('span');
qty_span.setAttribute("class", "quantity");
qty_span.appendChild(document.createTextNode(qty_text));
// Create price span
var price_span = document.createElement('span');
price_span.setAttribute("class", "price");
price_span.appendChild(document.createTextNode(price_text));
// Create pop btn span
var popbtn_span = document.createElement('span');
popbtn_span.setAttribute("class", "popbtn");
popbtn_span.setAttribute("data-original-title", "");
popbtn_span.setAttribute("title", "");
//popbtn_span.addEventListener( );
// Create a tag inside pop btn
var popbtn_a_span = document.createElement('a');
popbtn_a_span.setAttribute("class", "arrow");
popbtn_span.appendChild(popbtn_a_span);
// Create item span and text node
var item_span = document.createElement('span');
item_span.setAttribute("class", "itemName");
// Append span to li
entry_li.appendChild(qty_span);
entry_li.appendChild(item_span);
entry_li.appendChild(popbtn_span);
entry_li.appendChild(price_span);
// Create text node and insert qr-code result to li span
item_span.appendChild(document.createTextNode(x));
// Get list node and insert
var list_node = document.getElementById("qrdemo_list").lastChild;
// alert(list_node);
qrdemo_list.insertBefore(entry_li, qrdemo_list.childNodes[3]);
// Write x to console log
console.log(x);
}
// Popover JavaScript
$(function() {
var pop = $('.popbtn');
var row = $('.row:not(:first):not(:last)');
pop.popover({
trigger: 'manual',
html: true,
container: 'body',
placement: 'bottom',
animation: false,
content: function() {
return $('#popover').html();
}
});
pop.on('click', function(e) {
pop.popover('toggle');
pop.not(this).popover('hide');
});
$(window).on('resize', function() {
pop.popover('hide');
});
row.on('touchend', function(e) {
$(this).find('.popbtn').popover('toggle');
row.not(this).find('.popbtn').popover('hide');
return false;
});
});
<!-- Shopping Cart List HTML -->
<div class="col-md-7 col-sm-12 text-left">
<ul id="qrdemo_list">
<li class="row list-inline columnCaptions">
<span>QTY</span>
<span>ITEM</span>
<span>Price</span>
</li>
<li class="row">
<span class="quantity">1</span>
<span class="itemName">Birthday Cake</span>
<span class="popbtn"><a class="arrow"></a></span>
<span class="price">$49.95</span>
</li>
<li class="row">
<span class="quantity">50</span>
<span class="itemName">Party Cups</span>
<span class="popbtn"><a class="arrow"></a></span>
<span class="price">$5.00</span>
</li>
<li class="row">
<span class="quantity">20</span>
<span class="itemName">Beer kegs</span>
<span class="popbtn"><a class="arrow"></a></span>
<span class="price">$919.99</span>
</li>
<li class="row">
<span class="quantity">18</span>
<span class="itemName">Pound of beef</span>
<span class="popbtn"><a class="arrow"></a></span>
<span class="price">$269.45</span>
</li>
<li class="row">
<span class="quantity">1</span>
<span class="itemName">Bullet-proof vest</span>
<span class="popbtn" data-parent="#asd" data-toggle="collapse" data-target="#demo"><a class="arrow"></a></span>
<span class="price">$450.00</span>
</li>
<li class="row totals">
<span class="itemName">Total:</span>
<span class="price">$1694.43</span>
<span class="order"> <a class="text-center">ORDER</a></span>
</li>
<li class="row">
<!-- QR Code Images -->
<span class="itemName"><img src="img/AppleQRCode.png" width="100" height="100"></span>
<span class="price"><img src="img/OrangeQRCode.png" width="100" height="100"></span>
</li>
<li class="row">
<!-- device offline testing span -->
<span class="decode-value-offline">Unknown</span>
</li>
<li class="row totals">
<!-- Button to insert qr-code result to list -->
<span class="order"><a class="text-center" onclick="myFunction()">Insert</a></span>
<span class="itemName">Insert QR Code Result</span>
</li>
</ul>
</div>
<!-- Popover HTML -->
<!-- The popover content -->
<div id="popover" style="display: none">
<span class="glyphicon glyphicon-pencil"></span>
<span class="glyphicon glyphicon-remove"></span>
</div>
<!-- JavaScript includes -->
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/js/customjs.js"></script>
Appreciate the great support in advance and please contact me if additional information is needed for clarification.
JSFiddle of Fix: https://jsfiddle.net/0phz61w7/
The issue is that you need to delegate the event. Please do the following:
Change:
pop.on('click', function(e) {
pop.popover('toggle');
pop.not(this).popover('hide');
});
To:
$(document).on('click', '.popbtn', function(e) {
pop.popover('toggle');
pop.not(this).popover('hide');
});
Also, you need to remove the } from line 54, just after console.log(x);. That is throwing an error.
The above modification works, but in the code provided, .popbtn is not visible because the node is empty. So in the jsfiddle provided, I added a CSS rule to include the text POPBTN. Click that and an alert I added to the click event fires.
You need to delegate jquery function to the HTML elements created dynamically like this:
Change your following line
var pop = $('.popbtn');
var row = $('.row:not(:first):not(:last)');
like given here:
var pop = $(document).find('.popbtn');
var row = $(document).find('.row:not(:first):not(:last)');
Anyone in here familiar with LISTJS plugin? If so, I require your assistance.
Reffering to: http://codepen.io/javve/pen/zpuKF.
What I'm trying to achieve is NOT havin the search-input within the same div as the list.
I want the search-input in another div. Is this possible? If so, what do I do, I'm guessing I'm gonna have to edit the source code...?
To sum up - I wan't the input field in another div, not the "users" - as described below.
<div id="THIS IS WHERE I WANT MY INPUT FIELD"></div>
<div id="users">
<input class="search" placeholder="Search" />
<button class="sort" data-sort="name">
Sort by name
</button>
<ul class="list">
<li>
<h3 class="name">Jonny Stromberg</h3>
<p class="born">1986</p>
</li>
<li>
<h3 class="name">Jonas Arnklint</h3>
<p class="born">1985</p>
</li>
<li>
<h3 class="name">Martina Elm</h3>
<p class="born">1986</p>
</li>
<li>
<h3 class="name">Gustaf Lindqvist</h3>
<p class="born">1983</p>
</li>
</ul>
</div>
<script src="http://listjs.com/no-cdn/list.js"></script>
Probably you figured out a solution or you implemented the one above. I think that it's not OK to modify a plugin if you have alternatives. I had the same problem and I solved it by using the listObj.search from list.js documentation. The code will look something like this:
$("#searchInput").keyup(function () { // #searchInput is your input
var searchString = $(this).val(); // your searching string
searchList.search(searchString); // searchList is your new List
});
You can do it by editing the plugin, only some few lines of code to add some options to the plugin to make it accept sibling search input by id
First go to the init() method in the plugin to add some options and their default values, let say options.searchWithId which is a boolean that indicates if you want sible search input using an id and options.searchId which correspond to the Id of your search input:
// If not provided in the options it takes false by default
self.searchWithId = options.searchWithId || false;
// In case search input with id, initialise the id
self.searchWithId ? self.searchId = options.searchId || false : void 0;
After that you need to modify the input search object retrieval by adding those lines of code, just before the keyup event bind:
var searchInput = null;
if(list.searchWithId === false){
searchInput = getByClass(list.listContainer, list.searchClass);
}
else{
searchInput = $("#"+list.searchId);
}
And finally change the events binding like this:
events.bind(searchInput, 'keyup', function(e) {
var target = e.target || e.srcElement, // IE have srcElement
alreadyCleared = (target.value === "" && !list.searched);
if (!alreadyCleared) { // If oninput already have resetted the list, do nothing
searchMethod(target.value);
}
});
// Used to detect click on HTML5 clear button
events.bind(searchInput, 'input', function(e) {
var target = e.target || e.srcElement;
if (target.value === "") {
searchMethod('');
}
});
You can initialize your plugin this way:
var options = {
valueNames: [ 'name', 'born' ],
searchWithId: true,
searchId: "search-list"
};
var userList = new List('users', options);
and you put your search input where you want (outside, inside, ...)
<input id="search-list" class="search" placeholder="Search" />
<div id="users">
<button class="sort" data-sort="name">
Sort by name
</button>
<ul class="list">
<li>
<h3 class="name">Jonny Stromberg</h3>
<p class="born">1986</p>
</li>
<li>
<h3 class="name">Jonas Arnklint</h3>
<p class="born">1985</p>
</li>
<li>
<h3 class="name">Martina Elm</h3>
<p class="born">1986</p>
</li>
<li>
<h3 class="name">Gustaf Lindqvist</h3>
<p class="born">1983</p>
</li>
</ul>
</div>
I tested it and it works, if you want the entire file just let me know.
Update
Fiddle demo
This cannot be done like that, otherwise it wont have relation with your code below, that's the reason why you had to include it in your (Div) users, is there any particular reason you trying to put it in a different (DIV)
Search and sort can be triggered via javascript.
Like For search, suppose search input id is mySearch
$('#mySearch').on('keyup', function() {
var searchString = $(this).val();
userList.search(searchString);
});
To search against specific column :
$('#mySearch').on('keyup', function() {
var searchString = $(this).val();
userList.search(searchString, ['user']);
});
Similarly for sorting use sort function :
$('#mySort').on('click',function() {
userList.sort('user',{
order: "desc"
})
});