Clean up form hiding/showing logic
This commit is contained in:
parent
d6bae3b941
commit
d914ffab49
@ -40,6 +40,12 @@
|
||||
|
||||
<!-- Conditional logic for hiding and un-hiding fields. -->
|
||||
<script>
|
||||
|
||||
//
|
||||
// Helper functions for conditional field show/hide
|
||||
//
|
||||
|
||||
// Show or hide an element, or selection of elements, depending shouldShow
|
||||
function showIf(thingToShow, shouldShow) {
|
||||
if (shouldShow) {
|
||||
$(thingToShow).show()
|
||||
@ -47,126 +53,142 @@
|
||||
$(thingToShow).hide()
|
||||
}
|
||||
}
|
||||
// Returns true if checkbox is checked
|
||||
function isChecked(elem) {
|
||||
return elem.checked
|
||||
}
|
||||
|
||||
// Here we define the fields we need to conditionally toggle.
|
||||
// Returns a function that returns true if its parameter matches `condition`
|
||||
function isJust(condition) {
|
||||
return elem => elem.value === condition
|
||||
}
|
||||
|
||||
// Returns a function that returns true if its parameter is in `conditions`
|
||||
function isOneOf(conditions) {
|
||||
return elem => conditions.includes(elem.value)
|
||||
}
|
||||
|
||||
//
|
||||
// The big ol' list of controls and what sections they toggle the display of
|
||||
// TODO: Move this knowledge out of the template
|
||||
var conditionalFields = [
|
||||
{
|
||||
"field": "#id_location_context",
|
||||
"showHide": ["#div_id_type_of_ecosystem"],
|
||||
"condition": ["RUR"]
|
||||
},
|
||||
{ // 2.1 - Power Generation
|
||||
"field": "#id_sector_of_economy",
|
||||
"showHide": ["#power_generation_questions"],
|
||||
"condition": ["RN"]
|
||||
},
|
||||
{
|
||||
"field": "#id_generation_technology",
|
||||
"showHide": ["#div_id_biomass_detail"],
|
||||
"condition": ["BIO"]
|
||||
},
|
||||
{ // 2.2 - Power Grids
|
||||
"field": "#id_sector_of_economy",
|
||||
"showHide": ["#power_grids_energy_storage_questions"],
|
||||
"condition": ["PG"]
|
||||
},
|
||||
{ // 2.3 - Supply of minerals
|
||||
"field": "#id_sector_of_economy",
|
||||
"showHide": ["#mineral_commodity_questions"],
|
||||
"condition": ["SM"]
|
||||
},
|
||||
{ // 3.2
|
||||
"field": "#id_positive_or_negative",
|
||||
"showHide": ["#div_id_obstacles_and_hindrances"],
|
||||
"condition": ["P", "N"]
|
||||
}];
|
||||
//
|
||||
|
||||
// Here we define the checkboxes that we need to use to
|
||||
// conditionally toggle fields - they use slightly different
|
||||
// logic as they rely on the 'checked' attribute rather than value.
|
||||
var conditionalCheckboxes = [
|
||||
var showHideFields = [
|
||||
// 'Basic information' tab
|
||||
{
|
||||
checkbox: "#id_affects_indigenous",
|
||||
showHide: "#div_id_affects_indigenous_detail",
|
||||
control: 'location_context',
|
||||
showHide: '#div_id_type_of_ecosystem',
|
||||
visible: isJust('RUR') // Rural
|
||||
},
|
||||
|
||||
// Technical/economic tab
|
||||
{
|
||||
control: 'sector_of_economy',
|
||||
showHide: '#power_generation_questions',
|
||||
visible: isJust('RN') // Energy generation project
|
||||
},
|
||||
{
|
||||
control: 'generation_technology',
|
||||
showHide: '#div_id_biomass_detail',
|
||||
visible: isJust('BIO') // Bio-energy
|
||||
},
|
||||
|
||||
{
|
||||
control: 'sector_of_economy',
|
||||
showHide: '#power_grids_energy_storage_questions',
|
||||
visible: isJust('PG') // Energy networks or storage (stands for 'power grid')
|
||||
},
|
||||
|
||||
{
|
||||
control: 'power_technology',
|
||||
showHide: '#div_id_power_technology_other',
|
||||
visible: isJust('OT')
|
||||
},
|
||||
{
|
||||
control: 'power_technology',
|
||||
showHide: '#div_id_energy_storage_capacity',
|
||||
visible: isOneOf(['ES', 'OT']) // Storage / other
|
||||
},
|
||||
{
|
||||
control: 'power_technology',
|
||||
showHide: '#div_id_energy_transmission_capacity',
|
||||
visible: isOneOf(['PT', 'HN', 'OT']) // Transmission / heat / other
|
||||
},
|
||||
|
||||
{
|
||||
control: 'sector_of_economy',
|
||||
showHide: '#mineral_commodity_questions',
|
||||
visible: isJust('SM') // mining
|
||||
},
|
||||
{
|
||||
control: 'use_in_energy_economy',
|
||||
showHide: '#div_id_use_in_energy_economy_other',
|
||||
visible: isJust('OTR')
|
||||
},
|
||||
|
||||
{
|
||||
control: 'sector_of_economy',
|
||||
showHide: '#manufacturing_questions',
|
||||
visible: isJust('MA') // manufacturing
|
||||
},
|
||||
|
||||
|
||||
// Socio-environmental tab
|
||||
{
|
||||
control: 'positive_or_negative',
|
||||
showHide: '#div_id_obstacles_and_hindrances',
|
||||
visible: isOneOf(['P', 'N']) // positive/negative (process pro / vs)
|
||||
},
|
||||
{
|
||||
checkbox: "#id_shown_on_other_platforms",
|
||||
showHide: "#div_id_shown_on_other_platforms_detail"
|
||||
control: 'negative_case_reasons',
|
||||
showHide: '#div_id_negative_case_reasons_other',
|
||||
visible: isJust('OTHR')
|
||||
},
|
||||
|
||||
// Contact tab
|
||||
{
|
||||
checkbox: "#id_negative_case_reasons_8",
|
||||
showHide: "#div_id_negative_case_reasons_other"
|
||||
control: 'shown_on_other_platforms',
|
||||
showHide: '#div_id_shown_on_other_platforms_detail',
|
||||
visible: isChecked
|
||||
},
|
||||
{
|
||||
checkbox: "[name=use_in_energy_economy][value=OTR]",
|
||||
showHide: "#div_id_use_in_energy_economy_other"
|
||||
}
|
||||
];
|
||||
|
||||
//
|
||||
// Fields that require their own more advanced logic
|
||||
//
|
||||
|
||||
var conditionalControls = [
|
||||
{
|
||||
name: "power_technology",
|
||||
redraw: function() {
|
||||
const other = document.getElementById('id_id_power_technology_0_4')
|
||||
const panel = document.getElementById('div_id_power_technology_other')
|
||||
|
||||
showIf(panel, other.checked)
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
name: "power_technology",
|
||||
redraw: function() {
|
||||
const group = document.forms['case-study-form'].power_technology
|
||||
|
||||
// Storage / other
|
||||
let showStorage = ['ES', 'OT'].includes(group.value)
|
||||
|
||||
// Transmission / heat / other
|
||||
let showTransmission = ['PT', 'HN', 'OT'].includes(group.value)
|
||||
|
||||
showIf('#div_id_energy_storage_capacity', showStorage)
|
||||
showIf('#div_id_energy_transmission_capacity', showTransmission)
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
name: "sector_of_economy",
|
||||
redraw: function() {
|
||||
const sections = {
|
||||
RN: "power_generation_questions",
|
||||
PG: "power_grids_energy_storage_questions",
|
||||
SM: "mineral_commodity_questions",
|
||||
MA: "manufacturing_questions",
|
||||
}
|
||||
|
||||
for (const option of Object.keys(sections)) {
|
||||
const input = document.querySelector(`[name=sector_of_economy][value=${option}]`)
|
||||
const section = document.getElementById(sections[option])
|
||||
|
||||
showIf(section, input.checked)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
name: "sector_of_economy",
|
||||
name: 'sector_of_economy',
|
||||
redraw: function() {
|
||||
const sector = document.forms['case-study-form'].sector_of_economy
|
||||
const input = document.querySelector(`[name=positive_case_type][value=CORS]`)
|
||||
|
||||
// If sector of economy is transmission, mining, or processing
|
||||
// Then enable this input. Otherwise, disable.
|
||||
// TODO: Could make the row invisible
|
||||
input.disabled = ['PG', 'SM', 'MA'].includes(sector.value) ? false : true
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
name: "positive_or_negative",
|
||||
name: 'positive_or_negative',
|
||||
redraw: function() {
|
||||
const setting = document.forms['case-study-form'].positive_or_negative
|
||||
|
||||
//
|
||||
// This is some nasty hacking around wanting different field labels/
|
||||
// help texts depending on the positive_or_negative option.
|
||||
//
|
||||
// Each piece of text whose display is dependent on what option is selected
|
||||
// has the class 'organising', plus at least one of 'organising-vs/pro/none/idk'.
|
||||
//
|
||||
// The base `organising` class sets display: none. Then, we go through
|
||||
// all the elements tagged with the current choice, reset element-specific
|
||||
// display styling, and then apply `display: inline` just to the desired
|
||||
// elements.
|
||||
//
|
||||
|
||||
const relatedElements = [
|
||||
{ value: 'P', elements: '.organising-pro' },
|
||||
{ value: 'N', elements: '.organising-vs' },
|
||||
@ -190,96 +212,43 @@
|
||||
},
|
||||
]
|
||||
|
||||
// Define a function that hides the field and then creates a listener to toggle the field.
|
||||
// Takes a single conditionalField dictionary with (field, showHide and condition).
|
||||
function addConditionalField(item) {
|
||||
hideAll(item.showHide);
|
||||
$(item.field).change(function(){
|
||||
// Get the value of the option
|
||||
var value = $(this).val();
|
||||
|
||||
// Check the value matches any of the conditions.
|
||||
if (isInArray(value, item.condition)){
|
||||
showAll(item.showHide);
|
||||
} else {
|
||||
hideAll(item.showHide);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// This function does the same as addConditionalField except it checks the status of
|
||||
// checkboxes instead of fields.
|
||||
function addConditionalCheckbox(item) {
|
||||
$(item.showHide).hide();
|
||||
$(item.checkbox).change(function(){
|
||||
if ($(this).is(":checked")) {
|
||||
$(item.showHide).show();
|
||||
} else {
|
||||
$(item.showHide).hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
function show(tag) {
|
||||
$(tag).show();
|
||||
}
|
||||
|
||||
function hide(tag) {
|
||||
$(tag).hide();
|
||||
}
|
||||
|
||||
function showAll(tags) {
|
||||
tags.forEach(show);
|
||||
}
|
||||
|
||||
function hideAll(tags) {
|
||||
tags.forEach(hide);
|
||||
}
|
||||
|
||||
function isInArray(value, array) {
|
||||
return array.indexOf(value) > -1;
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$(function() {
|
||||
// Button classes for tab navigation
|
||||
$('.btnNext').click(function(){
|
||||
$('.btnNext').click(function() {
|
||||
$('.nav-tabs > .active').next('li').find('a').trigger('click');
|
||||
});
|
||||
|
||||
$('.btnPrevious').click(function(){
|
||||
$('.btnPrevious').click(function() {
|
||||
$('.nav-tabs > .active').prev('li').find('a').trigger('click');
|
||||
});
|
||||
|
||||
$('form').attr('novalidate', 'novalidate');
|
||||
|
||||
conditionalFields.forEach(addConditionalField);
|
||||
conditionalCheckboxes.forEach(addConditionalCheckbox);
|
||||
// Add conditional form show/hide logic
|
||||
for (const item of showHideFields) {
|
||||
const control = document.forms['case-study-form'][item.control]
|
||||
|
||||
conditionalFields.forEach(function(item){
|
||||
$(item.field).change();
|
||||
});
|
||||
$(control).change(() => {
|
||||
// Check the value matches any of the conditions.
|
||||
showIf(item.showHide, item.visible(control))
|
||||
});
|
||||
|
||||
conditionalCheckboxes.forEach(function(item){
|
||||
$(item.checkbox).change();
|
||||
});
|
||||
$(control).change();
|
||||
}
|
||||
|
||||
conditionalControls.forEach(function (group) {
|
||||
// Add handlers for more advanced form logic
|
||||
for (const group of conditionalControls) {
|
||||
$(`[name=${group.name}]`).on('change', group.redraw)
|
||||
group.redraw();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
<script>
|
||||
$(function() {
|
||||
initDrafts()
|
||||
initDrafts()
|
||||
|
||||
// Jump to error
|
||||
if ($('.has-error').length) {
|
||||
location.href = '#' + $('.has-error:first').attr('id');
|
||||
}
|
||||
})
|
||||
// Jump to error
|
||||
if ($('.has-error').length) {
|
||||
location.href = '#' + $('.has-error:first').attr('id');
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
Loading…
Reference in New Issue
Block a user