Need input in another div! #listjs - javascript

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"
})
});

Related

Add one div only once not as many times as "li" is added JS

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>

MDC Web: mdc-select update hidden input value on change (non-native select box) | JavaScript (JS)

Been doing well so far with MDC Web Components, but I've been hung up here for far too long. (Not strong in JS.)
mdc-select used to be non-native, then used native HTML select, and now once again it's non-native. For a while MDC Web supported a hidden input so that you could pass values to the server.
There's hardly any documentation - mostly just stuck users like me opening issues on GitHub:
Closed: MDC Select - no longer form input compatible #2221
Closed: [MDC Select] Example in README does send values to the web server #5295
Open: [MDCSelect] Add hidden input element to support HTML forms #5428
I need to set/update the value of a hidden input on MDCSelect change for multiple select boxes on the same page... I can get it to do it for ONE select box, but not multiple.
Here is the select box HTML:
<div class="mdc-select mdc-select--outlined region-select">
<div class="mdc-select__anchor demo-width-class">
<i class="mdc-select__dropdown-icon"></i>
<div id="demo-selected-text" class="mdc-select__selected-text" tabindex="0" aria-disabled="false" aria-expanded="false"></div>
<div class="mdc-notched-outline">
<div class="mdc-notched-outline__leading"></div>
<div class="mdc-notched-outline__notch" style="">
<label id="outlined-label" class="mdc-floating-label" style="">Region</label>
</div>
<div class="mdc-notched-outline__trailing"></div>
</div>
</div>
<div class="mdc-select__menu mdc-menu mdc-menu-surface demo-width-class">
<ul class="mdc-list">
<li data-value="" disabled="" aria-selected="false" role="option" class="mdc-list-item" tabindex="0"></li>
<li data-value="north" aria-selected="false" role="option" class="mdc-list-item" tabindex="-1">North</li>
<li data-value="east" aria-selected="false" role="option" class="mdc-list-item" tabindex="-1">East</li>
<li data-value="south" aria-selected="false" role="option" class="mdc-list-item" tabindex="-1">South</li>
<li data-value="west" aria-selected="false" role="option" class="mdc-list-item" tabindex="-1">West</li>
</ul>
</div>
<!-- THIS IS THE HIDDEN INPUT THANK YOU -->
<input type="hidden" id="name2" name="input_name2" value="" class="my_mdc-select__value" />
</div>
I've tried targeting the hidden input with id, name, and even class. I think I need some sort of integrated function, forEach, or loop - tried adding JS beneath each select with no avail. I've worked the examples (seen below) from other users and no success. JavaScript isn't my thing, I know what it supposed to be happening but don't know the function or loop syntax etc to make this work.
I need to make sure each set/update targets the correct hidden input associated with that particular select box.
Here is my JS that works for ONE select box but not multiple:
// Select Menu
import {MDCSelect} from '#material/select';
const selectElements = [].slice.call(document.querySelectorAll('.mdc-select'));
selectElements.forEach((selectEl) => {
const select = new MDCSelect(selectEl);
select.listen('MDCSelect:change', (el) => {
const elText = el.target.querySelector(`[data-value="${select.value}"]`).innerText;
console.log(`Selected option at index ${select.selectedIndex} with value "${select.value}" with a label of ${elText}`);
// this works but only saves one
document.querySelector('input.my_mdc-select__value').value = select.value;
});
});
Here is some code that others used that I haven't been able to modify/apply (taken from links above):
From nikolov-tmw:
document.querySelectorAll( '[data-mdc-auto-init="MDCSelect"]' ).forEach( function( sel ) {
sel.My_MDCSelect__Value = sel.querySelector('input.my_mdc-select__value');
if ( null !== sel.My_MDCSelect__Value ) {
sel.addEventListener( 'MDCSelect:change', function( a ) {
if ( sel.MDCSelect ) {
sel.My_MDCSelect__Value.value = sel.MDCSelect.value;
}
} );
}
} );
From daniel-dm:
<div class="mdc-select">
...
</div>
<input id="pet-select" type="hidden" name="pets">
<script>
const input = document.querySelector('#pet-select');
const select = document.querySelector('.mdc-select');
select.addEventListener('MDCSelect:change', e => {
input.value = e.detail.value;
});
</script>
Please help! This particular issue has been open since January (people struggling long before) with no clear solution to help non-JS developers implement MDCSelect boxes. Thanks in advance!
The problem is here:
document.querySelector('input.my_mdc-select__value').value = select.value;
Document.querySelector will find the first matching element in the whole document, so in your loop you're always accessing the same input element.
Instead, you should run querySelector method on the parent element of each hidden input, which in your loop will look like:
selectEl.querySelector('input.my_mdc-select__value').value = select.value;

