Week04 02 Forms JS - UX-UI-Design-Lab/DH150-UX-WebCoding GitHub Wiki

Agenda:

  1. Review/ Discussion: Lighthouse accessibility score
  2. (Input) forms
  3. Javascript html DOM manipulation

Accessibility score

We will start with the Chrome lighthouse accessibility scoring - if we understand how they calculate, it is helpful for us to code properly.

https://web.dev/accessibility-scoring/

Is there anything you found it interesting? solve your curiosity why in certain context your score gets down? Discuss and share your thoughts.


Let's see what kind of audit items are related to buttons, (hyper-)links or interactive elements.

  • buttons do not have an accessible name
  • links doesn't have discernible name

What do you think about these? Why do you think it matters how to name/label the buttons or links? Any specific example in experience? There are more audit items relevant in the below:

  • form fields have multiple labels.
  • frame or iframe elements do not have a title
  • image elements do not have [alt] attribute
  • input type="image" elements do not have [alt] text
  • form elements do not have associated labels
  • object elements do not have [alt] text

Form

<form> is html element that sets up to process the user's inputs. <form> in itself doesn't work or show anything but it serves to deliver the information collected by its children (or the user input elements it contains) to back-end servers. therefore, in <form>, we expect to have "submit", either as a button, to activate the delivery action between front-end (the webpage) to the back-end (network, or more specifically HTTP protocol).

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form

The elements you can include in <form> box are: <button>, <fieldset>, <input>, <object>, <output>, <select>, <textarea>. We will focus on <input> and <button> in this demo.

https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/elements

<input> can cover almost everthing listed above by its attribute type. You can particularly indicate what kind of input you are expecting.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input

https://developer.mozilla.org/en-US/docs/Learn/Forms/HTML5_input_types


Let's try one! The most frequently used case would be search. Maybe we can have fun to make a google like search site (of course it is fake, for markup only). So, I will put the basic layout of the information.

 <html>
 <head> </head>
 <style> </style>
   <body>

     <h1> Goooogle </h1>
     <input> search anything </input>
     <button> submit </button>

   <script> </script>
   </body>
 <html>

You can also use <input type="button" ...> instead of <button>. They are pretty similar but <button> can be easier to change styles.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button


Now It has the brand title Gooooogle, and input box, and a button! But let's make it look better (some css style - will mimic the google site). I will wrap h1, input, and button with div so that they can move them as one box. Then, pull that box down located in the center of the screen. This is a useful css code when you want to place the item centered (horizontal + vertical).

 #searchBox {
   position: absolute;
   top: 50%;
   left: 50%;
   transform: translate(-50%, -50%);
 }

make all center-aligned.

 #searchBox {
   ...
   text-align: center;
 }

Make the logo bigger (and responsive by using viewport unit vw) in a different color. First name it with id:

  <h1 id="logo"> Goooogle </h1>

Then add css codes in style:

 #logo {
   font-size: 10vw;
   color: hsla(220, 50%, 50%, 0.9);
 }

(if you want to make the colorful rainbow logo, try to change each letter's color)

 <h1 id="logo"> <span id="redG">G</span>oooogle </h1>

and style,

 #redG {
   color: red;
 }

Let's work on the input box. First, I will put the "search anything" as a default input of the box (= placeholder) which will be removed when a user starts typing in the input box.

 <input type="search" id="searchInput" placeholder="search anything">  </input>

And setup this for the any text input (by type = "text" or "search", they are pretty same). then, make the input box size properly - by font-size (to make the font responsive, I used vw and em together).

 #searchInput {
   width: 100%;
   font-size: calc(0.5vw + 1em);
   padding-top: 0.5em;
   padding-bottom: 0.5em;
   padding-left: 1em;
   padding-right: 2.5em;
   border-radius: 1.25em;

   border: 1px solid hsla(0, 0%, 70%, 0.5);
 }

And setup the button style (I will share the font-size and padding) and use the logo color as a focus color.

   #searchBTN {
     font-size: calc(0.5vw + 1em);
     padding: 0.5em 1em;
     border-radius: 1.25em;
     margin: 0.5em;
     background-color: hsla(220, 50%, 50%, 0.9);
     color: white;
     border: 1px solid hsla(220, 0%, 70%, 0.5);
   }

