Bootstrap5 implementation

This page demonstrates the features of this plugin, tested with Bootstrap 5.3.8 and jQuery 3.7.1. Very probably, this implementation will also work with older or newer releases of Bootstrap and jQuery: please report your successes.

Future developments:

Starting the "form-changes" plugin

Besides the two extra hidden fields in your form to handle versions (learn about form versions), you also need to start the jQuery plugin.

First, download the JavaScript and CSS components, and copy them to a location in your own website (for instance into the /assets/ directory). We have not yet set-up CDN or a npm package.

Add this to your HTML:

<head>
  <!-- load Bootstrap5 and jQuery libraries yourself-->

  <!-- load the form-changes plugin -->
  <script src="/assets/js/form-changes.js"></script>
  <link href="/assets/css/form-changes.css" rel="stylesheet" />

  <script>
    $(document).ready(function() {
      $("FORM#my_form").changes({style: 'pill'});
    });
  </script>
</head>

When you attach the changes plugin to your form, you can pass a configuration. You may use different configurations for different forms on your page. Currently, the only support option is style.

Display styles

Based on the same basic change specification, you can select different visualization styles. Specify the style at configuration, which overrules the data-change-style attribute on the form.

Style pill (the default) is a pretty heavy display of the change information. The only other option (at the moment) is style dot, which attempts to be helpful with less visual and logical load. The examples below demonstrate the differences.

Change history template

Form change information can be added to every kind of form field, and as special change notes. First a generic example:

<div>
  <label for="address" class="form-label">Home address</label>
  <input type="text" class="form-control" id="address"
      aria-describedby="address-descr" />
  <div id="address-descr" class="form-text">
    The address where your are personally registered to live.
  </div>
  <div class="change change-req" for="address"
      data-changed-in="20251010" data-summary="became required">
    New law requires that we know your residential address.
  </div>
</div>

Above HTML example shows a typical Bootstrap text input field. The <div> blocks tagged 'change' and 'change-note' are the additions handled by this plugin.

When the user's data is older than 'changed-in' (here version 20251010), then the change will be made visual to the user of the form. Not shown here is the 'change-hide' attribute, which is used when a new change block eclipses an older version. Some styles may use the 'summary' for immediate display. The content of the DIV.change may be displayed on demand.

As you could have guessed from the 'for' attribute: you may put the change describing block somewhere else in the HTML file: as long as it is part of the same form structure.

Pick values

How do you fill in the previously submitter data into your form. It is straight forward for most input fields, like text input and textarea. But is pretty tricky for checkboxes, radio buttons, and selects. The plugin helps:

<select class="form-control" data-pick="three">
<div data-checkbox="cb" data-pick="one,two">
<div data-radio="rb" data-pick="four">

When the form is loaded, the user's "picks" of the previous submissions are processed into checked and selected attributes. Convenient. Using 'data-pick', the plugin can give the revisiting user a bit more help as well.

Visualizations

Based on the applicable change blocks, visualizations are produced. The block either describes a mark, a note, or a form field.

Change notes

HTML blocks (usually fieldset blocks) which are marked with class 'change-note' are shown when the user's data version is older than 'data-changed-in' and not older than 'data-change-hide'.

When you use a fieldset block, then the additional class 'framed' can be used for a nice decoration. In that case, class 'dismissable' can be added to get a close symbol to click away the note.

<fieldset data-changed-in="20251010"
  class="change-note change-info framed dismissable">
  <legend>Info block</legend>
  This text provides some information about changes.
</fieldset>
Info block This text provides some information about changes.
Info block This text provides some information about changes, this without 'framed' and 'dismissable'.

Besides 'change-info' (blue), you can also use 'change-success' (green), 'change-danger' (read), and 'change-warning' (yellow).

Field got added, 'change-new'

Mainly used on INPUT and TEXTAREA element, but may appear with other elements as well. The visualization depends a bit on whether the element is required at the moment.

<div>
  <label for="animal" class="form-label">favorit animal</label>
  <input type="text" class="form-control"
     id="animal" required
     aria-describedby="animal-descr" />
  <div id="animal-descr" class="form-text">
    Specify the endangered spieces you want to support.
  </div>
  <div class="change change-new" for="animal"
      data-changed-in="20251010"
      data-summary="add pet">
    Your favorit animal will get an extra meal.
  </div>
</div>

When a summary is given. Red when required, green when optional. Hint: move over input.

Specify the endangered spieces you want to support.
Your favorit animal will get an extra meal.

Specify the endangered spieces you want to support.
Your favorit animal will get an extra meal.

When no summary is given. Red when required, green when optional. Hint: move over input.

Specify the endangered spieces you want to support.
Your favorit animal will get an extra meal.

