Global Elements
2
Footer Header Services Strip Services Tabs
Components
36
Card Carousel Cards Grid Content Overlap Content Strip Cta Bar Featured Article Featured Blocks Featured Expert Featured Pods Featured Tabs Form Block Full Screen Carousel Full Width Content Heading Strip Hero Hero Featured Links List Location Tabs Logo Carousel Map Block People Grid Quote Block Reviews Carousel Reviews Tabs Service Tiles Services Strip Services Tabs Staggered Content Sticky Accordion Sticky List Sub Navigation Team Carousel Team Filters Team Strip Tile Carousel Tile Grid

Form Block

Subscribe to our newsletter










    Field
    Field Type
    Field Name
    Instructions
    Block Data
    tab
    Heading Type
    select
    heading_type
    Heading Text
    text
    heading_text
    Copy
    wysiwyg
    copy
    Form
    post_object
    form
    Block Meta
    tab
    ID
    text
    block_id
    Block Classes
    text
    block_classes
    Block Theme
    select
    block_theme
    Background Colors
    select
    background_colors
    Padding Top
    select
    padding_top
    Padding Bottom
    select
    padding_bottom
    Margin Top
    select
    margin_top
    Margin Bottom
    select
    margin_bottom
    
    				
    @import "../../resources/scss/util/colours";
    @import "../../resources/scss/util/variables";
    @import "../../resources/scss/util/mixins";
    
    .block-form-block {
    	padding: rem-calc(48 0);
    	background-color: $veryLightBlue;
    
    	.heading {
    		@include fluid-type(28, 34);
    	}
    
    	&__heading {
    		margin-bottom: rem-calc(40);
    	}
    
    	&__copy {
    		margin-bottom: rem-calc(60);
    	}
    }
    
    class FormBlock {
    	/**
    	 * Create and initialise objects of this class
    	 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor
    	 * @param {object} block
    	 */
    	constructor() {
    		this.blocks = document.querySelectorAll('.block-form-block');
    		this.init();
    	}
    
    	/**
    	 * Example function to run class logic
    	 * Can access `this.block`
    	 */
    	init() {
    		this.blocks.forEach((block) => {
    
    			// Pre-select Vacancy
    			const vacanciesField = block.querySelector("#careers-select");
    			if (vacanciesField) {
    				const heroTitle = document.querySelector(".block-hero__heading");
    				if (heroTitle) {
    					let getTitle = heroTitle.querySelector(".heading");
    					if (getTitle) {
    						getTitle = getTitle.textContent.trim();
    						let getOption = document.querySelector(`option[value="${getTitle}"]`);
    						if (getOption) {
    							getOption.setAttribute('selected', 'selected');
    						}
    					}
    				}
    			}
    
    			// Pre-select Service
    			const servicesField = block.querySelector("#service-select");
    			if (servicesField) {
    
    				if (document.body.classList.contains("single-post")) {
    					const relatedServices = document.querySelector(".single-post__related-links-container");
    
    					if (relatedServices) {
    						let firstService = relatedServices.querySelector("a");
    
    						if (firstService) {
    							firstService = firstService.textContent.trim();
    							let getOption = document.querySelector(`option[value="${firstService}"]`);
    							if (getOption) {
    								getOption.setAttribute('selected', 'selected');
    							}
    						}
    					}
    
    				} else {
    					const heroTitle = document.querySelector(".block-hero__heading");
    					if (heroTitle) {
    						let getTitle = heroTitle.querySelector(".heading");
    						if (getTitle) {
    							getTitle = getTitle.textContent.trim();
    							let getOption = document.querySelector(`option[value="${getTitle}"]`);
    							if (getOption) {
    								getOption.setAttribute('selected', 'selected');
    							}
    						}
    					}
    				}
    			}
    
    			// Pre-select Event
    			const eventsField = block.querySelector("#events-select");
    			if (eventsField) {
    				const heroTitle = document.querySelector(".block-hero__heading");
    				if (heroTitle) {
    					let getTitle = heroTitle.querySelector(".heading");
    					if (getTitle) {
    						getTitle = getTitle.textContent.trim();
    						let getOption = document.querySelector(`option[value="${getTitle}"]`);
    						if (getOption) {
    							getOption.setAttribute('selected', 'selected');
    						}
    					}
    				}
    			}
    
    
    			// Services Select Field
    			var options = {
    				searchable: true,
    				placeholder: 'Choose a Service',
    				selectedOptions: [
    					'Family'
    				]
    			};
    			const serviceSelect = document.getElementById("service-select");
    
    			if (serviceSelect) {
    				NiceSelect.bind(serviceSelect, options);
    				const serviceOptions = serviceSelect.querySelectorAll(".list li");
    
    				if (document.body.classList.contains('single-service')) {
    					const hero = document.querySelector(".block-hero");
    					if (hero) {
    						const heroTitle = hero.querySelector(".heading");
    						if (heroTitle) {
    							const serviceText = heroTitle.textContent.trim();
    						}
    					}
    				}
    			}
    
    
    			// Careers Select Field
    			var careersOptions = {
    				searchable: true,
    				placeholder: 'Choose a Vacancy',
    			};
    
    			const careersSelect = document.getElementById("careers-select");
    
    
    			if (careersSelect) {
    				NiceSelect.bind(careersSelect, careersOptions);
    			}
    
    
    			// Events Select Field
    			var eventsOptions = {
    				searchable: true,
    				placeholder: 'Choose Event(s)',
    			};
    
    			const eventsSelect = document.getElementById("events-select");
    
    			if (eventsSelect) {
    				NiceSelect.bind(eventsSelect, eventsOptions);
    			}
    
    
    			// Custom Input Fields
    			const fileInputs = block.querySelectorAll(".file-input");
    
    			fileInputs.forEach((inputFile) => {
    				// Wrap the "Choose file" text so it can get replaced with the file name (used below)
    				inputFile.innerHTML = inputFile.innerHTML.replace('Choose file', 'Choose file');
    				
    				inputFile.addEventListener('change', (e) => {
    					// Get the selected file
    					const [file] = e.target.files;
    					// Get the file name and size
    					const { name: fileName, size } = file;
    					// Convert size in bytes to kilo bytes
    					const fileSize = (size / 1000).toFixed(2);
    					// Set the text content
    					const fileNameAndSize = `${fileName} - ${fileSize}KB`;
    					// Replace wrapped text and not the entire element (which previously eliminated the file input)
    					inputFile.querySelector('.choose-label').textContent = fileNameAndSize;
    				});
    			});
    
    		});
    	}
    }
    
    new FormBlock();
    

    Animation / States

    • As the user scrolls to this component the items will be lazyloaded and fade in one by one
    • Validation message will appear under each field, with the main form validation appearing under the submit button
    • The user will be required to accept the terms & conditions before submitting a form

    External Libraries

    • ScrollTrigger (GSAP)

    Notes (Design / Dev / SEO)

    • Within the CMS the user will be able to select which form to include in the component from forms created in Contact Form 7
    • The URL the form is submitted on will be stored against the form
    • If the form is submitted on a service or sector page this information will be stored against the form
    • NEED CONFIRMATION: Form data will be passed on to CRM