From 245f3089d0938b38a84f7a528a77aba50a09d4f3 Mon Sep 17 00:00:00 2001 From: VijithaEkanayake Date: Thu, 17 Dec 2020 21:35:20 +0530 Subject: [PATCH] Add enter handler for textbox Fixes: https://github.com/h2oai/wave/issues/372 --- py/examples/textbox.py | 6 ++++++ ui/src/textbox.test.tsx | 34 ++++++++++++++++++++++++++++++++++ ui/src/textbox.tsx | 9 +++++++++ 3 files changed, 49 insertions(+) diff --git a/py/examples/textbox.py b/py/examples/textbox.py index e86295d7db4..2872b7cd9ea 100644 --- a/py/examples/textbox.py +++ b/py/examples/textbox.py @@ -22,6 +22,11 @@ async def serve(q: Q): ui.text(f'textbox_multiline={q.args.textbox_multiline}'), ui.button(name='show_form', label='Back', primary=True), ] + elif q.args.enter_key_handler: + q.page['example'].items = [ + ui.text(f'textbox_enter_key_handler={q.args.enter_key_handler}'), + ui.button(name='show_form', label='Back', primary=True), + ] else: q.page['example'] = ui.form_card(box='1 1 4 10', items=[ ui.textbox(name='textbox', label='Standard'), @@ -36,6 +41,7 @@ async def serve(q: Q): ui.textbox(name='textbox_placeholder', label='With placeholder', placeholder='I need some input'), ui.textbox(name='textbox_disabled_placeholder', label='Disabled with placeholder', disabled=True, placeholder='I am disabled'), + ui.textbox(name='enter_key_handler', label='Submits the textbox value on Enter key', icon='Search'), ui.textbox(name='textbox_multiline', label='Multiline textarea', multiline=True), ui.button(name='show_inputs', label='Submit', primary=True), ]) diff --git a/ui/src/textbox.test.tsx b/ui/src/textbox.test.tsx index b9d3b2c8e25..4388ac9a764 100644 --- a/ui/src/textbox.test.tsx +++ b/ui/src/textbox.test.tsx @@ -101,4 +101,38 @@ describe('Textbox.tsx', () => { expect(syncMock).not.toBeCalled() }) + + it('Calls sync on key up - When the key is Enter key', () => { + const { getByTestId } = render() + + const syncMock = jest.fn() + T.qd.sync = syncMock + + fireEvent.keyUp(getByTestId(name), { key: 'Enter', target: { value: 'text' } }) + + expect(syncMock).toBeCalled() + }) + + it('Does not call sync on key up - When the key is not Enter key', () => { + const { getByTestId } = render() + + const syncMock = jest.fn() + T.qd.sync = syncMock + + fireEvent.keyUp(getByTestId(name), { key: 'A', target: { value: 'text' } }) + + expect(syncMock).not.toBeCalled() + }) + + it('Does not call sync on key up - When multiline is true', () => { + const { getByTestId } = render() + + const syncMock = jest.fn() + T.qd.sync = syncMock + + fireEvent.keyUp(getByTestId(name), { key: 'Enter', target: { value: 'text' } }) + + expect(syncMock).not.toBeCalled() + }) + }) \ No newline at end of file diff --git a/ui/src/textbox.tsx b/ui/src/textbox.tsx index dbb883b6238..2f7bd60a4b0 100644 --- a/ui/src/textbox.tsx +++ b/ui/src/textbox.tsx @@ -75,6 +75,13 @@ export const qd.args[m.name] = v ?? (m.value || '') if (m.trigger) qd.sync() }, + onKeyUp = ( event: React.KeyboardEvent, v?: string) => { + if ((event).key == "Enter" && event.target instanceof HTMLInputElement) { + v = v || (event.target as HTMLInputElement).value + qd.args[m.name] = v ?? (m.value || '') + qd.sync() + } + }, render = () => m.mask ? ( ) : ( @@ -108,6 +116,7 @@ export const multiline={m.multiline} type={m.password ? 'password' : undefined} onChange={m.trigger ? debounce(DEBOUNCE_TIMEOUT, onChange) : onChange} + onKeyUp={onKeyUp} /> )