Forum Archive

Ui SearchBar

DavinE

hey Guys,

Is it possible to create a Search Bar in the ui.View ??

thanks for reply

cvp

@DavinE If I correctly understand an UISearchBar is only a TextField.
Where do you want to display it and what does it search for?

DavinE

nothing special.. in a normal View... on the Top..
This needs only to pull a Name or Numbers to an Funktion like '0001' or 'Hager'

@cvp said:

@DavinE If I correctly understand an UISearchBar is only a TextField.

then i can tried to use an TexField with a search Button.. right_of

thanks @cvp

ps. i will show my result when i got it or i have other Questions :D

mikael

@DavinE, here’s a simple fuzzy matcher I found somewhere for another project, and found to work well:

def fuzzyfinder(input, collection, accessor=lambda x: x, sort_results=True):
    suggestions = []
    input = str(input) if not isinstance(input, str) else input
    pat = '.*?'.join(map(re.escape, input))
    pat = '(?=({0}))'.format(pat)
    regex = re.compile(pat, re.IGNORECASE)
    for item in collection:
        r = list(regex.finditer(accessor(item)))
        if r:
            best = min(r, key=lambda x: len(x.group(1)))
            suggestions.append((len(best.group(1)), best.start(), accessor(item), item))
    if sort_results:
        return (z[-1] for z in sorted(suggestions))
    else:
        return (z[-1] for z in sorted(suggestions, key=lambda x: x[:2]))
DavinE

simple ^^
@mikael said:

@DavinE, here’s a simple fuzzy matcher I found somewhere for another project, and found to work well:

def fuzzyfinder(input, collection, accessor=lambda x: x, sort_results=True): suggestions = [] input = str(input) if not isinstance(input, str) else input pat = '.*?'.join(map(re.escape, input)) pat = '(?=({0}))'.format(pat) regex = re.compile(pat, re.IGNORECASE) for item in collection: r = list(regex.finditer(accessor(item))) if r: best = min(r, key=lambda x: len(x.group(1))) suggestions.append((len(best.group(1)), best.start(), accessor(item), item)) if sort_results: return (z[-1] for z in sorted(suggestions)) else: return (z[-1] for z in sorted(suggestions, key=lambda x: x[:2]))

@mikael Thanks for your help!
but i don't understand how to call it....

i tried this:

print(fuzzyfinder('0040', QRCODES))

QRCODES is a list

or i´m complete wrong

mikael

@DavinE, oops, forgot the import re.

It’s a generator, so iterate over the results e.g. with a for loop, or get them all as a list:

print(list(fuzzyfinder('0040', codes)))
mikael

@DavinE, maybe, for QR codes, you would want an exact instead of a fuzzy match?

DavinE

@mikael Thanks for the great help!!

i have a example code...
it works but i´v got two issue...

  1. when i type '0' it Displays only one row.... i can't figuret out why....
  2. when i Type more Numbers (4) in my search field like '00030' i get an error.....:

ERROR:

line 96, in textfield_did_change
    self.wQRCODES = list(self.fuzzyfinder(search_text, QRCODES))
TypeError: 'NoneType' object is not iterable

This is my Code (Runnable):

import ui, re

