CMS Development

unesic
Member

Styling select input dropdown

SOLVE

Hello,

I'm trying to style the select input field's dropdown on a website so it follows the styleguide. I've managed to style the select field itself, but styling the dropdown turned out to be really tricky.

I added custom JavaScript that creates and injects custom HTML element that acts like a dropdown populated with custom elements that are options. It seems like everything works as expected until the form validation kicks in.

I made sure the real option's selected property is set to true, and its parent select field properties value and selectedIndex are also set accordingly. Inspecting the code in the developer console shows that both the value and selectedIndex are set, option's selected property is also set to true, but the form still throws an error.

Am I missing something obvious here?

0 Upvotes
1 Accepted solution
Anton
Solution
Recognized Expert | Diamond Partner
Recognized Expert | Diamond Partner

Styling select input dropdown

SOLVE

Okay.

So you've done it right by setting it up without adding the HubSpot CSS. But still - you can't technicaly modify the <option> dropdown. It's just not possible since - as I've said before - it will be rendered by the browser/os.

 

Here's an article which describes this topic in detail (and might help you)

https://css-tricks.com/dropdown-default-styling/

 

 

best,

Anton

Anton Bujanowski Signature

View solution in original post

0 Upvotes
3 Replies 3
Anton
Recognized Expert | Diamond Partner
Recognized Expert | Diamond Partner

Styling select input dropdown

SOLVE

Hi @unesic

since the regular/default dropdown is always rendered by the browser/os it's quite hard/impossible to style this.

 

But this doesn't mean that it's impossible at all. There are a few options how to generate/style a dropdown without using 

<select>
<option>Lorem ipsum </option>
<option>Ipsum dolor</option>
... </select>

One possible solution might be to create a regular list like

<ul class="dropdown">
<li>Lorem ipsum </li>
<li>Ipsum dolor</li>
...
</ul>

 

If you're using bootstrap 2(HubSpot default) here's a documentation how to do this:

https://getbootstrap.com/2.3.2/components.html#buttonDropdowns 

Documentation for bootstrap 3:

https://getbootstrap.com/docs/3.4/components/#dropdowns 

and for the currently latest bootstrap(4.x):

https://getbootstrap.com/docs/4.5/components/dropdowns/ 

 

here's the idea behind it:
you create a clickable element(<a>/<button> ...) and by clicking on it it will trigger a (css) animation to display the list

 

 

Hope this helps

 

best,

Anton

Anton Bujanowski Signature
unesic
Member

Styling select input dropdown

SOLVE

Hi Anton,

I probably should've specific that I'm using hubspot form with Set as raw HTML form option checked, with shortcode generated by HubSpot plugin for WordPress. I don't need to create a custom dropdown, but rather to modify the one hubspot provides which I managed to do, but the validation doesn't seem to like my solution. Here's the JavaScript code I have written for this problem so you get the idea of what I'm trying to accomplish:

const styleSelectInputs = _ => {
	let openedDropdown;

	const openDropdown = e => {
		const input = e.target;
		const dropdown = input.nextElementSibling;
		dropdown.style.display = 'block';
		openedDropdown = dropdown;
	}

	const closeDropdown = _ => {
		openedDropdown.style.display = 'none';
	}

	const setSelectValue = e => {
		e.stopPropagation();
		const selected = e.target;
		const allOptions = [...selected.parentNode.querySelectorAll('.hs-custom-option')]
		
		selected.classList.add('active');
		allOptions.forEach(option => option !== selected && option.classList.remove('active'));

		const input = selected.parentNode.previousElementSibling;
		const options = [...input.options];
		let selected_opt, selected_idx;
		options.forEach((option, i) => {
			if (option.value === selected.dataset.value) {
				selected_opt = option;
				selected_idx = i;
			}
		});

		selected_opt.selected = true;
		input.value = selected_opt.value;
		input.selectedIndex = selected_idx;
		input.classList.remove('invalid');
		input.classList.remove('error');
		
		closeDropdown();
	}

	const createOption = option => {
		const opt = document.createElement('div');
		opt.setAttribute('class', 'hs-custom-option');
		opt.dataset.value = option.value;
		opt.innerHTML = option.innerHTML;
		opt.addEventListener('click', setSelectValue);

		return opt;
	}

	const stylize = input => {
		const options = [...input.options];
		const newOptions = options.map(option => createOption(option));

		const container = document.createElement('div');
		container.setAttribute('class', 'hs-custom-container');
		container.style.display = 'none';
		newOptions.forEach(option => container.appendChild(option));

		input.insertAdjacentElement('afterend', container);
	}

	const init = _ => {
		const select_inputs = [...document.querySelectorAll('.hs-form fieldset .hs-form-field .input select.hs-input')]
		select_inputs.forEach(input => {
			stylize(input);
			input.addEventListener('click', openDropdown);
		})

		document.addEventListener('click', e => {
			if (e.target.nodeName !== 'SELECT' && !e.target.classList.contains('hs-input')) {
				closeDropdown();
			}
		})
	}

	init();
}

 

 

0 Upvotes
Anton
Solution
Recognized Expert | Diamond Partner
Recognized Expert | Diamond Partner

Styling select input dropdown

SOLVE

Okay.

So you've done it right by setting it up without adding the HubSpot CSS. But still - you can't technicaly modify the <option> dropdown. It's just not possible since - as I've said before - it will be rendered by the browser/os.

 

Here's an article which describes this topic in detail (and might help you)

https://css-tricks.com/dropdown-default-styling/

 

 

best,

Anton

Anton Bujanowski Signature
0 Upvotes