What is the best way to initialize listjs with divs - javascript

I am attempting to make a searchable database with list.js but the search function is not working. I am not sure if I initialized it correctly or what I am doing wrong. I am sure it is something obvious but I would love another set of eyes.
Here is my HTML
<body>
<div class="hof-list">
<input class="search" placeholder="Search for a member..."/><br>
<div class="list">
<div class="objects">
<div class="name">Lucille Ball</div>
<div class="year">2018</div>
</div>
<div class="objects">
<div class="name">Jeremy Jacobs</div>
<div class="year">2018</div>
</div>
<div class="objects">
<div class="name">Russell Salvatore</div>
<div class="year">2018</div>
</div>
<div class="objects">
<div class="name">John Albright</div>
<div class="year">2017</div>
</div>
<div class="objects">
<div class="name">Lousie Bethune</div>
<div class="year">2017</div>
</div>
<div class="objects">
<div class="name">Glenn Curtis</div>
<div class="year">2017</div>
</div>
<div class="objects">
<div class="name">John Oishei</div>
<div class="year">2018</div>
</div>
<div class="objects">
<div class="name">Mary Burnett Talbert</div>
<div class="year">2017</div>
</div>
</div>
</div>
</body>
Here is my script
var options = {
valueNames: ['name', 'year']
};
var hoflist = new List('hof-list', options);

According to docs it expects the following parameters: new List(id/element, options, values); where id/element is
id or element *required Id the element in which the list area should be initialized. OR the actual element itself.
So you should pass there an actual id (so you need to change it in your html), or, you can pass there an element with
new List(document.querySelector('.hof-list'), options)

Related

How to display only the highest "score" according to the text content inside each div?

I would like to archive the below by using JavaScript (or with jQuery). Here is the HTML structure:
<div class="score-set">
<div class="score-item">A<div id="score">96+</div></div>
<div class="score-item">B<div id="score">99</div></div>
<div class="score-item">C<div id="score">99</div></div>
<div class="score-item">D<div id="score">96-</div></div>
</div>
<div class="score-set">
<div class="score-item">A<div id="score">86</div></div>
<div class="score-item">B<div id="score">88</div></div>
<div class="score-item">C<div id="score">90</div></div>
<div class="score-item">D<div id="score">90+</div></div>
</div>
<div class="score-set">
<div class="score-item">A<div id="score">83-</div></div>
<div class="score-item">B<div id="score">83+</div></div>
<div class="score-item">C<div id="score">76</div></div>
<div class="score-item">D<div id="score">78</div></div>
</div>
The JavaScript will do the modification, and the desired results will be B 99 C90 A 83- , which looks like:
<div class="score-set">
<div class="score-item">B<div id="score">99</div></div>
</div>
<div class="score-set">
<div class="score-item">C<div id="score">90</div></div>
</div>
<div class="score-set">
<div class="score-item">A<div id="score">83-</div></div>
</div>
The rules are:
Ignore all non-number in id="score", eg. + and -, and do the ranking.
Show one highest score item.
If two score items are the same in a set, show just one according to the div item sequence inside <div class="score-set">, ie. in the above example A > B > C > D.
When writing the result, write the original div item, including + or -.
To be able to do this, it would be best to get each individual score-set and treat one after another.
For each score item, we need to first get the score and transform it (Array#map) into a number with no digits (.replace(\/D+/g, ''))and memorize the score item html object.
Number(scoreItem.querySelector('div').innerText.replace(/\D+/g, ''))
We can then sort the remaining ones in descending order and simply take the first one of the list. Can be done with Array#sort and destructuring assignment.
.sort(({ score: scoreA }, { score: scoreB }) => scoreB - scoreA)
Then finally we update the score set html.
scoreSet.innerHTML = '';
scoreSet.appendChild(scoreItem);
const scoreSets = document.getElementsByClassName('score-set');
for(const scoreSet of scoreSets){
const [{ scoreItem }] = Array
.from(scoreSet.getElementsByClassName('score-item'), scoreItem => ({
scoreItem,
// it would be better here to access the score using the id
// but `score` is used multiple times which makes getting
// the score element unreliable
score: Number(scoreItem.querySelector('div').innerText.replace(/\D+/g, ''))
}))
.sort(({ score: scoreA }, { score: scoreB }) => scoreB - scoreA)
scoreSet.innerHTML = '';
scoreSet.appendChild(scoreItem);
}
<div class="score-set">
<div class="score-item">A
<div id="score">96+</div>
</div>
<div class="score-item">B
<div id="score">99</div>
</div>
<div class="score-item">C
<div id="score">99</div>
</div>
<div class="score-item">D
<div id="score">96-</div>
</div>
</div>
<div class="score-set">
<div class="score-item">A
<div id="score">86</div>
</div>
<div class="score-item">B
<div id="score">88</div>
</div>
<div class="score-item">C
<div id="score">90</div>
</div>
<div class="score-item">D
<div id="score">90+</div>
</div>
</div>
<div class="score-set">
<div class="score-item">A
<div id="score">83-</div>
</div>
<div class="score-item">B
<div id="score">83+</div>
</div>
<div class="score-item">C
<div id="score">76</div>
</div>
<div class="score-item">D
<div id="score">78</div>
</div>
</div>
This can be MUCH simplified
Note I changed the invalid ID to class="score"
If you cannot do that, then change .querySelector(".score") to .querySelector("div")
document.querySelectorAll('.score-set').forEach(scoreSet => {
const scores = [...scoreSet.querySelectorAll(".score-item")];
scores.sort((a,b) => parseInt(b.querySelector(".score").textContent) - parseInt(a.querySelector(".score").textContent))
scoreSet.innerHTML ="";
scoreSet.append(scores[0])
})
<div class="score-set">
<div class="score-item">A
<div class="score">96+</div>
</div>
<div class="score-item">B
<div class="score">99</div>
</div>
<div class="score-item">C
<div class="score">99</div>
</div>
<div class="score-item">D
<div class="score">96-</div>
</div>
</div>
<div class="score-set">
<div class="score-item">A
<div class="score">86</div>
</div>
<div class="score-item">B
<div class="score">88</div>
</div>
<div class="score-item">C
<div class="score">90</div>
</div>
<div class="score-item">D
<div class="score">90+</div>
</div>
</div>
<div class="score-set">
<div class="score-item">A
<div class="score">83-</div>
</div>
<div class="score-item">B
<div class="score">83+</div>
</div>
<div class="score-item">C
<div class="score">76</div>
</div>
<div class="score-item">D
<div class="score">78</div>
</div>
</div>

How to include different view in the same html page with framework7?

I'm a beginner with framework 7. I'm developing a little app and I split the html code in different files because i have a lot of pages with div in common. My problem is: I have a page.html, inside my page.html I'd like to include different div in the same windows from different html files.
for example in php we can do it with a
include("");
but in framework7 I can include only one with
<div class="view view-main view-init" data-url="/page/" data-name="page"></div>
I'd like to include more one view like this
<div class="view view-main view-init" data-url="/page1/" data-name="page1"></div>
<div class="view view-main view-init" data-url="/page2/" data-name="page2"></div>
i put an image here to explain me better.
what i'd like to do
Thank you for your help.
pages.html
<div data-name="pages" class="page">
<div class="page-content pg-no-padding">
<div class="row justify-content-center">
<div class="col-100 tablet-100 desktop-80">
<div class="block">
<form class="list" id="pages1">
<div class="row justify-content-center">
<div class="block-title">
<h1> Pages</h1>
</div> <!--block-title-->
</div><!--row-->
<div class="row">
<div class="col">
<div class="block-title">
<h2> Card 1</h2>
</div>
<div class="card">
<div class="card-content card-content-padding">
<div class="row">
<div class="col-100 tablet-auto desktop-auto">
<div class="list no-hairlines-md">
<ul>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label">Input1</div>
<div class="item-input-wrap">
<input type="number" placeholder="" name="">
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label">Input2</div>
<div class="item-input-wrap">
<input type="number" placeholder="" name="">
<span class="input-clear-button"></span>
</div>
</div>
</li>
</ul>
</div>
</div><!--col-->
</div><!--row-->
</div><!--card-content-->
</div><!--card-->
</div><!--col-->
</div><!--row-->
Here I'd like to include the code inside pages1.html
Here I'd like to include the code inside pages2.html
</form>
</div><!--block-->
<div class="block">
<a class="col button button-fill" href="#">Salva</a>
</div>
</div><!--col-100-->
</div><!--row-->
</div> <!-- ./ page-content-->
pages1.html
<div class="row">
<div class="col">
<div class="block-title">
<h2> Card2</h2>
</div>
<div class="card">
<div class="card-content card-content-padding">
<div class="row">
<div class="col-100 tablet-auto desktop-auto">
<div class="list no-hairlines-md">
<ul>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label">Input1</div>
<div class="item-input-wrap">
<input type="number" placeholder="" name="">
<span class="input-clear-button"></span>
</div>
</div>
</li>
<li class="item-content item-input">
<div class="item-inner">
<div class="item-title item-label">Input2</div>
<div class="item-input-wrap">
<input type="number" placeholder="" name="">
<span class="input-clear-button"></span>
</div>
</div>
</li>
</ul>
</div>
</div><!--col-->
</div><!--row-->
</div><!--card-content-->
</div><!--card-->
</div><!--col-->
</div><!--row-->
To include Multiple Views Layout you need to do this:
You need to create wrapper with class views like this: <div class="views tabs">
You need to create div view like this: <div class="view view-main tab tab-active" id="view-1">.related page..</div><div class="view tab" id="view-2">.related page..</div>
You need to make sure thats only one views class wrapper.
In Js: You can control multiple views by this:
var view1 = app.views.create('#view-1', {...});
var view2 = app.views.create('#view-2', {...});
For more details: F7 View
For Embedded Multi view not like tab:
Example
Note: for each view in F7 is got 100% height...you need to make sure thats height is equal 100% finally
EDIT: After a long investigation, I found from the documentation that you can do it like this:
<!-- in your views page, just add these parameter to your view you want to inherit -->
<div class="view view-init" data-url="/your-page/" data-name="home" data-push-state="true">
...
</div>
And in your routers, will need to define your route as well:
var app = new Framework7({
root: '#app',
// Create routes for all pages
routes: [
{
path: '/',
url: 'index.html',
},{
// Add your contents page route
path: '/your-page/',
url: 'pages/your-page.html',
},
.....
});
Hope this help.

Cannot set .color property in JS

<button id="change_button" class="btn btn-primary" onclick="ColorMe()">CLICK ME</button>
<div class="container">
<div class="row">
<div class="col-md-4 col-sm-4">
<div class="grid_element">
<div class="title">
COLOR IS:
</div>
</div>
</div>
<div class="col-md-4 col-sm-4">
<div class="grid_element">
<div class="title">
COLOR IS:
</div>
</div>
</div>
<div class="col-md-4 col-sm-4">
<div class="grid_element">
<div class="title">
COLOR IS:
</div>
</div>
</div>
</div>
Clicking a button is supposed to color all the elements of class "grid_element" into red but in never happens.
function ColorMe() {
document.getElementsByClassName("grid_element").style.color = ("red");
}
The problem is said to be Cannot set property 'color' of undefined
at ColorMe (js.js:2) but I know it worked in the same way many times before.
The problem is that you are attempting to use the .style property on the collection of elements found by .getElementsByClassName() instead of on each of the elements within the collection.
Also (FYI), .getElementsByClassName() returns a "live" node list, which causes the entire DOM to be re-scanned every time you access the node list variable and that can impact performance quite a bit. There are limited use cases for that, so you probably want a "static" node list more often than not. For that, use .querySelectorAll().
function ColorMe() {
// Get all the matching elements into a JavaScript Array
var elements = Array.prototype.slice.call(document.querySelectorAll(".grid_element"));
// Loop over each element....
elements.forEach(function(el){
el.style.color = "red"; // Adjust the element's style
});
}
<button id="change_button" class="btn btn-primary" onclick="ColorMe()">CLICK ME</button>
<div class="container">
<div class="row">
<div class="col-md-4 col-sm-4">
<div class="grid_element">
<div class="title">
COLOR IS:
</div>
</div>
</div>
<div class="col-md-4 col-sm-4">
<div class="grid_element">
<div class="title">
COLOR IS:
</div>
</div>
</div>
<div class="col-md-4 col-sm-4">
<div class="grid_element">
<div class="title">
COLOR IS:
</div>
</div>
</div>
</div>

How to get all elementIDs that begin with a substring

I have this code:
HTML:
<div class="lists">
<div class="list 1">
<div id="productCheese">Cheese</div>
<div id="productBread">Bread</div>
<div id="productMilk">Milk</div>
<div id="productEgg">Egg</div>
<div id="addProduct">Add new product to list...</div>
</div>
<div class="list 2">
etc...
</div>
</div>
And JavaScript: (I want to get all elements with an ID that begins with 'product', but the '*' doesn't work for me...)
var node = document.getElementById("product"*);
(And some unnecessary event listeners...)
Now my question is: how to get all the elementIDs that begin with 'product'?
Attribute Selectors will provide what you're looking for. They are used with document.querySelector and document.querySelectorAll.
In your case, you can specify the attribute id that starts with product:
var nodes = document.querySelectorAll('[id^=product]');
Working example:
var nodes = document.querySelectorAll('[id^=product]');
console.log(nodes);
<div class="lists">
<div class="list 1">
<div id="productCheese">Cheese</div>
<div id="productBread">Bread</div>
<div id="productMilk">Milk</div>
<div id="productEgg">Egg</div>
<div id="addProduct">Add new product to list...</div>
</div>
<div class="list 2">
etc...
</div>
</div>
Well you've got pseudo code there; "product"* is a parse error.
You need to use a selector via querySelectorAll.
document.querySelectorAll('[id^="product"]');
This will return a nodelist, which you can then iterate over and do with what you will.
You don't need to give an unique id to each div. Just give to them class="product" and use document.querySelectorAll('.product')
i have test this code and get the desirable result
var matches = [];
var searchEles = document.getElementById("listone").children;
for(var i = 0; i < searchEles.length; i++) {
if(searchEles[i].id.includes('product')){
matches[i]=searchEles[i];
}
}
console.log(matches);
<div class="lists">
<div class="list 1" id="listone">
<div id="productCheese">Cheese</div>
<div id="productBread">Bread</div>
<div id="productMilk">Milk</div>
<div id="productEgg">Egg</div>
<div id="addProduct">Add new product to list...</div>
</div>
<div class="list 2">
etc...
</div>
</div>
with that way too!
var IDs = [];
$("#list").find("div").each(function(){
if(this.id.includes('product')){
IDs.push(this.id);
}
});
console.log(IDs);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="lists" id="list">
<div class="list 1" id="listone">
<div id="productCheese">Cheese</div>
<div id="productBread">Bread</div>
<div id="productMilk">Milk</div>
<div id="productEgg">Egg</div>
<div id="addProduct">Add new product to list...</div>
</div>
<div class="list 2" id="listtwo">
<div id="productCheese">Cheese</div>
<div id="productewqewewew">Bread</div>
<div id="productrerereilk</div>
<div id="producttrtytrut">Egg</div>
<div id="addProductccc">Add new product to list...</div>
</div>
</div>

Use Kendo UI Flip Effects / Combined Effects for multiple items on the same page

I need to use kendo ui to display between 6-60 items. Each using the flip effect here http://demos.telerik.com/kendo-ui/fx/combined
The products will be loaded from the database with the unique id like this:
<div class="row">
<div class="col-md-4 product-container">
<div id="productID1" class="productID">
<div class="product">
<div id="product-back1" class="product-desc">
<p>BACK</p>
</div>
<div id="product-front1" class="product-image">
<p>FRONT</p>
</div>
</div>
</div>
</div>
<div class="col-md-4 product-container">
<div id="productID2" class="productID">
<div class="product">
<div id="product-back2" class="product-desc">
<p>BACK</p>
</div>
<div id="product-front2" class="product-image">
<p>FRONT</p>
</div>
</div>
</div>
</div>
<div class="col-md-4 product-container">
<div id="productID3" class="productID">
<div class="product">
<div id="product-back3" class="product-desc">
<p>BACK</p>
</div>
<div id="product-front3" class="product-image">
<p>FRONT</p>
</div>
</div>
</div>
</div>
The problem is I need multiple panels on the page how can I make each "front" and "back" click unique.
var el = kendo.fx($('div[id^=productID]')),
flip = el.flip("horizontal", $('div[id^=product-front]'), $('div[id^=product-back]')),
zoom = el.zoomIn().startValue(1).endValue(1);
flip.add(zoom).duration(200);
$('div[id^=product-front]').click(function () {
flip.stop().play();
});
$('div[id^=product-back]').click(function () {
flip.stop().reverse();
});
I've tried loading each item into an array but have not found a good way to assure the correct item will be flipped.
Since every div[id^=product-front] is a child of div[id^=productID], you can find the children of that and use it.
replace flip.stop().play(); with
kendo.fx($(this)).flip("horizontal", $(this).children()[0], $(this).children()[1]).stop().play();

Categories