I’m creating an application that takes elements from a web page and exports json data.
I’m selecting all parent elements with jQuery and iterating over them. But I need to sort the collection before iterating so that the json exporter has the objects in a specific order and I need to do it based on nested child’s input value.
I don’t want to change the actual DOM, so my attempt so far has been to convert the jQuery collection to an actual array using toArray() but I’m not sure if that makes any sense. I’m stuck trying to sort the parent elements based on a value from the nested input in this array.
Here is my failed attempt at sorting:
//select all blockWraps
let blockWraps = $('.blockWrap');
beforeSort = blockWraps;
jqueryArray = blockWraps.toArray();
//lets try to sort to storyId order
function getSorted(arrayToSort) {
return arrayToSort.sort(function (a, b) {
console.log();
var aVal = parseInt(a.children[1].children[1].children[0].children[1]),
bVal = parseInt(b.children[1].children[1].children[0].children[1]);
return aVal - bVal;
});
}
afterSort = getSorted(jqueryArray);
My current attempt is pretty terrible, since it’s very prone to failure should some elements have a different amount of children.
Next I will paste in a sample element from a single parent element from the jQuery array. Let’s say I have six of these kinds of elements in my array. How can I sort the six ".blockWrap" elements in memory (but not in DOM) based on the value of the input of class ".blockid"?
So here’s how an entire parent element from the array looks like (there are several of these blockWrap parents in the array, but I didn’t want to repeat the code unnecessarily):
<div class="blockWrap characterRoot ui-draggable ui-draggable-handle" style="left: 0px; top: 2px;"><div class="line" data-block1="id0" data-block2="id1" data-buttonindextoconnectto="0" style="position: absolute; transform: rotate(54.0234deg); width: 123.068px; top: 210.906px; left: 196.297px;"></div>
<div class="contentWrap">
<div style="display: flex; align-items:center; justify-content: center;">
<div class="topConnectionSocket">o</div>
</div>
<div id="id0" class="block">
<div style="text-align: left;">
<span style="width: 15%; display:inline-block; text-align: right;">ID:</span><input class="blockid" style="width: 15%; display:inline-block;" readonly="" type="number" value="1">
</div>
<input type="text" class="characterName elementInfoField" placeholder="character name" value="MIKE">
<select name="blockType" class="selectBlockType">
<option value="line">Line</option>
<option value="question">Question</option>
<option value="fight">Fight</option>
</select>
<textarea class="dialogue" placeholder="Type the dialogue here" value="FIRST NODE" style="box-sizing: border-box;"></textarea>
<div>
<div class="optionsUnderDialogue" style="text-align: right;">
<div class="option1"></div>
<div class="option2"></div>
<div class="option3">
<span style=" text-align: right;">Next:</span><input class="next" style="display:inline-block;" type="number">
</div>
</div>
</div>
</div>
<div class="plusButtonContainer" style="display: flex; align-items: end; justify-content: center;">
<div class="blockPlusButton disabled" data-buttonindex="0" data-acceptclicks="false">-</div>
</div>
</div><!-- end contentwrap -->
<div class="blockWrap ui-draggable ui-draggable-handle" style="top: 294.969px; left: 145.297px;"><div class="line" data-block1="id1" data-block2="id2" data-buttonindextoconnectto="0" style="position: absolute; transform: rotate(166.449deg); width: 83.6247px; top: 218.969px; left: 125.282px;"></div>
<div class="contentWrap">
<div style="display: flex; align-items:center; justify-content: center;">
<div class="topConnectionSocket">o</div>
</div>
<div id="id1" class="block">
<div style="text-align: left;">
<span style="width: 15%; display:inline-block; text-align: right;">ID:</span><input class="blockid" style="width: 15%; display:inline-block;" readonly="" type="number" value="2">
</div>
<input type="text" class="characterName elementInfoField" placeholder="character name" value="MIKE">
<select name="blockType" class="selectBlockType">
<option value="line">Line</option>
<option value="question">Question</option>
<option value="fight">Fight</option>
</select>
<textarea class="dialogue" placeholder="Type the dialogue here" style="box-sizing: border-box;">CHILD NODE FOR TESTING</textarea>
<div>
<div class="optionsUnderDialogue" style="text-align: right;">
<div class="option1"></div>
<div class="option2"></div>
<div class="option3">
<span style=" text-align: right;">Next:</span><input class="next" style="display:inline-block;" type="number">
</div>
</div>
</div>
</div>
<div class="plusButtonContainer" style="display: flex; align-items: end; justify-content: center;">
<div class="blockPlusButton disabled" data-buttonindex="0" data-acceptclicks="false">-</div>
</div>
</div>
<div class="blockWrap ui-draggable ui-draggable-handle" style="top: 225.969px; left: -120.703px;"><div class="line" data-block1="id2" data-block2="id5" data-buttonindextoconnectto="2" style="position: absolute; transform: rotate(4.05637deg); width: 276.991px; top: 223.956px; left: 216px;"></div><div class="line" data-block1="id2" data-block2="id4" data-buttonindextoconnectto="1" style="position: absolute; transform: rotate(14.4028deg); width: 78.7726px; top: 223.812px; left: 184px;"></div><div class="line" data-block1="id2" data-block2="id3" data-buttonindextoconnectto="0" style="position: absolute; transform: rotate(166.449deg); width: 83.6247px; top: 218.969px; left: 151.985px;"></div>
<div class="contentWrap">
<div style="display: flex; align-items:center; justify-content: center;">
<div class="topConnectionSocket">o</div>
</div>
<div id="id2" class="block selected">
<div style="text-align: left;">
<span style="width: 15%; display:inline-block; text-align: right;">ID:</span><input class="blockid" style="width: 15%; display:inline-block;" readonly="" type="number" value="3">
</div>
<input type="text" class="characterName elementInfoField" placeholder="character name" value="MIKE">
<select name="blockType" class="selectBlockType">
<option value="line">Line</option>
<option value="question">Question</option>
<option value="fight">Fight</option>
</select>
<textarea class="dialogue" placeholder="Type the question" style="box-sizing: border-box;">CHILD NODE FOR TESTING</textarea>
<div>
<div class="optionsUnderDialogue" style="text-align: right;">
<div class="option1">
Answers: <input class="answerNumber" type="number" min="2" max="9" value="3">
</div>
<div class="option2"></div>
<div class="option3">
<span style=" text-align: right;">Next:</span><input class="next" style="display:inline-block;" type="number">
</div>
</div>
</div>
</div>
<div class="plusButtonContainer" style="display: flex; align-items: end; justify-content: center;">
<div class="blockPlusButton disabled" data-buttonindex="0" data-acceptclicks="false">-</div>
<div class="blockPlusButton disabled" data-buttonindex="1" data-acceptclicks="false">-</div><div class="blockPlusButton disabled" data-buttonindex="2" data-acceptclicks="false">-</div></div>
</div>
<div class="blockWrap ui-draggable ui-draggable-handle" style="top: 225.969px; left: -94px;">
<div class="contentWrap">
<div style="display: flex; align-items:center; justify-content: center;">
<div class="topConnectionSocket">o</div>
</div>
<div id="id3" class="block">
<div style="text-align: left;">
<span style="width: 15%; display:inline-block; text-align: right;">ID:</span><input class="blockid" style="width: 15%; display:inline-block;" readonly="" type="number" value="3">
</div>
<input type="text" class="characterName elementInfoField" placeholder="character name" value="MIKE">
<select name="blockType" class="selectBlockType">
<option value="answer0">answer</option>
</select>
<textarea class="dialogue" placeholder="Type the answer option here" style="box-sizing: border-box;">CHILD NODE FOR TESTING</textarea>
<div>
<div class="optionsUnderDialogue" style="text-align: right;">
<div class="option1"></div>
<div class="option2"></div>
<div class="option3">
<span style=" text-align: right;">Next:</span><input class="next" style="display:inline-block;" type="number">
</div>
</div>
</div>
</div>
<div class="plusButtonContainer" style="display: flex; align-items: end; justify-content: center;">
<div class="blockPlusButton" data-buttonindex="0" data-acceptclicks="true">+</div>
</div>
</div>
</div><div class="blockWrap ui-draggable ui-draggable-handle" style="top: 225.969px; left: 138px;">
<div class="contentWrap">
<div style="display: flex; align-items:center; justify-content: center;">
<div class="topConnectionSocket">o</div>
</div>
<div id="id4" class="block">
<div style="text-align: left;">
<span style="width: 15%; display:inline-block; text-align: right;">ID:</span><input class="blockid" style="width: 15%; display:inline-block;" readonly="" type="number" value="3">
</div>
<input type="text" class="characterName elementInfoField" placeholder="character name" value="MIKE">
<select name="blockType" class="selectBlockType">
<option value="answer1">answer</option>
</select>
<textarea class="dialogue" placeholder="Type the answer option here" style="box-sizing: border-box;">CHILD NODE FOR TESTING</textarea>
<div>
<div class="optionsUnderDialogue" style="text-align: right;">
<div class="option1"></div>
<div class="option2"></div>
<div class="option3">
<span style=" text-align: right;">Next:</span><input class="next" style="display:inline-block;" type="number">
</div>
</div>
</div>
</div>
<div class="plusButtonContainer" style="display: flex; align-items: end; justify-content: center;">
<div class="blockPlusButton" data-buttonindex="0" data-acceptclicks="true">+</div>
</div>
</div>
</div><div class="blockWrap ui-draggable ui-draggable-handle" style="top: 225.969px; left: 371px;"><div class="line" data-block1="id5" data-block2="id6" data-buttonindextoconnectto="0" style="position: absolute; transform: rotate(166.449deg); width: 83.6247px; top: 212.969px; left: 122.282px;"></div>
<div class="contentWrap">
<div style="display: flex; align-items:center; justify-content: center;">
<div class="topConnectionSocket">o</div>
</div>
<div id="id5" class="block">
<div style="text-align: left;">
<span style="width: 15%; display:inline-block; text-align: right;">ID:</span><input class="blockid" style="width: 15%; display:inline-block;" readonly="" type="number" value="3">
</div>
<input type="text" class="characterName elementInfoField" placeholder="character name" value="MIKE">
<select name="blockType" class="selectBlockType">
<option value="answer2">answer</option>
</select>
<textarea class="dialogue" placeholder="Type the answer option here" style="box-sizing: border-box;">CHILD NODE FOR TESTING</textarea>
<div>
<div class="optionsUnderDialogue" style="text-align: right;">
<div class="option1"></div>
<div class="option2"></div>
<div class="option3">
<span style=" text-align: right;">Next:</span><input class="next" style="display:inline-block;" type="number">
</div>
</div>
</div>
</div>
<div class="plusButtonContainer" style="display: flex; align-items: end; justify-content: center;">
<div class="blockPlusButton disabled" data-buttonindex="0" data-acceptclicks="false">-</div>
</div>
</div>
<div class="blockWrap ui-draggable ui-draggable-handle" style="top: 219.969px; left: -123.703px;">
<div class="contentWrap">
<div style="display: flex; align-items:center; justify-content: center;">
<div class="topConnectionSocket">o</div>
</div>
<div id="id6" class="block">
<div style="text-align: left;">
<span style="width: 15%; display:inline-block; text-align: right;">ID:</span><input class="blockid" style="width: 15%; display:inline-block;" readonly="" type="number" value="4">
</div>
<input type="text" class="characterName elementInfoField" placeholder="character name" value="MIKE">
<select name="blockType" class="selectBlockType">
<option value="line">Line</option>
<option value="question">Question</option>
<option value="fight">Fight</option>
</select>
<textarea class="dialogue" placeholder="Type the dialogue here" style="box-sizing: border-box;">CHILD NODE FOR TESTING</textarea>
<div>
<div class="optionsUnderDialogue" style="text-align: right;">
<div class="option1"></div>
<div class="option2"></div>
<div class="option3">
<span style=" text-align: right;">Next:</span><input class="next" style="display:inline-block;" type="number">
</div>
</div>
</div>
</div>
<div class="plusButtonContainer" style="display: flex; align-items: end; justify-content: center;">
<div class="blockPlusButton" data-buttonindex="0" data-acceptclicks="true">+</div>
</div>
</div>
</div></div></div></div></div>
Let me finish by saying that my whole approach to this might be unnecessarily complicated and might very well be missing something obvious.
>Solution :
Since the a and b passed to your sort callback function are DOM elements, you can call methods like querySelector on them.
So instead of trying to find your input by its specific "position" within the descendant structure, you can select it via its class, and then get its value:
a.querySelector('.blockid').value