Have two inline editable columns display as one inline editable column in the table

Have two inline editable columns display as one inline editable column in the table

jacktrapjacktrap Posts: 14Questions: 6Answers: 0
edited June 2021 in Editor

I don't have test code to attach as I haven't attempted to get this working because I don't know how (or if it's possible).

I need a single column called Result which is an editable field the user can enter a result for a test into (like in an exam). This column in data tables will represent two columns in the sql database (one is numeric, one is a Boolean). Depending on the result type that's expected for the test (row) the editable field will represent either the numeric result or the Boolean result. To the user this will appear as a single column though.

I have this working just fine as two separate columns, but it both looks confusing and is also adding an extra column on an already crowded table.

Is there anyway to achieve this? I've googled related questions and checked the examples and can't see how.

I'm currently disabling one of the columns using the below code. I want to do something similar but instead of disabling I want to swap out the editable TD per row, if that makes sense.

editor.dependent('resultTypeId', function ( val, data, callback ) {
    if (val == '1') {
        editor.enable( ['truthyResult'] );
        editor.disable( ['numericResult'] );
    } else {
        editor.disable( ['truthyResult'] );
        editor.enable( ['numericResult'] );
    }
  })

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 61,650Questions: 1Answers: 10,094 Site admin

    There is no way to do what you are looking for with Editor at this time I'm afraid. It can show only a single field in a single cell. With Editor 2 we introduced the ability to show multiple inline fields in multiple cells, but it is still limited to showing just one field in any one cell.

    A bubble edit is we closest we have for this.

    Allan

  • jacktrapjacktrap Posts: 14Questions: 6Answers: 0

    Thanks Allan. Is there no way to just hide one cell and shift the other one over? So rather than sharing a cell, they have their own cell but only display when applicable?

    I realize that's probably not possible but thought I'd ask because I'm desperate.

    Here you can see what I'm talking about. Currently two columns, it will never be both a numeric and boolean result, so I just need it to look like one column.

    If this is just straight up impossible let me know and I'll stop asking :blush:

  • allanallan Posts: 61,650Questions: 1Answers: 10,094 Site admin

    So how is that stored in the database? Do you have two different columns in the db as well, and one of them must be null or something?

    Can a row change between having a boolean result and a numeric result as a result of user input? i.e. can the user choose which one it is?

    Allan

  • jacktrapjacktrap Posts: 14Questions: 6Answers: 0

    Yes that's correct, in the database there's two columns, one for the numeric result (decimal) and one for the truthy result (bit). One is always NULL, because a test only ever requires a numeric result or a pass fail (never both). The tests are predetermined and this cannot be changed by the user.

    What I've done in the image posted above works file it's just the users complain it's confusing and are asking can it be displayed as one column.

  • allanallan Posts: 61,650Questions: 1Answers: 10,094 Site admin

    What I'm thinking is that when you click on a cell, you can tell Editor what form field you want it to edit - for example:

    $('#example').on( 'click', 'tbody td:not(:first-child)', function (e) {
      var rowData = table.row(this.parentNode).data();
    
      if (rowData.isBoolean) {
        editor.inline( this, 'myBooleanField' );
      }
      else {
        editor.inline( this, 'myNumericField' );
      }
    } );
    

    So based on some value in the row, you could actually trigger editing on different data, but in the same cell.

    That assumes that the user can't switch between the types though.

    Allan

  • jacktrapjacktrap Posts: 14Questions: 6Answers: 0
    edited July 2021

    Hi Allan,
    Thank you so much for your help. I now have it working as one column with the cursor which is great.

    The problem I have now is that KeyTable Editor functionality no longer works. I can navigate with the keyboard but hitting enter / escape throws an error. It's expecting me to declare the data variable for the column but because it's shared it's declared as null. Does this means I have to roll my own event listeners for all the KeyTable functionality?

    As you can see my rendered column can't have the data value of both NumericResult and TruthyResult so I declare it as null.

    {
                                data: null,
                                render: function (data, type, rowData) {
                                    if (rowData.supplierCompleteCount < rowData.supplierTotalCount) {
                                        return '<i class="fal fa-lock"></i>';
                                    } else {
    
                                        if (rowData.resultTypeId != 1) {
                                            if (rowData.anyImpurity || rowData.totalImpurity) return rowData.average != null ? rowData.impurityResultPassed ? "<span class='text-success'><b>" + rowData.average + "</b></span>" : "<span class='text-danger'><b>" + rowData.average + "</b></span>" : "<span class='text-secondary'>N/A</span>";
                                            if (data.numericResult == null && rowData.resultTypeId != 1) return rowData.average == null ? "<input class='form-control form-control-sm' disabled=disabled></input>" : rowData.status === "2" ? "<span class='text-success'><b>" + rowData.average + "</b></span>" : "<span class='text-danger'><b>" + rowData.average + "</b></span>";
                                            return rowData.resultTypeId != 1 ? rowData.status === "2" ? "<span class='text-success'><b>" + rowData.average + "</b></span>" : "<span class='text-danger'><b>" + rowData.average + "</b></span>" : "<span class='text-secondary'>N/A</span>";
                                        } else {
                                            if (data.truthyResult == null && rowData.resultTypeId == 1) return "<input class='form-control form-control-sm' disabled=disabled></input>";
                                            return rowData.resultTypeId == 1 ? data.truthyResult ? "<span class='text-success'><b>Passed</b></span>" : "<span class='text-danger'><b>Failed</b></span>" : "<span class='text-secondary'>N/A</span>"
                                        }
                                    }
    
                                }
    
                            }
    

  • jacktrapjacktrap Posts: 14Questions: 6Answers: 0

    Okay I'm getting close, so close I can sense victory.

    I have it working perfectly for double click

                         $('.testsTable').on('dblclick', 'tbody td:not(:first-child)', function (e) {
                        var rowData = testsTable.row(this.parentNode).data();
                        var index = testsTable.cell(this).index()
                        if (index.column == 8) {
                            if (rowData.resultTypeId == 1) {
                                editor.inline(this, 'truthyResult');
                            }
                            else if (rowData.anyImpurity != "true" && rowData.TotalImpurity != "true") {
                                editor.inline(this, 'numericResult');
                            }
                        }
                        if(index.column == 9 | index.column == 10){
                              editor.inline(this);
                        }
                    });
    

    However, for some reason the exact same code does not work with 'key' 'keydown' 'keyup' etc. because the event never gets triggered.

    Other keys seem to trigger it, but Enter never works. I think it's because KeyTable or Editor is interfering with the Enter key triggered event.

       $('.testsTable').on('key', 'tbody td:not(:first-child)', function (e) {
                        if (e.keyCode == 13) {
                            var rowData = testsTable.row(this.parentNode).data();
                            var index = testsTable.cell(this).index()
                            if (index.column == 8) {
                                if (rowData.resultTypeId == 1) {
                                    editor.inline(this, 'truthyResult', { onBlur: 'submit', submit: 'allIfChanged' });
    
                                }
                                else if (rowData.anyImpurity != "true" && rowData.TotalImpurity != "true") {
                                    editor.inline(this, 'numericResult', { onBlur: 'submit', submit: 'allIfChanged' });
                                }
                            }
                        }
                    });
    

    I'm only applying keys to this column, and no longer applied editor too, which I thought was the problem.

         keys: {
                    columns: [8]
                   },
    

    Is there something obvious I'm missing?

  • allanallan Posts: 61,650Questions: 1Answers: 10,094 Site admin

    KeyTable Editor functionality no longer works

    A sorry, I didn't realise you were using KeyTable. Yes, that is going to complicate matters a fair bit. Really what we want to do is use KeyTable's inline editing abilities, since it is actually relatively complex. But there isn't a way to pass in the field name to edit at the moment.

    This is relevant piece of code. Maybe what we need is a callback that would let you customise the field type (and also form options). Does that sound like a reasonable approach?

    Allan

  • jacktrapjacktrap Posts: 14Questions: 6Answers: 0

    Hi Allan,

    Yes it's making it a bit complicated. We got Enter for edit/submit working but we'd have to do something similar for all of keytables other functionality and it's a bit messy.

                    testsTable.on('key', function ( e, datatable, key, cell, originalEvent )  {
                        e.preventDefault();
                        if (key == 13 && editor.mode() == null) {
                            var index = cell.index();
                            var rowData = testsTable.row(index.row).data();
                            if (index.column == 8) {
                                if (rowData.resultTypeId == 1) {
                                    editor.inline(cell.node(), 'truthyResult', { onBlur: 'submit', submit: 'allIfChanged', onReturn: 'none'    });
                                }
                                else if (rowData.anyImpurity != "true" && rowData.TotalImpurity != "true") {
                                    editor.inline(cell.node(), 'numericResult', { onBlur: 'submit', submit: 'allIfChanged', onReturn: 'none' });
                                }
                            }
                        }
                        else if(key == 13 && editor.mode() == "edit")
                        {
                            editor.submit();
                        }
                    });
    

    " Does that sound like a reasonable approach?" Yes it does

  • allanallan Posts: 61,650Questions: 1Answers: 10,094 Site admin
    Answer ✓

    I've added that ability in here. It will be in the nightly build in the next few minutes, and if you could try using KeyTable from there (or copy that file locally) to try this feature out that would be great.

    Basically you can now have an editorOptions parameter in the keys object. It will be a function which returns an object - e.g.:

            keys: {
                columns: ':not(:first-child)',
                editor:  editor,
                editorOptions: function (cellIdx) {
                    return {
                        cell: cellIdx,
                        field: 'first_name'
                    };
                }
            },
    

    The object will contain:

    • cell (required) - The cell index to edit (passed in as the first parameter)
    • field - The field name to edit
    • options - form-options object for configuration.

    Hopefully that will help!

    Allan

  • jacktrapjacktrap Posts: 14Questions: 6Answers: 0

    Hi Allan,

    You're a legend. It's working perfectly now. Thank you so much.

                       keys: {
                            columns: [8],
                            editor:  editor, 
                            editorOptions: function (cellIdx) {
                                var field;
                                var rowData = testsTable.row( cellIdx.row ).data();
                                    if (rowData.resultTypeId == 1) {
                                        field = 'truthyResult';
                                    }
                                    else if (rowData.anyImpurity != "true" && rowData.TotalImpurity != "true") {
                                        field = 'numericResult';
                                    }
                                return {
                                    cell: cellIdx,
                                    field: field
                                };
                            }
                        },
    
Sign In or Register to comment.