How to attach jQuery pop-up event to dynamically created HTML List

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)');

Why is eventListener not being added?

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(...)

How to pass parameters to a javascript function from the element that calls the function?

I have a number of <li> items, which call the same onmouseover javascript function.
The function needs to extract some data from the element that calls it, to fill some name and tel variables. This data is typed in capitals in the html code below.
Any idea on how to do this is really appreciated.
My HTML:
<li id="item1" onmouseover= "onmouseoveragent(this)" >
<a href="some link">
<span class="hideme">name</span>
</a>
<p class="hideme"> NAME TO BE PASSED TO JS
<strong class="tel">NUMBER TO BE PASSED TO JS</strong>
</p>
</li>
MY javascript:
<script language="javascript" type="text/javascript">
function onmouseoveragent(e) {
var name = e.?????;
var tel = e.?????;
};
</script>
yes you do something like this
JAVASCRIPT:
var elements = document.getElementsByClassName('data-item');
var mouseoverHandler = function() {
var name = this.getElementsByClassName('name')[0].textContent,
tel = this.getElementsByClassName('tel')[0].textContent;
alert('Name - ' + name + "\nTel - " + tel);
}
for( var i = 0; i < elements.length; i++ ) {
var current = elements[i];
current.addEventListener('mouseover', mouseoverHandler);
}
HTML MARKUP:
<li id="item1" class="data-item">
<a href="some link">
<span class="hideme">name</span>
</a>
<p class="hideme">
<span class="name">John Smith</span>
<strong class="tel">555-666-777</strong>
</p>
</li>
<li id="item1" class="data-item">
<a href="some link">
<span class="hideme">name</span>
</a>
<p class="hideme">
<span class="name">Caprica Smith</span>
<strong class="tel">545-334-641</strong>
</p>
</li>
MDN - document.getElementsByClassName();
MDN - element.textContent
It won't be e.something because e is referring to the event that just happened, that has nothing to do the other elements in the DOM
Demo
Well, there is an easier way to do it, just traverse the childNodes of your current hovered element and parse the results. Here is a working JSFiddle of the snippet below(yes, it works with all the LIs matching that structure):
function onmouseoveragent(e) {
var children = this.childNodes,
name = null,
tel = null;
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (child.tagName === 'P') {
name = child.firstChild.nodeValue; // the first node is the text node
tel = child.childNodes[1].firstChild.nodeValue; // the strong's text node
break; // let's stop the iteration, we've got what we needed and the loop has no reason to go on
}
}
console.log(name, tel); // "NAME TO BE PASSED TO JS " "NUMBER TO BE PASSED TO JS"
}
The only difference in HTML is that you need to pass your handler this way:
<li id="item1" onmouseover="onmouseoveragent.call(this, event)">
So this inside the handler will refer to the element and not to the global object.
I suggest you two thing one change the structure of you li tag i.e; make the tag as shown
<li id="item1" class="someClass" >
<a href="some link">
<span class="hideme">name</span>
</a>
<p class="hideme">NAME TO BE PASSED TO JS </p>
<strong class="tel">NUMBER TO BE PASSED TO JS</strong>
</li>
remove strong from p because when you try to fetch p(data to be passed the strong tag will come along with it so better change it)
and also try jquery it will give you more flexibility and ease of use(what i feel)
$(".someClass").mouseover(function(e){
var name = $(e.target).find("p:first").html()
var tel = $(e.target).find("strong:first").html()
})
try this
function onmouseoveragent(e) {
var text = e.getElementsByClassName('hideme')[1].textContent;
var name = text.split("\n")[0]; var num = text.split("\n")[1]; alert(name); alert(num); }

Categories