Specify the endangered spieces you want to support.
Your favorit animal will get an extra meal.

The summary is ignored. Red when required, green when optional. Hint: move over input.

Specify the endangered spieces you want to support.
Your favorit animal will get an extra meal.

Specify the endangered spieces you want to support.
Your favorit animal will get an extra meal.

When you change the content of a field, the mark will be removed.

Field became required, 'change-req'

This change explains that an optional input field became required. When the field already has a value, you'll see no special marking.

<div>
  <label for="email" class="form-label">Email address</label>
  <input type="email" class="form-control" required
      id="email" aria-describedby="email-descr" />
  <div id="email-descr" class="form-text">
    Provide your email address.
  </div>
  <div class="change change-req" for="email"
      data-changed-in="20251010"
      data-summary="marketing">
    The marketing department will contact you.
  </div>
</div>

When the field has no value yet, then a red pill is shown. Examples with and without summary.

Provide your email address.
The marketing department will contact you.

Provide your email address.
The marketing department will contact you.

When the field has no value yet, then a red dot is shown. The summary is never shown.

Provide your email address.
The marketing department will contact you.

Provide your email address.
The marketing department will contact you.

When you change the content of a field, the mark will be removed.

Field is required, but no change description

When the "change-req" information is missing, or when the form is empty (fresh), then empty required fields will get marked anyway.

<div>
  <label for="nickname" class="form-label">Nickname</label>
  <input type="text" class="form-control"
      id="nickname" required
      aria-describedby="nickname-descr" />
  <div id="nickname-descr" class="form-text">
    The name other people see.
  </div>
</div>
The name other people see.

The name other people see.
The name other people see.

The name other people see.

When you add content to the field, the mark will be removed.

Options changed for select, 'change-sel'

When a SELECT relates to a block with change-set, then that's used as additional information about the changed options. However, it is already useful to have 'data-removed-in' and 'data-added-in' attributes top options.

See "pick". When the option is flagged as removed and not picked, then the SELECT will not show it. However, when it was previous chosen option, then it is kept and disabled. A new option is chosen and the select is marked with a "?".

When you do not use "pick", then your HTML template probably found another way to add selected to one OPTION. In that case, this plugin cannot warn the user about the changed value.

HTML and CSS offer very little styling and decoration for the OPTIONS, so little smart visualization is possible.

<div>
  <label for="bedrooms" class="form-label">Desired bedrooms</label>
  <select class="form-control"
      id="bedrooms" data-pick="three"
      aria-describedby="bedrooms-descr">
  <option disabled>one
  <option>two
  <option data-removed-in="20251010">three
  <option data-added-in="20251010">four
  <option data-removed-in="20240101">five
  <option>six
  </select>
  <div id="bedrooms-descr" class="form-text">
    How many bedrooms do you need in your new house?
  </div>
  <div class="change change-sel" for="bedrooms"
      data-changed-in="20251010">
    All three and five bedroom apartments have been converted into four bedrooms dwellings.
  </div>
</div>

When the old choice is not available anymore, then a red "?" is shown. New options lead to a green "+".

How many bedrooms do you need in your new house?
All three and five bedroom apartments have been converted into four bedrooms dwellings.

How many bedrooms do you need in your new house?
All three and five bedroom apartments have been converted into four bedrooms dwellings.

When the old choice is not available anymore, then a red dot is shown. New options lead to a green dot.

How many bedrooms do you need in your new house?
All three and five bedroom apartments have been converted into four bedrooms dwellings.

How many bedrooms do you need in your new house?
All three and five bedroom apartments have been converted into four bedrooms dwellings.

The markings disappear when you move away from the select box, to indicate that you have noticed the change.

Checkboxes

Checkbox lists are pretty verbose in Bootstrap's HTML. They are losely connected by their name. This plugin requires a wrapping container when you like to use 'data-pick' or a change description. The wrapper looks like this:

<div id="$id" data-checkbox="$name" data-pick="one,two">
  <label for="$id" class="form-label">Pick some numbers</label>
  <!-- checkbox list -->
  <div class="change change-cb" for="$id" data-changed-in="20251010">
    Describes the changes in the checkbox list.
  </div>
</div>

To make the HTML example below easier to read, we have removed 'class="form-check-input" type="checkbox"' from the '<input>' and 'class="form-check-label"' from each checkbox '<label>' in the example below.

<div id="cb_block" data-checkbox="cb" data-pick="one,two,four,five">
  <label for="cb_block" class="form-label">Pick some numbers</label>
  <div class="form-check">
    <input name="cb" value="one" id="cb_one">
    <label for="cb_one">One (picked)</label>
  </div>
  <div class="form-check">
    <input name="cb" value="two" id="cb_two">
    <label for="cb_two">Two (picked)</label>
  </div>
  <div class="form-check">
    <input name="cb" value="three" id="cb_three">
    <label for="cb_three">Three (not picked)</label>
  </div>
  <div class="form-check">
    <input name="cb" value="four" id="cb_four" disabled>
    <label for="cb_four">Four (picked, disabled)</label>
  </div>
  <div class="form-check" data-removed-in="20240101">
    <input name="cb" value="five" id="cb_five">
    <label for="cb_five">Five (removed, picked)</label>
  </div>
  <div class="form-check" data-removed-in="20240101">
    <input name="cb" value="six" id="cb_six">
    <label for="cb_six">Six (removed, not picked)</label>
  </div>
  <div class="form-check" data-added-in="20251010">
    <input name="cb" value="seven" id="cb_seven">
    <label for="cb_seven">Seven (added)</label>
  </div>
  <div class="form-check" data-added-in="20251010">
    <input name="cb" value="eight" id="cb_eight" required>
    <label for="cb_eight">Eight (added, required)</label>
  </div>
  <div class="change change-cb" for="cb_block"
      data-changed-in="20251010">
    Some numbers, and some were removed.
  </div>
</div>

The pill style tries to be as informative as possible, so it will show when picked fields were removed and when which were newly added. Checkbox Six has been removed, but was not selected anyway, so silently ignored.

Some numbers, and some were removed.

Where the "dot" style tries to be minimalistic, it silently removes pick Five. It also does not mark the new alternative Seven. It will only mark required checks when they are not set.

Some numbers, and some were removed.

Besides explicit removal as alternative, with possible explanation to the user, you can (of course) also remove the checkbox row from the form. This "changes" plugin cannot inform the user about removed picks. It depends on the importants if the option which alternative is better.

Required checkboxes without wrapper do work, but will not be able to provide additional information to the user, as the following example shows:

<label for="cb_read" class="form-label">Licenses:</label>
<div class="form-check" data-added-in="20251010">
  <input class="form-check-input" type="checkbox" name="read"
      value="read" id="cb_read" required>
  <label class="form-check-label" for="rb_read">
    Please confirm you read the conditions.
  </label>
</div>

The mark disappears when the checkbox is clicked. The mark will be green when the checkbox is already set.


The mark disappears when the checkbox is clicked. No mark will not appear when the checkbox is already set.


Radio buttons

Radio button lists are pretty verbose in Bootstrap's HTML. They are strongly connected by their name. This plugin requires a wrapping container when you like to use 'data-pick' or a change description. The wrapper looks like this:

<div id="$id" data-radio="$name" data-pick="two">
  <label for="$id" class="form-label">Prefered start position:</label>
  <!-- radio options list -->
  <div class="change change-rb" for="$id" data-changed-in="20251010">
    Picked option "Two" has been removed.
  </div>
</div>

To make the HTML example below easier to read, we have removed 'class="form-check-input" type="radio"' from the '<input>' and 'class="form-check-label"' from each checkbox '<label>' in the example below.

<div id="rb_block" data-radio="rb" data-pick="two">
  <label for="rb_block" class="form-label">Prefered start position:</label>
  <div class="form-check">
     <input name="rb" value="one" id="rb_one" disabled>
     <label for="rb_one">One (disabled)</label>
  </div>
  <div class="form-check" data-removed-in="20240101">
     <input name="rb" value="two" id="rb_two">
     <label for="rb_two">Two (pick, removed)</label>
  </div>
  <div class="form-check">
     <input name="rb" value="three" id="rb_three">
     <label for="rb_three">Three</label>
  </div>
  <div class="form-check" data-removed-in="20240101">
     <input name="rb" value="four" id="rb_four">
     <label for="rb_four">Four (removed)</label>
  </div>
  <div class="form-check" data-added-in="20251010">
     <input type="radio" name="rb" value="five" id="rb_five">
     <label for="rb_five">Five (added)</label>
  </div>
  <div class="change change-rb" for="rb_block" data-changed-in="20251010">
    Picked option "Two" has been removed.
  </div>
</div>

Pick "Two" has disappeared; the user should pick another option. Option "One" is disabled, so "Three" is suggested. "Four" was removed and not selected, so not shown. Five was added, and clearly flagged as new alternative.

Picked option "Two" has been removed.

The "dot" style uses the same icons as the "pill" style here, because they are very explanatory. In the future, a more lightweight display may be introduced. New options are not marked.

Picked option "Two" has been removed.

Besides explicit removal as alternative, with possible explanation to the user, you can (of course) also remove the radio button the form. This "changes" plugin cannot inform the user about the remove choice, which makes it confusing.