ASP.NET Gridview currently edited row does not show up in search

ASP.NET Gridview currently edited row does not show up in search

DinosbacsiDinosbacsi Posts: 4Questions: 1Answers: 0

Hi

So I have an ASP.NET application showing a gridview set up with boundfields and a commandfield for edit, save, delete. You can see it below:

<asp:GridView ID="AlternativIndexek" runat="server" ClientIDMode="Static" DataSourceID="DataSourceAlternativeIndexek" AutoGenerateColumns="false"
    CssClass="table table-hover w-100" GridLines="None" ShowFooter="true" OnPreRender="AlternativIndexek_PreRender"
    DataKeyNames="ID" OnRowUpdating="AlternativIndexek_RowUpdating" OnRowDeleting="AlternativIndexek_RowDeleting">
    <HeaderStyle CssClass="bg-BoschLightBlue text-white" />
    <Columns>
        <asp:BoundField DataField="Cikkszam" HeaderText="Cikkszám" ControlStyle-CssClass="form-control" />
        <asp:BoundField DataField="Szeria_index" HeaderText="Széria index" ControlStyle-CssClass="form-control" />
        <asp:BoundField DataField="Palettaegyseg" HeaderText="Palettaegység" ControlStyle-CssClass="form-control" />
        <asp:BoundField DataField="Helyettesio_index" HeaderText="Helyettesítő index" ControlStyle-CssClass="form-control" />
        <asp:BoundField DataField="Palettaegyseg_H" HeaderText="Helyettesítő palettaindex" ControlStyle-CssClass="form-control" />
        <asp:BoundField DataField="Szaknyelv" HeaderText="Szaknyelv" ControlStyle-CssClass="form-control" />
        <asp:BoundField DataField="Megjegyzes" HeaderText="Megjegyzés" ControlStyle-CssClass="form-control" />
        <asp:CommandField ShowEditButton="true" ButtonType="Image" EditImageUrl="../Images/EKAER/edit.png" UpdateImageUrl="../Images/EKAER/upload.png" CancelImageUrl="../Images/EKAER/abort-frame.png"
            ShowDeleteButton="true" DeleteImageUrl="../Images/EKAER/delete.png" ControlStyle-Height="32px" />
    </Columns>
</asp:GridView>

It is then converted to use datatables on document ready, as:

$(document).ready(function () {
    $('#AlternativIndexek').DataTable({
        "stateSave": true,
        "stateDuration": 60 * 10,
        "ordering": false,
        "language": {
            url: '//cdn.datatables.net/plug-ins/1.13.6/i18n/hu.json'
        },
        initComplete: function () {
            this.api()
                .columns()
                .every(function () {
                    let column = this;

                    if (column.index() < 7) {
                        let title = column.header().textContent;

                        // Create input element
                        let input = document.createElement('input');
                        input.classList.add("form-control");
                        input.classList.add("search-field");
                        input.placeholder = title;
                        column.footer().replaceChildren(input);

                        // Event listener for user input
                        input.addEventListener('keyup', () => {
                            if (column.search() !== this.value) {
                                column.search(input.value).draw();
                            }
                        });
                    }

                });
            $('#AlternativIndexek').DataTable().columns.adjust();
        }
    })
});

It works perfectly for the most part. My only issue is that when the search field is used and a row is selected for editing, then that row turns into an edit row as it should, but then the search no longer finds it, so the row disappears. So when you search for a row and click edit, it is just gone. Of course, if you then remove your search prompt, then the edited row will be there somewhere, but for a multi page table, it could be anywhere...
For clarification, this occurs with both the combined search field at the top and also with the separate search boxes in the footer of each column.

Anyone has a solution for this? I assume the only problem is that the search function no longer finds the row as it has been converted to an edit row, meaning the cells now contains textboxes instead of just text. Is it possible to extend the search to find values inside textboxes or the whole html of each row instead or something?

