Let row indices equal the visual order?

Let row indices equal the visual order?

dredgydredgy Posts: 16Questions: 5Answers: 0

I have a datatable that is used as an input to a database, with the order being manually decided by the user (whatever the user inputs is placed verbatim into the DB).

This means I want the user to be able to insert rows at any point in the data table. Sometimes rows will group together under a "parent". You can see my previous thread for that, but basically each row is classed as either a "normal" row or an "instruction row". Instruction rows are differentiated by a CSS class (for styling reasons) as well a hidden column "rowType". I also have an additional "key" column which is used for ordering. Rows that belong together (so a parent & all of the instructions below it) all have the same key, which means a row can be visually inserted below another row.

Unfortunately, the indices don't reflect the visual order, which gives a few undesired behaviors.

Is there a way to make the indices match the visual order of the table? Even if it's something quick and dirty like convert the table to HTML, then reinitialize it? Preferably while maintaining classes on trs and tds. Or any other way?

Answers

  • kthorngrenkthorngren Posts: 21,173Questions: 26Answers: 4,923
    edited November 2020

    Is there a way to make the indices match the visual order of the table?

    The Datatable indexes are based on the order of the rows as they are added to the table.

    Sounds like you can order the table by the "key" column then by the "rowType" column to achieve what you want. Suspect you are already doing this. Then when the new row is added it should be inserted under the parent row. Are you trying to push this to the end of that group? If yes, do each of the instruction rows have a unique incrementing ID that we can use for the sorting?

    Sounds like you can use the "key" column to simplify the solution in your other thread. It can be used as part of a filter to to fetch all the rows with that key for to use the select() API.

    Can you build a simple test case that has an example of your data so we can help with ideas of how to achieve your solution?
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • dredgydredgy Posts: 16Questions: 5Answers: 0

    Yes my function ended up being a tiny bit different than what you suggest in the last thread (though iirc it still just iterates through adjacent nodes). I am sorting by key, but not by rowtype at this stage.

    Here is just all the code, am in the midst of simplifying and tidying it all up now:
    http://live.datatables.net/befepoqi/1/edit?js,output

    It is designed for a fixed screen size, so you will have to scroll horizontally a bit to see all the buttons.

    But to recreate the biggest issue with it as it currently stands:

    1. Click "Burger", "Hot Dog" and "Balter IPA" in that order. This should add those three to the table.
    2. In the table, select "Hot Dog". Then press the button for "No Pineapple" or "Seafood Allergy". This should add that instruction below the Hot Dog.
    3. Deselect hot dog.
    4. Select "Balter IPA". This will select Balter IPA, but it will also select the instruction that was just added. Needed behaviour is for that instruction to be "appended" to Hot Dog instead.

    Cheers Kevin. Once I'm done with this if you want to spend a half day or two checking over and optimizing the JS let me know your rates.

  • kthorngrenkthorngren Posts: 21,173Questions: 26Answers: 4,923

    Looks like you are trying to do multiple things when selecting the rows:

                orderBox.on( 'select', function ( e, row, type, indexes ) {
                            if (voidMode == true) {
                                setVoidMode(false);   
                                voidSpecificRow(row);
                                updateTotal();                        
                            } else {
                                updateSelectedTotal();
                            }
                    } )
                 
                orderBox.one('select', function (e, row, type, indexes) {
                     selectInstructions(row.index());
                  }); 
                  
                orderBox.one('deselect', function (e,row, type, indexes) {
                    selectInstructions(row.index(), 'deselect');
                });    
                    
                orderBox.on('deselect',  function ( e, row, type, indexes ) {
                        updateSelectedTotal();
                })
    

    I'm not sure what all those functions do but I think what you are seeing with the row selections due to using a combination of orderBox.on( 'select' and orderBox.one('select'. I think they are causing items to be selected or remain selected that you don't want.

    Instead of using orderBox.one('select' to highlight the instructions maybe a tr click event would be more appropriate. In the event you can simply add the selected class instead of selecting the rows.

    Here is an example with your data:
    http://live.datatables.net/vuloyumo/1/edit

    The example is probably not complete for what you need. Like it doesn't check for duplicate instructions per item.

    When selecting or deselecting a row the click event is used to add or remove the selected class. It first gets all the rows using row-selector as a function to return the rows with the same item number (column 6). I'm assuming thats how you are tying the items and instructions together. The click event happens before the selected class is added or removed so it inverts the boolean value and adds or removes the class approrpiately.

    The buttons are used to add the instructions. The button 'click' event will use rows().every() to loop through all the selected rows to add the instruction. You may or may not want to loop all the selected rows so this can be changed.

    It adds this row:

    ["INSTRUCTION02", 0, instruction, "0.00", "", "0.00", 0, "xinstruction"];
    

    Where instruction is the value of the clicked button, ie No Pineapple. Inside the loop it gets the item row's item number (column 6) then replaces the campe position in the above array. The loop adds the 'elected' class and draws the row.

    Note I change the last value to xinstruction and changed the table order to order: [[ 6, "asc" ], [7, 'asc']],. This sorts by item number first then by either item or xinstruction.

    Hope this helps you with your solution. Its not a full solution and may still have conflicts with what you are doing.

    I don't have a way to charge for extra projects. The developers may be interested in going through your code for a fee. PM @allan or @colin to find out more.

    Kevin

  • dredgydredgy Posts: 16Questions: 5Answers: 0

    Thanks for all the help, it is really appreciated. But making datatables do what I wanted was alot of effort.

    I tore it all down and rewrote it in pure JS, manipulating the DOM directly, and everything is working great.

    Sorry to waste your time, but thanks again!

This discussion has been closed.