Maybe good to add hover effect with a shadow:

 #searchInput:hover {
   filter: drop-shadow(1px 1px 5px hsla(220, 0%, 70%, 0.7))
 }

In addition, for the button, I will add css code to change the cursor to make the cursor shape as pointer:

 #searchBTN:hover {
   filter: drop-shadow(1px 1px 5px hsla(220, 0%, 70%, 0.7));
   cursor: pointer;
 }

Maybe better to have stronger visual focus, since the blue over blue button may not be easy to spot. You can add multiple borders, especially using box-shadow. You can see at least three ways you can add the border lines.

 #searchBTN:focus {
   filter: drop-shadow(1px 1px 5px hsla(220, 0%, 70%, 0.7));
   border: 3px solid hsla(220, 50%, 70%, 0.5);
   box-shadow: 0px 0px 0px 6px hsla(320, 50%, 50%, 0.5);
   outline: 5px solid hsla(320, 50%, 50%, 1);
 }

 #searchInput:focus {
   filter: drop-shadow(1px 1px 5px hsla(220, 0%, 70%, 0.7));
   border: 1px solid hsla(220, 50%, 70%, 0.5);
   box-shadow: 0px 0px 0px px hsla(320, 50%, 50%, 0.5);
   outline: 5px solid hsla(320, 50%, 50%, 1);
 }

It is enough review for styling - so let's make this work. I will set name attribute of input so I can use the entered input value (typing) later. Then, I will wrap the user-input part with <form>

 <div id="searchBOX">
   <h1 id="logo"> Goooogle </h1>
   <form>
     <input type="search" id="searchInput" name="searchQuary" placeholder="search anything">  </input>
     <button id="searchBTN">
       search
     </button>
   </form>
 </div>

What I plan to do is to use the user's input (a word) and replace the Goooogle logo with that word. It is the ultimate goal the activity. But first, we need to understand how javascript works (over html).


Javascript, basics

Javascript is (metaphorically) the group of servants - if you remember Downton Abbey, they are hidden and work silently and follow the directions. But each of them are very much isolated and can see only what they are supposed to know (or be allow to know). Therefore the direction (script) should be written based on their ability.

To start, you can check if you can communicate via javascript. In <script>, try:

  • alert("hi!");
  • console.log("hey~");

Alert message box will be shown with the text "hi!". If you open inspect > console (and check the log), you can see "hey~" there. I prefer using the silent hidden way by console.log - alert is sometimes too bothering and hard to turn off.

These are often used to check what javascript understand by that line of the code. If the message shows something different from what you expect, you need to check the logic or pre-condition you assumed what javascript would know, but actually not.

html DOM

The cool thing javascript can do is to access the every corder of html and do what you commend to do. But, to make it possible, javascript first need to know the structure of the house (html), for example where is the main room, where is master's bed room, where is kitchen, where is library. The structure of html (house) that javascript understand is called "Document-Object-Model" or DOM.

https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction

In javascript, the content and structure of <html> that javascript belongs to is "document". The document has tree structure (but not the tree in the nature but tree in data structure). Each tag (html element) is a node of the tree.

html DOM

from https://www.w3schools.com/whatis/whatis_htmldom.asp