QRCODES = [
    ['0015', '+1', '', 'bin erstmal nur der selbe Text!!'],
    ['0008', '-1', '', 'bin erstmal nur der selbe Text!!'],
    ['0025', '+2', '', 'bin erstmal nur der selbe Text!!'],
    ['0049', '-2', '', 'bin erstmal nur der selbe Text!!'],
    ['0013', '+3', '', 'bin erstmal nur der selbe Text!!'],
    ['0124', '-3', '', 'bin erstmal nur der selbe Text!!'],
    ['0072', '+4', '', 'bin erstmal nur der selbe Text!!'],
    ['0074', '-4', '', 'bin erstmal nur der selbe Text!!'],
    ['0122', '+5', '', 'bin erstmal nur der selbe Text!!'],
    ['0035', '-5', '', 'bin erstmal nur der selbe Text!!'],
    ['0003', '+6', '', 'bin erstmal nur der selbe Text!!'],
    ['0022', '-6', '', 'bin erstmal nur der selbe Text!!'],
    ['0125', '+7', '', 'bin erstmal nur der selbe Text!!'],
    ['0006', '-7', '', 'bin erstmal nur der selbe Text!!'],
    ['0043', '+8', '', 'bin erstmal nur der selbe Text!!'],
    ['0045', '-8', '', 'bin erstmal nur der selbe Text!!'],
    ['0048', '+9', '', 'bin erstmal nur der selbe Text!!'],
    ['0050', '-9', '', 'bin erstmal nur der selbe Text!!'],
    ['0071', '+10', '', 'bin erstmal nur der selbe Text!!'],
    ['0068', '-10', '', 'bin erstmal nur der selbe Text!!'],
    ['0123', '+11', '', 'bin erstmal nur der selbe Text!!'],
    ['0038', '-11', '', 'bin erstmal nur der selbe Text!!'],
    ['0039', '+12', '', 'bin erstmal nur der selbe Text!!'],
    ['0040', '-12', '', 'bin erstmal nur der selbe Text!!'],
    ['0030', '+13', '', 'bin erstmal nur der selbe Text!!'],
    ['0028', '-13', '', 'bin erstmal nur der selbe Text!!'],
    ['0029', '+14', '', 'bin erstmal nur der selbe Text!!'],
    ['0037', '-14', '', 'bin erstmal nur der selbe Text!!'],
    ['0036', '+15', '', 'bin erstmal nur der selbe Text!!'],
    ['0075', '-15', '', 'bin erstmal nur der selbe Text!!'],
    ['0005', '+16', '', 'bin erstmal nur der selbe Text!!'],
    ['0076', '-16', '', 'bin erstmal nur der selbe Text!!'],
    ['0010', '+17', '', 'bin erstmal nur der selbe Text!!'],
    ['0120', '-17', '', 'bin erstmal nur der selbe Text!!'],
    ['0371', '+18', '', 'bin erstmal nur der selbe Text!!'],
    ['0372', '-18', '', 'bin erstmal nur der selbe Text!!'],
    ['0374', '+19', '', 'bin erstmal nur der selbe Text!!'],
    ['0212', '-19', '', 'bin erstmal nur der selbe Text!!'],
    ['0211', '+20', '', 'bin erstmal nur der selbe Text!!'],
    ['0126', '-20', '', 'bin erstmal nur der selbe Text!!'],
]

class main(ui.View):
    def __init__(self):
        symbol_table = ui.TableView(
            background_color='black',
            frame=self.bounds, flex='WH',
        )
        self.wQRCODES = QRCODES
        data_source = symbol_table.data_source = ui.ListDataSource(QRCODES)
        symbol_table.data_source.tableview_cell_for_row = self.tableview_cell_for_row
        symbol_table.data_source.tableview_number_of_rows = self.tableview_number_of_rows

        search_field = ui.TextField(
            frame=(8,8, self.width-16, 40),
            flex='W',
            clear_button_mode='always',
            delegate=data_source,
        )
        search_field.delegate.textfield_did_change = self.textfield_did_change

        symbol_table.y = search_field.height + 16
        symbol_table.height -= (search_field.height + 16)
        self.add_subview(search_field)
        self.add_subview(symbol_table)
        #symbol_table.present()
        self.present('fullscreen')

    def tableview_number_of_rows(self, tableview, section):
        self.tableview = tableview
        return len(self.wQRCODES)

    def tableview_cell_for_row(self, tableview, section, row):
        cell = ui.TableViewCell()
        cell.selectable = False

        symbol_name = self.wQRCODES[row][0]

        cell.text_label.text = symbol_name

        return cell

    def textfield_did_change(self, textfield):
        search_text = textfield.text.strip().lower()
        if search_text == '':
            self.wQRCODES = QRCODES
            self.tableview.reload()
        else:
            self.wQRCODES = list(self.fuzzyfinder(search_text, QRCODES))
            self.tableview.reload()

    def fuzzyfinder(self, input, collection, accessor=lambda x: x, sort_results=True):
        suggestions = []
        input = str(input) if not isinstance(input, str) else input
        pat = '.*?'.join(map(re.escape, input))
        pat = '(?=({0}))'.format(pat)
        regex = re.compile(pat, re.IGNORECASE)
        for item in collection:
            r = list(regex.finditer(accessor(item[0])))
            if r:
                best = min(r, key=lambda x: len(x.group(1)))
                suggestions.append((len(best.group(1)), best.start(), accessor(item), item))
        if sort_results:
            return (z[-1] for z in sorted(suggestions))
        else:
            return (z[-1] for z in sorted(suggestions, key=lambda x: x[:2]))

if __name__ == '__main__':
    main()

i hope you guys can help me out here :)
ty

DavinE

i found my solution ;)
Code above works!