[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