Web Platform HTML

Forms and Widgets Revisited

Clicks

For a button to do anything, you need to wire up a Javascript function to handle when it is clicked. It is possible to use a "inline" event handler such as the the following:

In HTML:

<button onclick='onImportantButtonClick()'>
    Click me
</button>

In Javascript:

function onImportantButtonClick() {
    console.log("Clicked!");
}

There are a number of drawbacks with this approach, and it's recommended to "wire-up" the event in Javascript instead. This means you need some way of referring to or selecting the button, by way of the HTML structure, a class or ID.

HTML:

<button id="importantButton">
    Click me
</button>

Accompanying Javascript:

document.getElementById("importantButton").addEventListener("click", function(e){
    console.log("Clicked!");
});

Value changes

INPUT, SELECT and TEXTAREA elements fire the change event when they have well, changed.

HTML:

<select id="fruit">
  <option value="50">Apple</option>
  <option value="55" selected>Orange</option>
  <option value="60">Peach</option>
</select>

Javascript:

var elems = document.getElementById('fruit').addEventListener('change', function(e) {
  console.log(e.target.value); // Prints 50, 55 or 60 when changed
});

Getting value

General values

For many elements, you check the value property of the form element:

<input type="text" name="nameInput" value="Alice">
var val = document.querySelector('input[name="nameInput"]').value;
console.log(val); // Prints 'blue', 'green' or 'red' depending on selected

Things are trickier for multi-element forms of input such as a collection of radio buttons or checkboxes. Read on...

Radio buttons/checkboxes

<input name="favColour" type="radio" value="blue"> Blue
<input name="favColour" type="radio" value="red"> Red
<input name="favColour" type="radio" value="green"> Green
var val = document.querySelector('input[name="favColour"]:checked').value;
console.log(val); // Prints 'blue', 'green' or 'red' depending on selected option

Reusing event handlers

It can be the case that you have several buttons, but want same bit of Javascript to respond to them. In the Javascript, you need some way of diffentiating which button was pressed in order to react slightly differently. You could use the content of the button, its id or your own custom attribute.

Here's an example using the content of the button:

<button class="colourSwatch">
    Blue
</button>
<button class="colourSwatch">
    Red
</button>
<button class="colourSwatch">
    Green
</button>
<div id="colourResult">Click a colour</div>

Javascript:

function onSwatchClicked(e) {
  var displayEl = document.getElementById('colourResult');
  var buttonClicked = e.target;
  // Set text colour according to the text from the button
  // Tip: to use the id of the clicked element, use buttonClicked.id
  displayEl.style.color = buttonClicked.innerText;
}

var elems = document.getElementsByClassName('colourSwatch');
for (var el of elems) {
    el.addEventListener('click', onSwatchClicked);
}

The downside of using the content of the element is that it is visible - we might rather respond from an internal attribute. Associating our own data in our attributes to elements can be very useful.

Since we want to avoid setting a class for each button, we'll enclose them in a DIV as a way of grouping them and referring to them as a set.

HTML:

<div id="buttonPad">
    <button data-colour="blue">1</button>
    <button data-colour="red">2</button>
    <button data-colour="green">3</button>
</div>
<div id="colourResult">Click a colour</div>

Javascript:

function onSwatchClicked(e) {
  var displayEl = document.getElementById('colourResult');
  var buttonClicked = e.target;
  // Set text colour according to the 'data-colour' attribute from the button
  displayEl.style.color = buttonClicked.getAttribute('data-colour');
}

var elems = document.getElementById('buttonPad').children;
for (var el of elems) {
    el.addEventListener('click', onSwatchClicked);
}

Getting all form data

If you have a FORM element which is appropriately named:

<form name="robot">
    <label>Age <input name="age"></label>
    ...
</form>

You can get all the data with:

var form = new FormData(document.querySelector('form[name="robot"]'));
for (var [key, value] of form.entries()) {
    console.log(key + " = " + value);
};

Or get a specific named value:

console.log(form.get('age'));