First part [solved]
Given this HTML
<div id="search_filters">
<section class="facet clearfix"><p>something</p><ul>...</ul></section>
<section class="facet clearfix"><p>something1</p><ul>...</ul></section>
<section class="facet clearfix"><p>something2</p><ul>...</ul></section>
<section class="facet clearfix"><p>something3</p><ul>...</ul></section>
<section class="facet clearfix"><p>something4</p><ul>...</ul></section>
</div>
I can select all the section with
const select = document.querySelectorAll('section[class^="facet clearfix"]');
The result is a nodelist with 5 children.
What I'm trying to accomplish is to select only the section containing the "something3" string.
This is my first attempt:
`const xpathResult = document.evaluate( //section[p[contains(.,'something3')]],
select, null, XPathResult.ANY_TYPE, null );
How can I filter the selection to select only the node I need?
Second part:
Sorry for keeping update the question but it seems this is a problem out of my actual skill.. Now that i get the Node i need to work in what i've to do it's to set a custom order of the li in the sections:
<ul id="" class="collapse">
<li>
<label>
<span>
<input>
<span>
<a> TEXT
</a>
</span>
</input>
</span>
</label>
</li>
<li>..</li>
Assuming there are n
var sorOrder = ['text2','text1','text4','text3']
I think this approach should lead you to the solution. Giving your HTML
<div id="search_filters">
<section class="facet clearfix"><p>something</p><ul>...</ul></section>
<section class="facet clearfix"><p>something1</p><ul>...</ul></section>
<section class="facet clearfix"><p>something2</p><ul>...</ul></section>
<section class="facet clearfix"><p>something3</p><ul>...</ul></section>
<section class="facet clearfix"><p>something4</p><ul>...</ul></section>
</div>
I would write this js
const needle = "something3";
const selection = document.querySelectorAll('section.facet.clearfix');
let i = -1;
console.info("SELECTION", selection);
let targetIndex;
while(++i < selection.length){
if(selection[i].innerHTML.indexOf(needle) > -1){
targetIndex = i;
}
}
console.info("targetIndex", targetIndex);
console.info("TARGET", selection[targetIndex]);
Then you can play and swap elements around without removing them from the DOM.
PS. Since you know the CSS classes for the elements you don't need to use the ^*
(start with) selector. I also improved that.
PART 2: ordering children li based on content
const ul = selection[targetIndex].querySelector("ul"); // Find the <ul>
const lis = ul.querySelectorAll("li"); // Find all the <li>
const sortOrder = ['text2', 'text1', 'text4', 'text3'];
i = -1; // We already declared this above
while(++i < sortOrder.length){
const li = [...lis].find((li) => li.innerHTML.indexOf(sortOrder[i]) > -1);
!!li && ul.appendChild(li);
}
This will move the elements you want (only the one listed in sortOrder
) in the order you need, based on the content and the position in sortOrder
.