Searching on internal information?

Searching on internal information?

nettlesnettles Posts: 4Questions: 0Answers: 0
edited May 2009 in General
Hi,

I'm using datatables to display inventory information to players for a game i'm writing. It's working great, but I've run into an issue. I can solve it, but I want to see if there's a better way before I start rewriting fnDeleteRow ;)

Due to ajax interactions elsewhere in the app, the tables need to be searched based on the item id, which is normally hidden. I do not want the table to redraw or anything, and the only piece of data I have is the item id. I do not have any dom elements.

I could not find any way via the public API to create custom search queries, so I wrote my own that greps through aoData._aData directly to find what I need, and get the dt index so I can use the API from then on.

This works fine for me.

However, I'm hitting a problem when that item's quantity hits 0, and I need to remove the item from the table. fnDeleteRow() works fine for preventing it from being drawn, but as per the comments, it does not actually remove the data from the table.

This means my custom finder finds the data even after it should be gone from the table.

This means either:

a) I have to write a better search function, but cannot find any documentation that would make this possible.

or

b) I rewrite fnDeleteRow to remove data from aoData and update the indices as necessary. This kind of sucks to do, but I'm going to do it if I have to because this is a showstopper otherwise.

I really hope there is a way to just write a better search function. All I have to search on is my (unique) item id, but that should be enough.

Thanks for all the works you've done.

Replies

  • allanallan Posts: 63,578Questions: 1Answers: 10,483 Site admin
    Hi nettles,

    Thanks for your comprehensive post and kind words about DataTables.

    DataTables does present an API for custom searching (new in the 1.5 beta series so not yet fully documented) when you can see an example of here: http://datatables.net/1.5-beta/examples/api/range_filtering.html . It might be possible for you to convert your custom filter to something which uses this (I presume your query is too complete for fnFilter() which is possibly the best way to go with custom filtering - particularly with it's regex and single column options?).

    The other option I see is to modify your search algorithm to use aiDisplay and aiDisplayMaster. These two internal variables are used to tell DataTables what information from aoData it can display (they are indexes of aoData). Therefore deleted rows are removed from these arrays and not from aoData (which as you correctly point out would mess up the indexes). So what you could do is loop over these arrays (the master is used for what can be displayed before filtering, and the other for what will be displayed after filtering), and use the values from those arrays to get the aoData elements which are available for drawing.

    For example:

    oSettings.aoData[ oSettings.aiDisplay[0] ]._aData

    will give you the data array for the first row that DataTables will display (after sorting and filtering).

    Hope this helps.

    Regards,
    Allan
  • nettlesnettles Posts: 4Questions: 0Answers: 0
    Hi,

    Thanks for getting back to me.

    The filtering API in datatables won't work for this, because I don't want to actually filter visible table rows or redraw the table at all (except in the case i need to actually update table data, of course.) I want to find a piece of data in the table regardless of what is currently showing (in fact, there's a fair chance the row I need to work with is not currently visible in the table,) which is a totally different operation than filtering the data.

    I did look into rummaging through aiDisplay and aiDisplayMaster, but was not able to see via Firebug what happens to them when rows are hidden/shown. They always looked like empty arrays from my inspections. Ugh.

    I'll take another spike at aiDisplay and aiDisplayMaster, but it really looks like I'm going to have to hack fnDeleteRow at this point.

    Thanks again.
  • nettlesnettles Posts: 4Questions: 0Answers: 0
    Hm, spoke a bit too soon.

    I got all my tests to pass now with an additional check for the id within aiDisplayMaster, but I wonder about data inconsistency in the case of adding and removing a row multiple times (i.e. user uses last of that item, row disappears; user gets another of that same item, row reappears, but is there bad data hanging around now?

    I guess I'll cross that bridge when I come to it.

    thanks!
  • nettlesnettles Posts: 4Questions: 0Answers: 0
    edited May 2009
    EDIT: sorry, ive made about 10 attempts to use wiki markup to make this code readable, but nothing works. i have no idea what i need to do to make it mark up correctly.

    And yes, the data inconsistency was a real problem and basically put me back to square one.

    edit again - my code here was bad, so I removed it. it just leads to more and more data consistency problems and things like fnGetPosition start to fail.

    I going to move in another direction I think. Sorry to waste your time.
  • allanallan Posts: 63,578Questions: 1Answers: 10,483 Site admin
    Hi nettles,

    Using [ code ] and [ /code ] (without the spaces) will format the code. This doesn't work correctly in Safari for some reason which I've yet to figure out, which is why it's not correctly advertised.

    So if you do want to continue doing what you were, perhaps the easiest thing would be a one line alteration to the fnDeleteRow() API functions (which I am considering putting in anyway) - and that is to set the value of aoData[ iDelete ] to null. Then when you come to your custom filtering function, you can do "if ( aoData[ i ] != null ) { ... }".

    Looking back at your post about aiDisplay and aiDisplayMaster:

    aiDisplayMaster - Array of indexes (of aoData) which is sorted but NOT filtered (i.e. all the rows are in there)
    aiDisplay - Array of indexes (of aoData) which is both sorted and filtered (i.e. rows which do not match the filtering criterion are not there).

    It sounds like what you want to do could be achieved in this manner, but perhaps the small alteration to fnDeleteRow() would be the path of least resistance :-)

    Regards,
    Allan
This discussion has been closed.