Is DataTables.Api a row-selector?

Is DataTables.Api a row-selector?

sliekenssliekens Posts: 97Questions: 17Answers: 2
edited June 2017 in DataTables

I'm confused about one of the examples for edit. This code works, but I don't understand why.

//  Edit all selected rows in a DataTable:
editor.edit(
    table.rows( { selected: true } ).indexes()
);

The example calls rows().indexes() and passes its return value of type DataTables.Api to edit(). I'm confused because this API operates on a row-selector argument and the documentation for that does not list DataTables.Api as a valid argument. The documentation does mention that an array of integers is a valid argument, but DataTables.Api instances are only array-like objects instead of real arrays.

Should I assume that any DataTables.Api instance can be a valid row-selector as long as its items are themselves valid row-selector or is there something else going on?

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,689Questions: 1Answers: 10,500 Site admin
    Answer ✓

    In this particular case, yes that is a safe assumption. Basically what is happening is that the API instance return from your rows().indexes() call is being used as a row selector by Editor, passing into rows(). Because it looks like an array of indexes, that is how it is treated.

    I'll update the documentation for that. Good point.

    Allan

  • sliekenssliekens Posts: 97Questions: 17Answers: 2
    edited June 2017

    Oh so can't I just pass the return value of rows() as the first argument and eliminate the conversion from rows to indexes to rows?

    editor.edit( table.rows( { selected: true } ) );
    

    Or else, can I pass any instance of selector-modifier to edit() and let the edit() API find the rows?

    editor.edit( { selected: true } );
    
  • allanallan Posts: 63,689Questions: 1Answers: 10,500 Site admin

    editor.edit( table.rows( { selected: true } ) );

    Yes, you can do that, although it isn't explicitly documented.

    editor.edit( { selected: true } );

    You can't do that though since it isn't an API instance. If it works, its unexpected!

    Allan

  • sliekenssliekens Posts: 97Questions: 17Answers: 2

    You will be surprised by the results of my experiment.

    See this example with three different ways of calling edit()
    http://live.datatables.net/zivilifa/4/edit?js,output

    • Button 1 uses the return value of rows(selector-modifier).indexes()
    • Button 2 uses the return value of rows(selector-modifier)
    • Button 3 uses the just the selector-modifier

    Select a single row and try all the buttons.
    Button 1 works, button 2 works, button 3 unexpectedly works.

    Change the selection to multiple rows and retry all the buttons.
    Button 1 still works, button 2 stopped working, button 3 unexpectedly still works.

  • sliekenssliekens Posts: 97Questions: 17Answers: 2
    edited June 2017

    Slightly related (sorry if this should be a different thread).

    There's a number of APIs with a similar pattern where the documentation contradicts the actual behavior. I'm talking about (almost) every API that takes some kind of selector and an optional selector modifier.

    Example

    function row( rowSelector [, modifier ] )
    https://datatables.net/reference/api/row()

    Here, the rowSelector part is documented as required but it is not actually needed because undefined is a valid instance of row-selector.

    // valid code because undefined is used implicitly
    var row = table.row():
    

    Per the documentation, if you want to only use a modifier, you'd have to explicitly pass in undefined for the selector.

    var row = table.row(undefined, { selected: true }):
    

    The surprising, undocumented behavior is that you can skip the selector.

    // This works but documentation says it shouldn't
    var row = table.row({ selected: true }):
    

    I think this is true for row(), column() and cell().

    The point that I'm trying to make is that a selector-modifier seems to be a valid argument to any method that requires a selector of some sort as the first argument, such as edit(row-selector).

  • allanallan Posts: 63,689Questions: 1Answers: 10,500 Site admin

    It is yes - this is explicitly documented for the plural selectors - e.g rows().

    I didn't document it for the singular methods since I wasn't really expecting it to be used there and thought it might be confusing (e.g.table.row( { page: 'current' } ) doesn't make much sense, but it is valid - it will just truncate the result to 1 row).

    That perhaps changed when I introduced the selector modifier extensions so things like selected: true could be used where it is valid to have only a single row selected and it makes sense to use row() there.

    I'll update the documentation with a note about this. Thanks for pointing out that discrepancy.

    Allan

  • sliekenssliekens Posts: 97Questions: 17Answers: 2

    It's starting to click in my mind now. Do the singular methods follow the same code path as the plural methods and then truncate the result set to a single item? Or do the singular methods have separate code paths and it's all just very similar code?

  • allanallan Posts: 63,689Questions: 1Answers: 10,500 Site admin

    Do the singular methods follow the same code path as the plural methods and then truncate the result set to a single item?

    Yup - same code path. This is where it runs the selector as normal and then truncates as required.

    Allan

  • sliekenssliekens Posts: 97Questions: 17Answers: 2

    Okay thanks for the help. With this information, I can finally fix the TypeScript definition files over at DefinitelyTyped.
    https://github.com/StevenLiekens/DefinitelyTyped/commits/improve-datatables.net/types/datatables.net

  • allanallan Posts: 63,689Questions: 1Answers: 10,500 Site admin

    Brilliant! I'll see if I can contribute as well.

    Allan

This discussion has been closed.