From 3a53ffcc235d8ded61026a49c25b40aef88c0a2b Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Fri, 28 Jun 2019 13:06:43 -0500 Subject: [PATCH] Add `NumericInputWidget` for use with Buefy themes uses a Vue.js component for better logic encapsulation --- tailbone/forms/widgets.py | 12 ++++++ .../static/js/tailbone.buefy.numericinput.js | 38 +++++++++++++++++++ tailbone/templates/deform/numericinput.pt | 12 ++++++ tailbone/templates/themes/falafel/base.mako | 4 ++ 4 files changed, 66 insertions(+) create mode 100644 tailbone/static/js/tailbone.buefy.numericinput.js create mode 100644 tailbone/templates/deform/numericinput.pt diff --git a/tailbone/forms/widgets.py b/tailbone/forms/widgets.py index cdb628ec..d8976337 100644 --- a/tailbone/forms/widgets.py +++ b/tailbone/forms/widgets.py @@ -58,6 +58,18 @@ class NumberInputWidget(dfwidget.TextInputWidget): autocomplete = 'off' +class NumericInputWidget(NumberInputWidget): + """ + This widget only supports Buefy themes for now. It uses a + ```` component, which will leverage the ``numeric.js`` + functions to ensure user doesn't enter any non-numeric values. Note that + this still uses a normal "text" input on the HTML side, as opposed to a + "number" input, since the latter is a bit ugly IMHO. + """ + template = 'numericinput' + allow_enter = True + + class PercentInputWidget(dfwidget.TextInputWidget): """ Custom text input widget, used for "percent" type fields. This widget diff --git a/tailbone/static/js/tailbone.buefy.numericinput.js b/tailbone/static/js/tailbone.buefy.numericinput.js new file mode 100644 index 00000000..706c79a8 --- /dev/null +++ b/tailbone/static/js/tailbone.buefy.numericinput.js @@ -0,0 +1,38 @@ + +const NumericInput = { + template: [ + '', + '' + ].join(' '), + + props: { + name: String, + value: String, + allowEnter: Boolean + }, + + methods: { + + keyDown(event) { + // by default we only allow numeric keys, and general navigation + // keys, but we might also allow Enter key + if (!key_modifies(event) && !key_allowed(event)) { + if (!this.allowEnter || event.which != 13) { + event.preventDefault() + } + } + }, + + valueChanged(value) { + this.$emit('input', value) + } + + } +} + +Vue.component('numeric-input', NumericInput) diff --git a/tailbone/templates/deform/numericinput.pt b/tailbone/templates/deform/numericinput.pt new file mode 100644 index 00000000..4c54dd2c --- /dev/null +++ b/tailbone/templates/deform/numericinput.pt @@ -0,0 +1,12 @@ +
+ + +
diff --git a/tailbone/templates/themes/falafel/base.mako b/tailbone/templates/themes/falafel/base.mako index a4aa63d4..08557741 100644 --- a/tailbone/templates/themes/falafel/base.mako +++ b/tailbone/templates/themes/falafel/base.mako @@ -293,8 +293,12 @@ ${self.buefy()} ${self.fontawesome()} + ## some commonly-useful logic for detecting (non-)numeric input + ${h.javascript_link(request.static_url('tailbone:static/js/numeric.js') + '?ver={}'.format(tailbone.__version__))} + ## Tailbone / Buefy stuff ${h.javascript_link(request.static_url('tailbone:static/js/tailbone.buefy.datepicker.js') + '?ver={}'.format(tailbone.__version__))} + ${h.javascript_link(request.static_url('tailbone:static/js/tailbone.buefy.numericinput.js') + '?ver={}'.format(tailbone.__version__))} ${h.javascript_link(request.static_url('tailbone:static/js/tailbone.buefy.oncebutton.js') + '?ver={}'.format(tailbone.__version__))} ${h.javascript_link(request.static_url('tailbone:static/js/tailbone.buefy.timepicker.js') + '?ver={}'.format(tailbone.__version__))} ${h.javascript_link(request.static_url('tailbone:static/js/tailbone.buefy.grid.js') + '?ver={}'.format(tailbone.__version__))}