Javascript can access to DOM node only by asking the document (that means the <html> the top of the tree, but people call it as root.

Here is the process how you can let javascript to access the html element

  • ask the document to find the element you want to access, and get the address of it (so javascript can visit)
  • write down the address in the empty notepad (= var, first define a variable and put the address there)
  • visit that address, open and get inside to find the value you want to change

I will repeat this process in javascript way

  • ask document to find the address of the element by css selector, document.querySelector("SOMETHING");
  • define a variable, ex. mySOMETHING, and put the address document found. var mySOMETHING = document.querySelector("SOMETHING");
  • visit the address and open it, and find the attribute you want to change, mySOMETHING.style.color
  • put the new value for that attribute. mySOMETHING.style.color = "darkgreen";

Let's convert it to javascript:

first, I will double-check the element and decide how I would like to call/find it.

  <h1 id="logo"> Goooogle </h1>

I know I can find this element by h1 or #logo for css Selector (the way how css calls it). I will use id, #logo.

In <script>:

 var myLogo = document.querySelector("#logo");

I can check if javascript can find it. Let's see what it has in style, the color.

 console.log(myLogo.style.color);

and what the text inside the html h1 tag is about (= the "Gooogle" text) - it is called "innerHTML". Case sensitive.

 console.log(myLogo.innerHTML);

if I open the developer tool (inspect) > console, I can see two lines about color and the text inside of the tag.

So, if I want to change the value of those attribute,

 myLogo.innerHTML = "Yoooch!";
 myLogo.style.color = "darkgreen";

https://developer.mozilla.org/en-US/docs/Web/API/Document_object_model/Locating_DOM_elements_using_selectors

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var

for your curiosity, there can be other ways to clear the variable in js:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const


basic syntax

The basic rules about how to write javascript codes:

  • each line of comment should end with ; (semicolon)
  • it is case sensitive, be cautious when you use upper cases
  • camel case (ex. oneTwo) : because javascript doesn't like dash/hyphen -, the css properties with - will be understood as camel case. The first letter of the second keyword will turn uppercase. Ex. background-color will be backgroundColor in js
  • normally, . in the method (function) of the js means "open and go inside" (totally my way of understanding!)

setting up // location of script

Where you place the script (instruction), javascript may or may not handle your commend properly.

  • Try to move the whole <script> before <body> -- what happens?
  • Try to move the whole <script> inside html, before #logo -- test it and see what happens.

Because javascript can only know about the html DOM (of the current html) by the line it placed, so if the html you want to know appears after <script>, javascript would show this kind of error:

Uncaught TypeError: Cannot read property 'innerHTML' of null

The best place is, therefore, at the very end of the body, before you place </body> to make sure no more element need to be counted.

what if I have <script> after <body> but before </html> -- actually it will work too but may not work in a certain situation.


Event handling (ex. mouse event)

Let's find the way to get the input text from <input>. We know what we set up the placeholder. In the similar way, the input text is supposed to be saved in value attribute.

 var myInput = document.querySelector("#searchInput");
 console.log(myInput.placeholder);
 console.log(myInput.value);

To see more attribute you can refer to: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input

At the initial state, there is no user input, so myInput.value shows NULL (which means empty or nothing).

What we need to somebody who will watch the input box and get the text. We will use "button" for that purpose. So, the scenario is, when the button clicked, check inputbox and get whatever the user entered. Make sure the button is ready.

 <button type="button" id="searchBTN">

First, I need to find the button.

 var myBTN = document.querySelector("#searchBTN");

and for this button, I need to install a special headset (or a receiver?) to listen. This is what we call "event listener". To use the event listener, you need to specify what kind of event you want the button to watch out (otherwise, there are so many things going on and easily distracted and confused...). I would say, "button, you need to listen only the click event, which means when the mouse clicks on you". then, I will say, when it happens do this (and assign the job to do = function). Let call that job-to-do after click event as "changeLogo".

 myBTN.addEventListener("click", changeLogo);

Now, I need to describe the detail instruction for changeLogo. It is actually a function (= a set of instructions). I will use function() to define the instructions and name it as changeLogo().

 var newLogo = "";

first, be ready with the variable that save the inputed text -- let's call it newLogo. I will put the initial value as NULL string, or "".

and define changeLogo(). It is a function, which means it contains the multiple lines of code in it - so, curly bracket { } is used.

 function changeLogo() {
   newLogo = myInput.value;  /* get the string from input box */
   myInput.value = "";       /* to reset the input */
   console.log(newLogo);     /* check the input text is correctly saved in newLogo */
   myLogo.innerHTML = newLogo;   /* put that user-input in myLogo */
 }

Test and check if your input changes the logo properly.

NOTE: enter doesn't work for changeLogo -- can you guess why? how would you want to try to make enter work in the same way the button click?

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener


activity: JS DOM manipulation

Can you make your own example of this fake search site?

  • place the logo + input box + button (ex. "change") in the center of the screen
  • make a focus visible
  • add javascript to handle logo text
  • add javascript to get the user input from input box
  • add javascript (mouse click event) for the button to replace the logo text with the input text
  • feel free to have fun to change other styles of the logo (background color, color, font size)
  • (extra) can you change the background color of the whole body into black?

Submit the url of the work by Thursday midnight.


⚠️ **GitHub.com Fallback** ⚠️