ttkbootstrap icon indicating copy to clipboard operation
ttkbootstrap copied to clipboard

Search by column

Open dmalves opened this issue 2 years ago • 2 comments

Is your feature request related to a problem? Please describe.

Hi, there is no way to search by column, unless I access internal variables. I was able to search by column name comparing the searchcriteria to specific row[column_index] value. Here is a screenshot of the modified tableview example from master repository:

tabela

So, my use case here is search selecting what column to apply the search. I am not interested on adding more GUI complexity (combobox), but I just want a function to searchbycolumn without accessing _filtedered interval variable of tableview. Here is my search function. It is a modified version of _search_table_data.

search function:

    def _pesquisa(self):
        index = self._cbo_search.current()
        header = self._colsearch[index]
        # header is the column header I will apply the search (string)
        # header is selected on the combobox
     
        # searchcriteria comes from the Entry
        searchcriteria = self._entry_search.get()

        col_index = -1
        for coluna in self._table.tablecolumns:
            if coluna.headertext == header:
                col_index = int(coluna.cid)
                break
        # col_index is the index of the column I will apply the search
        if col_index >= 0:
           # _table is a Tableview, and _filtederd bugs me. I don't want to access private variables.
            self._table._filtered = True
            self._table.tablerows_filtered.clear()
            self._table.unload_table_data()
            for row in self._table.tablerows:
               # compare only with desired column
                if searchcriteria.lower() in row.values[col_index].lower():
                    self._table.tablerows_filtered.append(row)
            self._table._rowindex.set(0)
            self._table.load_table_data()

Describe the solution you'd like

My solution is:

  1. change searchcriteria to: searchcriteria: Union[str, tuple[str,str]]
  • if searchcriteria is a string, nothing changes.
  • if searchcriteria is a tuple (searchstring,columnstring), search by column
  1. change _search_table_data:

    • it has to handle both cases.
    • criteria.lower() is inside the loop. It make things slower.
  2. make search_table_data public. So we can write custom search GUI.

This solution has no impact on code that already uses searchcriteria as a string, but add functionality. This solution has no impact on the GUI already used for searching, but gives the possibility of a custom GUI for searching.

Describe alternatives you've considered

  • Drop searchcriteria and search entry
  • Write public search function (with search by column support) and let the user deal with the GUI for searching.

Additional context

No response

dmalves avatar Jul 22 '22 21:07 dmalves

Bug fix of my code above: if the cell has an integer, there is a bug while executing lower().

this line: if searchcriteria.lower() in row.values[col_index].lower():

to this line: if searchcriteria.lower() in str(row.values[col_index]).lower():

dmalves avatar Jul 22 '22 23:07 dmalves

@dmalves @israel-dryer

In addition to applying .lower(), you should also remove accents and special characters from the terms to be searched, something like this:

import unicodedata

item_no_accents = ''.join((c for c in unicodedata.normalize('NFD', str(row.values[col_index]).lower()) if unicodedata.category(c) != 'Mn'))
searchcriteria_no_accents = ''.join((c for c in unicodedata.normalize('NFD', searchcriteria.lower()) if unicodedata.category(c) != 'Mn'))

if searchcriteria_no_accents in list_item_no_accents:
    ...

I don't know if this is unfeasible in larger databases.


So if there is a term in the table

metáfora

you can search just by the term:

meta

antrrax avatar Jul 25 '22 01:07 antrrax