def unrestricted_input(doc): input_box = AutocompleteInput(css_classes=["foo"], completions=["100001", "12344556"], restrict=False) input_box.on_change('value', counter.increment) plot = Plot() doc.add_root(column(input_box, plot))
def create_document(directory, chat_titles): (message_df, reacts, title, participants) = parse_json_messages(directory) # ------------------------------------------------------------------------- # Plot Message Timeseries: # ------------------------------------------------------------------------- # Create a color palette to use in plotting: """ Might raise an error when number of people in the group chat is > 20""" colour_palette = Category20[20][0:len(participants)] message_panel = create_message_timeseries_panel(message_df, title, participants, colour_palette) # --------------------------------------------------------------------------+ # Plot Reaction Panel: # --------------------------------------------------------------------------+ reacts_panel = create_react_breakdown_panel(reacts, title, participants, colour_palette) # --------------------------------------------------------------------------+ # Create Panel to Summarise Individual Statistics: # --------------------------------------------------------------------------+ message_log_panel = create_message_log_panel(message_df, title, participants, colour_palette) # --------------------------------------------------------------------------+ # Compile Bokeh Application: # --------------------------------------------------------------------------+ tabs = Tabs(tabs=[message_panel, reacts_panel, message_log_panel]) directory_search = AutocompleteInput(completions = list(chat_titles.keys()), width = 400, height = 30, sizing_mode = "fixed", align = 'end') directory_search.on_change("value", update_data) search_text = Div( text = "<i>Search Chats:</i>", height_policy = "max", sizing_mode = "scale_both", align = "end", style = {"font-family": 'Verdana', "font-size": "17px"} ) # A title which could be included in the top left of the document title = Div( text = "<b>Messenger Analysis</b>", height_policy = "max", sizing_mode = "fixed", align = "start", style = {"font-family": 'Verdana', "font-size": "16px"} ) layout = column(row(search_text,directory_search, Spacer( width=35, height=40, sizing_mode="fixed"), align = "end"), tabs, sizing_mode = "scale_width") return layout
def test_restrict(self, bokeh_model_page) -> None: """Test effect of 'restrict=False' with explicit JS callback""" text_input = AutocompleteInput(css_classes=["foo"], completions = ["aAaBbb", "aAaBbB"], restrict=False) text_input.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector('.foo input') text = "not in completions" enter_text_in_element(page.driver, el, text, click=1, enter=True) results = page.results assert results['value'] == text assert page.has_no_console_errors()
def test_server_on_change_round_trip_partial_entry( self, bokeh_server_page: BokehServerPage) -> None: input_box = AutocompleteInput() modify_doc, plot = mk_modify_doc(input_box) page = bokeh_server_page(modify_doc) # double click to highlight and overwrite old text el = find_element_for(page.driver, input_box, "input") enter_text_in_element(page.driver, el, "100", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == ["400", "100001"] enter_text_in_element(page.driver, el, "123", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == ["100001", "12344556"] # Check clicking outside input also triggers enter_text_in_element(page.driver, el, "319", click=2, enter=False) page.click_canvas_at_position(plot, 10, 10) page.eval_custom_action() results = page.results assert results['data']['val'] == ["12344556", "3194567289"]
def test_unrestricted_selection_callback_count( self, bokeh_server_page: BokehServerPage) -> None: class CallbackCounter: def __init__(self) -> None: self.count = 0 def increment(self, attr, old, new) -> None: self.count += 1 self.new = new counter = CallbackCounter() input_box = AutocompleteInput(completions=["100001", "12344556"], restrict=False) def unrestricted_input(doc): input_box.on_change('value', counter.increment) plot = Plot() doc.add_root(column(input_box, plot)) page = bokeh_server_page(unrestricted_input) el = find_element_for(page.driver, input_box, "input") enter_text_in_element(page.driver, el, "ASDF", enter=True) assert (counter.count == 1) assert (counter.new == "ASDF")
def test_server_on_change_round_trip_menu_entry( self, bokeh_server_page: BokehServerPage) -> None: input_box = AutocompleteInput() modify_doc, _ = mk_modify_doc(input_box) page = bokeh_server_page(modify_doc) # double click to highlight and overwrite old text el = find_element_for(page.driver, input_box, "input") enter_text_in_element(page.driver, el, "123", click=2, enter=False) enter_text_in_element(page.driver, el, Keys.DOWN, click=0) page.eval_custom_action() results = page.results assert results['data']['val'] == ["400", "12344557"] enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = find_element_for(page.driver, input_box, ".bk-menu") items = el.find_elements_by_tag_name("div") hover_element(page.driver, items[1]) items[1].click() page.eval_custom_action() results = page.results assert results['data']['val'] == ["400", "12344557"]
def set_tbl_logic(source: ColumnDataSource, choices: AutocompleteInput, patchsources: Dict[str, Tuple], countytable_cds: ColumnDataSource, rtplot: Figure, plots: List[Dict], ms_plot: Figure) -> None: someargs = dict(source=source, rtplot=rtplot, rtxaxis=rtplot.xaxis[0], rtyaxis=rtplot.yaxis[0], ms_plot=ms_plot, ms_plot_xaxis=ms_plot.xaxis[0], ms_plot_yaxis0=ms_plot.yaxis[0], choices=choices, countytable_cds=countytable_cds, patchsources=patchsources) someargs['xaxes'], someargs['yaxes'], someargs['plots'] = [], [], [] for p in plots: someargs['xaxes'].append(p['plot'].xaxis[0]) someargs['yaxes'].append(p['plot'].yaxis[0]) someargs['plots'].append(p['plot']) tblcallback = CustomJS(args=someargs, code=constants.tblcallback_code) countytable_cds.selected.js_on_change('indices', tblcallback) # set additional callback on autocompeleteinput linking table row selected someargs = dict(source=source, choices=choices, countytable_cds=countytable_cds) inputtbl_callback = CustomJS(args=someargs, code=constants.autocomplete_in_tbl_code) choices.js_on_change('value', inputtbl_callback)
def test_min_characters(self, bokeh_model_page): text_input = AutocompleteInput(title="title", css_classes=["foo"], completions = ["100001", "12344556", "12344557", "3194567289", "209374209374"], min_characters=1) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' in el.get_attribute('style') # double click to highlight and overwrite old text el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "1", click=2, enter=False) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 3 assert items[0].text == "100001" assert items[1].text == "12344556" assert items[2].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') assert "bk-active" not in items[2].get_attribute('class')
def test_mouse_hover(self, bokeh_model_page): text_input = AutocompleteInput(title="title", css_classes=["foo"], completions = ["100001", "12344556", "12344557", "3194567289", "209374209374"]) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' in el.get_attribute('style') el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') # hover over second element items = el.find_elements_by_tag_name("div") hover_element(page.driver, items[1]) assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class')
def test_min_characters(self, bokeh_model_page: BokehModelPage) -> None: text_input = AutocompleteInput(title="title", completions=[ "100001", "12344556", "12344557", "3194567289", "209374209374", "aaaaaa", "aaabbb", "AAAaAA", "AAABbB" ], min_characters=1) page = bokeh_model_page(text_input) el = find_element_for(page.driver, text_input, ".bk-menu") assert 'display: none;' in el.get_attribute('style') # double click to highlight and overwrite old text el = find_element_for(page.driver, text_input, "input") enter_text_in_element(page.driver, el, "1", click=2, enter=False) el = find_element_for(page.driver, text_input, ".bk-menu") assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 3 assert items[0].text == "100001" assert items[1].text == "12344556" assert items[2].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') assert "bk-active" not in items[2].get_attribute('class')
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1], val=["a", "b"])) plot = Plot( plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0, ) plot.add_glyph(source, Circle(x="x", y="y", size=20)) plot.add_tools( CustomAction( callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")) ) ) input_box = AutocompleteInput(css_classes=["foo"]) input_box.title = "title" input_box.value = "400" input_box.completions = [ "100001", "12344556", "12344557", "3194567289", "209374209374", ] def cb(attr, old, new): source.data["val"] = [old, new] input_box.on_change("value", cb) doc.add_root(column(input_box, plot))
def test_displays_text_input(self, bokeh_model_page): text_input = AutocompleteInput(css_classes=["foo"], completions = ["100001", "12344556", "12344557", "3194567289", "209374209374"]) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector('.foo input') assert el.get_attribute('type') == "text" assert page.has_no_console_errors()
def test_arrow_cannot_escape_menu(self, bokeh_model_page): text_input = AutocompleteInput(title="title", css_classes=["foo"], completions = ["100001", "12344556", "12344557", "3194567289", "209374209374"]) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' in el.get_attribute('style') el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') # arrow down moves to second item enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class') # arrow down again has no effect enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class') # arrow up moves to first item enter_text_in_element(page.driver, el, Keys.UP, click=0, enter=False) assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') # arrow up again has no effect enter_text_in_element(page.driver, el, Keys.UP, click=0, enter=False) assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') assert page.has_no_console_errors()
def build_autocomplete_grph_driver(rtplot: Figure, plots: List, ms_plot: Figure, patchsources: Dict[str, Tuple], source: ColumnDataSource, default_county: str, counties: pd.Index) -> Tuple[CDSView, AutocompleteInput]: choices = AutocompleteInput(completions=counties.tolist(), case_sensitive=False, value=default_county, title='Search for county or select from table:', name="county_input", width_policy='fit', css_classes=['autocomplete_input'], min_width=250, align="start") someargs = dict(source=source, rtplot=rtplot, rtxaxis=rtplot.xaxis[0], rtyaxis=rtplot.yaxis[0], ms_plot=ms_plot, ms_plot_xaxis=ms_plot.xaxis[0], ms_plot_yaxis0=ms_plot.yaxis[0], plots=plots, choices=choices, patchsources=patchsources) someargs['xaxes'], someargs['yaxes'], someargs['plots'] = [], [], [] for p in plots: someargs['xaxes'].append(p['plot'].xaxis[0]) someargs['yaxes'].append(p['plot'].yaxis[0]) someargs['plots'].append(p['plot']) callback = CustomJS(args=someargs, code=constants.autocomplete_input_code) choices.js_on_change('value', callback) js_filter = CustomJSFilter(args=dict(choices=choices), code=constants.cdsview_jsfilter_code) view = CDSView(source=source, filters=[js_filter]) return view, choices
def test_displays_menu(self, bokeh_model_page) -> None: text_input = AutocompleteInput( title="title", css_classes=["foo"], completions=[ "100001", "12344556", "12344557", "3194567289", "209374209374", ], fuzzy_comparison=False, ) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" in el.get_attribute("style") # double click to highlight and overwrite old text el = page.driver.find_element_by_css_selector(".foo input") enter_text_in_element(page.driver, el, "100", click=2, enter=False) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" not in el.get_attribute("style") items = el.find_elements_by_tag_name("div") assert len(items) == 1 assert items[0].text == "100001" assert "bk-active" in items[0].get_attribute("class") el = page.driver.find_element_by_css_selector(".foo input") enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" not in el.get_attribute("style") items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute("class") assert "bk-active" not in items[1].get_attribute("class") enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" not in items[0].get_attribute("class") assert "bk-active" in items[1].get_attribute("class") assert page.has_no_console_errors()
def test_displays_text_input(self, bokeh_model_page: BokehModelPage) -> None: text_input = AutocompleteInput(completions=[ "100001", "12344556", "12344557", "3194567289", "209374209374" ]) page = bokeh_model_page(text_input) el = find_element_for(page.driver, text_input, "input") assert el.get_attribute('type') == "text" assert page.has_no_console_errors()
def generateAutocompleteWidget(destination_number=1, initial_value="", name=None, placeholder=None): if name is None: name = f'Destination {destination_number}' if placeholder is None: placeholder = 'Enter Location' autocomplete = AutocompleteInput(name=name, completions=['test'], title=name, min_characters=3, value=initial_value, placeholder=placeholder) def autocomplete_callback(attr, old, new): if (len(new) > 0): pass autocomplete.on_change('value_input', autocomplete_callback) return autocomplete
def test_case_insensitivity(self, bokeh_model_page) -> None: text_input = AutocompleteInput( title="title", css_classes=["foo"], case_sensitive=False, completions=["100001", "aaaaaa", "aaabbb", "AAAaAA", "AAABbB"], fuzzy_comparison=False, ) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" in el.get_attribute("style") # double click to highlight and overwrite old text el = page.driver.find_element_by_css_selector(".foo input") enter_text_in_element(page.driver, el, "aAa", click=2, enter=False) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" not in el.get_attribute("style") items = el.find_elements_by_tag_name("div") assert len(items) == 4 assert items[0].text == "aaaaaa" assert items[1].text == "aaabbb" assert items[2].text == "AAAaAA" assert items[3].text == "AAABbB" assert "bk-active" in items[0].get_attribute("class") el = page.driver.find_element_by_css_selector(".foo input") enter_text_in_element(page.driver, el, "aAaB", click=2, enter=False) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" not in el.get_attribute("style") items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "aaabbb" assert items[1].text == "AAABbB" assert "bk-active" in items[0].get_attribute("class") assert "bk-active" not in items[1].get_attribute("class") enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "aaabbb" assert items[1].text == "AAABbB" assert "bk-active" not in items[0].get_attribute("class") assert "bk-active" in items[1].get_attribute("class") assert page.has_no_console_errors()
def modify_doc(doc): #callback function def autocomplete_update(attrname, old, new): stream.event(gene=new) print(autocomplete.value) #callback function def dropdown_update(attrname, old, new): streamSet.event(set=new) stream.event(set=new) print(dropdown.value) #initialize dropdown to select cell type dropdown = Select(title="Cell Set", value="all", options=['all', 'microglia']) #initialize autocomplete field for querying genes autocomplete = AutocompleteInput( title="Type in a gene and select from the dropdown", value="", completions=getGenes()) #callbacks dropdown.on_change('value', dropdown_update) autocomplete.on_change('value', autocomplete_update) #get graphs and store in variables hvplot = renderer.get_plot(dmap_query, doc) hvplot_full = renderer.get_plot(dmap_cluster, doc) #create view for HTML plot = gridplot([[autocomplete, dropdown], [hvplot.state, hvplot_full.state]]) #add view to HTML doc doc.add_root(plot)
def test_case_insensitivity(self, bokeh_model_page: BokehModelPage) -> None: text_input = AutocompleteInput( title="title", case_sensitive=False, completions=["100001", "aaaaaa", "aaabbb", "AAAaAA", "AAABbB"]) page = bokeh_model_page(text_input) el = find_element_for(page.driver, text_input, ".bk-menu") assert 'display: none;' in el.get_attribute('style') # double click to highlight and overwrite old text el = find_element_for(page.driver, text_input, "input") enter_text_in_element(page.driver, el, "aAa", click=2, enter=False) el = find_element_for(page.driver, text_input, ".bk-menu") assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 4 assert items[0].text == "aaaaaa" assert items[1].text == "aaabbb" assert items[2].text == "AAAaAA" assert items[3].text == "AAABbB" assert "bk-active" in items[0].get_attribute('class') el = find_element_for(page.driver, text_input, "input") enter_text_in_element(page.driver, el, "aAaB", click=2, enter=False) el = find_element_for(page.driver, text_input, ".bk-menu") assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "aaabbb" assert items[1].text == "AAABbB" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "aaabbb" assert items[1].text == "AAABbB" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class') assert page.has_no_console_errors()
def test_server_on_change_no_round_trip_without_enter_or_click( self, bokeh_server_page: BokehServerPage) -> None: input_box = AutocompleteInput() modify_doc, _ = mk_modify_doc(input_box) page = bokeh_server_page(modify_doc) el = find_element_for(page.driver, input_box, "input") enter_text_in_element( page.driver, el, "pre", enter=False) # not change event if enter is not pressed page.eval_custom_action() results = page.results assert results['data']['val'] == ["a", "b"]
def test_case_sensitivity(self, bokeh_model_page) -> None: # case_sensitive=True by default text_input = AutocompleteInput( title="title", css_classes=["foo"], completions=["100001", "aAaaaa", "aAaBbb", "AAAaAA", "aAaBbB"]) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' in el.get_attribute('style') # double click to highlight and overwrite old text el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "aAa", click=2, enter=False) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 3 assert items[0].text == "aAaaaa" assert items[1].text == "aAaBbb" assert items[2].text == "aAaBbB" assert "bk-active" in items[0].get_attribute('class') el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "aAaB", click=2, enter=False) el = page.driver.find_element_by_css_selector('.foo .bk-menu') assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "aAaBbb" assert items[1].text == "aAaBbB" assert "bk-active" in items[0].get_attribute('class') enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "aAaBbb" assert items[1].text == "aAaBbB" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class') assert page.has_no_console_errors()
def test_displays_menu(self, bokeh_model_page: BokehModelPage) -> None: text_input = AutocompleteInput(title="title", completions=[ "100001", "12344556", "12344557", "3194567289", "209374209374" ]) page = bokeh_model_page(text_input) el = find_element_for(page.driver, text_input, ".bk-menu") assert 'display: none;' in el.get_attribute('style') # double click to highlight and overwrite old text el = find_element_for(page.driver, text_input, "input") enter_text_in_element(page.driver, el, "100", click=2, enter=False) el = find_element_for(page.driver, text_input, ".bk-menu") assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 1 assert items[0].text == "100001" assert "bk-active" in items[0].get_attribute('class') el = find_element_for(page.driver, text_input, "input") enter_text_in_element(page.driver, el, "123", click=2, enter=False) el = find_element_for(page.driver, text_input, ".bk-menu") assert 'display: none;' not in el.get_attribute('style') items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" in items[0].get_attribute('class') assert "bk-active" not in items[1].get_attribute('class') enter_text_in_element(page.driver, el, Keys.DOWN, click=0, enter=False) items = el.find_elements_by_tag_name("div") assert len(items) == 2 assert items[0].text == "12344556" assert items[1].text == "12344557" assert "bk-active" not in items[0].get_attribute('class') assert "bk-active" in items[1].get_attribute('class') assert page.has_no_console_errors()
def test_server_restrict(self, bokeh_server_page) -> None: """Test effect of 'restrict=False' without explicit callback.""" text_input = AutocompleteInput(css_classes=["foo"], completions = ["aAaBbb", "aAaBbB"], restrict=False) def add_autocomplete(doc): # note: for some reason, bokeh_server_page requires a 'canvas' in the document plot = Plot() doc.add_root(column(text_input,plot)) page = bokeh_server_page(add_autocomplete) el = page.driver.find_element_by_css_selector('.foo input') text = "not in completions" enter_text_in_element(page.driver, el, text, click=1, enter=True) assert text_input.value == text assert page.has_no_console_errors()
def test_server_restriction_to_list( self, bokeh_server_page: BokehServerPage) -> None: """Test that input entered manually doesn't end up in the value.""" text_input = AutocompleteInput(completions=["aAaBbb"], restrict=True) def add_autocomplete(doc): # note: for some reason, bokeh_server_page requires a 'canvas' in the document plot = Plot() doc.add_root(column(text_input, plot)) page = bokeh_server_page(add_autocomplete) el = find_element_for(page.driver, text_input, "input") text = "not in completions" enter_text_in_element(page.driver, el, text, click=1, enter=True) assert text_input.value == '' assert page.has_no_console_errors()
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1], val=["a", "b"])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) input_box = AutocompleteInput(css_classes=["foo"]) input_box.title = "title" input_box.value = "400" input_box.completions = ["100001", "12344556", "12344557", "3194567289", "209374209374"] def cb(attr, old, new): source.data['val'] = [old, new] input_box.on_change('value', cb) doc.add_root(column(input_box, plot))
def test_displays_text_input(self, bokeh_model_page) -> None: text_input = AutocompleteInput( css_classes=["foo"], completions=[ "100001", "12344556", "12344557", "3194567289", "209374209374", ], fuzzy_comparison=False, ) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector(".foo input") assert el.get_attribute("type") == "text" assert page.has_no_console_errors()
def test_min_characters(self, bokeh_model_page) -> None: text_input = AutocompleteInput( title="title", css_classes=["foo"], completions=[ "100001", "12344556", "12344557", "3194567289", "209374209374", "aaaaaa", "aaabbb", "AAAaAA", "AAABbB", ], min_characters=1, fuzzy_comparison=False, ) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" in el.get_attribute("style") # double click to highlight and overwrite old text el = page.driver.find_element_by_css_selector(".foo input") enter_text_in_element(page.driver, el, "1", click=2, enter=False) el = page.driver.find_element_by_css_selector(".foo .bk-menu") assert "display: none;" not in el.get_attribute("style") items = el.find_elements_by_tag_name("div") assert len(items) == 3 assert items[0].text == "100001" assert items[1].text == "12344556" assert items[2].text == "12344557" assert "bk-active" in items[0].get_attribute("class") assert "bk-active" not in items[1].get_attribute("class") assert "bk-active" not in items[2].get_attribute("class")
def __init__(self, doc, idx, plots, callback=None, refresh_rate=500, collection=None, **kwargs): super().__init__(doc, callback=callback, refresh_rate=refresh_rate, collection=collection, **kwargs) self._countername_autocomplete = AutocompleteInput( name=f"Autocomplete_{BaseWidget.instance_num}", title="Countername:", completions=counternames, width=200, ) self._collection_widget = DataCollectionSelect(doc, self._set_collection, width=120) self._selected_collection = None self._name = f"Line {idx}" self._name_edit = TextInput(title="Change name:", value=self._name, width=150) self._name_edit.on_change("value", self._change_name) self._title = Div(text=f"<h3>{self._name}</h3>") self._delete = Button(label="Remove", width=70, button_type="danger") self._delete.on_click(lambda: callback(idx)) self._to_plot = Select(options=plots, value=plots[0], title="To plot:", width=70) # Instance infos self._locality_input = TextInput(title="Locality #id:", value="0", width=70) self._locality_select = Select(options=[], title="Locality #id:", value="0", width=70) self._thread_id = TextInput(title="Worker #id:", width=70, value="0") self._pool = TextInput(title="Pool name:", width=70) self._pool_select = Select(options=[], title="Pool name:", width=70) self._is_total = RadioGroup(labels=["Yes", "No"], active=0, width=30) self._is_total.on_change("active", self._change_is_total) self._root = column( row(self._title, self._name_edit), self._delete, row( self._to_plot, self._collection_widget.layout(), self._countername_autocomplete, self._locality_input, self._pool, row(Div(text="Is total?"), self._is_total), empty_placeholder(), ), )
RadioButtonGroup( labels=["Radio Option 1", "Radio Option 2", "Radio Option 3"], button_type="default", active=0), RadioButtonGroup( labels=["Radio Option 4", "Radio Option 5", "Radio Option 6"], button_type="primary", active=1), RadioButtonGroup( labels=["Radio Option 7", "Radio Option 8", "Radio Option 9"], button_type="success", active=2), TextInput(placeholder="TextInput 1"), TextInput(placeholder="TextInput 2"), TextInput(placeholder="TextInput 3"), AutocompleteInput(placeholder="AutocompleteInput 1 ...", completions=["aaa", "aab", "aac", "baa", "caa"]), AutocompleteInput(placeholder="AutocompleteInput 2 ...", completions=["AAA", "AAB", "AAC", "BAA", "CAA"]), AutocompleteInput(placeholder="AutocompleteInput 3 ...", completions=["000", "001", "002", "100", "200"]), AutocompleteInput(placeholder="AutocompleteInput 4 ...", completions=["foo", "foobar", "fuzzymatch", "foozzy"], fuzzy_threshold=4), DatePicker(value=date(2018, 9, 1)), DatePicker(value=date(2018, 9, 2)), DatePicker(value=date(2018, 9, 3)), ) #Slider(value=10, start=0, end=100, step=0.5), #RangeSlider(value=[20, 30], start=0, end=100, step=0.5), #DateSlider(value=date(2018, 9, 1), start=date(2018, 1, 1), end=date(2018, 12, 31)),
dropdown = Dropdown(label="Dropdown button", button_type="warning", menu=menu) dropdown_split = Dropdown(label="Split button", button_type="danger", menu=menu, split=True) checkbox_group = CheckboxGroup(labels=["Option 1", "Option 2", "Option 3"], active=[0, 1]) radio_group = RadioGroup(labels=["Option 1", "Option 2", "Option 3"], active=0) checkbox_button_group = CheckboxButtonGroup(labels=["Option 1", "Option 2", "Option 3"], active=[0, 1]) radio_button_group = RadioButtonGroup(labels=["Option 1", "Option 2", "Option 3"], active=0) checkbox_button_group_vertical = CheckboxButtonGroup(labels=["Option 1", "Option 2", "Option 3"], active=[0, 1], orientation="vertical") radio_button_group_vertical = RadioButtonGroup(labels=["Option 1", "Option 2", "Option 3"], active=0, orientation="vertical") text_input = TextInput(placeholder="Enter value ...") completions = ["aaa", "aab", "aac", "baa", "caa"] autocomplete_input = AutocompleteInput(placeholder="Enter value (auto-complete) ...", completions=completions) text_area = TextAreaInput(placeholder="Enter text ...", cols=20, rows=10, value="uuu") select = Select(options=["Option 1", "Option 2", "Option 3"]) multi_select = MultiSelect(options=["Option %d" % (i+1) for i in range(16)], size=6) multi_choice = MultiChoice(options=["Option %d" % (i+1) for i in range(16)]) slider = Slider(value=10, start=0, end=100, step=0.5) range_slider = RangeSlider(value=[10, 90], start=0, end=100, step=0.5) date_slider = DateSlider(value=date(2016, 1, 1), start=date(2015, 1, 1), end=date(2017, 12, 31))