Is there a better way to control showing/hiding of child rows than re-toggling?

Is there a better way to control showing/hiding of child rows than re-toggling?

dtuser1854dtuser1854 Posts: 5Questions: 1Answers: 0

I have a datatable that is responsive. The first cell has an icon in it, which when clicked shows a modal.

The issue is that when someone clicks the icon, the child row state toggles, which is not ideal behavior. Ideally I would like the click not to be passed through to datatables if the target is one of these icons. I have tried a bunch of things, but so far been unable to catch it and stop any propagation. I do not wish to put the child toggle in the first column and move the icon with the modal to the second column.

So, my solution is to double the calls:

    $(document).on("click", "#datatable td:first-child .open-modal", function (e) {
        $(this).closest('td').trigger('click');      
        openModal();
    });

This works, but it feels like a bit of a hack, and I'm wondering if there is a better way to do it.

Thanks!

Answers

  • rf1234rf1234 Posts: 2,368Questions: 76Answers: 341

    I do not wish to put the child toggle in the first column and move the icon with the modal to the second column.

    This should be what you are looking for:
    https://datatables.net/reference/option/responsive.details.target

  • dtuser1854dtuser1854 Posts: 5Questions: 1Answers: 0

    This should be what you are looking for:
    https://datatables.net/reference/option/responsive.details.target

    I'm not sure I understand how to use it for what I want. I still want the first td to toggle the child row, just not if the click was on the icon that is within the td.

    If I set the target to 'td:first-child' it still triggers when someone clicks on the icon.

  • rf1234rf1234 Posts: 2,368Questions: 76Answers: 341

    I still want the first td to toggle the child row, just not if the click was on the icon that is within the td.

    Sorry, you lost me :smile:

    Maybe someone else can help you with this.

  • kthorngrenkthorngren Posts: 16,828Questions: 25Answers: 3,989

    It sounds like you are trying to combine Child Row Details and Responsive icons and click events in the same column. See if this thread gives you some ideas.

    Might be best for you to create a simple test case representing what you ahve so we can take a look to offer suggestions.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • dtuser1854dtuser1854 Posts: 5Questions: 1Answers: 0

    Thanks for the input. I looked at the thread, but it didn't help me find a solution.

    Here is a simple test case: https://jsfiddle.net/btq164w0/

    Note that that the click handler for the icon is bound to the document not the table/td/a specifically because in the real application the table is loaded in dynamically as a result of a user action and therefore not available to be bound to when the js loads.

    If you click on the ugly blue i in the example you get an alert to simulate the modal, and you will see it also toggles the child row.

    I want the i to be in the first column and I want to prevent the child row being toggled when clicking on the i. I still want the child row to be toggled when clicking in the first td (but outside of the i).

    Hope that makes sense, thanks!

  • allanallan Posts: 56,888Questions: 1Answers: 9,042 Site admin

    Yes, that makes sense - thanks for the test case. The issue is that Responsive's own click event handler is being triggered before your own, so all the stopPropagation() etc won't help. Responsive is binding on the table body, so to "beat" it you would need to have your event handler trigger before then - which means binding at that level or sooner: https://jsfiddle.net/hzjaxL2u/ .

    As you say, this is an application, so perhaps you could do:

    $(table.table().body()).on('click', 'td a', ...);
    

    i.e. don't depend upon the table selector, but rather use the DataTables API to get the tbody.

    Alternatively, put either the responsive control into its own column or put your i icon into its own column. Are either of them options?

    The final option would be to put an event into Responsive which would trigger a function that would check if you want to actually show the row details or not.

    Allan

  • dtuser1854dtuser1854 Posts: 5Questions: 1Answers: 0

    As per my other comments, the first two options aren't ideal (the first one because I don't have a table at the ideal time to load the js, the second one isn't ideal due to aesthetics).

    The final option would be to put an event into Responsive which would trigger a function that would check if you want to actually show the row details or not.

    Can you expand on what you mean by "put an event into Responsive" please? It sounds like what I'm after, but I'm not sure how to achieve this in code. Would I have access to the event object from there in order to tell if the target was the icon or not?

    Thanks!

  • kthorngrenkthorngren Posts: 16,828Questions: 25Answers: 3,989

    Can you invoke the the click event inside initComplete to use the suggestion Allan provided?

    Kevin

  • allanallan Posts: 56,888Questions: 1Answers: 9,042 Site admin

    What I was thinking of an event being added into the Responsive code around this point and you'd add a listener for it and have the ability to cancel that event.

    The other option, thinking about it more, would be to make the code in that event handler an API method, so you could disable Responsive's own event handler and instead call the new API method to toggle the details row yourself.

    The second might have more utility in the long run... (mulling it over... :)).

    Allan

  • dtuser1854dtuser1854 Posts: 5Questions: 1Answers: 0

    @kthorngren - that worked :) Thanks!

    @allan - I see - you're talking about changing the actual datatables code, which I think is best for me to avoid. I was thinking maybe there was a way to specify a callback that would determine whether the child rows are shown or not. That, or the API method would be awesome, but putting the event handler inside initComplete as suggested by @kthorngren works for me.

    Many thanks to you both for your help!

  • allanallan Posts: 56,888Questions: 1Answers: 9,042 Site admin

    Awesome - good to hear you've got a solution that works for you.

    I'll continue to think about the API option as I can see some utility in that.

    Allan

Sign In or Register to comment.