Enhanced HTML Columns for Input fields

Enhanced HTML Columns for Input fields

k2heikkilak2heikkila Posts: 4Questions: 0Answers: 0
edited May 2009 in Plug-ins
I have a large, spreadsheet-like table. The table cells are all input fields. I have written a plugin to do the type-detection and sorting (using a new column type). However, the filtering and updating is a problem.

The updating: If someone updates one of the cells, I need to update the cached data structure, so on the next sort it sorts correctly. I tried the fnUpdate, but I need to pass in the whole input element to update. My guess is if I get that working it'll flash for the user as the old input element goes away (on blur/change) and the new one is replaced.

The filtering: The internal data array holds the innerHTML of the TD (including input, value=, class= etc). There does not appear to be a way to override this via a plugin. The "html" style column strips away the nodes, so I can't use that for input values, as the value is in the node.

Ideally what I would like is to just store/work with the input values (not the innerHTML). A way to set a new custom column type to override how you are building your internal data array. I would then just do a $('myinput').val() for each cell instead of stripping the nodes (like in the html type columns). Then the sorting would work correctly, updating I could just pass in the new value to fnUpdate(), and filtering would work, as well.

I could certainly customize the library, but you have been doing a nice job of making hooks available on the sort/detection side of things, it would be nice to extend this architecture to the data storage side.

I'm using v1.4.3, but would happily move to 1.5 if these items are addressed.

Thanks!

Kelly

Replies

  • allanallan Posts: 63,573Questions: 1Answers: 10,483 Site admin
    Hi Kelly,

    The updating: fnUpdate() is indeed the correct way to update the cells, although with a few cravats. fnUpdate() expects an array of data, so that will just blindly replace the inner elements - you can use html for this if you want, but it will case any event handlers to be lost on the update. You are right that this would flash for he user, although I think that if you do this and then focus() on the new element it will happen so quickly that the user wouldn't see it. The alternative is to use the internal information from DataTables (aoData contains _aData and nTr) which you can update are required. Might be best to have a look at how fnUpdate() works and adapt it for your own needs.

    The filtering: This is an interesting one. DataTables 1.5 does indeed provide a hook for custom filtering, however this is still done on the internal data storage, rather than what is present in the DOM. One option that you have here then is to have a keyup() event handler which will update a field in the table which you custom filter can then match upon. I'll add to my to-do list to have a think and see about adding something it to cope with this type of situation.

    Regards,
    Allan
  • k2heikkilak2heikkila Posts: 4Questions: 0Answers: 0
    Allan-
    Thanks for the response.

    On the filtering: I was able to get this to work by modifying _fnDataToSearch:
    [code]
    function _fnDataToSearch ( sData, sType )
    {
    if ( sType == "html" )
    {
    return sData.replace(/\n/g," ").replace( /<.*?>/g, "" );
    }
    else if (sType == "input" )//"input" is my custom column type
    {
    /*Build a mock object so I can get the val, rather than parsing the innerHTML*/
    return $('').append(sData.replace(/\n/g," ")).children(0).val();
    }
    else if { /*...*/}
    [/code]
    But rather than changing the core code, it would be great if _fnDataToSearch would call the function for whatever the column type is, like in the sorting (maybe oFilter['input-filter']). Then I could do whatever I want in my own function.

    As for the update. I tried this, which gets called on blur of an iput element:
    [code]
    $.fn.dataTableExt.oApi.fnUpdateDataOnly = function (oSettings, pos, inputHTML)
    {
    oSettings.aoData[pos[0]]._aData[pos[1]] = inputHTML;
    this.oApi._fnBuildSearchArray(oSettings, 1);
    }
    [/code]
    Using this, the search array does get updated and will find my new value when the user searches. However, the column sorting does not recognize the new value and sorts from the old value. Am I setting the background data structure incorrectly? Is there something else I need to update?

    Thanks again!

    Kelly
  • k2heikkilak2heikkila Posts: 4Questions: 0Answers: 0
    I finally got this working. I realized I didn't really need to send a full clone of my inputHTML to the oSettings.aoData[pos[0]]._aData[pos[1]], just a dummy node, because I'm not re-rendering it. I just needed the input and the value, so my sorting/searching changes work.

    Please do condsider adding a hook to the _fnDataToSearch area for custom column types. If that was in place I wouldn't need to edit the core at all.

    Thanks for the help. I've been really happy with DataTables.

    -Kelly
  • allanallan Posts: 63,573Questions: 1Answers: 10,483 Site admin
    Hi Kelly,

    Good to hear you got this sorted!

    I fully agree - I think this will be a fantastic area to expand the DataTables API into. This is something I was thinking about when I was writing that particular function, although at the time I wasn't sure exactly how it might be used. With your example this can be clearly seen ow - thanks! I'm planning to add a new API to make use of the features and dom position that DataTables presents in the next release, and I'll see if I can come up with a nice way of putting _fnDataToSearch() calls into an API as well.

    Regards,
    Allan
  • k2heikkilak2heikkila Posts: 4Questions: 0Answers: 0
    Once you have that in place, I could probably publish what I did for input fields as a plugin.
  • allanallan Posts: 63,573Questions: 1Answers: 10,483 Site admin
    Hi Kelly,

    I've just released DataTables 1.5 beta 9 which includes $.fn.dataTableExt.ofnSearch which should do exactly what you are looking for. Could you have a look and see if this meets what you expecting from this API?

    Thanks,
    Allan
This discussion has been closed.