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

Time:09-07

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  style="left: 0px; top: 2px;"><div  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 >
                <div style="display: flex; align-items:center; justify-content: center;">
                    <div >o</div>
                </div>
                    <div id="id0" >
                        <div style="text-align: left;">
                            <span style="width: 15%; display:inline-block; text-align: right;">ID:</span><input  style="width: 15%; display:inline-block;" readonly="" type="number" value="1">
                        </div>
                        <input type="text"  placeholder="character name" value="MIKE">
                        <select name="blockType" >
                            <option value="line">Line</option>
                            <option value="question">Question</option>
                            <option value="fight">Fight</option>

                        </select>
                        <textarea  placeholder="Type the dialogue here" value="FIRST NODE" style="box-sizing: border-box;"></textarea>
                        <div>
                        <div  style="text-align: right;">
                            <div ></div>
                            <div ></div>
                            <div >
                                <span style=" text-align: right;">Next:</span><input  style="display:inline-block;" type="number">
                            </div>
                        </div>
                        </div>

                        
                    </div>
                    <div  style="display: flex; align-items: end; justify-content: center;">
                        <div  data-buttonindex="0" data-acceptclicks="false">-</div>
                    </div>
                </div><!-- end contentwrap -->
                
            <div  style="top: 294.969px; left: 145.297px;"><div  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 >
                    <div style="display: flex; align-items:center; justify-content: center;">
                        <div >o</div>
                    </div>
                        <div id="id1" >
                            <div style="text-align: left;">
                                <span style="width: 15%; display:inline-block; text-align: right;">ID:</span><input  style="width: 15%; display:inline-block;" readonly="" type="number" value="2">
                            </div>
                            <input type="text"  placeholder="character name" value="MIKE">
                            

            <select name="blockType" >
                <option value="line">Line</option>
                <option value="question">Question</option>
                <option value="fight">Fight</option>
            </select>
            
                            <textarea  placeholder="Type the dialogue here" style="box-sizing: border-box;">CHILD NODE FOR TESTING</textarea>
                            <div>
                            <div  style="text-align: right;">
                                <div ></div>
                                <div ></div>
                                <div >
                                    <span style=" text-align: right;">Next:</span><input  style="display:inline-block;" type="number">
                                </div>
                            </div>
                            </div>

                            
                        </div>
                        <div  style="display: flex; align-items: end; justify-content: center;">
                            <div  data-buttonindex="0" data-acceptclicks="false">-</div>
                        </div>
                    </div>
                    
                <div  style="top: 225.969px; left: -120.703px;"><div  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  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  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 >
                    <div style="display: flex; align-items:center; justify-content: center;">
                        <div >o</div>
                    </div>
                        <div id="id2" >
                            <div style="text-align: left;">
                                <span style="width: 15%; display:inline-block; text-align: right;">ID:</span><input  style="width: 15%; display:inline-block;" readonly="" type="number" value="3">
                            </div>
                            <input type="text"  placeholder="character name" value="MIKE">
                            

            <select name="blockType" >
                <option value="line">Line</option>
                <option value="question">Question</option>
                <option value="fight">Fight</option>
            </select>
            
                            <textarea  placeholder="Type the question" style="box-sizing: border-box;">CHILD NODE FOR TESTING</textarea>
                            <div>
                            <div  style="text-align: right;">
                                <div >
            Answers: <input  type="number" min="2" max="9" value="3">
        </div>
                                <div ></div>
                                <div >
                                    <span style=" text-align: right;">Next:</span><input  style="display:inline-block;" type="number">
                                </div>
                            </div>
                            </div>

                            
                        </div>
                        <div  style="display: flex; align-items: end; justify-content: center;">
                            <div  data-buttonindex="0" data-acceptclicks="false">-</div>
                        <div  data-buttonindex="1" data-acceptclicks="false">-</div><div  data-buttonindex="2" data-acceptclicks="false">-</div></div>
                    </div>
                    
                <div  style="top: 225.969px; left: -94px;">
                <div >
                    <div style="display: flex; align-items:center; justify-content: center;">
                        <div >o</div>
                    </div>
                        <div id="id3" >
                            <div style="text-align: left;">
                                <span style="width: 15%; display:inline-block; text-align: right;">ID:</span><input  style="width: 15%; display:inline-block;" readonly="" type="number" value="3">
                            </div>
                            <input type="text"  placeholder="character name" value="MIKE">
                            

            <select name="blockType" >
                <option value="answer0">answer</option>
            </select>
            
                            <textarea  placeholder="Type the answer option here" style="box-sizing: border-box;">CHILD NODE FOR TESTING</textarea>
                            <div>
                            <div  style="text-align: right;">
                                <div ></div>
                                <div ></div>
                                <div >
                                    <span style=" text-align: right;">Next:</span><input  style="display:inline-block;" type="number">
                                </div>
                            </div>
                            </div>

                            
                        </div>
                        <div  style="display: flex; align-items: end; justify-content: center;">
                            <div  data-buttonindex="0" data-acceptclicks="true"> </div>
                        </div>
                    </div>
                    
                </div><div  style="top: 225.969px; left: 138px;">
                <div >
                    <div style="display: flex; align-items:center; justify-content: center;">
                        <div >o</div>
                    </div>
                        <div id="id4" >
                            <div style="text-align: left;">
                                <span style="width: 15%; display:inline-block; text-align: right;">ID:</span><input  style="width: 15%; display:inline-block;" readonly="" type="number" value="3">
                            </div>
                            <input type="text"  placeholder="character name" value="MIKE">
                            

            <select name="blockType" >
                <option value="answer1">answer</option>
            </select>
            
                            <textarea  placeholder="Type the answer option here" style="box-sizing: border-box;">CHILD NODE FOR TESTING</textarea>
                            <div>
                            <div  style="text-align: right;">
                                <div ></div>
                                <div ></div>
                                <div >
                                    <span style=" text-align: right;">Next:</span><input  style="display:inline-block;" type="number">
                                </div>
                            </div>
                            </div>

                            
                        </div>
                        <div  style="display: flex; align-items: end; justify-content: center;">
                            <div  data-buttonindex="0" data-acceptclicks="true"> </div>
                        </div>
                    </div>
                    
                </div><div  style="top: 225.969px; left: 371px;"><div  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 >
                    <div style="display: flex; align-items:center; justify-content: center;">
                        <div >o</div>
                    </div>
                        <div id="id5" >
                            <div style="text-align: left;">
                                <span style="width: 15%; display:inline-block; text-align: right;">ID:</span><input  style="width: 15%; display:inline-block;" readonly="" type="number" value="3">
                            </div>
                            <input type="text"  placeholder="character name" value="MIKE">
                            

            <select name="blockType" >
                <option value="answer2">answer</option>
            </select>
            
                            <textarea  placeholder="Type the answer option here" style="box-sizing: border-box;">CHILD NODE FOR TESTING</textarea>
                            <div>
                            <div  style="text-align: right;">
                                <div ></div>
                                <div ></div>
                                <div >
                                    <span style=" text-align: right;">Next:</span><input  style="display:inline-block;" type="number">
                                </div>
                            </div>
                            </div>

                            
                        </div>
                        <div  style="display: flex; align-items: end; justify-content: center;">
                            <div  data-buttonindex="0" data-acceptclicks="false">-</div>
                        </div>
                    </div>
                    
                <div  style="top: 219.969px; left: -123.703px;">
                <div >
                    <div style="display: flex; align-items:center; justify-content: center;">
                        <div >o</div>
                    </div>
                        <div id="id6" >
                            <div style="text-align: left;">
                                <span style="width: 15%; display:inline-block; text-align: right;">ID:</span><input  style="width: 15%; display:inline-block;" readonly="" type="number" value="4">
                            </div>
                            <input type="text"  placeholder="character name" value="MIKE">
                            

            <select name="blockType" >
                <option value="line">Line</option>
                <option value="question">Question</option>
                <option value="fight">Fight</option>
            </select>
            
                            <textarea  placeholder="Type the dialogue here" style="box-sizing: border-box;">CHILD NODE FOR TESTING</textarea>
                            <div>
                            <div  style="text-align: right;">
                                <div ></div>
                                <div ></div>
                                <div >
                                    <span style=" text-align: right;">Next:</span><input  style="display:inline-block;" type="number">
                                </div>
                            </div>
                            </div>

                            
                        </div>
                        <div  style="display: flex; align-items: end; justify-content: center;">
                            <div  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.

CodePudding user response:

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
  • Related