Thank you in advance.

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 21,292Questions: 26Answers: 4,944
    edited January 11

    The sorting of the table will affect where the row is displayed. If you change the data in the sorted column then the row might be resorted to a row that is not displayed on the current page.

    Same with searching, if you search for a row then clear the search it might not be displayed on the current page.

    Does this describe what you are seeing?

    I assume the only problem is that the search function no longer finds the row as it has been converted to an edit row, meaning the cells now contains textboxes instead of just text.

    Thats possible too. I'm guessing you are using Javascript utilities to modify the contents of the row to create the textboxes. Datatables won't know about these changes as they are made outside of Datatables utilities. See this FAQ for details and solutions.

    You could use the Editor for this. Sounds like you are doing something like this example. Or, if you don't want to use Editor, you could have behavior similar to the example and when clicking outside of the row the edit mode is turned off.

    If you need specific help it would be best to provide a running example showing what you have so we can see the code flow and offer suggestions.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • DinosbacsiDinosbacsi Posts: 4Questions: 1Answers: 0

    The sorting of the table will affect where the row is displayed. If you change the data in the sorted column then the row might be resorted to a row that is not displayed on the current page.

    That is not exactly the issue, as sorting right now is turned off for the table. And when not using the search function, it works fine. So let's say I click the edit button in the 5th row, then the 5th row will turn into edit mode and everything works as expected. This even works with paging, so let's say I go to page 4 in the table, click the 6th row, then the page re-renders and I still see the 4th page and the 6th row is not editable.

    Thats possible too. I'm guessing you are using Javascript utilities to modify the contents of the row to create the textboxes.

    I am using the standard ASP.NET Gridview functions, which I believe works by the server handling the button click then re-rendering the table. This way the currently edited row will already render with the textboxes in place before the datatables script runs. As the page refreshes, the unformatted table is even visible for a split second, with the textboxes already there in the row in question, then the datatables script formats it properly.

    You could use the Editor for this. Sounds like you are doing something like this example.

    Yes, the end result is pretty much like what you linked, except the ASP.NET equivalent. Instead of client side script changing the table, it's the server handling the logic then sending the re-rendered table for the client.

    So I think the issue might be that the search function in the datatables script searches for text in the table cells, but not for text in inputs inside the cells. So as a result, the currently edited row does not show up in the search results.

  • kthorngrenkthorngren Posts: 21,292Questions: 26Answers: 4,944

    So as a result, the currently edited row does not show up in the search results.

    Sounds like all the updates are perform outside of Datatables functionality. So Datatables won't know about the changes. As a result searching, sorting and paging will be based on what is in Datatables data cache, which it builds during initialization, and not on what is currently in the table. See the FAQ I linked to.

    The row().invalidate() API will only work with tr elements that remain in the document. I'm not sure how ASP.NET Gridview updates the table. If the elements, of the edited row, are removed and added new then row().invalidate() won't have the new element to work with. If the element remains in the doc and is simply updated then row().invalidate() should work.

    Also Datatables probably won't know about Gridview deleted rows . You will probably need to use row().delete() instead. To add rows you will need to use row.add().

    Another option, although drastic, is to use destroy or destroy() and reinitialize Datatables each time an update occurs to re-read the table data into Datatables cache.

    Kevin

  • DinosbacsiDinosbacsi Posts: 4Questions: 1Answers: 0

    Sounds like all the updates are perform outside of Datatables functionality.

    Technically they are, as everything is handled on the server side. But then the whole page gets rerendered and the datatables initialization is called each time by $(document).ready. So datatables should see every change on the server side and from what I can see, it really does so, since from the client perspective it's a new table re-rendered each time.

    So I don't think the issue is that Datatables can't see the changes. Because for example if I search for a row, then click edit, then as mentioned the row disappears. But then I can click edit on another row, now the previous row will re-appear and the recently clicked row will disappear. So the only problem is that a row opened for editing does not show up in the search results.

    After a bit of testing, it really does look like the problem is that the cell contents get put into textboxes when a row is in edit mode. Because I did a test where I replaced one of the BoundField columns with a TemplateField and made it so the data appears inside textboxes in each cell. This way the search does not work for that column. If it is a label instead of a textbox, then the search works.

    So I wonder if somehow the search function could be modified to detect content from inputs inside the cells as well. I assume currently it only tries to get .innerText or something and that skips inputs? Or maybe the cell().data() checks run into some error case that automatically results in the row getting hidden?

    Or is there a way to make the search function skip/always show rows with a certain class/style? Because then I could probably make it so rows in edit mode have a certain class, and the search function would not filter for that class, therefore the edit row always remains visible.

  • kthorngrenkthorngren Posts: 21,292Questions: 26Answers: 4,944
    Answer ✓

    I think I understand what you are saying. Take a look at the columns.type docs. Sounds like you will need to use Orthogonal data to return the inputs value for the filter process. Something like this example:
    https://live.datatables.net/zukacehi/107/edit

    Set the columns.targets to the appropriate columns.

    Kevin

  • DinosbacsiDinosbacsi Posts: 4Questions: 1Answers: 0

    Thanks for the tip, kthorngren.

    I managed to make it somewhat work by adding the data-search attributes for the row in edit on code behind. Now the contents of the textboxes get set as data-search values, I can see them with inspect element.

    What's weird is that now the issue is solved for some rows, but still not all. Some rows will remain after searching and clicking edit, while others will not. I'm not quite sure why, because they all look the same DOM.

    But at least it is progress in the right direction, thank you.

  • kthorngrenkthorngren Posts: 21,292Questions: 26Answers: 4,944
    edited January 22

    Possibly you need to use cell().invalidate() after updating the data-search attribute. See this updated example with columns.render removed.
    https://live.datatables.net/zukacehi/109/edit

    Also the table cells need to have the data-search attribute applied before initializing Datatables for Datatables to use that attribute for that column. The data-search attribute is applied only to the Position column. Updates to this column work. However updates to other columns don't as they didn't start with the data-search attribute.

    You can comment out the cell().invalidate() to see affect.

    Kevin

Sign In or Register to comment.