I have a HTML list with rearrangable divs, they can be moved up and down, once rearranged I need to change the array with the same order of the HTML elements.
HTML:
<div id="List">
<div id="listUnit2" class="row">
<div class="text-center" style="width:50px;">
<p>Orange</p>
</div>
</div>
<div id="listUnit1" class="row">
<div class="text-center" style="width:50px;">
<p>Pear</p>
</div>
</div>
<div id="listUnit0" class="row">
<div class="text-center" style="width:50px;">
<p>Apple</p>
</div>
</div>
</div>
Array:
"listArray": [
{
"id": 0,
"name": "apple",
},
{
"id": 1,
"name": "pear",
},
{
"id": 2,
"name": "orange",
},
]
How can I get this result using the id value as a reference?
"listArray": [
{
"id": 2,
"name": "orange",
},
{
"id": 1,
"name": "pear",
},
{
"id": 0,
"name": "apple",
},
]
I tried:
var unitsRows = document.querySelectorAll("#list .row");
var newList = [];
for (var row of unitsRows) {
var rowId = row.id
rowId = rowId.replace('listUnit', "");
var newEl = listArray[rowId];
newList.push(newEl);
}
listArray = newList;
The order of the objects changes but it's not the same of the HTML after some rearrangmet.
You can do this every time it changes.
I had to fix your invalid markup
const listArray = [...document.querySelectorAll("#List .row")]
.map(row => ({ id: +row.id.match(/\d+/g), name: row.querySelector('div').textContent.trim() }))
console.log(listArray)
<div id="List">
<div id="listUnit2" class="row">
<div class="text-center" style="width:50px;">
<p>Orange</p>
</div>
</div>
<div id="listUnit1" class="row">
<div class="text-center" style="width:50px;">
<p>Pear</p>
</div>
</div>
<div id="listUnit0" class="row">
<div class="text-center" style="width:50px;">
<p>Apple</p>
</div>
</div>
</div>
1- Your html code is wrong, modify the structure.
2- You have an element with id='List', not an element with class=list. And you need the children of that div, So modify your selector:
var unitsRows = document.querySelectorAll("#List .row");
3- Get text of p element with:
let text = document.querySelectorAll(`#${itm.id} p`)[0].textContent.trim();
var unitsRows = document.querySelectorAll("#List .row");
let newList = [];
unitsRows.forEach(itm => {
let text = document.querySelectorAll(`#${itm.id} p`)[0].textContent.trim();
newList.push({
id: itm.id.replace('listUnit', ""),
text
})
})
console.log(newList)
<div id="List">
<div id="listUnit2" class="row">
<div class="text-center" style="width:50px;">
<p>Orange</p>
</div>
</div>
<div id="listUnit1" class="row">
<div class="text-center" style="width:50px;">
<p>Pear</p>
</div>
</div>
<div id="listUnit0" class="row">
<div class="text-center" style="width:50px;">
<p>Apple</p>
</div>
</div>
</div>
You can get the list on UI, then you sort the listArray based on it.
listArray.sort(function (a, b) {
return names.indexOf(a.name) - names.indexOf(b.name);
});
I updated your code and print the result in the console. You can check it:
var listArray = new Array({
"id": 0,
"name": "apple",
}, {
"id": 1,
"name": "pear",
}, {
"id": 2,
"name": "orange",
});
var unitsRows = document.querySelectorAll(".row p");
var names = [];
[].forEach.call(unitsRows, function(item) {
names.push(item.innerHTML.toLowerCase());
});
listArray.sort(function (a, b) {
return names.indexOf(a.name) - names.indexOf(b.name);
});
console.log('Result', listArray);
<div id="List">
<div id="listUnit2" class="row">
<div class="text-center" style="width:50px;">
<p>Orange</p>
</div>
</div>
</div>
<div id="listUnit1" class="row">
<div class="text-center" style="width:50px;">
<p>Pear</p>
</div>
</div>
</div>
</div>
<div id="listUnit0" class="row">
<div class="text-center" style="width:50px;">
<p>Apple</p>
</div>
</div>
</div>
</div>