Skip to content Skip to sidebar Skip to footer

How To Style HtmlService Form Elements With Labels Above Input?

I am trying to recreate a form that was written with the deprecated UiApp into an HtmlService version. I inherited most of this code so I am trying to learn/improve/tidy as I go. T

Solution 1:

If you're including the default Stylesheet.html file, it also pulls in Google's css file, https://ssl.gstatic.com/docs/script/css/add-ons.css. (Your stylesheet doesn't do this - you should, why re-invent the wheel?)

That css file provides the styling you're looking for, providing that you apply the appropriate classes to your form elements. This is all documented in CSS Package for Add-ons, which is easy to miss if you're not working on an add-on!

Control of input field labels is described on that page, under Text fields. Starting with that, here's an overview of the required changes. The full code is in a runnable snippet below, so you can grab a copy there, as well as see it in action.

  • Instead of plain-text field labels, use <label> elements.

    Their example shows use of for="field-id" to associate labels with elements, but under HTML5 we now use form="field-id" instead.

  • Group the <label> and <input> elements together within a <div>, and apply the styling classes inline and form-group to the div.

    Input elements need id attributes for this to work. Unless you're submitting a form via POST, they don't need a name. (That's not the topic of this question - 'nuff said.)

    <div class="inline form-group">
      <label form="city">City</label>
      <input type="text" id="city" style="width: 150px;">
    </div>
    

    Note that in this example from the documentation, there is still a style attribute for the field width, which was what you wanted to avoid in your question #2. The reasoning behind doing this is that we're using generalized css classes to style common attributes of related elements - this keeps our look consistent. By keeping element-specific styling that doesn't affect the overall appearance within the elements themselves, we avoid clutter in the css file. This is consistent with the principle of separating design & development concerns, although seeing the style attribute might make you think otherwise.

  • Consider the input fields one block, and the submit button (+ any other buttons) as another, and put them in separate divs, with class="block". This will provide vertical spacing between them.

    <div class="block">
      ... input fields ...
    </div>
    
    <div class="block">
      ... button(s) ...
    </div>
    
  • When using <datalist> elements to provide auto-completion, watch the names. For example, you had an input element named depot and a datalist with the same id. By using the plural form for the datalist, an id collision is avoided while improving code readability.

    Also - <option> should be self-closing when you're setting a value. Browsers will usually figure it out, but better to get it right, and remember the />.

    <div class="inline form-group">
      <label form="depot">Depot/Site</label>
      <input id="depot" list="depots" name="depot" style="width: 100px;">
      <datalist id="depots">
        <option value="COMPANY (H&S Projects Team" />
        <option value="CS - C** Street Depot" />
      </datalist>
    </div>
    

<link href="https://ssl.gstatic.com/docs/script/css/add-ons.css"  />
<!-- The above css link has been relocated from Stylesheet.html for
     compatibility with the Stack Snippet tool.
-->

<html>

<body>
  <h3>ProReactive Hazard Logging v3.0.0</h3>
  <form action="<?= action ?>" method="post">
    <div class="block">
      <div class="inline form-group">
        <label form="date">Date</label>
        <input type="date" id="date" name="date" style="width: 100px;" />
      </div>
      <div class="inline form-group">
        <label form="depot">Depot/Site</label>
        <input id="depot" list="depots" name="depot" style="width: 100px;">
        <datalist id="depots">
          <option value="COMPANY (H&S Projects Team" />
          <option value="CS - C** Street Depot" />
        </datalist>
      </div>
      <div class="inline form-group">
        <label form="reporter">Reporter</label>
        <input type="text" name="reporter" style="width: 100px;" />
      </div>
      <div class="inline form-group">
        <label form="details">Contact No</label>
        <input type="text" name="details" id="details" style="width: 100px;" />
      </div>
      <div class="inline form-group">
        <label form="source">Source Code</label>
        <input list="sources" name="source" id="source" style="width: 100px;">
        <datalist id="sources">
          <option value="01 - Accident/Incident investigations & reports" />
          <option value="02 - Company or location H&S Committee / Forum actions" />
          <option value="03 - Emergency Preparedness reviews/activities" />
        </datalist>
      </div>
      <div class="inline form-group">
        <label form="hazard">Hazard Code</label>
        <input list="hazards" name="hazard" style="width: 100px;">
        <datalist id="hazards">
          <option value="01 - Access equipment fault" />
          <option value="02 - Assault - verbal/physical" />
          <option value="03 - Blocked/held open fire route/exit" />
          <option value="04 - Contractor / visitor non-compliance or poor/unsafe practice" />
        </datalist>
      </div>
      <div class="inline form-group">
        <label form="details">Brief Details</label>
        <input type="text" name="details" id="details" />
      </div>
      <div class="inline form-group">
        <label form="description">Full Description</label>
        <input type="text" name="description" id="description" />
      </div>
      <div class="inline form-group">
        <label form="priority">Priority Code</label>
        <input list="priorities" name="priority" id="priority">
        <datalist id="priorities">
          <option value="02 - WITHIN 24-48 HOURS" />
          <option value="03 - WITHIN 1 WEEK" />
          <option value="04 - WITHIN 1 MONTH" />
          <option value="05 - WITHIN 3 MONTHS" />
          <option value="06 - FOR MANAGEMENT DISCUSSION" />
        </datalist>
      </div>
    </div>

    <div class="block">
      <input type="submit" value="SUBMIT" />
    </div>
  </form>
</body>

</html>

Addendum - examining add-ons.css

You can see what the styling for Google's recommended classes are by visiting the css file. The css defines the spatial relationships between labels & input elements via form-group.

.inline {
  display: inline-block;
}

.inline + .inline {
  margin-left: 12px;
}

...

.form-group label + input,
.form-group label + select,
.form-group label + textarea {
  display: block;
}

Solution 2:

Part 2 answered:

I had missed the line:

<?!=HtmlService.createHtmlOutputFromFile('Stylesheet').getContent();?>

at the start of my code and this now works! Any answers to part 1 massively appreciated!


Post a Comment for "How To Style HtmlService Form Elements With Labels Above Input?"