Answers.Body: <p>Since the shuffled markup is the root of the problem, one might follow examples from the Craft control panel source that serialize the form's data and submit via AJAX (and often <code>$.proxy()</code> to help with scope).</p>
  
  <p>This is a lot of work, however, for minor stylistic gain. <strong>If the problem is limited to presentation, the solution should be too.</strong> @narration_sd helped me see how fragile the jQuery hack is compared to a CSS hack, and so in lieu of The Perfect Answer I've created a <code>pseudo-hud-footer</code> class to wrap my action buttons. It's inelegant, looks identical, and it's less risky than my previous workaround:</p>
  
  <pre><code>.approval-request-form .field { margin-top: 0; margin-bottom: 0; }
  .pseudo-hud-footer {
      position: relative;
      left: -24px;
      bottom: -24px;
      border-radius: 0 0 4px 4px;
      padding: 6px 24px 10px 24px;
      width: 100%;
      height: 35px;
      background-image: -webkit-linear-gradient(#ecedef, #e9eaec);
      background-image: -moz-linear-gradient(#ecedef, #e9eaec);
      background-image: -ms-linear-gradient(#ecedef, #e9eaec);
      background-image: -o-linear-gradient(#ecedef, #e9eaec);
      background-image: linear-gradient(#ecedef, #e9eaec);
      -webkit-box-shadow: inset 0 2px 1px -2px rgba(0, 0, 0, 0.2);
      -moz-box-shadow: inset 0 2px 1px -2px rgba(0, 0, 0, 0.2);
      box-shadow: inset 0 2px 1px -2px rgba(0, 0, 0, 0.2);
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-26T22:12:21.000Z
Answers.LastActivityDate: 2017-05-26T22:18:04.797Z
Answers.LastEditDate: 2017-05-26T22:18:04.797Z
Answers.UserDisplayName: Matt Stein
Body: <p>I'm working on a Dashboard widget from which users can submit entries for review from a Garnish HUD, like so...</p>
  
  <p><a href="https://i.sstatic.net/seifg.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/seifg.png" alt="Garnish HUD without a footer."></a></p>
  
  <p>I've started by placing a hidden form next to each little <em>Submit</em> button... </p>
  
  <pre><code>&lt;form method="post" class="approval-request-form hidden" action="/actions/plugin/submitPost"&gt;
      &lt;input type="hidden" name="entryId" value="{{ element.id }}"&gt;
      {{ forms.textareaField({
          name: 'notes',
          label: 'Review Note',
          instructions: 'Add a note for the person reviewing your work.',
          maxlength: 140
      }) }}
  
      &lt;div class="buttons right"&gt;
          &lt;div class="btn cancel"&gt;Cancel&lt;/div&gt;
          &lt;input type="submit" class="btn submit" value="Submit for Review"&gt;
      &lt;/div&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>Once that little button is clicked, I clone the form into a new Garnish HUD with delightful ease:</p>
  
  <pre><code>jQuery(function(){
      $('.request-approval').click(function(e){
          e.preventDefault();
          var $form = $(e.target).siblings('.approval-request-form').first().clone().removeClass('hidden');
          var hud = new Garnish.HUD(e.target, $form);
      });
  });
  </code></pre>
  
  <p>This works great! I can post to my controller and all is well. Moments later, it occurs to me that I need some field validation and that it'd be nice to use a HUD footer (with its gray backdrop) and hook up my cancel button...</p>
  
  <p><a href="https://i.sstatic.net/6BMKR.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/6BMKR.png" alt="The new goal: Garnish HUD with footer."></a></p>
  
  <p>I wrap my form's buttons in <code>class="hud-footer"</code>, which applies exactly the style I want...</p>
  
  <pre><code>&lt;form method="post" class="approval-request-form hidden" action="/actions/plugin/submitPost"&gt;
      &lt;input type="hidden" name="entryId" value="{{ element.id }}"&gt;
      {{ forms.textareaField({
          name: 'notes',
          label: 'Review Note',
          instructions: 'Add a note for the person reviewing your work.',
          maxlength: 140
      }) }}
      &lt;div class="hud-footer"&gt;
          &lt;div class="buttons right"&gt;
              &lt;div class="btn cancel"&gt;Cancel&lt;/div&gt;
              &lt;input type="submit" class="btn submit" value="Submit for Review"&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>This is where the pain starts, because my submit button looks fantastic yet does nothing. After a while I realize it's because <a href="https://github.com/pixelandtonic/garnishjs/blob/develop/src/HUD.js" rel="nofollow noreferrer">HUD.js</a> redraws things and pulls the action buttons out of my <code>&lt;form&gt;</code> element where they <em>would have</em> known what to do...</p>
  
  <pre><code>&lt;div class="hud has-footer"&gt;
      &lt;div class="tip tip-top"&gt;&lt;/div&gt;
      &lt;form class="body"&gt;
          &lt;div class="main-container"&gt;
              &lt;div class="main"&gt;
                  &lt;form method="post" class="approval-request-form last" action="/actions/plugin/submitPost"&gt;
                  ... my form elements without .buttons ...
                  &lt;/form&gt;
                  &lt;object tabindex="-1" type="text/html" data="about:blank" style="display: block; position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; border: none; padding: 0px; margin: 0px; opacity: 0; z-index: -1000; pointer-events: none;"&gt;&lt;/object&gt;
              &lt;/div&gt;
          &lt;/div&gt;
          &lt;div class=""&gt;&lt;/div&gt;
      &lt;/form&gt;
      &lt;div class="hud-footer"&gt;
          &lt;div class="buttons right last"&gt;
              &lt;div class="btn cancel" tabindex="0"&gt;Cancel&lt;/div&gt;
              &lt;input type="submit" class="btn submit" value="Submit for Review"&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>After some trial and error, I wind up sneaking a hidden submit button into my form and "clicking" it with JavaScript via the HUD's <code>onSubmit</code> property...</p>
  
  <pre><code>jQuery(function(){
      $('.request-approval').click(function(e){
          e.preventDefault();
          var $form = $(e.target).siblings('.approval-request-form').first().clone().removeClass('hidden');
          var hud = new Garnish.HUD(e.target, $form, { closeBtn: $form.find('.cancel'), onSubmit: submitForm });
  
          function checkForm() {
              $form.find('.submit').trigger('click');
          }
      });
  });
  </code></pre>
  
  <p>That successfully reaches into my form and submits it (and allows me to add some validation logic later), but <strong>how can I use the HUD's footer button to submit the form in <code>.main</code> without the questionable hackery of triggering a click on a hidden button?</strong></p>
  
  <p>I suspect I'm either missing something or not thinking quite like the Garnish HUD wants me to. The closest example I've found is the element editor you'd see working with Assets, which serializes and posts its form data via AJAX. I could mimic that instead, but I'd rob myself and our fair Stack Exchange of a learning opportunity.</p>
  
Tags: <plugin-development><control-panel><garnish><dashboard-widgets><hud>
Title: How can I submit a form from a Garnish HUD footer?
ThreadText: # How can I submit a form from a Garnish HUD footer?
  
  (Asked by: username_0 on 2017-05-26)
  
  I'm working on a Dashboard widget from which users can submit entries for review from a Garnish HUD, like so...
  
  [![Garnish HUD without a footer.](https://i.sstatic.net/seifg.png)](https://i.sstatic.net/seifg.png)
  
  I've started by placing a hidden form next to each little *Submit* button...
  
  ```
  <form method="post" class="approval-request-form hidden" action="/actions/plugin/submitPost">
      <input type="hidden" name="entryId" value="{{ element.id }}">
      {{ forms.textareaField({
          name: 'notes',
          label: 'Review Note',
          instructions: 'Add a note for the person reviewing your work.',
          maxlength: 140
      }) }}
  
      <div class="buttons right">
          <div class="btn cancel">Cancel</div>
          <input type="submit" class="btn submit" value="Submit for Review">
      </div>
  </form>
  
  ```
  
  Once that little button is clicked, I clone the form into a new Garnish HUD with delightful ease:
  
  ```
  jQuery(function(){
      $('.request-approval').click(function(e){
          e.preventDefault();
          var $form = $(e.target).siblings('.approval-request-form').first().clone().removeClass('hidden');
          var hud = new Garnish.HUD(e.target, $form);
      });
  });
  
  ```
  
  This works great! I can post to my controller and all is well. Moments later, it occurs to me that I need some field validation and that it'd be nice to use a HUD footer (with its gray backdrop) and hook up my cancel button...
  
  [![The new goal: Garnish HUD with footer.](https://i.sstatic.net/6BMKR.png)](https://i.sstatic.net/6BMKR.png)
  
  I wrap my form's buttons in `class="hud-footer"`, which applies exactly the style I want...
  
  ```
  <form method="post" class="approval-request-form hidden" action="/actions/plugin/submitPost">
      <input type="hidden" name="entryId" value="{{ element.id }}">
      {{ forms.textareaField({
          name: 'notes',
          label: 'Review Note',
          instructions: 'Add a note for the person reviewing your work.',
          maxlength: 140
      }) }}
      <div class="hud-footer">
          <div class="buttons right">
              <div class="btn cancel">Cancel</div>
              <input type="submit" class="btn submit" value="Submit for Review">
          </div>
      </div>
  </form>
  
  ```
  
  This is where the pain starts, because my submit button looks fantastic yet does nothing. After a while I realize it's because [HUD.js](https://github.com/pixelandtonic/garnishjs/blob/develop/src/HUD.js) redraws things and pulls the action buttons out of my `<form>` element where they *would have* known what to do...
  
  ```
  <div class="hud has-footer">
      <div class="tip tip-top"></div>
      <form class="body">
          <div class="main-container">
              <div class="main">
                  <form method="post" class="approval-request-form last" action="/actions/plugin/submitPost">
                  ... my form elements without .buttons ...
                  </form>
                  <object tabindex="-1" type="text/html" data="about:blank" style="display: block; position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; border: none; padding: 0px; margin: 0px; opacity: 0; z-index: -1000; pointer-events: none;"></object>
              </div>
          </div>
          <div class=""></div>
      </form>
      <div class="hud-footer">
          <div class="buttons right last">
              <div class="btn cancel" tabindex="0">Cancel</div>
              <input type="submit" class="btn submit" value="Submit for Review">
          </div>
      </div>
  </div>
  
  ```
  
  After some trial and error, I wind up sneaking a hidden submit button into my form and "clicking" it with JavaScript via the HUD's `onSubmit` property...
  
  ```
  jQuery(function(){
      $('.request-approval').click(function(e){
          e.preventDefault();
          var $form = $(e.target).siblings('.approval-request-form').first().clone().removeClass('hidden');
          var hud = new Garnish.HUD(e.target, $form, { closeBtn: $form.find('.cancel'), onSubmit: submitForm });
  
          function checkForm() {
              $form.find('.submit').trigger('click');
          }
      });
  });
  
  ```
  
  That successfully reaches into my form and submits it (and allows me to add some validation logic later), but **how can I use the HUD's footer button to submit the form in `.main` without the questionable hackery of triggering a click on a hidden button?**
  
  I suspect I'm either missing something or not thinking quite like the Garnish HUD wants me to. The closest example I've found is the element editor you'd see working with Assets, which serializes and posts its form data via AJAX. I could mimic that instead, but I'd rob myself and our fair Stack Exchange of a learning opportunity.
  
  **Tags:** plugin-development, control-panel, garnish, dashboard-widgets, hud
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2017-05-26. Score: 3 | Accepted answer
  
  Since the shuffled markup is the root of the problem, one might follow examples from the Craft control panel source that serialize the form's data and submit via AJAX (and often `$.proxy()` to help with scope).
  
  This is a lot of work, however, for minor stylistic gain. **If the problem is limited to presentation, the solution should be too.** @narration\_sd helped me see how fragile the jQuery hack is compared to a CSS hack, and so in lieu of The Perfect Answer I've created a `pseudo-hud-footer` class to wrap my action buttons. It's inelegant, looks identical, and it's less risky than my previous workaround:
  
  ```
  .approval-request-form .field { margin-top: 0; margin-bottom: 0; }
  .pseudo-hud-footer {
      position: relative;
      left: -24px;
      bottom: -24px;
      border-radius: 0 0 4px 4px;
      padding: 6px 24px 10px 24px;
      width: 100%;
      height: 35px;
      background-image: -webkit-linear-gradient(#ecedef, #e9eaec);
      background-image: -moz-linear-gradient(#ecedef, #e9eaec);
      background-image: -ms-linear-gradient(#ecedef, #e9eaec);
      background-image: -o-linear-gradient(#ecedef, #e9eaec);
      background-image: linear-gradient(#ecedef, #e9eaec);
      -webkit-box-shadow: inset 0 2px 1px -2px rgba(0, 0, 0, 0.2);
      -moz-box-shadow: inset 0 2px 1px -2px rgba(0, 0, 0, 0.2);
      box-shadow: inset 0 2px 1px -2px rgba(0, 0, 0, 0.2);
  }
  
  ```
  
  
  ---
  
  