Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Sort elements in a jQuery collection based on a nested input value, but don't change the DOM

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading