Contextual parts of a form, where fields should be displayed/hidden depending other field values can be placed in dropdown.
To collapse or expand content the Bootstrap Collapse is used.
Inside the the element .collapse, the form elements are advised to be placed inside
an element with class .vi-form__inset. It provides a visual queue (the border) to the
optional form elements.
As per Bootstrap documentation, the trigger can be a button, or can be made dependent on a value of a field as displayed in following examples.
Note: The examples show possible technical implementations, since actual combinations of fields / triggers and validations are infinite.
Example shows a Button used to expand / collapse the extra field.
<!-- Form -->
<form action="#form-cc973c" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
<div class="form-group">
<label for="control-e55288">Field 1
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-e55288" name="name-6bb3ab" placeholder="Field 1" required type="text">
</div>
<div class="form-group">
<label for="control-69e28b">Field 2
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-69e28b" name="name-edb32a" placeholder="Field 2" required type="text">
</div>
<div class="mb-20">
<!-- Button type: outline -->
<button data-toggle="collapse" aria-expanded="false" data-target="#sg-43ab98" type="button" class="vi-btn-outline vi-btn-outline--no-pointer vi-btn">More Fields</button>
</div>
<div class="collapse" id="sg-43ab98">
<div class="pb-20">
<div class="vi-form__inset">
<div class="form-group">
<label for="control-10c293">Field 3
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-10c293" name="name-a280d4" placeholder="Field 3" required type="text">
</div>
</div>
</div>
</div>
<div>
<!-- Button type: solid -->
<button type="submit" class="vi-btn-solid vi-btn">Submit</button>
</div>
<script>
// see Bootstrap Documentation
$(function() {
var $collapsible = $('#sg-43ab98');
$collapsible.find(':input').prop('disabled', true);
$collapsible
.on('shown.bs.collapse', function() {
$collapsible.find(':input').prop('disabled', false);
})
.on('hidden.bs.collapse', function() {
$collapsible.find(':input').prop('disabled', true);
});
});
</script>
</form>
Expanded startingpoint example.
<!-- Form -->
<form action="#form-bdd11b" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
<div class="form-group">
<label for="control-709d0c">Field 1
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-709d0c" name="name-765287" placeholder="Field 1" required type="text">
</div>
<div class="form-group">
<label for="control-89767d">Field 2
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-89767d" name="name-6e05e4" placeholder="Field 2" required type="text">
</div>
<div class="mb-20">
<!-- Button type: outline -->
<button data-toggle="collapse" aria-expanded="false" data-target="#sg-e422b1" type="button" class="vi-btn-outline vi-btn-outline--no-pointer vi-btn">Less Fields</button>
</div>
<div class="collapse show" id="sg-e422b1">
<div class="pb-20">
<div class="vi-form__inset">
<div class="form-group">
<label for="control-71d83d">Field 3
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-71d83d" name="name-65c9ed" placeholder="Field 3" required type="text">
</div>
</div>
</div>
</div>
<div>
<!-- Button type: solid -->
<button type="submit" class="vi-btn-solid vi-btn">Submit</button>
</div>
<script>
// see Bootstrap Documentation
$(function() {
var $collapsible = $('#sg-e422b1');
$collapsible.find(':input').prop('disabled', false);
$collapsible
.on('shown.bs.collapse', function() {
$collapsible.find(':input').prop('disabled', false);
})
.on('hidden.bs.collapse', function() {
$collapsible.find(':input').prop('disabled', true);
});
});
</script>
</form>
Example shows a Button to add an array of extra fields
<!-- Form -->
<form action="#form-00413b" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
<div class="form-group">
<label for="control-37da1a">Field 1
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-37da1a" name="name-c22d22" placeholder="Field 1" required type="text">
</div>
<div class="form-group">
<label for="control-e7b55d">Field 2
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-e7b55d" name="name-754901" placeholder="Field 2" required type="text">
</div>
<p class="mb-20">Do you want to add an extra item?</p>
<div id="dynamic-fields-container"></div>
<div class="mb-20">
<!-- Button type: outline -->
<button id="add-item" type="button" class="vi-btn-outline vi-btn-outline--no-pointer vi-btn"><!-- Icon plus-sign (mods: --button-start) -->
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" sg-icons-dir="sg/components/icon/icons" role="img" class="vi-icon vi-icon--button-start" aria-label="plus-sign"><polygon points="10 6 6 6 6 2 5 2 5 6 1 6 1 7 5 7 5 11 6 11 6 7 10 7"></polygon></svg>
Add Item</button>
</div>
<div>
<!-- Button type: solid -->
<button type="submit" class="vi-btn-solid vi-btn">Submit</button>
</div>
<script id="form-template" type="text/template">
<div class="collapse" id="item-{{id0}}">
<div class="pb-20">
<div class="vi-form__inset">
<div class="vi-flexbox flex-row-reverse justify-content-between">
<!-- Button type: outline -->
<button id="button-{{id0}}" type="button" class="align-self-start vi-btn-outline vi-btn-outline--no-pointer vi-btn"><!-- Icon cross-sign (mods: --button-start) -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" sg-icons-dir="sg/components/icon/icons" role="img" class="vi-icon vi-icon--button-start" aria-label="cross-sign" width="12" height="12"><path d="M10.5 2.5l-.7-.7-4.2 4.1-4.1-4.1-.7.7 4.1 4.1-4.1 4.2.7.7 4.1-4.2 4.2 4.2.7-.7-4.2-4.2z"></path></svg>
Remove</button>
<p class="text-dominant vi-type vi-type--header-regular">Add item</p>
</div>
<div class="form-group"><label for="sg-452a85-{{id0}}">Name
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="sg-452a85-{{id0}}" name="sg-452a85-{{id0}}" placeholder="Name" required type="text">
</div><div class="form-group"><label for="sg-2ddeae-{{id0}}">Description
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="sg-2ddeae-{{id0}}" name="sg-2ddeae-{{id0}}" placeholder="Description" required type="text">
</div><div class="form-group"><label for="sg-a1321a-{{id0}}">Document
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<div class="custom-file">
<input aria-required="true" class="custom-file-input" id="sg-a1321a-{{id0}}" name="sg-a1321a-{{id0}}" required type="file">
<label class="custom-file-label" for="sg-a1321a-{{id0}}">
Please select a file
</label>
</div>
</div><div class="form-group"><label for="sg-42ed0c-{{id0}}">Item
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<select aria-required="true" class="custom-select" id="sg-42ed0c-{{id0}}" name="sg-42ed0c-{{id0}}" required>
<option disabled="disabled" hidden="hidden" selected value="">Pick one
</option>
<option value="item-1">Item 1</option>
<option value="item-2">Item 2</option>
</select>
</div><div class="form-group" id="group_id"><div class="custom-checkbox custom-control custom-control--top">
<input aria-required="true" class="custom-control-input" id="sg-73a4be-{{id0}}" name="sg-73a4be-{{id0}}" required type="checkbox">
<label class="custom-control-label" for="sg-73a4be-{{id0}}">
Don't you agree?
</label>
</div>
</div><div class="form-group"><div class="custom-checkbox custom-control">
<input aria-required="true" class="custom-control-input" id="sg-1d034c-{{id0}}" name="sg-1d034c-{{id0}}" required type="checkbox">
<label class="custom-control-label" for="sg-1d034c-{{id0}}">
Pug yr pop-up.
</label>
</div>
<div class="custom-checkbox custom-control">
<input aria-required="true" class="custom-control-input" id="sg-1d034c-{{id0}}" name="sg-1d034c-{{id0}}" required type="checkbox">
<label class="custom-control-label" for="sg-1d034c-{{id0}}">
Seitan meditation iphone.
</label>
</div>
<div class="custom-checkbox custom-control">
<input aria-required="true" class="custom-control-input" id="sg-1d034c-{{id0}}" name="sg-1d034c-{{id0}}" required type="checkbox">
<label class="custom-control-label" for="sg-1d034c-{{id0}}">
Vinyl master aesthetic.
</label>
</div>
<div class="custom-checkbox custom-control">
<input aria-required="true" class="custom-control-input" id="sg-1d034c-{{id0}}" name="sg-1d034c-{{id0}}" required type="checkbox">
<label class="custom-control-label" for="sg-1d034c-{{id0}}">
Phlogiston freegan skateboard.
</label>
</div>
</div><div class="form-group"><div class="custom-switch custom-control">
<input aria-required="true" class="custom-control-input" id="sg-74340a-{{id0}}" name="sg-74340a-{{id0}}" required type="checkbox">
<label class="custom-control-label" for="sg-74340a-{{id0}}">
Vhs helvetica phlogiston.
</label>
</div>
</div><div class="form-group"><div class="custom-radio custom-control">
<input aria-required="true" class="custom-control-input" id="sg-23a97d-{{id0}}" name="sg-23a97d-{{id0}}" required type="radio">
<label class="custom-control-label" for="sg-23a97d-{{id0}}">
Pinterest helvetica cliche.
</label>
</div>
<div class="custom-radio custom-control">
<input aria-required="true" class="custom-control-input" id="sg-23a97d-{{id0}}" name="sg-23a97d-{{id0}}" required type="radio">
<label class="custom-control-label" for="sg-23a97d-{{id0}}">
Irony vegan fingerstache.
</label>
</div>
<div class="custom-radio custom-control">
<input aria-required="true" class="custom-control-input" id="sg-23a97d-{{id0}}" name="sg-23a97d-{{id0}}" required type="radio">
<label class="custom-control-label" for="sg-23a97d-{{id0}}">
Tumblr pop-up swag.
</label>
</div>
</div><div class="vi-date-select" data-date-format="dd/mm/yy">
<label class="mb-0 vi-date-select__label" for="sg-348243-{{id0}}">
Set a date
</label>
<div class="vi-date-select__trigger-container">
<input autocomplete="off" class="datepicker-trigger custom-select form-control" id="sg-348243-{{id0}}" name="sg-348243-{{id0}}" placeholder="Choose date" required>
<div class="vi-date-select__clear-container">
<!-- Icon cross-sign -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" sg-icons-dir="sg/components/icon/icons" role="img" class="vi-icon" aria-label="cross-sign" width="16" height="16"><path d="M14 3l-.8-.8-5.6 5.7L2 2.2l-.8.8 5.7 5.6-5.7 5.7.8.7 5.6-5.7 5.6 5.7.8-.7-5.7-5.7z"></path></svg>
</div>
</div>
</div>
<p class="mt-10 mb-0 text-muted small">The date-select component must be initialized after it's added to the DOM.</p>
</div>
</div>
</div>
</script>
<script>
$(function() {
let formCounter = 0;
$('#add-item').click(function() {
formCounter++;
// Create unique IDs using the counter
const id0 = Math.random().toString(36).substr(2, 9);
// Get the template and replace placeholders with the actual values
let template = $('#form-template').html();
template = template.replace(/{{id0}}/g, id0);
// Append the filled template to the dynamic fields container
$('#dynamic-fields-container').viFormDynamicFieldsContainer().append(template);
// Line to initialize date select (only new ones will be initialized)
$('#dynamic-fields-container').find('.vi-date-select').viDateSelect()
$(`#item-${id0}`).collapse('show')
// Add close behavour
$(`#button-${id0}`).on('click', function() {
// see Bootstrap Documentation
$(`#item-${id0}`).collapse('hide').on('hidden.bs.collapse', function() {
$(this).collapse('dispose').remove();
});
})
});
});
</script>
</form>
Example shows a checkbox used to expand / collapse the extra field.
Please see source code for the javascript to create the behaviour.
<!-- Form -->
<form action="#form-acd870" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
<div class="form-group">
<label for="control-ea809d">Field 1
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-ea809d" name="name-491761" placeholder="Field 1" required type="text">
</div>
<div class="form-group" id="sg-6c1c49">
<div class="custom-checkbox custom-control custom-control--top">
<input class="custom-control-input" id="control-6186e6" name="name-7ad425" type="checkbox">
<label class="custom-control-label" for="control-6186e6">
More options
</label>
</div>
</div>
<div class="collapse" id="sg-62d495">
<div class="pb-20">
<div class="vi-form__inset">
<div class="form-group">
<label for="control-3904bb">Field 2
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-3904bb" name="name-b4596a" placeholder="Field 2" required type="text">
</div>
</div>
</div>
</div>
<div>
<!-- Button type: solid -->
<button type="submit" class="vi-btn-solid vi-btn">Submit</button>
</div>
<script>
// see Bootstrap Documentation
$(function() {
var $collapsible = $('#sg-62d495');
$collapsible.find(':input').prop('disabled', true);
$('#sg-6c1c49 input').on('change', function() {
if ( $(this).is(':checked') ) {
$collapsible.collapse('show').find(':input').prop('disabled', false);
} else {
$collapsible.collapse('hide').find(':input').prop('disabled', true);
}
});
});
</script>
</form>
Expanded startingpoint example.
<!-- Form -->
<form action="#form-45c01b" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
<div class="form-group">
<label for="control-b510b9">Field 1
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-b510b9" name="name-a7e371" placeholder="Field 1" required type="text">
</div>
<div class="form-group" id="sg-41672e">
<div class="custom-checkbox custom-control custom-control--top">
<input checked class="custom-control-input" id="control-24441b" name="name-8195a5" type="checkbox">
<label class="custom-control-label" for="control-24441b">
Less options
</label>
</div>
</div>
<div class="collapse show" id="sg-ab049b">
<div class="pb-20">
<div class="vi-form__inset">
<div class="form-group">
<label for="control-6a5a35">Field 2
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-6a5a35" name="name-32b582" placeholder="Field 2" required type="text">
</div>
</div>
</div>
</div>
<div>
<!-- Button type: solid -->
<button type="submit" class="vi-btn-solid vi-btn">Submit</button>
</div>
<script>
// see Bootstrap Documentation
$(function() {
var $collapsible = $('#sg-ab049b');
$collapsible.find(':input').prop('disabled', false);
$('#sg-41672e input').on('change', function() {
if ( $(this).is(':checked') ) {
$collapsible.collapse('show').find(':input').prop('disabled', false);
} else {
$collapsible.collapse('hide').find(':input').prop('disabled', true);
}
});
});
</script>
</form>
Example shows radio buttons used to expand / collapse the extra fields.
Please see source code for the javascript to create the behaviour.
<!-- Form -->
<form action="#form-a84c0a" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
<div class="form-group">
<label for="control-25e5c8">Field 1
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-25e5c8" name="name-e3bedc" placeholder="Field 1" required type="text">
</div>
<div class="form-group" id="sg-8dd86b">
<div class="custom-radio custom-control">
<input aria-required="true" class="custom-control-input" id="control-511295" name="name-e57ab6" required type="radio" value="sg-36d417">
<label class="custom-control-label" for="control-511295">
Show Field 2
</label>
</div>
<div class="collapse" id="sg-36d417">
<div class="py-10">
<div class="vi-form__inset">
<div class="form-group">
<label for="control-7da15c">Field 2
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-7da15c" name="name-4a65d0" placeholder="Field 2" required type="text">
</div>
</div>
</div>
</div>
<div class="custom-radio custom-control">
<input aria-required="true" class="custom-control-input" id="control-754335" name="name-e57ab6" required type="radio" value="sg-375db7">
<label class="custom-control-label" for="control-754335">
Show Field 3
</label>
</div>
<div class="collapse" id="sg-375db7">
<div class="py-10">
<div class="vi-form__inset">
<div class="form-group">
<label for="control-5e813e">Field 3
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-5e813e" name="name-2a1e88" placeholder="Field 3" required type="text">
</div>
</div>
</div>
</div>
</div>
<div>
<!-- Button type: solid -->
<button type="submit" class="vi-btn-solid vi-btn">Submit</button>
</div>
<script>
// see Bootstrap Documentation
$(function() {
$('#sg-8dd86b input').on('change', function() {
var $input = $(this);
var $visibleCollapable = $input.parents('.vi-form').find('.collapse.show');
var $hiddenCollapse = $('#' + $input.val());
if ($visibleCollapable.length) {
// wait until the visible collapse is hidden.
$visibleCollapable.one('hidden.bs.collapse', function() {
$hiddenCollapse.collapse('show').find(':input').prop('disabled', false);
}).collapse('hide').find(':input').prop('disabled', true);
} else {
$hiddenCollapse.collapse('show').find(':input').prop('disabled', false);
}
}).parents('.vi-form').find('.collapse').find(':input').prop('disabled', true);
});
</script>
</form>
Expanded startingpoint example.
<!-- Form -->
<form action="#form-b92c20" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
<div class="form-group">
<label for="control-b0c164">Field 1
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-b0c164" name="name-dca171" placeholder="Field 1" required type="text">
</div>
<div class="form-group" id="sg-903a66">
<div class="custom-radio custom-control">
<input aria-required="true" checked class="custom-control-input" id="control-135b01" name="name-e57ab6" required type="radio" value="sg-09943c">
<label class="custom-control-label" for="control-135b01">
Show Field 2
</label>
</div>
<div class="collapse show" id="sg-09943c">
<div class="py-10">
<div class="vi-form__inset">
<div class="form-group">
<label for="control-c91b53">Field 2
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-c91b53" name="name-c53abd" placeholder="Field 2" required type="text">
</div>
</div>
</div>
</div>
<div class="custom-radio custom-control">
<input aria-required="true" class="custom-control-input" id="control-913d4b" name="name-e57ab6" required type="radio" value="sg-00e93e">
<label class="custom-control-label" for="control-913d4b">
Show Field 3
</label>
</div>
<div class="collapse" id="sg-00e93e">
<div class="py-10">
<div class="vi-form__inset">
<div class="form-group">
<label for="control-96005c">Field 3
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-96005c" name="name-1982eb" placeholder="Field 3" required type="text">
</div>
</div>
</div>
</div>
</div>
<div>
<!-- Button type: solid -->
<button type="submit" class="vi-btn-solid vi-btn">Submit</button>
</div>
<script>
// see Bootstrap Documentation
$(function() {
$('#sg-903a66 input').on('change', function() {
var $input = $(this);
var $visibleCollapable = $input.parents('.vi-form').find('.collapse.show');
var $hiddenCollapse = $('#' + $input.val());
if ($visibleCollapable.length) {
// wait until the visible collapse is hidden.
$visibleCollapable.one('hidden.bs.collapse', function() {
$hiddenCollapse.collapse('show').find(':input').prop('disabled', false);
}).collapse('hide').find(':input').prop('disabled', true);
} else {
$hiddenCollapse.collapse('show').find(':input').prop('disabled', false);
}
}).parents('.vi-form').find('.collapse:not(.show)').find(':input').prop('disabled', true);
});
</script>
</form>
Example shows select fiels used to expand / collapse the extra fields.
Please see source code for the javascript to create the behaviour.
<!-- Form -->
<form action="#form-220b7c" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
<div class="form-group">
<label for="control-334625">Field 1
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-334625" name="name-035a72" placeholder="Field 1" required type="text">
</div>
<div class="form-group" id="sg-771a6a">
<label for="control-b9ceaa">Choose option.
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<select aria-required="true" class="custom-select" id="control-b9ceaa" name="name-b3c53a" required>
<option disabled hidden="hidden" selected value="">Choose
</option>
<option value="other-option-x">Other option x</option>
<option value="show-field-2">Show Field 2</option>
<option value="other-option-y">Other option y</option>
<option value="other-option-z">Other option z</option>
</select>
</div>
<div class="collapse" id="sg-713a2a">
<div class="pb-20">
<div class="vi-form__inset">
<div class="form-group">
<label for="control-b02272">Field 2
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-b02272" name="name-07b705" placeholder="Field 2" required type="text">
</div>
</div>
</div>
</div>
<div>
<!-- Button type: solid -->
<button type="submit" class="vi-btn-solid vi-btn">Submit</button>
</div>
<script>
// see Bootstrap Documentation
$(function() {
var $collapsible = $('#sg-713a2a');
$collapsible.find(':input').prop('disabled', true);
$('#sg-771a6a select').on('change', function() {
var $input = $(this);
if ($input.val() == 'show-field-2') {
$collapsible.collapse('show').find(':input').prop('disabled', false);
} else {
$collapsible.collapse('hide').find(':input').prop('disabled', true);
}
});
});
</script>
</form>
Expanded startingpoint example.
<!-- Form -->
<form action="#form-38d5ea" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
<div class="form-group">
<label for="control-9cb6e8">Field 1
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-9cb6e8" name="name-573388" placeholder="Field 1" required type="text">
</div>
<div class="form-group" id="sg-8ae0da">
<label for="control-600d30">Choose option.
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<select aria-required="true" class="custom-select" id="control-600d30" name="name-308ce3" required>
<option disabled hidden="hidden" selected value="">Choose
</option>
<option value="other-option-x">Other option x</option>
<option selected value="show-field-2">Show Field 2</option>
<option value="other-option-y">Other option y</option>
<option value="other-option-z">Other option z</option>
</select>
</div>
<div class="collapse show" id="sg-317892">
<div class="pb-20">
<div class="vi-form__inset">
<div class="form-group">
<label for="control-69e148">Field 2
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-69e148" name="name-644eca" placeholder="Field 2" required type="text">
</div>
</div>
</div>
</div>
<div>
<!-- Button type: solid -->
<button type="submit" class="vi-btn-solid vi-btn">Submit</button>
</div>
<script>
// see Bootstrap Documentation
$(function() {
var $collapsible = $('#sg-317892');
$collapsible.find(':input').prop('disabled', false);
$('#sg-8ae0da select').on('change', function() {
var $input = $(this);
if ($input.val() == 'show-field-2') {
$collapsible.collapse('show').find(':input').prop('disabled', false);
} else {
$collapsible.collapse('hide').find(':input').prop('disabled', true);
}
});
});
</script>
</form>
Example shows a form with two kinds of checkbox fields.
Normal checkboxes and checkboxes that control contextual fields.
<!-- Form -->
<form action="#form-b9e9e6" autocomplete="off" class="vi-form vi-typesystem" data-validate="true" novalidate>
<div class="form-group" id="context-080d81">
<div class="custom-checkbox custom-control">
<input class="custom-control-input" id="control-c89400" name="name-6463d9" type="checkbox">
<label class="custom-control-label" for="control-c89400">
Normal checkbox
</label>
</div>
<div class="custom-checkbox custom-control">
<input class="custom-control-input" data-collapse-id="context-2dd595" id="control-eebc26" name="name-8757a6" type="checkbox">
<label class="custom-control-label" for="control-eebc26">
More options
</label>
</div>
<div class="collapse" id="context-2dd595">
<div class="py-10">
<div class="vi-form__inset">
<div class="form-group">
<label for="control-355237">Extra Field 1
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-355237" name="name-43494d" placeholder="Extra Field 1" required type="text">
</div>
</div>
</div>
</div>
<div class="custom-checkbox custom-control">
<input class="custom-control-input" id="control-e1a16b" name="name-044570" type="checkbox">
<label class="custom-control-label" for="control-e1a16b">
Normal checkbox
</label>
</div>
<div class="custom-checkbox custom-control" id="context-3b3618">
<input class="custom-control-input" data-collapse-id="context-381b0a" id="control-e05b93" name="name-944bb7" type="checkbox">
<label class="custom-control-label" for="control-e05b93">
More options
</label>
</div>
<div class="collapse" id="context-381b0a">
<div class="py-10">
<div class="vi-form__inset">
<div class="form-group">
<label for="control-00039b">Extra Field 2
<span aria-hidden="true" class="vi-form__required">(required)</span></label>
<input aria-required="true" class="form-control" id="control-00039b" name="name-670c84" placeholder="Extra Field 2" required type="text">
</div>
</div>
</div>
</div>
</div>
<div>
<!-- Button type: solid -->
<button type="submit" class="vi-btn-solid vi-btn">Submit</button>
</div>
<script>
// see Bootstrap Documentation on collapse
// The contextual part.
$(function() {
$('#context-080d81 input[data-collapse-id]').on('change', function() {
var $input = $(this);
var checked = $input.is(':checked')
var $content = $('#' + $input.data('collapse-id'));
if (!$content.length) return;
if (checked) {
$content.collapse('show').find(':input').prop('disabled', false);
} else {
$content.collapse('hide').find(':input').prop('disabled', true);
}
})
$('#context-080d81').find('.collapse:not(.show)').find(':input').prop('disabled', true);
});
// The validation part.
$('#context-3b3618').on('validate', function(e, field, isValid, eventType) {
if (eventType != 'submit') return;
// if all checkboxed in group checked.
if ($('#context-080d81 :checkbox:checked').length) {
isValid(true)
} else {
isValid(false, 'Please select at least one box');
}
});
</script>
</form>
The following stylesheets are required to display this component.
The following additional stylesheet is used to display the example(s).
The following javascripts are required to display this component.
Usage documentation can be found here.
Changelog
Fix
- 19 Feb 2025 - fix(form): resolve mutation observer recursion issue in Safari
- 13 Feb 2025 - feat(form): fix form reset validation messages
- 11 Sep 2024 - Fix broken label issue (webkit only!)
- 01 Jun 2023 - Fix read-only styling to input, select and textarea. Fixes placeholder combobox.
- 23 May 2023 - Removed a11y default success message; Business requirement.
- 28 Apr 2023 - Fix safaris hard disable color override.
- 15 Feb 2023 - Combobox validation
- 18 Jan 2023 - Fix background-clip setting.
- 28 June 2022 - Fix scrollparent detector
- Make Safari (the new IE6) understand how parenthesis work when direction is rtl.
- Remove previous work around.
- Try to work around chrome mobile bug (1197882) where long datalists overlap keyboard.
- Fix chrome bug (674447, 849616) where datalist gets detached by scrolling.
- Wrapping of lang filenames in file field.
- PBS support: fix box-shadow on custom-control
- Regression: accent colors not picked up by sass.
- Allow re-enabled fields to validate.
- Remove file field blur validation.
- A11y: …show hidden span tag with this value”name of the file + “selected” add role=”alert”
- A11y: Redundantly add attribute
aria-required=true to elements with attribute required
- A11y: …add a hidden span tag with this value”name of the file + “uploaded” add role=”alert”
- Form Validation message not showing, when element hidden.
- IE11 premature error throwing.
- Better align custom indicators regardless font / line-height used.
- Remove background color IE11 from focused select.
Changed
- 09 Jan 2025 - feat(multiple-select): Show options with empty value.
- 30 Jun 2023 - Disabled state of checkbox/radio and switch.
Added
- 28 Aug 2024 - Add dynamic form fields example + added $.fn.viFormDynamicFieldsContainer() to assign to a dynamic fields container and keep validation in sync.
- 17 May 2023 - Form reset removes validation messages.
- 15 Mar 2023 - Allow browse button text to be changed.
- 15 Feb 2023 - Combobox reset
- 2 Dec 2022 - Add size sm size to text-fields.
- 14 Nov 2022 - Add data attribute
data-keyup to allow for keyup validation on a field. (required by wizard#contextual-fields)
- Add an example of a paragraph
- An example of labels on select fields.
- PBS support
- Examples of contextual form fields.
- Add
--top modifier to .custom-control for long labels.
- A11y: File field focus outline same as links.
- On submit focus on first invalid element
- Missing File Browser field
- RTL support
- Documentation
- Changed checkbox outline according new design input.
- Initial draft