Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Row selection? #208

Open
michael-erasmus opened this issue Nov 29, 2023 · 10 comments · Fixed by #235
Open

Row selection? #208

michael-erasmus opened this issue Nov 29, 2023 · 10 comments · Fixed by #235

Comments

@michael-erasmus
Copy link

I'm using itables in a Shiny app and I was wondering if there's a way I can implement row selection?

@michael-erasmus
Copy link
Author

Oh I found this in the documentation: https://mwouts.github.io/itables/advanced_parameters.html#select-rows

So it's not currently supported? Any way I could implement it myself?

@mwouts
Copy link
Owner

mwouts commented Nov 29, 2023

Thanks for looking into this! Do you think you could add the extension to the connected template https://github.com/mwouts/itables/blob/main/itables/html/datatables_template_connected.html ? That would be a great start !

@michael-erasmus
Copy link
Author

Sorry I actually don't have the bandwidth to do a full PR, but I can document a hacky workaround I was able to figure out.

I manually added the select extension js/css files and then I inject my own document.ready code into my webpage

app_ui = ui.page_fluid(
  ui.head_content(
          ui.tags.link(rel="stylesheet", type="text/css", href="https://cdn.datatables.net/buttons/2.4.2/css/buttons.dataTables.min.css"),
          ui.tags.script(src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js"),
          ui.tags.link(rel="stylesheet", type="text/css", href="https://cdn.datatables.net/select/1.7.0/css/select.dataTables.min.css"),
          ui.tags.script(src="https://cdn.datatables.net/select/1.7.0/js/dataTables.select.min.js")
        
        
        # custom js to send the selected row data to Shiny server
        ui.HTML("""
        <script>
            const attachSelectHandler = function() {
                setTimeout(function() { //hack to wait for the table to initialized
                    dt = $('table').DataTable();
                    dt.on('select', function (e, dt, type, indexes) {
                        if (type === 'row' && indexes.length > 0) {
                            // Send the selected row data to Shiny server
                            var index = indexes.pop();
                            console.log('selected index', index);
                            Shiny.setInputValue('selectedRow', index);
                        }
                    });
                },2000);
            };
            $(document).ready(function () {
                attachSelectHandler();
                Shiny.addCustomMessageHandler("clearSelection", function(message) {
                    console.log('clearSelection');
                    Shiny.setInputValue('selectedRow', 0);
                    attachSelectHandler();
                });
            });
        </script>
        """)
        
        ...
)

Then in my server code I can make sure to initialized DT with select=True

def server(input, output, session):
     async def clear_selection(): #this can be called to clear the selection from the server
        await session.send_custom_message(type="clearSelection", message=None)

    @render.ui
    def ouput_df():
        df = get_df()
        dt_html = DT(df, select=True)
        return ui.HTML(dt_html)

I'll leave it to you if you want to keep the issue open!

@mwouts
Copy link
Owner

mwouts commented Dec 2, 2023

Thanks! Yes, please leave the issue open. Thanks for the Shiny code, I am sure it will be helpful to others until we can support extensions in itables!

@mwouts mwouts mentioned this issue Mar 11, 2024
7 tasks
@mwouts
Copy link
Owner

mwouts commented Mar 16, 2024

Row selection is now supported (well, included in the default bundle) in itables==2.0. @michael-erasmus do you think you could update your example above? Thanks!

@maxmoro
Copy link

maxmoro commented Jun 1, 2024

Thank you for the great tool. I also see the select row is now available, but how can I get the selected row id? what is the input element I can use from Shiny?

@mwouts
Copy link
Owner

mwouts commented Jun 1, 2024

Thanks @maxmoro . Well while the select extension is bundled within ITables, so rows can be selected, at the moment it's not possible yet to get this information back in Python (the code above was for an earlier version of ITables). I'll update this issue when I find out how to do this.

@maxmoro
Copy link

maxmoro commented Jun 2, 2024

Thank you @mwouts for the prompt reply. I perfectly understand. I was able to adapt the code above to get the row_id. I'm good for the moment, and I'm happy to test the updated select version as soon is out.

@mwouts
Copy link
Owner

mwouts commented Jun 2, 2024

Oh great! Can you share back how you do it? Thanks!

@maxmoro
Copy link

maxmoro commented Jun 3, 2024

Unfortunately my code it is not fully working, I didn't notice I was reloading the jquery library twice. (so multiple tables have been created)
I'm now stuck at the error DataTable is not a function (I'm very new to JS)
This is my snippet of the attachSelectHandler code

const attachSelectHandler = function() {
                console.log('p1')
                setTimeout(function() { //hack to wait for the table to initialized
                    var tables = $('.dataTable')
                    console.log('p2')
                    console.log(tables)
                    tables.each(function() {
                        var table = $(this).DataTable();
                        console.log('c')
                        // console.log(table)
                        table.on('select', function (e, dt, type, indexes) {
                            if (type === 'row' && indexes.length > 0) {
                                // console.log('d')
                                tableId = dt.table().node().id
                                // Send the selected row data to Shiny server
                                var index = indexes.pop();
                                // console.log(tableId)
                                console.log('selected index', index);
                                Shiny.setInputValue(`${tableId}_selectedRow`, index);
                            };
                        });
                    });
                },2000);
            };

Looking at the web, looks like the right library is not loaded. or we need a defer on jquery.dataTable.mins.js link

Or, do you have any insight?

@mwouts mwouts reopened this Jun 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants