Add support for Buefy autocomplete; several other form tweaks
at least the Edit User form should work now, for instance
This commit is contained in:
parent
d7e19865de
commit
2b6d88105c
16 changed files with 390 additions and 42 deletions
|
@ -1,4 +1,5 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## -*- coding: utf-8; -*-
|
||||
|
||||
## TODO: This function signature is getting out of hand...
|
||||
<%def name="autocomplete(field_name, service_url, field_value=None, field_display=None, width='300px', select=None, selected=None, cleared=None, change_clicked=None, options={})">
|
||||
<div id="${field_name}-container" class="autocomplete-container">
|
||||
|
@ -56,3 +57,31 @@
|
|||
});
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
<%def name="tailbone_autocomplete_template()">
|
||||
<script type="text/x-template" id="tailbone-autocomplete-template">
|
||||
<div>
|
||||
|
||||
<b-autocomplete ref="autocomplete"
|
||||
:name="name"
|
||||
v-show="!selected"
|
||||
v-model="autocompleteValue"
|
||||
:data="data"
|
||||
@typing="getAsyncData"
|
||||
@select="selectionMade"
|
||||
@input="itemSelected"
|
||||
keep-first>
|
||||
<template slot-scope="props">
|
||||
{{ props.option.label }}
|
||||
</template>
|
||||
</b-autocomplete>
|
||||
|
||||
<b-button v-if="selected"
|
||||
style="width: 100%; justify-content: left;"
|
||||
@click="clearSelection()">
|
||||
{{ selected.label }} (click to change)
|
||||
</b-button>
|
||||
|
||||
</div>
|
||||
</script>
|
||||
</%def>
|
||||
|
|
|
@ -2,10 +2,14 @@
|
|||
css_class css_class|field.widget.css_class;
|
||||
oid oid|field.oid;
|
||||
field_display field_display;
|
||||
style style|field.widget.style"
|
||||
id="${oid}-container"
|
||||
class="autocomplete-container">
|
||||
style style|field.widget.style;
|
||||
url url|field.widget.service_url;
|
||||
use_buefy use_buefy|0;"
|
||||
tal:omit-tag="">
|
||||
|
||||
<div tal:condition="not use_buefy"
|
||||
id="${oid}-container"
|
||||
class="autocomplete-container">
|
||||
<input type="hidden"
|
||||
name="${name}"
|
||||
id="${oid}"
|
||||
|
@ -98,5 +102,16 @@
|
|||
}
|
||||
);
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div tal:condition="use_buefy"
|
||||
tal:define="vmodel vmodel|'field_model_' + name;"
|
||||
tal:omit-tag="">
|
||||
<tailbone-autocomplete name="${name}"
|
||||
service-url="${url}"
|
||||
v-model="${vmodel}"
|
||||
initial-label="${field_display}">
|
||||
</tailbone-autocomplete>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,26 @@
|
|||
<div class="checkbox">
|
||||
<input tal:define="name name|field.name;
|
||||
true_val true_val|field.widget.true_val;
|
||||
css_class css_class|field.widget.css_class;
|
||||
style style|field.widget.style;
|
||||
oid oid|field.oid"
|
||||
type="checkbox"
|
||||
<div tal:define="name name|field.name;
|
||||
true_val true_val|field.widget.true_val;
|
||||
css_class css_class|field.widget.css_class;
|
||||
style style|field.widget.style;
|
||||
oid oid|field.oid;
|
||||
use_buefy use_buefy|0;"
|
||||
tal:omit-tag="">
|
||||
|
||||
<div tal:condition="not use_buefy" class="checkbox">
|
||||
<input type="checkbox"
|
||||
name="${name}" value="${true_val}"
|
||||
id="${oid}"
|
||||
tal:attributes="checked cstruct == true_val;
|
||||
class css_class;
|
||||
style style;" />
|
||||
</div>
|
||||
|
||||
<div tal:condition="use_buefy"
|
||||
tal:define="vmodel vmodel|'field_model_' + name;">
|
||||
<b-checkbox name="${name}"
|
||||
v-model="${vmodel}"
|
||||
native-value="${true_val}">
|
||||
{{ ${vmodel} }}
|
||||
</b-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
|
60
tailbone/templates/deform/checked_password.pt
Normal file
60
tailbone/templates/deform/checked_password.pt
Normal file
|
@ -0,0 +1,60 @@
|
|||
<div i18n:domain="deform" tal:omit-tag=""
|
||||
tal:define="oid oid|field.oid;
|
||||
name name|field.name;
|
||||
css_class css_class|field.widget.css_class;
|
||||
style style|field.widget.style;
|
||||
use_buefy use_buefy|0;">
|
||||
|
||||
<div tal:condition="not use_buefy" tal:omit-tag="">
|
||||
${field.start_mapping()}
|
||||
<div>
|
||||
<input type="password"
|
||||
name="${name}"
|
||||
value="${field.widget.redisplay and cstruct or ''}"
|
||||
tal:attributes="class string: form-control ${css_class or ''};
|
||||
style style;
|
||||
attributes|field.widget.attributes|{};"
|
||||
id="${oid}"
|
||||
i18n:attributes="placeholder"
|
||||
placeholder="Password"/>
|
||||
</div>
|
||||
<div>
|
||||
<input type="password"
|
||||
name="${name}-confirm"
|
||||
value="${field.widget.redisplay and confirm or ''}"
|
||||
tal:attributes="class string: form-control ${css_class or ''};
|
||||
style style;
|
||||
confirm_attributes|field.widget.confirm_attributes|{};"
|
||||
id="${oid}-confirm"
|
||||
i18n:attributes="placeholder"
|
||||
placeholder="Confirm Password"/>
|
||||
</div>
|
||||
${field.end_mapping()}
|
||||
</div>
|
||||
|
||||
<div tal:condition="use_buefy">
|
||||
${field.start_mapping()}
|
||||
<b-input type="password"
|
||||
name="${name}"
|
||||
value="${field.widget.redisplay and cstruct or ''}"
|
||||
tal:attributes="class string: form-control ${css_class or ''};
|
||||
style style;
|
||||
attributes|field.widget.attributes|{};"
|
||||
id="${oid}"
|
||||
i18n:attributes="placeholder"
|
||||
placeholder="Password">
|
||||
</b-input>
|
||||
<b-input type="password"
|
||||
name="${name}-confirm"
|
||||
value="${field.widget.redisplay and confirm or ''}"
|
||||
tal:attributes="class string: form-control ${css_class or ''};
|
||||
style style;
|
||||
confirm_attributes|field.widget.confirm_attributes|{};"
|
||||
id="${oid}-confirm"
|
||||
i18n:attributes="placeholder"
|
||||
placeholder="Confirm Password">
|
||||
</b-input>
|
||||
${field.end_mapping()}
|
||||
</div>
|
||||
|
||||
</div>
|
|
@ -58,12 +58,14 @@
|
|||
|
||||
<div tal:condition="use_buefy"
|
||||
tal:define="vmodel vmodel|'field_model_' + name;"
|
||||
tal:omit-tag="">
|
||||
>
|
||||
<input type="hidden" name="__start__" value="${name}:sequence"
|
||||
tal:condition="multiple" />
|
||||
<b-select tal:attributes="name name;
|
||||
id oid;
|
||||
placeholder '(please choose)';
|
||||
class string: form-control ${css_class or ''};
|
||||
multiple multiple;
|
||||
:multiple str(multiple).lower();
|
||||
size size;
|
||||
style style;
|
||||
v-model vmodel;
|
||||
|
@ -88,6 +90,8 @@
|
|||
</tal:loop>
|
||||
|
||||
</b-select>
|
||||
<input type="hidden" name="__end__" value="${name}:sequence"
|
||||
tal:condition="multiple" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
27
tailbone/templates/deform/textarea.pt
Normal file
27
tailbone/templates/deform/textarea.pt
Normal file
|
@ -0,0 +1,27 @@
|
|||
<div tal:define="rows rows|field.widget.rows;
|
||||
cols cols|field.widget.cols;
|
||||
css_class css_class|field.widget.css_class;
|
||||
oid oid|field.oid;
|
||||
name name|field.name;
|
||||
style style|field.widget.style;
|
||||
use_buefy use_buefy|0;"
|
||||
tal:omit-tag="">
|
||||
|
||||
<div tal:condition="not use_buefy" tal:omit-tag="">
|
||||
<textarea tal:attributes="rows rows;
|
||||
cols cols;
|
||||
class string: form-control ${css_class or ''};
|
||||
style style;
|
||||
attributes|field.widget.attributes|{};"
|
||||
id="${oid}"
|
||||
name="${name}">${cstruct}</textarea>
|
||||
</div>
|
||||
|
||||
<div tal:condition="use_buefy"
|
||||
tal:define="vmodel vmodel|'field_model_' + name;">
|
||||
<b-input type="textarea"
|
||||
name="${name}"
|
||||
v-model="${vmodel}">
|
||||
</b-input>
|
||||
</div>
|
||||
</div>
|
32
tailbone/templates/deform/textinput.pt
Normal file
32
tailbone/templates/deform/textinput.pt
Normal file
|
@ -0,0 +1,32 @@
|
|||
<span tal:define="name name|field.name;
|
||||
css_class css_class|field.widget.css_class;
|
||||
oid oid|field.oid;
|
||||
mask mask|field.widget.mask;
|
||||
mask_placeholder mask_placeholder|field.widget.mask_placeholder;
|
||||
style style|field.widget.style;
|
||||
use_buefy use_buefy|0;"
|
||||
tal:omit-tag="">
|
||||
<div tal:condition="not use_buefy" tal:omit-tag="">
|
||||
<input type="text" name="${name}" value="${cstruct}"
|
||||
tal:attributes="class string: form-control ${css_class or ''};
|
||||
style style;
|
||||
attributes|field.widget.attributes|{};"
|
||||
id="${oid}"/>
|
||||
<script tal:condition="mask" type="text/javascript">
|
||||
deform.addCallback(
|
||||
'${oid}',
|
||||
function (oid) {
|
||||
$("#" + oid).mask("${mask}",
|
||||
{placeholder:"${mask_placeholder}"});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div tal:condition="use_buefy"
|
||||
tal:define="vmodel vmodel|'field_model_' + name;"
|
||||
tal:omit-tag="">
|
||||
<b-input name="${name}"
|
||||
v-model="${vmodel}">
|
||||
</b-input>
|
||||
</div>
|
||||
</span>
|
|
@ -11,7 +11,38 @@
|
|||
${form.render(buttons=capture(self.render_form_buttons))|n}
|
||||
</%def>
|
||||
|
||||
<%def name="render_buefy_form()">
|
||||
<div class="form">
|
||||
<tailbone-form></tailbone-form>
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
<%def name="render_form_complete()">
|
||||
% if use_buefy:
|
||||
${self.render_form()}
|
||||
<script type="text/x-template" id="form-page-template">
|
||||
<div style="display: flex; justify-content: space-between;">
|
||||
|
||||
<div class="form-wrapper">
|
||||
${self.render_buefy_form()}
|
||||
</div>
|
||||
|
||||
<div style="display: flex; align-items: flex-start;">
|
||||
<div class="object-helpers">
|
||||
${self.object_helpers()}
|
||||
</div>
|
||||
|
||||
<ul id="context-menu">
|
||||
${self.context_menu_items()}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</script>
|
||||
<div id="form-page-app">
|
||||
<form-page></form-page>
|
||||
</div>
|
||||
% else:
|
||||
<div style="display: flex; justify-content: space-between;">
|
||||
|
||||
<div class="form-wrapper">
|
||||
|
@ -29,6 +60,7 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="modify_tailbone_form()">
|
||||
|
@ -43,8 +75,14 @@
|
|||
|
||||
Vue.component('tailbone-form', TailboneForm)
|
||||
|
||||
const FormPage = {
|
||||
template: '#form-page-template'
|
||||
}
|
||||
|
||||
Vue.component('form-page', FormPage)
|
||||
|
||||
new Vue({
|
||||
el: '#tailbone-form-app'
|
||||
el: '#form-page-app'
|
||||
})
|
||||
|
||||
</script>
|
||||
|
@ -53,6 +91,6 @@
|
|||
|
||||
${self.render_form_complete()}
|
||||
|
||||
% if form.use_buefy:
|
||||
% if use_buefy:
|
||||
${self.make_tailbone_form_app()}
|
||||
% endif
|
||||
|
|
|
@ -91,21 +91,10 @@
|
|||
% for field in form.fields:
|
||||
% if field in dform:
|
||||
<% field = dform[field] %>
|
||||
% if isinstance(field.schema.typ, colander.Date):
|
||||
field_model_${field.name}: null,
|
||||
% elif isinstance(field.schema.typ, deform.FileData):
|
||||
field_model_${field.name}: null,
|
||||
% else:
|
||||
field_model_${field.name}: ${'null' if field.cstruct is colander.null else json.dumps(field.cstruct)|n},
|
||||
% endif
|
||||
field_model_${field.name}: ${form.get_vuejs_model_value(field)|n},
|
||||
% endif
|
||||
% endfor
|
||||
% endif
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<div id="tailbone-form-app">
|
||||
<tailbone-form></tailbone-form>
|
||||
</div>
|
||||
|
|
|
@ -20,16 +20,28 @@
|
|||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="render_form()">
|
||||
<%def name="render_buefy_form()">
|
||||
<br />
|
||||
% if use_buefy:
|
||||
<b-notification type="is-danger" :closable="false">
|
||||
You are about to delete the following ${model_title} and all associated data:
|
||||
</b-notification>
|
||||
% else:
|
||||
<p>You are about to delete the following ${model_title} and all associated data:</p>
|
||||
% endif
|
||||
|
||||
${parent.render_form()}
|
||||
${parent.render_buefy_form()}
|
||||
</%def>
|
||||
|
||||
<%def name="render_form_buttons()">
|
||||
<br />
|
||||
% if use_buefy:
|
||||
<b-notification type="is-danger" :closable="false">
|
||||
Are you sure about this?
|
||||
</b-notification>
|
||||
% else:
|
||||
<p>Are you sure about this?</p>
|
||||
% endif
|
||||
<br />
|
||||
|
||||
${h.form(request.current_route_url(), class_=None if form.use_buefy else 'autodisable')}
|
||||
|
@ -39,15 +51,13 @@
|
|||
<once-button tag="a" href="${form.cancel_url}"
|
||||
text="Whoops, nevermind...">
|
||||
</once-button>
|
||||
% else:
|
||||
<a class="button" href="${form.cancel_url}">Whoops, nevermind...</a>
|
||||
% endif
|
||||
% if form.use_buefy:
|
||||
<once-button type="is-primary" native-type="submit"
|
||||
<once-button type="is-primary is-danger"
|
||||
native-type="submit"
|
||||
text="Yes, please DELETE this data forever!">
|
||||
</once-button>
|
||||
% else:
|
||||
${h.submit('submit', "Yes, please DELETE this data forever!", class_='button is-primary')}
|
||||
<a class="button" href="${form.cancel_url}">Whoops, nevermind...</a>
|
||||
${h.submit('submit', "Yes, please DELETE this data forever!", class_='button is-primary')}
|
||||
% endif
|
||||
</div>
|
||||
${h.end_form()}
|
||||
|
|
|
@ -141,13 +141,12 @@
|
|||
<input type="hidden"
|
||||
name="uuids"
|
||||
:value="checkedRowUUIDs()" />
|
||||
<b-button type="is-primary"
|
||||
native-type="submit"
|
||||
icon-pack="fas"
|
||||
icon-left="object-ungroup"
|
||||
:disabled="checkedRows.length != 2">
|
||||
Merge 2 ${model_title_plural}
|
||||
</b-button>
|
||||
<once-button type="is-primary"
|
||||
native-type="submit"
|
||||
icon-left="object-ungroup"
|
||||
:disabled="checkedRows.length != 2"
|
||||
text="Merge 2 ${model_title_plural}">
|
||||
</once-button>
|
||||
% else:
|
||||
${h.hidden('uuids')}
|
||||
<button type="submit" class="button">Merge 2 ${model_title_plural}</button>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
## -*- coding: utf-8; -*-
|
||||
<%namespace file="/grids/nav.mako" import="grid_index_nav" />
|
||||
<%namespace file="/feedback_dialog_buefy.mako" import="feedback_dialog" />
|
||||
<%namespace file="/autocomplete.mako" import="tailbone_autocomplete_template" />
|
||||
<%namespace name="base_meta" file="/base_meta.mako" />
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
@ -30,6 +31,11 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
## TODO: should move template to JS, then can postpone the JS
|
||||
${tailbone_autocomplete_template()}
|
||||
${h.javascript_link(request.static_url('tailbone:static/js/tailbone.buefy.autocomplete.js') + '?ver={}'.format(tailbone.__version__))}
|
||||
|
||||
<header>
|
||||
|
||||
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue