[Bps-public-commit] rt-extension-formtools branch dynamic-forms-from-config updated. 0.53-105-g67fb2ac
BPS Git Server
git at git.bestpractical.com
Mon Nov 13 23:55:53 UTC 2023
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt-extension-formtools".
The branch, dynamic-forms-from-config has been updated
via 67fb2ac26029c1b57fe30ee1d131f4c0bc9d3bd2 (commit)
via e428dbf0fba430514c1f612c2f08d5df9abad232 (commit)
via 5c053ff9334891570ec0fd6db9a6e3810056e99e (commit)
via 7673b5c026e1e59292e41e30c84015c3a418b01a (commit)
from defce7e7150c69539ca8b9245ca3bf49f098242f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 67fb2ac26029c1b57fe30ee1d131f4c0bc9d3bd2
Author: sunnavy <sunnavy at bestpractical.com>
Date: Mon Nov 13 18:28:48 2023 -0500
Support client validation(required) for fields
diff --git a/html/Admin/FormTools/Modify.html b/html/Admin/FormTools/Modify.html
index c09a33b..e982797 100644
--- a/html/Admin/FormTools/Modify.html
+++ b/html/Admin/FormTools/Modify.html
@@ -106,6 +106,14 @@
<&| /Elements/LabeledValue, Label => loc('Tooltip') &>
<input name="tooltip" type="text" class="form-control" value="" />
</&>
+ <&| /Elements/LabeledValue, Label => '' &>
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input" id="<% CSSClass($item) %>-validation" type="checkbox" name="validation" value="1" />
+ <label class="custom-control-label" for="<% CSSClass($item) %>-validation">
+ <&|/l&>Require</&>
+ </label>
+ </div>
+ </&>
<&| /Elements/LabeledValue, Label => '' &>
<div class="custom-control custom-checkbox">
<input class="custom-control-input" id="<% CSSClass($item) %>-hide" type="checkbox" name="hide" value="1" />
@@ -158,6 +166,14 @@
<&| /Elements/LabeledValue, Label => loc('Tooltip') &>
<input name="tooltip" type="text" class="form-control" placeholder="<% $tooltips{$item} // '' %>" value="" />
</&>
+ <&| /Elements/LabeledValue, Label => '' &>
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input" id="<% CSSClass($item) %>-validation" type="checkbox" name="validation" value="1" />
+ <label class="custom-control-label" for="<% CSSClass($item) %>-validation">
+ <&|/l&>Require</&>
+ </label>
+ </div>
+ </&>
% if ( %dependent_custom_fields ) {
<&| /Elements/LabeledValue, Label => '' &>
<div class="custom-control custom-checkbox">
@@ -409,6 +425,14 @@
<&| /Elements/LabeledValue, Label => loc('Tooltip') &>
<input name="tooltip" type="text" class="form-control" placeholder="<% $tooltips{$item->{arguments}{name}} // '' %>" value="<% $item->{arguments}{tooltip} // '' %>" />
</&>
+ <&| /Elements/LabeledValue, Label => '' &>
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input" id="formtools-element-<% $form_page_id{$page_name} %>-<% $i %>-validation" type="checkbox" name="validation" value="1" <% $item->{arguments}{validation} ? q{checked="checked"} : '' |n %> />
+ <label class="custom-control-label" for="formtools-element-<% $form_page_id{$page_name} %>-<% $i %>-validation">
+ <&|/l&>Require</&>
+ </label>
+ </div>
+ </&>
% if ( !RT::Extension::FormTools::is_core_field($item->{arguments}{name}) ) {
% if ( %dependent_custom_fields ) {
<&| /Elements/LabeledValue, Label => '' &>
diff --git a/html/FormTools/Field b/html/FormTools/Field
index 07160be..abdb48d 100644
--- a/html/FormTools/Field
+++ b/html/FormTools/Field
@@ -145,6 +145,9 @@ $default = '' unless defined $default;
<&| /Elements/LabeledValue, RawLabel => $m->interp->apply_escapes($field_label, 'h') . $after_label, LabelSpanClass => $tooltip ? 'prev-icon-helper' : '', LabelTooltip => $tooltip &>
<div data-name="<% $cf ? $cf->Name : '' %>"
+% if ( $ARGS{validation} ) {
+ data-validation="<% $ARGS{validation} %>"
+% }
% if ( $ARGS{dependent_validation} && $ARGS{dependent_validation}{enabled} && $ARGS{dependent_validation}{name} ) {
% my $dependent_cf = RT::CustomField->new($session{CurrentUser});
% $dependent_cf = RT::CustomField->new( $session{'CurrentUser'} );
diff --git a/html/Forms/dhandler b/html/Forms/dhandler
index 3508d63..82c0995 100644
--- a/html/Forms/dhandler
+++ b/html/Forms/dhandler
@@ -38,7 +38,38 @@ foreach my $element ( @{$form_config->{'formtools-pages'}{$page}{'content'}} ) {
<script type="text/javascript">
jQuery(function () {
- jQuery('[data-dependent-name]').each(function () {
+ jQuery('[data-validation]').each(function () {
+ const elem = jQuery(this);
+ if ( elem.find('.selectize-input').length ) {
+ elem.find(':input:first').change(function () {
+ if ( jQuery(this).val() ) {
+ elem.find('.selectize-input').removeClass('required invalid');
+ elem.find(':input:visible').attr('required', false);
+ }
+ else {
+ elem.find('.selectize-input').addClass('required invalid');
+ elem.find(':input:visible').attr('required', true);
+ }
+ }).change();
+ }
+ else {
+ elem.find(':input:visible').attr('required', true);
+
+ if ( elem.find('select.selectpicker').length ) {
+ elem.find('select.selectpicker option[value=""]').remove();
+ if ( !elem.find('select.selectpicker').val() ) {
+ elem.find('select.selectpicker').val(null); // Do not automatically select the first valid option
+ }
+ elem.find('select.selectpicker').attr('required', true);
+ }
+ else if ( elem.find('input[type=radio]').length ) {
+ elem.find('input[type=radio][value=""]').closest('div.custom-control').remove();
+ }
+ }
+
+ });
+
+ jQuery('[data-dependent-name]:not([data-validation])').each(function () {
const dependent_name = jQuery(this).attr('data-dependent-name');
const values = JSON.parse(jQuery(this).attr('data-dependent-values'));
const target = jQuery(this);
diff --git a/static/js/rt-extension-formtools.js b/static/js/rt-extension-formtools.js
index 2f405e0..63ba4cf 100644
--- a/static/js/rt-extension-formtools.js
+++ b/static/js/rt-extension-formtools.js
@@ -138,6 +138,16 @@ formTools = {
delete value.arguments.tooltip;
}
+ const validation = form.find(':input[name=validation]');
+ if ( validation.length ) {
+ if ( validation.is(':checked') ) {
+ value.arguments.validation = 1;
+ }
+ else {
+ delete value.arguments.validation;
+ }
+ }
+
const dependent_validation = form.find(':input[name=dependent_validation]');
if ( dependent_validation.length ) {
value.arguments.dependent_validation ||= {};
commit e428dbf0fba430514c1f612c2f08d5df9abad232
Author: sunnavy <sunnavy at bestpractical.com>
Date: Mon Nov 13 17:05:15 2023 -0500
Support dependent validation for cf select/radio inputs
diff --git a/html/Forms/dhandler b/html/Forms/dhandler
index a777df7..3508d63 100644
--- a/html/Forms/dhandler
+++ b/html/Forms/dhandler
@@ -72,10 +72,36 @@ jQuery(function () {
}
}
+ // Toggle "(No value)" on show to catch all cases including page re-rendering after clicking "Back"
+ if ( target.find('select.selectpicker').length ) {
+ target.find('select.selectpicker').on('show.bs.select', function() {
+ if ( jQuery(this).hasClass('required') ) {
+ jQuery(this).parent().find('.dropdown-menu li.disabled').addClass('hidden');
+ }
+ else {
+ jQuery(this).parent().find('.dropdown-menu li').removeClass('hidden');
+ }
+ });
+ }
+
if ( matched ) {
+ if ( target.find('select.selectpicker').length ) {
+ target.find('select.selectpicker option[value=""]').attr('selected', false).attr('disabled', true);
+ target.find('select.selectpicker').addClass('required').selectpicker('refresh');
+ }
+ else if ( target.find('input[type=radio]').length ) {
+ target.find('input[type=radio][value=""]').prop('checked', false).attr('disabled', true);
+ }
target.find(':input:visible').attr('required', true);
}
else {
+ if ( target.find('select.selectpicker').length ) {
+ target.find('select.selectpicker option[value=""]').attr('disabled', false);
+ target.find('select.selectpicker').removeClass('required').selectpicker('refresh');
+ }
+ else if ( target.find('input[type=radio]').length ) {
+ target.find('input[type=radio][value=""]').attr('disabled', false);
+ }
target.find(':input:visible').attr('required', false);
}
};
commit 5c053ff9334891570ec0fd6db9a6e3810056e99e
Author: sunnavy <sunnavy at bestpractical.com>
Date: Mon Nov 13 10:22:49 2023 -0500
Tweak label for dependent validation as it just means "required" right now
diff --git a/html/Admin/FormTools/Modify.html b/html/Admin/FormTools/Modify.html
index 0b15c56..c09a33b 100644
--- a/html/Admin/FormTools/Modify.html
+++ b/html/Admin/FormTools/Modify.html
@@ -163,7 +163,7 @@
<div class="custom-control custom-checkbox">
<input class="custom-control-input" id="<% CSSClass($item) %>-depedent-validation" type="checkbox" name="dependent_validation" value="1" />
<label class="custom-control-label has-text-input" for="<% CSSClass($item) %>-depedent-validation">
- <&|/l&>Show validation if</&>
+ <&|/l&>Require if</&>
<div class="d-inline-block">
<select name="dependent_name" class="form-control">
<option value=""><&|/l&>(no value)</&></option>
@@ -415,7 +415,7 @@
<div class="custom-control custom-checkbox">
<input class="custom-control-input" id="formtools-element-<% $form_page_id{$page_name} %>-<% $i %>-depedent-validation" type="checkbox" name="dependent_validation" value="1" <% $item->{arguments}{dependent_validation}{enabled} ? 'checked="checked"' : '' |n %> />
<label class="custom-control-label has-text-input" for="formtools-element-<% $form_page_id{$page_name} %>-<% $i %>-depedent-validation">
- <&|/l&>Show validation if</&>
+ <&|/l&>Require if</&>
<div class="d-inline-block">
<select name="dependent_name" class="form-control selectpicker">
<option value=""><&|/l&>(no value)</&></option>
commit 7673b5c026e1e59292e41e30c84015c3a418b01a
Author: sunnavy <sunnavy at bestpractical.com>
Date: Mon Nov 13 09:55:48 2023 -0500
Always enable core level cf validations
diff --git a/etc/sample_form.json b/etc/sample_form.json
index 8987269..6583632 100644
--- a/etc/sample_form.json
+++ b/etc/sample_form.json
@@ -19,7 +19,6 @@
"next" : ""
},
"page2" : {
- "validation" : 1,
"name" : "Page Two",
"content" : [
{
@@ -77,11 +76,9 @@
}
],
"name" : "Review Selections",
- "validation" : 1,
"next" : "submit"
},
"page1" : {
- "validation" : 1,
"name" : "Page One",
"content" : [
{
@@ -97,7 +94,6 @@
"type" : "component",
"arguments" : {
"default" : "preferred username",
- "show_validation" : 1,
"name" : "Username"
}
}
diff --git a/html/Admin/FormTools/Modify.html b/html/Admin/FormTools/Modify.html
index 98d22fc..0b15c56 100644
--- a/html/Admin/FormTools/Modify.html
+++ b/html/Admin/FormTools/Modify.html
@@ -158,14 +158,6 @@
<&| /Elements/LabeledValue, Label => loc('Tooltip') &>
<input name="tooltip" type="text" class="form-control" placeholder="<% $tooltips{$item} // '' %>" value="" />
</&>
- <&| /Elements/LabeledValue, Label => '' &>
- <div class="custom-control custom-checkbox">
- <input class="custom-control-input" id="<% CSSClass($item) %>-validation" type="checkbox" name="show_validation" value="1" checked="checked" />
- <label class="custom-control-label" for="<% CSSClass($item) %>-validation">
- <&|/l&>Show validation</&>
- </label>
- </div>
- </&>
% if ( %dependent_custom_fields ) {
<&| /Elements/LabeledValue, Label => '' &>
<div class="custom-control custom-checkbox">
@@ -305,14 +297,6 @@
<&| /Elements/LabeledValue, Label => loc('Sort Order') &>
<input name="sort_order" class="form-control" value="<% $form->{'formtools-pages'}{$page_name}{sort_order} %>" />
</&>
- <&| /Elements/LabeledValue, Label => '' &>
- <div class="custom-control custom-checkbox">
- <input class="custom-control-input" id="<% $form_page_id{$page_name} %>-validation" type="checkbox" name="validation" value="1" <% $form->{'formtools-pages'}{$page_name}{validation} ? 'checked="checked"' : '' |n%> />
- <label class="custom-control-label" for="<% $form_page_id{$page_name} %>-validation">
- <&|/l&>Enable validation</&>
- </label>
- </div>
- </&>
% # Do not delete the last one
% if ( $form->{'formtools-pages'}{$page_name}{next} ) {
@@ -426,14 +410,6 @@
<input name="tooltip" type="text" class="form-control" placeholder="<% $tooltips{$item->{arguments}{name}} // '' %>" value="<% $item->{arguments}{tooltip} // '' %>" />
</&>
% if ( !RT::Extension::FormTools::is_core_field($item->{arguments}{name}) ) {
- <&| /Elements/LabeledValue, Label => '' &>
- <div class="custom-control custom-checkbox">
- <input class="custom-control-input" id="formtools-element-<% $form_page_id{$page_name} %>-<% $i %>-validation" type="checkbox" name="show_validation" value="1" <% $item->{arguments}{show_validation} ? q{checked="checked"} : '' |n %> />
- <label class="custom-control-label" for="formtools-element-<% $form_page_id{$page_name} %>-<% $i %>-validation">
- <&|/l&>Show validation</&>
- </label>
- </div>
- </&>
% if ( %dependent_custom_fields ) {
<&| /Elements/LabeledValue, Label => '' &>
<div class="custom-control custom-checkbox">
diff --git a/html/FormTools/Field b/html/FormTools/Field
index 98127eb..07160be 100644
--- a/html/FormTools/Field
+++ b/html/FormTools/Field
@@ -8,7 +8,6 @@ $default => undef
$cols => undef
$rows => undef
$empty_allowed => 1
-$show_validation => 0
$show_label => 1
$disables => {}
$enabled_by => []
@@ -179,7 +178,6 @@ $default => undef
$cols => undef
$rows => undef
$empty_allowed => 1
-$show_validation => 0
$disables => {}
$after_input => ''
$cf => undef
@@ -255,7 +253,7 @@ $input_name => undef
&>
% if (my $msg = $m->notes('InvalidField-' . $cf->Id)) {
<span class="cfinvalidfield my-1 d-inline-block"><% $msg %></span>
-% } elsif ($show_validation and $cf->FriendlyPattern) {
+% } elsif ($cf->FriendlyPattern) {
<span class="cfhints my-1 d-inline-block">
<% $cf->FriendlyPattern %>
</span>
diff --git a/html/FormTools/Form b/html/FormTools/Form
index e6b7215..8dca906 100644
--- a/html/FormTools/Form
+++ b/html/FormTools/Form
@@ -5,7 +5,6 @@ $include_header => 1
$include_page_layout => 1
$include_tabs => 0
$ShowBar => 1
-$validation => 0
$enable_persisting => 1
$forbid_persisting => {}
$form_id => undef
@@ -33,7 +32,7 @@ my %request_args = $m->request_args;
my @results;
my $real_next = delete $request_args{_form_tools_next};
-if ($validation && $real_next) {
+if ($real_next) {
my $queue = $m->notes('queue');
# registered validation
if (my $validation = $m->notes('validation')) {
@@ -118,15 +117,13 @@ $next_for_validation ||= $m->caller(1)->path;
<div id="formtools-form-body" class="container p-4 formtools-base-style">
<form
method="POST"
- action="<% $validation ? $next_for_validation : $next %>"
+ action="<% $next_for_validation %>"
enctype="multipart/form-data"
<% defined $form_id ? ' id="'.$form_id.'"' : '' |n %>
<% defined $form_name ? ' name="'.$form_name.'"' : '' |n %>
<% defined $form_classes ? ' class="'.$form_classes.'"' : '' |n %>
>
-% if ($validation) {
<input type="hidden" name="_form_tools_next" value="<%$next%>" />
-% }
<%$content|n%>
% if ($enable_persisting) {
diff --git a/html/Forms/dhandler b/html/Forms/dhandler
index 64db5d6..a777df7 100644
--- a/html/Forms/dhandler
+++ b/html/Forms/dhandler
@@ -1,5 +1,4 @@
<&|/FormTools/Form, next => $base_path . $form_name . '/' . $form_config->{'formtools-pages'}{$page}{'next'},
- validation => $form_config->{'formtools-pages'}{$page}{'validation'},
next_for_validation => $base_path . $form_name . '/' . $page,
results_ref => \@results,
self_service => $SelfService,
@@ -164,9 +163,7 @@ $m->notes( page_title => $form_config->{'formtools-pages'}{$page}{'name'} );
my $base_path = '/Forms/';
$base_path = '/SelfService' . $base_path if $SelfService;
-my $validation = $form_config->{'formtools-pages'}{$page}{'validation'};
-
-if ( $validation and not $ARGS{'validation_ok'} ) {
+if ( not $ARGS{'validation_ok'} ) {
# If validation is enabled and it didn't pass, don't create
$create_ticket = 0;
}
@@ -179,14 +176,9 @@ my $show_back = 0;
my $index = 0;
my $back_page;
-# When validation is enabled for this page, it submits to itself
-# first, so the back button only needs to go back 1. Otherwise,
-# current page was "next" on submit, so we need to go back 2.
-my $go_back_count = $validation ? 1 : 2;
-
foreach my $page_index ( @form_pages ) {
if ( $page_index eq $page ) {
- $back_page = $form_pages[$index - $go_back_count];
+ $back_page = $form_pages[$index - 1];
last;
}
$index++;
diff --git a/static/js/rt-extension-formtools.js b/static/js/rt-extension-formtools.js
index 3a38734..2f405e0 100644
--- a/static/js/rt-extension-formtools.js
+++ b/static/js/rt-extension-formtools.js
@@ -138,17 +138,6 @@ formTools = {
delete value.arguments.tooltip;
}
- const validation = form.find(':input[name=show_validation]');
- if ( validation.length ) {
- if ( validation.is(':checked') ) {
- value.arguments.show_validation = 1;
- }
- else {
- delete value.arguments.show_validation;
- }
- }
-
-
const dependent_validation = form.find(':input[name=dependent_validation]');
if ( dependent_validation.length ) {
value.arguments.dependent_validation ||= {};
@@ -207,13 +196,8 @@ formTools = {
let page = jQuery(this).data('page');
content[page] ||= {};
- for ( let attr of ['name', 'sort_order', 'validation'] ) {
- if ( attr === 'validation' ) {
- content[page][attr] = jQuery(this).closest('div.tab-pane').find(':input[name="' + attr + '"]').is(':checked') ? 1 : 0;
- }
- else {
- content[page][attr] = jQuery(this).closest('div.tab-pane').find(':input[name="' + attr + '"]').val();
- }
+ for ( let attr of ['name', 'sort_order'] ) {
+ content[page][attr] = jQuery(this).closest('div.tab-pane').find(':input[name="' + attr + '"]').val();
}
content[page]['content'] ||= [];
-----------------------------------------------------------------------
Summary of changes:
etc/sample_form.json | 4 ---
html/Admin/FormTools/Modify.html | 30 ++++++++--------
html/FormTools/Field | 7 ++--
html/FormTools/Form | 7 ++--
html/Forms/dhandler | 71 +++++++++++++++++++++++++++++++------
static/js/rt-extension-formtools.js | 16 +++------
6 files changed, 86 insertions(+), 49 deletions(-)
hooks/post-receive
--
rt-extension-formtools
More information about the Bps-public-commit
mailing list