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>
Related
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>
I need to move some text from demoBoxA to demoBoxB.
The demoBoxA parent element has an id selector, but the child element below it has no identifiable selector.
Is it possible to select the text content directly? Then move it into the demoBoxB sub-element (the demoBoxB sub-element has an id selector)
There are 2 difficulties with this issue.
The content of demoBoxA is dynamically generated by the program and the sort is not fixed. There are no identifiable selectors for the subelements.
only need to select part of the content. For example, in the example below, just move the phone model text of "Google", "Huawei", "BlackBerry".
Any help, thanks in advance!
<div class="container" id="demoBoxA">
<div class="row">
<div class="col-md-6">Samsung</div>
<div class="col-md-6">Galaxy S10</div>
</div>
<div class="row">
<div class="col-md-6">Google</div>
<div class="col-md-6">Pixel 4</div>
</div>
<div class="row">
<div class="col-md-6">Sony</div>
<div class="col-md-6">Xperia 5</div>
</div>
<div class="row">
<div class="col-md-6">Huawei</div>
<div class="col-md-6">Mate 30 5G</div>
</div>
<div class="row">
<div class="col-md-6">BlackBerry</div>
<div class="col-md-6">KEY2</div>
</div>
<div class="row">
<div class="col-md-6">Apple</div>
<div class="col-md-6">iPhone 8</div>
</div>
</div>
<div class="container" id="demoBoxB">
<div class="row">
<div class="col-md-6">Google</div>
<div class="col-md-6" id="pixel"></div>
</div>
<div class="row">
<div class="col-md-6">Huawei</div>
<div class="col-md-6" id="mate"></div>
</div>
<div class="row">
<div class="col-md-6">BlackBerry</div>
<div class="col-md-6" id="key2"></div>
</div>
</div>
You can chain selectors like this:
var rows = document.querySelectorAll("#demoBoxA > .row");
That will return a list of all rows inside of demoBoxA. If you need more info about chaining selectors, you can read about it here.
Then, to move the rows you can do this:
var demoBoxB = document.getElementById('demoBoxB');
rows.forEach((row) => {
demoBoxB.appendChild(row);
});
If you just want the text inside each of the columns, you can do this:
var columns = document.querySelectorAll("#demoBoxA > .col-md-6");
var texts = [];
columns.forEach((column) => {
texts.push(column.innerText);
});
Now, texts is an array of the text contents of each column.
If you want to select the cellphone models for each brand, you can do this:
var cols = Array.from(document.querySelectorAll("#demoBoxA > .col-md-6"));
var samsungCol = cols.find((col) => {
return col.textContent == "Samsung";
});
var samsungPhones = [];
samsungCol.parentNode.childNodes.forEach((col) => {
if (col != samsungCol) {
samsungPhones.push(col);
}
});
Now, samsungPhones is a list of columns, one for each Samsung phone (for example).
You can use html drag api .
Just add draggable=true for elements you want to drag and add event listeners for dragstart and dragend
html
<div class="container" id="demoBoxA">
<div class="row " draggable="true">
<div class="col-md-6">Samsung</div>
<div class="col-md-6">Galaxy S10</div>
</div>
<div class="row" draggable="true">
<div class="col-md-6">Google</div>
<div class="col-md-6">Pixel 4</div>
</div>
<div class="row" draggabble="true">
<div class="col-md-6">Sony</div>
<div class="col-md-6">Xperia 5</div>
</div>
</div>
<div class="container " id="demoBoxB">
<div class="row " draggable="true">
<div class="col-md-6">Google</div>
<div class="col-md-6" id="pixel"></div>
</div>
<div class="row" draggable="true">
<div class="col-md-6">Huawei</div>
<div class="col-md-6" id="mate"></div>
</div>
<div class="row" draggable="true">
<div class="col-md-6">BlackBerry</div>
<div class="col-md-6" id="key2"></div>
</div>
</div>
js
document.addEventListener('dragstart', function(e)
{
item = e.target;
}, false);
document.addEventListener('dragend', function(e)
{
document.getElementById("demoBoxB").appendChild(item)
}, false);
Note : you might have to add conditions to check whether the drop is actually happening in demoboxB
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)
Here, I have two different container. First one is group of anchor links. There is no elements in html. Section one different group of content blocks. How to an append elements based on group of content blocks.
Here is my html,
<div id="group1">
<div class="parent1">
</div>
<div class="parent2">
</div>
<div class="parent3">
</div>
</div>
<div id="group2">
<div class="parentMain1">
<div class="content">test</div>
<div class="content">test</div>
<div class="content">test</div>
</div>
<div class="parentMain2">
<div class="content">test</div>
<div class="content">test</div>
</div>
<div class="parentMain3">
<div class="content">test</div>
</div>
</div>
My result should be,
<div id="group1">
<div class="parent1">
1
2
3
</div>
<div class="parent2">
1
2
</div>
<div class="parent3">
1
</div>
</div>
<div id="group2">
<div class="parentMain1">
<div class="content">test</div>
<div class="content">test</div>
<div class="content">test</div>
</div>
<div class="parentMain2">
<div class="content">test</div>
<div class="content">test</div>
</div>
<div class="parentMain3">
<div class="content">test</div>
</div>
</div>
How to achieve this one with jquery?
You can try this code :
// get all direct child of group 2 element
$('#group2').children().each(function (i, e) {
// get direct child of group 2 element's child
var length = $(this).children().length;
// loop over particular length
for (var m = 1; m <= length; m++) {
// create anchor element
$('<a/>', {
href: '#',
text: m
}).appendTo($('div#group1').find('div:eq(' + i + ')')); // append to group 1 element respectively
}
});
DEMO
What I want to achieve using jQuery probably is to rearrange the positions of the following sections on page load, in 2 ways. The first is to sort it by data-order value ascending, and the other through an array where it will be in this sorting 3-1-2
How can this be achieved?
<section class="aboutus" data-order="1">
<div class="container">
<div class="row">
<div class="col-sm-12">
<p>content here</p>
</div>
</div>
</div>
</section>
<section class="questions" data-order="3">
<div class="container">
<div class="row">
<div class="col-sm-12">
<p>content here</p>
</div>
</div>
</div>
</section>
<section class="contact" data-order="2">
<div class="container">
<div class="row">
<div class="col-sm-12">
<p>content here</p>
</div>
</div>
</div>
</section>
I found this code that uses an array for this, however it requires specific classes, but I want it to be as universal as possible, no classes or ids.
var myArray = ['2', '3', '1'];
var elArray = [];
$('.imgs').each(function() {
elArray[$(this).data('image-id')] = $(this);
});
$.each(myArray,function(index,value){
$('#container').append(elArray[value]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div id='container'>
<div class="imgs" data-image-id='1'>1</div>
<div class="imgs" data-image-id='2'>2</div>
<div class="imgs" data-image-id='3'>3</div>
</div>
Try
// elements
var elems = $("[data-order]");
// ordering map
var elArray = ["3", "1", "2"];
// replace `elems` `outerHTML`
$.map(elArray, function(order, i) {
var el = elems.filter(function() {
// ie < 11 does not appear to support `dataset`
// jQuery `.data()` appear to cast `String` "3" to `Number` `3`
// utilize equality operator `==` to convert operands
return $(this).data("order") == order
});
elems.eq(i)[0].outerHTML = el[0].outerHTML
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<section class="aboutus" data-order="1">
<div class="container">
<div class="row">
<div class="col-sm-12">
<p>content here 1</p>
</div>
</div>
</div>
</section>
<section class="questions" data-order="3">
<div class="container">
<div class="row">
<div class="col-sm-12">
<p>content here 3</p>
</div>
</div>
</div>
</section>
<section class="contact" data-order="2">
<div class="container">
<div class="row">
<div class="col-sm-12">
<p>content here 2</p>
</div>
</div>
</div>
</section>
jsfiddle http://jsfiddle.net/saf77L4w/4/
You can obtain the element just using their data-sort attribute (although this will place all items on the page in the same sorted list, so you would have to restrict this if you wanted to use it multiple times on a page).
var elArray = [];
$('[data-order]').each(function() {
elArray[$(this).data('order')] = this;
});
for(var i = 0; i < elArray.length; i++) {
if (typeof elArray[i] === 'undefined') continue;
$('#result').append(elArray[i]);
}
I have added an element with the id "result" to place the sorted items in - but you can do this differently if you wish.
See it running on JSFiddle.