RMIT Orb, translucent, glowing like a legless jellyfish Web Programming - eOOOOO

Welcome to Web Programming

Instructions

In the Drop Down Navigation, select which lectures you want to read. The navigation buttons are toggle buttons, press once to show the lecture, press again to hide. Your selections will be stored locally and remembered the next time you visit on this machine.

Alternatively, you can Search for a word or a phrase (must be at least two letters). All slides in the course with that word or phrase will appear. eg search for 'color' if you want to see all slides with the word 'color' in it.

If you want to hide/show these instructions, click the Instructions checkbox.

If you see something you like in these slides, right click and select inspect element. More often than not, you will be able to see the code that makes it work or style that makes it pretty.

Finally, if you want to print these slides, they will restyle into a more printer-friendly format. Make sure to elect A4 Portrait mode!

Emergency Procedure Information Student Statement

Before starting our session today, RMIT wishes to make you aware of the Emergency Procedures that are in place for your safety. Please look around and familiarize yourself with the emergency exits in this room and do this for each new venue in which you attend classes. Evacuation plans are located in all corridors.

Alert Tone (Beep Beep)

On hearing the Alert tone, you should:

  • check your area for fire, smoke or other abnormal situations
  • await further instructions relayed over the public address system, or from the floor warden or wardens (members of the emergency control organisation)
  • prepare yourself to evacuate the building e.g. commence shutdown of work by saving any computer files you are working on, switch off electrical appliances, close gas valves and make the area safe to leave (if safe to do so)
  • commence evacuation if there is immediate danger.

You are not required to evacuate unless instructed to do so by an announcement made over the public address system, a direction from the floor warden or wardens (members of the Emergency Control Organisation), a direction from RMIT Security, or a direction from the attending Emergency Service.

Evacuate Tone (Whoop Whoop)

On hearing the Evacuate tone or if directed to evacuate by the floor warden or wardens (members of the Emergency Control Organisation) you should:

  • proceed to evacuate the building via the marked exits and stairs
  • proceed to evacuate in an orderly fashion to the Assembly Area indicated on the evacuation diagrams
  • follow the directions from announcements made over the public address system, the directions from the floor warden or wardens (members of the Emergency Control Organisation), the directions from RMIT Security, or the direction from the attending Emergency Service.
  • commence evacuation if there is immediate danger.

Do Not:

  • carry occupant(s) with disabilities down stairs or escalators
  • use lifts or escalators to evacuate the building except when instructed to do so by the attending Emergency Service, RMIT Security or by a member of the Emergency Control Organisation
  • congregate outside the building entrances unless instructed to do so by an announcement made over the public address system, a direction from the Floor Warden or Wardens (members of the Emergency Control Organisation), a direction from RMIT Security, or a direction from the attending Emergency Service
  • re-enter the building until advised that it is safe to return to the building by the attending Emergency Service, RMIT Security or by a member of the Emergency Control Organisation
  • carry on with business - this causes delays, which may put your life and those of others in danger if the emergency is not controlled
  • try to contact anyone to find out what is going on - this congests the telephone system and hampers control of the emergency.

RMIT thanks you for your cooperation.

Welcome!Lect 0, P 1

Web Programming
COSC2453 / COSC2690

Lecture 0 - Administrivia

AdministriviaLect 0, P 2
  1. Important Dates
  2. Consultation and Support
  3. Course Overview
  4. Course Timeline
  5. Textbooks
  6. Plagiarism
Important DatesLect 0, P 3

Bookmark this url ...

https://www.rmit.edu.au/students/my-course/important-dates/2023/oua

Dates you need to be concerned about (in order):

  • Last day to add a course.
  • Last day to withdraw without paying or failing.
  • Last day to withdraw without failing.
  • Exam timetable release date – exams currently suspended due to Covid 19!
Consultation and SupportLect 0, P 4

Questions and Queries

Don't be shy!

Maybe the student sitting next to you has a better idea of what's going on. If they have no clue either, maybe your question is a good one worth asking.

Any general questions regarding course material, timeline and assignment tasks will most likely be of value to other students. As far as possible, post your questions on the Canvas discussion boards so that all students will have a chance to benefit.

Your question may start a discussion thread that is far richer than a short "rushed" answer given by a single staff member!

Consultation and SupportLect 0, P 5

Staff Communications

However, not all questions and queries are appropriate for public viewing, for example anything of a personal nature should not be posted to Canvas. In these instances, please talk to staff directly:

Tutor or Marker
Workshop related questions, general assignment-related questions, minor issues when working within a group, initial assignment mark & feedback queries
Instructor
Webinar related issues, course content, follow-up assignment mark & feedback queries, staff behaviour etc.

There are more levels of management above the teaching staff, if your matter is not resolved it will be escalated to the course coordinator, to the program manager, to the deans, to the courts etc.

Consultation and SupportLect 0, P 6

University Resources

Two useful pages explaining student support services can be found here:
https://www.rmit.edu.au/students/my-course
https://www.rmit.edu.au/students/support-services

RMIT Special Consideration
For exam deferral, extensions of longer than 7 days, or when the reason for your request is of a highly personal nature (for example serious health issues, domestic violence issues, etc.), you should apply directly to Special Consideration. The reasons for your extension will be kept confidential and not shared with teaching staff.
https://www.rmit.edu.au/students/my-course/assessment-results/special-consideration-extensions/special-consideration
RMIT Equitable Learning Services
The Equitable Learning Services unit assists students living with a disability, long term illness and/or mental health condition. Teaching staff are advised of your condition and are given advice on how to cater to your specific needs. Often you get a chance to sit exams with more favourable conditions (smaller room, rest breaks, scribe to write out your answers etc.)
https://www.rmit.edu.au/students/support-services/equitable-learning
RMIT Counselling Service
The RMIT Counselling Service provides a high quality professional psychological service in a safe, friendly and confidential environment for you to talk and deal with personal issues and mental health.
https://www.rmit.edu.au/students/support-services/health-safety-wellbeing/mental-health-counselling/counselling
RMIT University Student Union (RUSU)
The RMIT University Student Union will give you independent advice and can offer advice on a range of issues. Their services are free, confidential and available to ALL RMIT students.
https://www.rusu.rmit.edu.au/studentrights

A lot of help is available. Do not leave things until the last minute. It is far easier to resolve problems when there is sufficient time!

Any IT issues, contact the RMIT helpdesk
https://www.rmit.edu.au/students/support-services/it-support-systems/it-connect
Course OverviewLect 0, P 7

Why HTML, CSS, Javascript and PHP?

Very roughly speaking:

  • HTML allows for the creation of static web page content.
  • CSS adds style: sizing, color, layout, etc.
  • JavaScript adds client-side scripting: real-time user interaction.
  • PHP adds server-side scripting: dynamic web page content, secure data processing.

We will cover all of these ideas in detail in this course. The important point for now is that these four technologies work together to enable you implement extremely flexible web-based pages, sites, and applications.

Course OverviewLect 0, P 8

Course Completion

On completion of this course you should be able to:

  • Explain the functions of clients and servers on the Web
  • Build web pages using HTML, and style them using CSS
  • Implement client-side scripts using JavaScript
  • Implement server-side scripts using PHP
  • Design and implement an interactive web site with consideration of issues relating to usability, accessibility and internationalisation
Course OverviewLect 0, P 9

Who Uses This Stuff?

People who want to build their own websites with personalized features such as:

  • Personalized layouts
  • Online forms
  • User and document management systems
  • Payment systems
  • Specialized search functions
  • A lot of advanced functions

People who want to become a web developer:

Course OverviewLect 0, P 10

Are These Technologies Used Commercially?

Some popular sites that use (or used) PHP:

  • Wikipedia
  • Facebook
  • Yahoo!
  • Wordpress
  • Tumblr
  • Baidu

View W3Techs estimates of the percentage of websites using various client-side and server-side programming languages:

Course TimelineLect 0, P 11

Course Topics and Timeline

WeekWeekly Focus
0Administrivia
1HTML [1], and webservice setup [1]
2HTML [2], and webservice setup [2]
3HCI & CSS [1]
4CSS [2]
5CSS [3]
6Javascript [1]
7Javascript [2]
8PHP [1]
9PHP [2]
10PHP [3]
11PHP [4]
12PHP [5] & Course revision
13Revision and Review
Course TimelineLect 0, P 12

Course Assessment

Final Grade Calculator


0%

There will be four assignments made up of one or two components:

  • Project Component (worth 95%): Constitutes a phased website development and build.
  • Test Component (worth 5%): Discussion topics will be released periodically to test your comprehension of teaching materials and skills, in addition to completion of webinar and workshop (ie "lab") exercises each week.

Assessment Summary

Assignment 1 - due at the end of week 4 (10%)
Git & Coreteaching setup / HTML & Wireframe focus and debugging / code upgrade exercise (9%)
Earliest best discussion response (1%)
Assignment 2 - due at the end of week 8 (30%)
HTML, CSS & Javascript-like focus (28%)
Next earliest best 2 discussion responses (2%)
Assignment 3 - due at the end of week 12 (40%)
Javascript & basic PHP focus (38%)
Next earliest best 2 discussion responses (2%)
Assignment 4 - due at the end of week 14 (20%)
All materials & advanced PHP focus (20%)

There are no hurdles, just add the assignment scores together to get your final grade. In fact, why not use our handy calculator on the right!

TextbooksLect 0, P 13

Textbooks

Whilst textbooks are not 100% essential to pass this course, some students do find them helpful and/or reassuring. Here are a selection of recommended textbooks for this course.

Learning PHP, MySQL, JavaScript, CSS & HTML5
by Robin Nixon
HTML & CSS AND Javascript & jQuery AND PHP & MySQL
by Jon Duckett
Learning PHP, MySQL & JavaScript: With jQuery, CSS & HTML5 HTML & CSS AND Javascript & jQuery AND PHP & MYSQL<br>by Jon Duckett
This book can be bought from:
O’Reilly Publishing, Book Depository or Amazon
These 3 books are available individually or as a package set:
Wiley Publishing, Booktopia or Amazon
Free associated web resources can be found here:
https://htmlandcssbook.com, https://javascriptbook.com, https://phpandmysql.com.

Disclaimer: Trevor Reynolds is listed as part of the "review team" in Jon Duckett's latest book, but receives no royalties or other monetary rewards.

Don't forget to check Booko, an australian bookshop comparison website.

PlagiarismLect 0, P 14

Plagiarism is an offence

To avoid plagiarism, you must give credit whenever you use:

  • Another person’s idea, opinion, or theory
  • Any facts, statistics, graphs, drawings, or any other pieces of information that are not common knowledge
  • Quotations of another person’s actual spoken or written words
  • Paraphrasing of another person’s spoken or written words

All submitted work without citation must be your own

Let's be honest, if you ignore free media resources, tutorials and all the "how to"s on the internet your progress in this course will be very slow. To cite the work and ownership of others, place something simple inside comments near the included work.

...
<!-- Original image below sourced for educational purposes: www.coke.com/coke-can.jpg -->
<img src='coke-can.jpg' alt='inviting cold coke can, dripping with condensation'/>
...
<!-- Original CSS code sourced and adapted for educational purposes:
     http://www.lynda.com/CSS-tutorials/Creating-Responsive-Web-Design/110716-2.html -->
...

A marker must be able to identify:

  • what is your work, and what is not your work;
  • what you have researched, and from where it came from;
  • what code you have used as a starting point and what are your adaptions.

One suggestion is to keep your code and any library or API code in separate files, and always be clear in comments throughout your code.

As a guide, if you are mindlessly copying and pasting code that you do not understand, STOP!

If your citations are not clear, a marker will presume that all of your code has been externally sourced and mark accordingly.
Lecture 1

Web Programming
COSC2413 / 2426 / 2453

Lecture 1 - HTML 1

HTML IL1, S1
  1. The World Wide Web
  2. HTML Version 1
  3. HTML Versions 2 & 3
  4. HTML Version 4
  5. XHTML
  6. HTML5
  7. Webpage Example
The World Wide WebL1, S2

The Internet

  • The Internet is a system of millions of networks, including private, public, government, business and academic, are linked by various networking technologies, including electronic, wireless and optical
  • The networks use particular protocols to communicate, such as the Internet protocol suite (TCP/IP)
  • This theoretically allows any computer or device to communicate with another computer or device, as long as they're connected to the Internet

The World Wide Web

  • The World Wide Web (or just "the Web") is an information space built on top of the Internet
  • Documents and other resources on the Web are identified by a URI (Universal Resource Identifier)
  • Web documents are written in a type of markup language called HTML.
  • These resources are linked together using hyperlinks
The World Wide WebL1, S3

How Does the Web Work?

  • The World Wide Web uses a client-server model
  • A web server is a program running on a computer whose purpose is to deliver documents to other computers on request. A web server runs continuously, waiting for new requests
  • A web client, or browser, is a program that runs on a personal computer, smart-phone, or other device, and requests web pages from a server as the user asks for them. When a page has been received, the client then renders it for display
  • Web browsers and servers communicate with each other using HTTP, the HyperText Transfer Protocol
  • The World Wide Web is the global body of information available via HTTP or more commonly HTTPS (S = secure / encrypted)
The World Wide WebL1, S4

Client-Server Example

  1. The user runs a web browser on their computer, which starts up showing the RMIT Computer Science home page
  2. The user clicks on an underlined link, "about RMIT" which is linked to https://www.rmit.edu.au/about.php
  3. The web browser connects via the internet to the remote computer specified by the link www.rmit.edu.au, and using the secure HTTP protocol https://, asks the web server on the remote computer for the web page located in the directory / called about.php
  4. The remote web server responds by sending the HTML text of that web page back to the client's machine
  5. The web browser on the client's machine then processes the HTML text and displays the web page on the user's screen

Every time you select a page, a transaction like this takes place.

The World Wide WebL1, S5

Hypertext

  • Conventional writing is linear, but humans think in an associative way by connecting things together
  • Hypertext attempts to bridge the gap, by representing information in discrete pieces of data, called nodes, connected by links
  • The user controls the order in which the text is viewed, not the author
  • The purpose of links is to suggest paths, rather than determine the viewing order
  • The World Wide Web is a hypertext

HTML as Hypertext

  • The Hypertext Markup Language (HTML) is a high level markup language (set of rules) that describes the content of web pages
  • Each web page can be considered a hypertext node. Each node is written in HTML, and can contain embedded links to other nodes (other web pages)
  • HTML is made up of tags, attributes which are located inside an opening tag, and innerHTML which is placed between an opening and closing tag and can be plain text or more (nested) tags
  • <p>We all study at <a href="http://www.rmit.edu.au">RMIT University</a> in Australia</p>
    • p a paragraph tag
    • innerHTML "We all study at ... in Australia"
    • a a hyperlink tag
    • href a hyperlink attribute
    • innerHTML "RMIT University"
The World Wide WebL1, S6

HTML, Head and Body Elements

When you open a modern HTML document, you will see a DOCTYPE declaration, followed by a root <html> element which represents the entire document.

Inside the <html> element there are two child elements <head> and <body>:

<!doctype html>
  <html>
    <head> ... </head>
    <body> ... </body>
  </html>

Note that the <!doctype html> element is empty, ie it "stands alone", whilst the other three elements are paired, ie there is an opening and a closing tag with conent inside.

These two child elements are analogous to what we would normally see in a book or other physical document:

  • <head> contains information about the book or document, publisher, author, title; more or less the 'cover' and 'covering pages'. In HTML there is also meta data, style and scripts.
  • <body> contains the 'human readable' content of the book or document, sections, chapters, headings, paragraphs, images etc. In HTML, this is where you put all readable page content.
HTML Version 1L1, S7

Invention of the World Wide Web

Sir Tim berners-Lee at the 2012 Olymic Games opening ceremonySir Tim Berners-Lee is largely credited for pioneering Hypertext Markup Language (HTML), inventing the World Wide Web in 1989, and giving his invention away for free.

Without his generosity, everytime you clicked on a hyperlink like this one (during the patent period), a small royalty fee would have to be paid to Tim or to CERN, where he was employed at the time.

Tim Berners-Lee was awarded the 2016 ACM A.M. Turing Award, sometimes called the "Nobel Prize in Computing".

To get a sense of what was present in a very early web document, have a look at the source code of the very first web page ever written in HTML Version 0: Browser or Terminal

NB: Apologies if this is not obvious but do not use any of this code in your assignment, it is extremely out of date! See all of the errors here. A better starting document can be found here: https://www.w3schools.com/html/

Early ELementsL1, S8

Head Elements

The head element contains elements related to the publishing of the document and are generally "machine use only".

Meta Elements

<meta> elements supply information about the document such as author, description, keywords, etc. but this list has expanded to include charset, viewport, etc. The tag has several attributes with name & http-equiv used in combination with content, and charset:

  • <meta charset="UTF-8"> ... Page uses the UTF8 charset, all the world's characters and emojis too!
  • <meta http-equiv="content-type" content="text/html; charset=UTF-8"> ... Same as above but with extra steps.
  • <meta name="author" content="Tim Berners-Lee"> ... Author is Tim Berners-Lee
  • <meta name="description" content="Welcome to the Web"> ... Page is a "Welcome to the Web" page
  • <meta name="keywords" content="World Wide Web, www, CERN project"> ... Related words & phrases, search terms etc.
  • <meta name="viewport" content="width=device-width, initial-scale=1.0"> ... Look good on smart phones, they're a thing now.

Title Element

The <title> element supply information about the document such as author, description, keywords, etc. but this list has expanded to include charset, viewport, etc. The tag has several attributes with name & http-equiv used in combination with content, and charset:

HTML Version 1L1, S9

Body Elements

The first envisioned documents to be hosted on the World Wide Web were of a scientific and technical nature, viewed on a terminal program. For this reason, the first elements created were a hierarchy of headings (h1 - h6), paragraphs, lists, and of course hyperlinks to other web documents:

  • <h1> ... </h1>

    top level heading element with content, defined with paired tags
  • <h2> ... </h2>

    second level heading element with content, defined with paired tags
  • <h3> ... </h3>

    third level heading element with content, defined with paired tags
  • <h4> ... </h4>

    fourth level heading element with content, defined with paired tags
  • <h5> ... </h5>
    fifth level heading element with content, defined with paired tags
  • <h6> ... </h6>
    sixth level heading element with content, defined with paired tags
  • <p> ... </p>
    paragraph element with content, defined with paired tags

  • <a href="../DataSources/Top.html">What's out there?</a>
    Hyperlinks to other documents using an href attribute in the opening anchor tag.
  • <dl><dt> ... </dt></dl>
    Definition list item nested in a definition list block, both defined with paired tags
  • <ul><li> ... </li></ul>
    Simple list item in an unordered list block, both defined with paired tags, just like this one!

All of the above elements survive today, but not all tags survived, one of the first elements to become redundant was the <NEXTID N="55"> element, an empty element with an attribute, that denoted the numbered physical NeXT machine that the resource was located on.

HTML Version 1L1, S10

Anchor Element in Detail

The anchor tag can be used to link to other documents:

<a href='anotherpage.html'>Go to a document in the same directory</a>

<a href='subdirectory/anotherpage.html'>Go to a document in a sub-directory</a>

<a href='../anotherpage.html'>Go to a document in the parent directory</a>

<a href='/~eOOOOO/wp/anotherpage.html'>Go to a document in your wp directory</a>

<a href='http://anotherserver.com/anotherpage.html'>Go to a document on another server</a>

And jump to another position in the current document:

<a href='#end'>Skip to the end</a>
<p> Once upon a time ...
<p> Blah blah blah ...
...
<p id='end'> ... and they lived happily ever after.</p>

Or even send someone an email:

<a href='mailto:eOOOOO@student.rmit.edu.au'>Mail Me</a>

Mail Me

HTML Version 1L1, S11

Summary

By the time HTML version 1 had been finalised, there were enough HTML document elements that would allow a computer to render a simple word-processor generated document with:

  • meta tags containing author details, keywords, creation & last modified dates etc,
  • headings ( <h1> - <h6> ),
  • paragraphs ( <p> ),
  • lists ( <ul>, <ol>, <dl> ),
  • list items ( <li> ) - just like these!

Here is a comprehensive list of the tags and attributes, not all of which are still in use today!
http://www.w3.org/History/19921103-hypertext/hypertext/WWW/MarkUp/Tags.html

HTML Versions 2 & 3L1, S12

Exponential Growth - 1990s

The World Wide Web Consortium (W3C) was founded in 1994 to develop, expand and advance HTML standards. It is an international community where member organizations, a full-time staff, and the public work together to develop Web standards. The W3C’s primary activity is to develop protocols and guidelines that ensure long-term growth for the Web

Around this time the World Wide Web began to grow exponentially, and computer operating systems with a Graphical User Interfaces (GUI) became commonplace.

The W3C standards body were overwhelmed by this fast growing technological demand and a new group called the HTML Working group was set up in 1997 to take over progress and development, leaving W3C free to concentrate on maintaining the standards.

New tags and attributes that were created and are still around today include:

  • <b> & <i> To give text a bold and italicised style respectively.
  • <strong> & <em> To give text a strong and emphasised style respectively.
  • <img> To place images in a document with descriptive text inside an alt attribute.
  • <table> To organise tabular data in rows and columns.
  • <div> & <span> To mark out "non-semantic" but logical areas of the page content.

Trivia: Having images in a webpage is something that Tim Berners-Lee didn't think was necessary initially!

HTML Versions 2 & 3L1, S13

Bold/Strong and Italic/Emphasised Text

The <b> and <i> were introduced to make text bold and italicised but there was fierce debate amongst the Standards and Working Group members that these elements were purely stylistic and had no semantic meaning, so two more elements strong and em were introduced to convey semantic meaning and for a while the use of <b> and <i> was discouraged in favour of these alternative elements.

But - spoilers!<b> and <i> were brought back into the HTML5 standard with new / clarified semantic meaning:

  • <b> ... represents a span of text to which attention is being drawn for utilitarian purposes without conveying any extra importance and with no implication of an alternate voice or mood ...
  • <i> ... represents a span of text in an alternate voice or mood, or otherwise offset from the normal prose in a manner indicating a different quality of text ...
  • <strong> ... represents a span of text mark up a warning or caution notice ...
  • <em> ... represents a span of text to place or stress emphasis in order to change the meaning of the sentence ...

Taken from: https://www.w3.org/International/questions/qa-b-and-i-tags and https://html.spec.whatwg.org/multipage/text-level-semantics.html

For this reason, this lecture series makes a departure from default styling. Text inside the <em> element will have an underlined style and text inside the <i> element will have an italic style.

I'm still confused about this, can you elaborate more? Have you ever had the experience where two friends in your social group fall out over something and the rest of you try and work out what the fight is about but neither side seems to be making any sense but it's clear that both feel very strongly about their position and they are making everyone miserable and forcing everyone to pick a side and then (thank the gods!) one day they get together and sort out their differences and they come back and tell everyone everything is fixed and why, and everyone listens but still noone else has a clue what they're talking about, but it doesn't matter anymore because everyone is so happy that the fighting is over and everyone can get back to normal life? Well ... it's exactly like that.
HTML Versions 2 & 3L1, S14

Table Element

The <table> element allows us to output tabular data in a webpage. The table rows <tr> contain table cells, either header cells <th> or data cells <td>, with content inside.

A table can be divided into three semantic parts to contain table rows: a header <theader>, a body <tbody>, a footer <tfooter>. It can also have a caption <caption>.

The table cells can span columns (ie expand vertically) with a colspan attribute, or span rows with a rowspan attribute.

<table>
  <caption> ... </caption>
  <theader>
    <tr>
      <th> ... </th>
    </tr>
  </theader>
  <tbody>
    <tr>
      <td> ... </td>
    </tr>
  </tbody>
  <tfooter>
    <tr>
      <th rowspan='3'> ... </th>
    </tr>
  <tfooter>
</table>
HTML Versions 2 & 3L1, S15

Table Example


HTML Versions 2 & 3L1, S16

Div and Span

Quality Street chocolate box, demonstrating that the box is like a div, wrappers are like spans and chocolates are like the contentAs web documents evolved beyond simple "word processing" documents, it became obvious that context-free containers were needed to mark out logical areas of a webpage. Two elements were introduced called <div> and <span>.

In some ways, a <div> is like a box of chocolates and <span>s are like individually wrapped chocolates (see image).

<div> is a block element that can be used to group other block and inline elements inside. Divs can be targeted with CSS or Javascript. Click on the div element below to see more:

Hello, I am a div. Click on me to see where I begin and end!

Whereas <span> is an inline element that can be used to group other inline elements inside. Spans can be targeted with CSS or Javascript. Click on the span elements below to see more:

Hello, I am a paragraph and I contain a number of span elements. Here is the first one: "Hello, I am span number 1. Click on me to see where I begin and where I end!", thanks span#1, here is the second span: "Hello, I am span number 2. Click on me to see where I begin and end!", thanks span#2, and here is the third span: "Hello, I am span number 3, thanks for making it this far. Click on me to see where I begin and end!", thanks span#3.

HTML Versions 2 & 3L1, S17

Block and Inline Elements

By now you should be aware that some HTML elements are block elements, like headings, paragraphs, horizontal rules, lists and list elements, tables and table rows. These are generally recognised as 'taking up the whole width of the window', for example this paragraph.

Other elements are inline elements, such as strong text like this, emphasised text like this, anchor elements like this, table cells, images, line breaks are rendered inline and many can occupy the same line, perhaps even breaking across lines if they reach the end of the window. NB: <th> and <td> elements don't break across lines, but will share a line with other <th> and <td> elements inside a <tr> element..

Some of the elements above have title attributes that explain their block / inline status. Move your mouse over the elements to see more.

In general, inline elements should never contain block elements, for example <p><em>is allowed</em></p> but <em><p>is not allowed</p></em>.

However, there are three paired inline elements that break this rule: <form>, <button> and in HTML 5 <a> was added to the list.

HTML Versions 2 & 3L1, S18

Attributes: id & class

If you view the source code, you will see that this slide has an id and a class attribute.

Sourcecode example of class and id

The id attribute is an optional attribute designed to uniquely identify an element.

  • An element should only have one id.
  • No two elements in a document should have the same id.

Think about your student ID. You should only have one, and no two students at RMIT should ever share the same SID:

<p id='eOOOOO'>There can only be one!</p>

The class attribute, also optional, identifies a set of elements, and elements can belong to more than one class.

  • An element can have more than one class.
  • Elements in a document can share the same class.

Think about your classes and class-mates. Students should have many classes and many class-mates:

<p id='eOOOOO' class='COSC2413 COSC1078 COSC2625'>I know you from somewhere ...</p>
<p id='s1234568' class='COSC2413 COSC1078 COSC2625'>We are in Intro to IT too</p>
<p id='s1234569' class='COSC2413 COSC1078 COSC2625'>Don't forget BITS!</p>

The need for these identifying attributes will become clear when using CSS and javascript.

HTML Version 4L1, S19

Separation of Style and Content

One significat reversed feature of HTML3.2 was the introduction of new tags and attributes to control font, style, color, border and alignment. These have been deprecated and removed from the current day standard.

The first step towards modernising HTML3.2 was to separate style from content. The following changes were made in HTML version 4.01 (strict) which was adopted in 1999:

  • Styling tags such as <center>, <font>, <strike>, <u> were removed / deprecated.
  • Styling Attributes such as align, color, height, width, border were removed / deprecated.

Today, we are expected to use Cascading Style Sheets as much as possible to style web pages (more in lectures 3 & 4).

If your tag or attribute is adding style, you are doing it wrong!

XHTMLL1, S20

Adhering to a Strict XML Syntax

With the emergence of WAP enabled phones and other "underpowered" web devices around the turn of the century, there was a push to develop webpages with a very strict XML syntax. XHTML 1.0 was a reformulation of HTML4 in XML and was designed to allow web content on a wide range of less sophisticated devices, not just on personal computers.

Let us not dwell too much on the details of this standard. Rules were strict!

  • All tags must be lowercase
    <a href=' ... '> and <body>
  • Tags must be closed, even the empty ones
    eg <p> ... </p> and <br /> etc
  • Tags must be nested correctly
    eg <strong><em> ... </em></strong> etc
  • Attributes need a value in quotes, even when it is clear what they mean.
    eg href='http://google.com'
  • Attributes need a value, even when the attribute makes it clear what is required
    eg checked='checked'

Providing a simple <html> opening tag at the top of an XHTML document was no longer enough. We had to write this:

<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">

Rightly or wrongly, development of XHTML2.0 was abandoned in 2009 in favour of developing a new HTML5 standard http://www.w3.org/2009/06/xhtml-faq.html with a much simpler doctype declaration.

<!doctype html>
<html lang="en">
HTML5L1, S21

Rules Revision

By the time HTML5 was adopted in October 2014, smartphones and other mobile devices had been introduced and were more technologically advanced than many 20th century desktop computers.

HTML5 adopted the more sensible strategies found in previous HTML standards (eg simpler doctype, lowercase tags, correct nesting of tags), but is not constrained by the overtly strict XML syntax found in XHTML:

  • Empty tags don't need a closing slash
    eg <br /> can be written as <br>
  • Values with no spaces don't need quotes
    eg value='1' can be written as value=1
  • "Obvious" attributes can be minimised
    eg selected='selected' can be written as selected

This course will focus on the HTML5 syntax, but you should be aware of syntax variations found in previous standards as you may be called on to maintain or upgrade pages from older HTML syntax in the work place.

Today HTML has been classified as a "living standard" and we may never see a formal "HTML6" or beyond. The living standard, ie an up to date specification, can be found here: https://html.spec.whatwg.org/

You can check the validity of your HTML code at any time here: https://validator.w3.org/nu/

HTML5L1, S22

New Elements and Attributes

HTML5 introduced more tags and attributes that are useful, including:

  • Semantic tags that help search engines analyse your page content and optimise your website ranking
    eg <header>, <nav>, <main>, <article>, <section>, <footer> etc.
  • Form input types and attributes that make web development easier
    eg email, date, color, range, pattern, required etc.
  • New <video> and <audio> elements that replace the need for third party plugins such as Quicktime™, Flash™ etc.

We will look at these elements and attributes in more detail next week!

A new meta tag was introduced primarily to assist the display of content at a reasonable starting size on mobile devices:

<meta name="viewport" content="width=device-width, initial-scale=1">

HTML5L1, S23

HTML Entities

In a webpage, such as this one, if you want to refer to a paragraph tag like this: <p>, you may fall into the trap of coding just "<p>". Unfortunately, if you do this, the browser will interpret the tag as markup and not render it the way you want because the < and > characters are reserved to mark out tags. We call these sorts of characters meta-characters because they 'mean something'.

If you want to use the literal versions of these characters in a webpage, you need to use HTML Entities which are escape sequences beginning with an ampersand character &, followed by a character sequence eg lt for < and gt for >, and ending with a semi colon character ; .

If you view the source code of this slide, you will see many examples of these:

screenshot of this slide

In the source code, you will also see that to display

  • & you need the code &amp;
  • &amp; you need the code &amp;amp;
  • &amp;amp; you need the code &amp;amp;amp;
  • ...
  • This list will continue on to (infinity).
HTML5L1, S24

HTML Entities

HTML entites are also used to encode unusual characters not easily found on keyboards such as:

Bullet points and arrows
↓ ↕ • ▸
&darr; &varr; &bull; &rtrif;
Mathematical Symbols
π ∮ ≃ ⊆
&pi; &conint; &sime; &sube;
Commercial marks
™ © ® Ⓢ
&trade; &copy; &reg; &oS;
Accented and unusual letters
Ç Ë Ø Þ
&Ccedil; &Euml; &Oslash; &THORN;
Fractions
½ ¾ ⅓ ⅖
&half; &frac34; &frac13; &frac25;
HTML5L1, S25

UTF-8 Character Encoding

However, special character encoding is becoming less of a problem as character encoding in HTML5 is UTF-8 by default. This means that all unicode characters (currently over 1.1 million) can be represented in a web document.

One Byte (128 characters)
Includes original ASCII keyboard characters
Two Bytes (1,920 characters)
Includes most European and Middle Eastern characters
Three Bytes (63,488 characters)
Includes most Asian language characters
Four Bytes (can accomodate 2,031,616 characters)
Includes everything else, obscure Asian language characters, ancient Mayan and Egyptian hieroglyphs; and recently emojies were added to the list! We can now turn :-D into 😋.

Extra: Click here to read more about Unicode, or to view a graph of estimated encoding usage on the web, click here.

Webpage ExampleL1, S26

A First Webpage

Let's have a look at a very simple webpage that demonstrates some of the elements we have encountered.


Welcome!Lect 2, P.1

Web Programming
COSC2413 / 2426 / 2453

Lecture 2 - HTML 2

Lecture 2.1Lect 2, P.2

Part 1: HTML5 Updates and Upgrades

HTML5 Updates and UpgradesLect 2, P.3
  1. Multimedia
  2. iFrame
  3. Semantic Elements
MultimediaLect 2, P.4

Third Party Plugins

Native support for multimedia was very poor before HTML5. Any multimedia (audio, visual, PDFs, flash etc) required a third party plugin from the vendor to tell the browser how to render the content and so web pages were dependent on vendor upkeep of these plugins and any security vulnerabilities.

Below is a legacy screen-capture of an Adobe Flash website, Adobe implement the "free model", ie providing free viewing plugins to all users and charging a subscription free for their creation and authoring tool.

Adobe Flash Professional, now rebuilt and renamed as Adobe Animate

MultimediaLect 2, P.5

Object and Param Elements

To include content that is still not natively supported by the web browser, such as java applets, PDFs and Flash files, we use the <object> element and specify the source using the data attribute.

<object data='interactive-car-ad.swf'></object>

Parameters can be defined for a plug-in using <param> elements.

The <object> element allows you to nest other fallback objects if the user-agent (third party "helper application") is not supported.

<object type='application/x-shockwave-flash'>
  <param name='movie' value='interactive-car-ad.swf'>
  <object data='movie-of-car.mp4' type='application/mpeg'>
    <object data='passable-car-animation.gif' type='image/gif'>
      If all else fails, this message and a link:
      <a href='car-webpage.html'>Please buy this car</a>
    </object>
  </object>
</object>
MultimediaLect 2, P.6

Embed Element

The <embed> element is a "lightweight" empty version of the <object> element with a more familiar src attribute and it does not have any fallback options.

<embed src='car-ad.swf' type='application/x-shockwave-flash'>
<p>Can you see the car ad above? No? Oh ... never mind.</p>

The element has had an interesting past! Although unofficially and widely supported in web browsers since the mid 1990s, it was not part of any HTML standard until the W3C included it as part of the HTML5 specification.

MultimediaLect 2, P.7

Audio Element

The <audio> element allows you to play an audio file. You can allow the user to control sound playback by supplying a controls attribute, and have it pre-load using preload='auto'. In addition, a message can be shown to the user when the audio element is not supported in their browser.

<audio id='meow' src='app/audio/Meow.mp3' preload='auto' controls>No Sound For You!</audio>

a cute kitten


Or use javascript to play sounds in response to user events (more on that in the javascript lectures).

Kitten can be poked (mouse click), stroked (mouse wheel) and dragged.

MultimediaLect 2, P.8

Video Element

The <video> element allows you to play a video file. You can allow the user to control sound playback by supplying a controls attribute, and have it pre-load using preload='auto', although this is not recommended when designing for portable devices, mobile phones etc. In addition, alternative content or a message can be shown to the user when the video element is not supported in their browser.

<video id='nye' src='app/video/NYE2015.mp4' controls width=598 height=180>No Video For You!</video>

For <video>, <img> and other visual elements, integer height and width attributes let the browser know how much space in pixels to reserve. Even though these are strictly styling attributes, they are so important that they are included in the HTML markup.

For other types of sizing (eg percentage sizes), use CSS instead.

MultimediaLect 2, P.9

Audio & Video

The new <audio> and <video> elements, native to HTML5, share many other attributes such as loop to continuously loop, volume to set the volume.

For a full list see http://www.w3schools.com/tags/ref_av_dom.asp.

They both support multiple sources, so that if a browser does not support a media type (a common issue, especially with video), a second fallback source can be selected.

<video ... >
  <source src='first-choice.mp4' type='video/mp4'>
  <source src='second-choice.ogg' type='video/ogg'>
  Plain text message: browser does not support HTML5 video.
</video>
MultimediaLect 2, P.10

SVG Markup Language

Scalable Vector Graphics are graphical elements, rendered differently to plain pixelated images. To the right are 10 <polygon> elements inside a <svg> element matching the two repeating Penrose tiles found at Storey Hall and in other architectural examples around the world.

<svg ... >
  <polygon points='...' style='...'>
  ...
<svg>

SVG has had good support for many years and it is no longer necessary to use an object element to include this into a webpage. It is not covered in detail in the course, but those interested in design may like to know how to embed artwork directly into a webpage. Visit http://www.w3schools.com/graphics/svg_intro.asp to get started.

Inkscape is a free drawing program you can use to create scalable vector graphics.

MultimediaLect 2, P.11

Canvas Element

Blank Canvas for Painting

The <canvas> element allows a developer to include both 2D and 3D graphics, still or animated. Drawing is done using a script such as javascript, on the right is a "micro painting" application that uses the canvas element.

Like the <video> & <img> elements, <canvas> has height & width attributes, and a fallback message if the canvas element is not supported (see right).

<canvas id='canvas' width='200' height='200' onmousemove='...'>
  Blank Canvas for Painting
</canvas>

Visit http://www.w3schools.com/html/html5_canvas.asp to get started with simple 2D drawings.
Visit http://www.kevs3d.co.uk/dev/canvasmark/ to run some 3D graphic tests on your machine.

iFrameLect 2, P.12

iFrame Element

It is possible to embed another webpage inside a page using an <iframe> element. The element has a number of attributes, including the familiar height, width and src attributes.

<iframe height='...' width='...' src='https://www.youtube.com/embed/0fjE1A80w2s'></iframe>.

Using an iframe element to include web content is not considered good practice, but it is the method YouTube requires you to use at the time of writing. Youtube does this to track views and provide a fair share of advertising revenue to the authors.

Using an iframe element raises some security concerns. There is a new HTML5 sandbox attribute that allows the main page to control the behavior of the iframed page.

Likewise, by placing the following meta tag in your head element:
<meta http-equiv="X-Frame-Options" content="deny">
you can stop your page from being included in another page's iframe.

Semantic ElementsLect 2, P.13

Page Structure

Last week we saw that the first HTML standards provided "word processing"-like elements to contain text. This was done for two key reasons:

  1. So that the information could be understood by a human, eg for a user or developer.
  2. So that the document could be understood by a computer, eg a search engine or web crawler.

We also saw the creation of two context-free container elements in HTML4 called <div> and <span>. These elements allow us to group content together into larger logical areas.

But <div> and <span> are generic elements and do not provide AI or search engines with any context. The W3C and Working Groups saw a need for more semantic grouping elements that are more descriptive and allow both humans and computers to understand the page content better.

HTML4 / XHTML "Header" Example

<div id='header-stuff'>Company masthead / header content goes here</div>

HTML5 "Header" Example

<header>Company masthead / header content goes here</header>
Semantic ElementsLect 2, P.14

New Body Decendants

The vast majority of webpages contain:

  • A masthead area for the logo and the organisation's name
  • A navigation area for links to other pages within the website
  • A main area for the "real" body or page content of the page.
  • A footer for copyright information, secondary links, eg social media etc.

Four new semantic elements have been created to be placed directly inside the <body> element to assist users, developers, computers and search engines understand the page structure better:

<body>

  • <header>, not to be confused with the <head> element!
  • <nav>
  • <main>
  • <footer>

</body>

In last week's lab, you should see that the assignment 1 template page already has these elements.

Semantic ElementsLect 2, P.15

New Main Elements

Within the <main> element (primarily), content can be divided into further logical areas:

<main>

  • <article>, a block of content that could stand alone, such as these "lecture 2" slides.
  • <section>, a block of content that is logically distinct, but part of something greater, such as just this slide.
  • <aside>, a block of content that adds detail to a section, but is not essential for understanding.
  • <figure>, a block of images, diagrams, code samples etc can be grouped as a figure.
    • The figure element has a child <figcaption> element to attach a caption.

</main>

A helpful article explaining this in more detail, with a helpful flowchart, can be found here: http://html5doctor.com/lets-talk-about-semantics.

Semantic ElementsLect 2, P.16

Details and Summary

The <details> element is similar to an aside. It contains content that is designed to be hidden by default. It has a child <summary> element that is designed to be visible at all times. When the user clicks on contains the summary, the content will be made visible or will hide.

<details>
  <summary>See More (always visible)</summary>
  <p>Paragraph 1 (hidden until details expanded) ... </p>
  ...
</details>

This slide series has a details element in the main navigation area so that the full navigation doesn't block out the page content when not wanted.

screenshot of select modules code details

Semantic ElementsLect 2, P.17

Inline Elements

New inline semantic elements to complement existing elements such as <abbr>, <strong>, <em>, <q>, <code>, <kbd> include:

  • <cite> is now the cited title of a work - https://www.w3.org/TR/html-markup/cite.html.
  • <mark> to mark or highlight text.
  • <meter> contains a rating, such as a movie review or a pressure guage. Meter text goes here
  • <progress> shows how something is progressing, such as a download or a users progression through a multi-page form. Progress text goes here
  • <time> contains a time or a date.
  • <wbr> is an optional <br> element. It alerts the browser to where you would prefer a line break to occur in a long word if there is not enough room for it on one line. For example, there is one inside this link: supercalifragilisticexpialidocious. Can you find it?
The semantic elements we have looked at are not a complete set.
For a more comprehensive list of new semantic elements, visit this link: http://www.w3schools.com/html/html5_semantic_elements.asp
Lecture 2.2Lect 2, P.18

Part 2: Web Forms

Web FormsLect 2, P.19
  1. Form and Form Attributes
  2. Original Input Elements
  3. Original Paired Elements
  4. Label Element
  5. New HTML5 Form Elements
  6. New HTML5 Attributes
  7. Form Example
Form and Form AttributesLect 2, P.20

Form Example

Below is an example of what the RMIT Helpdesk's webform looks like at the time of writing. The image is clickable and will take you to the form, should you ever need to contact them about an IT related issue (hint hint).

myTechSupport at RMIT

Form and Form AttributesLect 2, P.21

Form and Form Attributes

A webform allows a user to submit input data to a server, usually to a processing script. Form elements are contained inside a <form> element.

Three key attributes are:

  • action which is the where the data is being sent (ie the destination URL).
  • method which is how the data is being sent.
  • enctype which is how the data is encoded.
<form action='processing.php' method='...' enctype='...'>

... form input elements go here ...

</form>
Form and Form AttributesLect 2, P.22

Method Attribute

There are two ways that form data can be sent:

  • method='get': data is visible, is sent in the url of the request. The amount of data that can be sent is limited to several kiB. The data is saved in the client's browser history and can be bookmarked by the user.
  • method='post': more secure, is sent in the main body of the request. The amount of data is not limited, except in a practical sense. The data is not cached or saved on the client's computer.

You should use the get method only for requests for non-secure data, e.g. retrieval of map data, trip data, google searches, etc.

<form action='traintimetable.com' method='get' ... > ... </form>

You should use the post method for submission of personal and/or sensitive data such as username, password, date of birth fields, etc.

<form action='mybank.com' method='post' ... > ... </form>

postcard and postal envelope demonstrating similarities with get and post methods

Form and Form AttributesLect 2, P.23

Enctype Attribute

The enctype attribute is optional, if not included, data is sent using application/x-www-form-urlencoded by default. This means many troublesome characters such as spaces are encoded for safe transmission and will be automatically decoded on the server.

<form ... enctype='application/x-www-form-urlencoded'> ... </form>

However, if you wish to upload files in your form, you will need to use the multipart/form-data, which means that file data is not encoded.

<form ... enctype='multipart/form-data'> ... </form>

Finally, there is the option to send data as text/plain, which means only spaces are encoded during transmission.

<form ... enctype='text/plain'> ... </form>

Original Input ElementsLect 2, P.24

Input Element

All form input elements have the following fields which allow the form to submit data to a processing script:

  • name='...': The name of the input, transmitted to the processing script.
  • value='...': The value of the input, transmitted to the processing script.
  • readonly: Stops the user from modifying the input. Useful if automating the field value using javascript.
  • disabled: Stops the browser from sending the input. Useful if disabling field submission using javascript.

The first field we will look at is the <input /> element. It is a multi-purpose input element and how it is displayed is controlled with its type='...' attribute.

<form ... >
  <input type='...' name='...' value='...' />
  ...
</form>
Original Input ElementsLect 2, P.25

Traditional Input Types

Before HTML5, the available input element types were:

  • type='text': displays a single line text field for user input.
  • type='password': as above, but user input is masked.
  • type='hidden': not displayed, a field that is transmitted, but name and value are hidden from the user.
  • input='radio': displays as round select buttons, users may select one option.
  • type='checkbox': displays as square select boxes, users may select multiple options.
  • type='file': displays a box with a browse button, allows users to upload a file.
  • type='button': displays as a button, used to run scripts, such as a calculator, not practical for transmission of useful data.
  • type='reset': displays as a button, resets the form fields to their default values.
  • type='submit': displays as a button, submits all form data to the processing script named in action attribute.
  • type='image': displays as an image, behaves as a submit button. This field requires additional src and alt attributes.
Original Input ElementsLect 2, P.26

Types: text, password, hidden

<input type='text' name='uid' value='eOOOOO' />

<input type='password' name='uid' value='eOOOOO' />

<input type='hidden' name='uid' value='eOOOOO' />

Nothing to see, but it is there!

Original Input ElementsLect 2, P.27

Types: radio, checkbox

Values for radio and checkbox inputs are not displayed, only transmitted, so we have to write them out next to the input.

<input type='radio' name='gender' value='male' />Male,
<input type='radio' name='gender' value='female' />Female,
<input type='radio' name='gender' value='other' />Other.

Male, Female, Other.

<input type='checkbox' name='seeks[]' value='male' />Male,
<input type='checkbox' name='seeks[]' value='female' />Female,
<input type='checkbox' name='seeks[]' value='other' />Other.

Male, Female, Other.

When offering multiple select options, you need to submit all the values as an array or list. This is why the name has square brackets [ ] after it.

If offering only one option, you do not need the square brackets, eg

<input type='checkbox' name='spam' value='yes' />Sign up for our newsletter.

Sign up for our newsletter.

Original Input ElementsLect 2, P.28

Types: file, button

Submitted files will be stored in a temporary area with a temporary name. No value attribute is required as the file content is the value.

<input type='file' name='assignment' />

Although button is a valid type, it is not usually used to contain form data, so it does not need a name attribute. It's value is printed on the button.

<input type='button' name='not-needed' value='Click me' />

Original Input ElementsLect 2, P.29

Types: reset, submit, image

The reset button is not used as widely as it was in the past. It allows a user to reset the form to its starting values (usually blank). Its value is printed on the button, so use a value like 'reset'.

<input type='reset' name='not-needed' value='Reset, ie erase all your input!' />

Every form needs a submit button and a form can have more than one submit button. When this button is clicked, all form data is sent to the processing script.

<input type='submit' name='sign-in' value='Sign in to your account' />
<input type='submit' name='sign-up' value='Register and sign in ' />

The image type is also a submit button, not an image upload button. It is used if you want a more distinct submit button.

<input type='image' src='app/img/panic-button.png' alt='PANIC!' />

Original Paired ElementsLect 2, P.30

Paired Elements

There are other form elements that should be familiar to you that require an opening and a closing tag.

  • <select> ..... </select>: The select element can be used to create a drop-down box or a combo box.
  • <option> ..... </option>: The option element(s) go inside a select element or an optgroup element. Each is an option the user can select.
  • <optgroup> . </optgroup>: Optional elements that go inside a select element, grouping similar options together in a select element.
  • <textarea> . </textarea>: A multiple line text box for users to enter more than one line of text.
  • <button> ..... </button>: Very similar to the button input type, except HTML markup can be displayed on the button.
  • <fieldset> . </fieldset>: Not an input element, but visually groups together inputs that are related.
Original Paired ElementsLect 2, P.31

Select Element

The <select> element has a name attribute and no value attribute. It has two optional attributes size which is the number of rows to display, and multiple which allows users to select more than one item. Providing either of these two will change the display from a drop-down box to a combo box.

<select name='santas-list'> ... </select>

<select name='santas-list' size='3'> ... </select>

<select name='santas-list[]' size='3' multiple> ... </select>

These selects are empty at the moment. What we need are options!

Original Paired ElementsLect 2, P.32

Option Element

Each <option> element has a value attribute and no name attribute. It also has an optional selected attribute to make it selected by default. The text inside the option is displayed to the user. This allows us to show something user-friendly to the user and submit something computer-friendly to the server.

Unless the first option is a 'default' option, we should but in a blank 'please select' option so that the user is prompted to make a selection.

<select name='santas-list'>
  <option value='' selected>Please Select</option>
  <option value='s1234567'>Alice Liddell</option>
  <option value='s1234568'>Bob D&apos;Builder</option>
  <option value='s1234569'>Carol Singers</option>
</select>

<select name='santas-list[]' size='3' multiple>
  <option value=''>Please Select</option>
  <option value='s1234567'>Alice Liddell</option>
  <option value='s1234568'>Bob D&apos;Builder</option>
  <option value='s1234569'Carol Singers</option>
</select>

Original Paired ElementsLect 2, P.33

Optgroup Element

Options can be grouped inside an <optgroup> element. This element has a label attribute.

<select name='santas-list'>
  <option value=''>Please Select</option>
  <optgroup label='naughty'>
    <option value='s1234567'>Alice Liddell</option>
  </optgroup>
  <optgroup label='nice'>
    <option value='s1234568'>Bob D&apos;Builder</option>
    <option value='s1234569' >Carol Singers</option>
  </optgroup>
</select>

Disabling a block of options is easy with optgroups:

<select name='santas-list[]' size='6' multiple>
  <option value=''>Please Select</option>
  <optgroup label='naughty' disabled>
    <option value='s1234567'>Alice Liddell</option>
  </optgroup>
  <optgroup label='nice'>
    <option value='s1234568' selected>Bob D&apos;Builder</option>
    <option value='s1234569' selected>Carol Singers</option>
  </optgroup>
</select>

No presents for Alice this year!

Original Paired ElementsLect 2, P.34

Textarea Element

The <textarea> element has a name attribute and two 'size' attributes cols & rows, which is the number of columns and rows to display. The element has no value attribute: its value is the content between the tags.

It is used for submitting longer pieces of text such as Canvas discussion board posts, ITS helpdesk requests etc.

<textarea cols='80' rows='9'>
  This is where the textarea value is ...
  If you want to put text ... at these instructions!
  What else can I tell you? ... row and col settings.
</textarea>

Original Paired ElementsLect 2, P.35

Button Element

The <input type='button' /> empty element displays the value on the button. Sometimes you want a more user-friendly message for the user and a more computer-friendly message for the computer.

The <button> paired element allows for this: what is between the tags is displayed on the button (ie not the value).

<button ... value='PID-04651' ... >Buy Now!</button>

The <button> element has a type='...' attribute that allows it to function as a submit button (default), a reset button or as a plain button (not the default). It also allows you to put HTML markup on the button to make for a more impressive button.

<button type='reset'>
  <strong>EMERGENCY</strong><br>
  <img src='app/img/panic-button.png' alt='RESET!' /><br>
  <strong>EMERGENCY</strong>
</button>

Original Paired ElementsLect 2, P.36

Fieldset Element

The <fieldset> element has a child <legend> element (not a simple caption attribute, that would be too logical!) which describes the input elements you have grouped.

<fieldset>
  <legend>About You</legend>
  <p>Firstname:<br>
     <input type='text' name='firstname' /></p>
  <p>Lastname:<br>
     <input type='text' name='lastname' /></p>
  ...
</fieldset>

About You

Firstname:

Lastname:

...

Label ElementLect 2, P.37

Labels for Inputs

In addition to label attributes, there are also <label> elements which make a form more usable by extending the "click" area of an input to an associated label. This is very useful when dealing with physically small inputs such as radio and checkbox elements.

Set the label element's for attribute to the input's id attribute and the link is created.

<input type=radio id='Alice'  name='prez'/> <label for='Alice'  >Alice Liddel</label>
<input type=radio id='Bob'    name='prez'/> <label for='Bob'    >Bob the Builder</label>
<input type=radio id='Carol'  name='prez'/> <label for='Carol'  >Carol Singers</label>
<input type=radio id='Donald' name='prez'/> <label for='Donald' >Donald Duck</label>

Now you can click on the candidate's name as well as the radio button to select the candidate of your choice - assuming the election isn't rigged!

Presidential Election


New HTML5 Form ElementsLect 2, P.38

Additional Input Types

HTML5 saw the introduction of many new types to complement the 'overworked' text input element. Selection is enhanced in many examples and some input validation takes place in others. Here are a selection of the better supported ones:

  • type='email': displays as a text box, but field will be checked for email compatible input.
  • type='number': displays as a text box, but field will be checked for numeric input. An allowed range can be specified.
  • type='url': displays as a text box, but field will be checked for url compatible input.
  • type='color': displays a color palette for user to select.
  • type='date': displays a calendar for user to select. An allowed range can be specified.
  • type='range': displays as a slider (eg the font size adjust in this website). An allowed step and range can be specified.
  • list='...': displays as a combined text box and dropdown list. It links to a new HTML5 <datalist> element. As the user types in the text box, matching options from the datalist are displayed in a dropdown list.
New HTML5 Form ElementsLect 2, P.39

Types: email, number, url

<input type='email' name='myemail' value='eOOOOO@student.rmit.edu.au' />

<input type='url' name='myurl' value='https://titan.csit.rmit.edu.au/~eOOOOO/wp' />

<input type='number' name='mynumber' value='10' />

New HTML5 Form ElementsLect 2, P.40

Types: color, date, range

<input type='color' name='mycolor' value='#BADA55' />

<input type='date' name='dateofbirth' value='1998-01-01' />

<input type='range' name='percent' value='50' />

New HTML5 Form ElementsLect 2, P.41

Datalist element and list attribute

At the time of writing, the <datalist> element is not implemented in Safari. It contains empty <option> elements that have value attributes.

The <datalist> element needs to have an id attribute which the <input> element references:

<input  list='students' name='myentry' />
<datalist id='students'>
  <option value='Alice Liddell'  >s1234567</option>
  <option value='Bob the Builder'>s1234568</option>
  <option value='Carol Singers'  >s1234569</option>
  <option value='Donald Duck'    >s1234569</option>
</datalist>

New HTML5 AttributesLect 2, P.42

Additional Input Attributes

New attributes that improve functionality in both new and old form elements were introduced in HTML5. Previously, a developer would use javascript to create the functionality. This is not a complete list, just a selection of the more popular ones:

  • placeholder='...': Places text, usually light grey, in an empty text box or area that is automatically cleared when a user starts typing.
  • autocomplete='...': Allow browser to autocomplete user's input from past entries. This can be turned off and on.
  • required: Will prevent form submission if left blank. Provides a pop up warning message if left blank.
  • pattern='...': Matches input to a regular expression (we will cover regular expressions in a later lecture). Provides a pop up warning message with optional / addition comments inside the title='...' attribute if the input does not match the pattern.
  • min='...' and max='...': provides a valid range for number fields, date fields etc.
  • step='...': Provides an incremental step size for number fields, date fields etc.
New HTML5 AttributesLect 2, P.43

Attributes: placeholder & autocomplete

<input type='text' name='firstname' placeholder='First Name'/>

<input type='text' name='firstname' placeholder='First Name' autocomplete='off'/>

If using your personal computer, your browser may suggest your first name in the first field and suggest nothing in the second field.

New HTML5 AttributesLect 2, P.44

Attributes: required & pattern

<input type='text' name='firstname' placeholder='First Name' required/>

<input type='text' ... pattern='Steve' title='Your first name must be Steve'/>

New HTML5 AttributesLect 2, P.45

Attributes: min, max & step

Choose an integer between 1 and 10:

<input type='number' min='1' max='10' step='1'/>

Choose an odd integer between 11 and 111:

<input type='number' min='11' max='111' step='2'/>

What happens if you leave the fields blank?It will allow the blank field to pass, which is bad. Make sure you use the required attribute as well to stop invalid data from being submitted.
New HTML5 AttributesLect 2, P.46

Data attributes

Data attributes can be part of any HTML element BUT are particularly useful in form elements where additional information can be stored to be accessed using a client side programming language such as Javascript. The name can be anything you choose (within reason of course), as long as you add the prefix data- to it, eg a ticket price to a ticket quantity field:

<input type='number' name='ticketQty' id='ticketQty' data-ticketPrice='20.5' />

<select name='ticketQtySelect' id='ticketQtySelect' data-ticketPrice='50.1' > ... </select>

You can then use Javascript to provide a subtotal by accessing the element's value attribute and dataset property (covered in the Javascript slides):

Tickets are $20.50 each:

$

Tickets are $50.10 each:

$

Form ExampleLect 2, P.47

A First Form

Let's have a look at a very simple form with 4 text fields and a submit button. The form is using the get method, so you can see the data in the url.

During development, it is helpful to have target='_blank' inside the opening form tag to place the server's response page in a new window. Once development is complete, the target attribute can be deleted.


Form ExampleLect 2, P.48

Suitable Form Data

1950s grocery store, woman is checking out groceries and being served by a man. Woman claims purchases comes to a dollar, man incorrectly assumes the customer is rightWhen collecting data from a user, we need to make a decision on what data we can trust the client to send to the server and what data should be calculated by the server based on the users selections.

Consider the following form data. Can we trust the client to supply the server with the correct details? What form field will be appropriate for the form data?

Number of products / servicesYes: If the client is dishonest, they will get less or more than they really want.
To stop "honest" users form making a mistake, integer quantities should be in a drop down field or collected in a number field with min, step and max attributes so that half a seat or 1.5 cars can't be ordered.
Product / service codeYes: If the client is dishonest, they will get something that they did not order.
To stop honest users from being confused, a "human readable" description of the product should be displayed and a product code should be stored in a hidden field or as a value in an option field, ie something that the customer does not normally see and select.
Product / service priceNo: If the client is able to submit price information to the server it will be troublesome for the business to prove that the client did not legitimatly sell the product at a discounted price.
To help honest users, the product prices should be shown and prices can be calculated client side BUT all price calculations should be re-calculated on the server accessing price information stored on the server.
Total priceNo: Never rely on the user to tell you what the total is!
Welcome!Lect 3, P.1

Web Programming
COSC2413 / 2426 / 2453

Lecture 3 - HCI & CSS

Lecture 3.1Lect 3, P.2

Part 1: Human Computer Interaction (HCI)

HCILect 3, P.3
  1. Designing Usable Websites
  2. Creating Usable Websites
  3. Targeting Audiences
  4. Accessibility Concerns
Designing Usable WebsitesLect 3, P.4

Human Computer Interaction (HCI)

Design, Implement and Evaluate steps forming a closed loop around a user or developer at computer in centre.HCI is the study of interaction between human and computers.

The design of an interface requires understanding of users, and their tasks.

Designing with users:

  • Plan and design task examples, together with users
  • Develop and build prototypes
  • Evalute through observation of users, replan & redesign.

Design should be based on a user's:

  • abilities
  • context
  • tasks
  • real needs

It's important to consider all potential users, e.g. novice, expert, ...

Designing Usable WebsitesLect 3, P.5

Why An Interface Design Process?

two corner drawers, each with a handle that blocks the other from opening

It's very easy to jump into detailed design that:

  • Is founded on incorrect requirements.
  • Has inappropriate dialogue flow.
  • Is not easily used.
  • Is never tested until it is too late.

It has been estimated that over 60% of large software projects go over cost, often because:

  • Clients often do not understand their own requirements.
  • As development progresses, overlooked tasks and requirements become obvious.
  • As development progresses, clients request changes, unaware of the extra work required.
  • There is insufficient client-developer-user communication and understanding.

When it comes to initial planning and design, "pay a little more now, or pay a lot more later" can come back to haunt both the client and the developer. If the developer is not careful, a loosely worded contract can turn what looked like a profitable venture into an ongoing loss-making saga.

Note that usability is vital in many areas, not just the web, and not just computer science!

Designing Usable WebsitesLect 3, P.6

Website Page Design

Each web page should be consistently designed across a website. Each page should:

  • Have a header area with title and ideally a logo.
  • Have easily accessible buttons for navigation.
  • Contain an indication of which page the user is on.
  • Contain a main area that houses all of the content.
  • Have a footer which contains contact details, privacy & policy links.
  • Contain data (can be meta-data) about the author, creation date and last revision date.

Having a webpage template and common external style sheets will help you achieve this.

Content Placement

Be aware that space at the top of a page, commonly referred to as above the line is far more valuable than space below the line, ie which can only be reached by scrolling.

  • Your header and navigation should be larger than it needs to be.
  • Make sure that the most important page content is near the top of the page.
  • Users will only scroll down if you have captured their attention and they have a sense that there is useful information to be found.
Designing Usable WebsitesLect 3, P.7

Website Navigation

A navigation bar is a collection of links to major pages on the site. They should, in general, should look and behave the same way on every page.

  • Navigation bars can be placed at the top, bottom, or side of each page, and should include links to the essential pages of the site.
  • Larger websites often employ primary and secondary navigation bars to make navigation more managable.
  • A user may come to your site on any page from a search engine result or bookmark. Make sure you have a link to the home page on every page.

Site Maps, Indexing Pages, and Search

To make content managable in larger websites, site maps, index pages and search facilities improve accessibility.

  • Site maps act as a table of contents for your web site. Like a table of contents in a book, they need not list every page on the site, but should provide the visitor with an overview of the main areas and sub-areas within the site.
  • Indexing pages are like a site map, but links are laid out in alphabetical order, not in a logical order. It can be helpful for users looking for a particular issue or concept, particularly useful in technical websites.
  • Search facility allows users to locate information within your site. This website's search box allows you to search topics that you might be having trouble understanding or locate a specific slide. Every slide with your search phrase will appear in the order that they are presented in this course.
Designing Usable WebsitesLect 3, P.8

Use of Text

People read differently online, on the web, readers tend to skim. It's important to keep paragraphs short, make them easy to understand, but not so short that they say nothing.

Like this one.

Similarly, it's important to make your text as readable as possible:

  • Avoid marketing terminology and advertising copy.
  • Use objective language.
  • Keep your audiences in mind (there's a theme here!).
Designing Usable WebsitesLect 3, P.9

Use of Images

A couple sitting together in a cinema watching a film in a cinema with 3D glasses whilst eating popcorn and drinking soda from gold colored containers whilst others behind them look on ... that said, one looks like they are sleeping ...Graphics can dramatically enhance the look of a web site, especially when they have a consistent "look and feel", or are developed as part of an integrated site theme.

Whilst images should always supplement text, a well composed picture can be more effective than a few paragraphs of sales and marketing text. Consider the picture to the right:

  • How much information is communicated instantly to the user?
  • How many words would it take you to describe everything that you see?
  • How likely is it that a user would read all those words?
Creating Usable WebsitesLect 3, P.10

Robin Williams' Page Design

Frequently used principles for designing a page are:

  • Contrast: different elements should be very different.
  • Repetition: repeating elements should have the same design layout.
  • Alignment: everything on a page should be there for a reason and have a visual connection to something else.
  • Proximity: related elements should be close together.

These principles can be applied by computer scientists, regardless of your ability as a graphic artist. For more information, visit http://www.ratz.com/robin.

Creating Usable WebsitesLect 3, P.11

Contrast

Different elements should be very different.

  • Differences in color, size, or shape can be used to distinguish one text (or images) from other text (or images).
    • That is, if two elements are not intended to be treated as being "the same", then don't make them look similar.
  • Examples for text include changing the formatting to bold, italic, or CAPS.
    • But this only works if used sparingly...
  • For a page overall, consider whether the difference between areas (e.g. content, ads, navigation areas, user comments, etc.) are easily distinguishable.

Repetition

Repeating visual elements of a page lends the content unity and cohesiveness, and makes it easier for a user to understand what is being presented.

  • Content that appears on multiple pages (e.g. a navigation bar) should appear in the same place, and look the same, on each page.
    • Improves readability, as the user can easily identify different types of content.
  • Format text consistently.
    • If sub-section headings are in bold and 14pt font, then all sub-section headings should look like this.
  • While it's sometimes tempting to be creative, usually it's worth striving for consistency with conventions established by other websites.
    • Jakob Nielsen's "Law" of the Web User Experience: "users spend most of their time on other websites".
Creating Usable WebsitesLect 3, P.12

Alignment

Aligning layout elements has a direct impact on the readability and comprehension of page content.

  • Typically documents should have a small number of vertical baselines.
    • For example, standard paragraphs, indentation levels of lists, etc.
  • Alignment directly conveys notions of structure.
    • Things that are related, or are of the same "importance", should have the same alignment.
  • Alignment is also important for things such as forms. Having form inputs aligned correctly can make the form much easier to use.

Proximity

Things that are related, or logically belong together, should be located near each other.

  • Also called the Gestalt Principle -- humans perceive relationships between things that are closer together.
  • It it usually helpful to group related items together.
    • Consider menus in software applications -- commands are not in one giant list, but rather grouped by related functionaliy.
Creating Usable WebsitesLect 3, P.13

Designing for Different Devices

When building a website, you can fall into the trap of developing a website that looks good and works well on your machine and just your machine! Users will be viewing your website on desktops, laptops, tablets and phones.

  • Test your website to see how it adapts to different size screens.
  • Resize your browser window to be wider and narrower to simulate different screen sizes and test your work in more than one browser.
  • Users may be on the move, viewing your page on a mobile device with limited access to the internet.
  • Make sure that your links and buttons are large enough to click and that images and multimedia resources are not larger than they need to be.

Most modern browsers have an inspector or developer area where different devices can be simulated. That said, the regular resizing of s browser window whilst developing, checking that content reflows and adapts nicely, goes a long way to solving layout issues!

Targeting AudiencesLect 3, P.14

Know Your Audience

Client and developers often have firm opinions about what their clients need and want and mis-judge the way their customers will use the website, but do they involve the clients in the dialog?

Consider a typical university website, what will the following audiences be looking for?

  • Current Students
  • Prospective Students
  • Current Staff
  • Prospective Staff
  • Australian Government Auditors
  • International University Rankers, eg http://www.topuniversities.com/

Stakeholders is a term used to refer to all people involved with a project, including end-users (ie customers). As much as possible, involve all stakeholders in designing, testing and evaluating a new system.

Targeting AudiencesLect 3, P.15

Catering to Conflicting Audiences

Often a webpage will appeal to one type of audience, but will alienate another. Consider a functions venue that accept bookings from wedding parties and night-club promotors.

  • Wedding parties might think that a nightclub venue would be trashy.
  • Night club patrons might think that a weddings venue would be uncool.

A generally accepted design pattern is to have:

  • General Landing Pages: pages that appeal to the widest possible audience which contain areas to more specialised "sub-areas" or "sub-pages".
  • Sub Pages / Areas: pages that are customised to appeal to a particular audience.

This process can be repeated for sub-sub groups, particularly in large organisations. For example, Crown Casino has a diverse and complex business structure and its website channels customers through a series of general and specialised landing pages before directing them to a final suitable page.

Accessibility ConcernsLect 3, P.16
It's not just a good idea that makes commercial sense, it's the law!

Disability Discrimination Act

Cow pilots with clumbsy hooves, unable to fly a plane built by racoonsThe Disability Discrimination Act makes it against the law to discriminate against someone on the basis of disability, including in the provision of goods, services and facilities.

The definition of disability is wide, but web developers need to be concerned with accessability needs related to:

  • Physical: Does your website discriminate those who cannot use a mouse or a keyboard? Make sure that users can use the tab key to navigate form elements, using tabindex={number} in input elements if need be.
  • Visual: Does your website have good contrast between background and foreground? Does it use readable fonts for large blocks of text? This is good practice for all users, but when catering for users with visual impairment and color blindness this is non-negotiable. A good website for theme generators and color blindness simulation can be found here: http://paletton.com.
  • Intellectual: When writing, make sure that your sentences are simple and concise. Some may pontificate on whether it is axiomatic to be propitious or eleemosynary when scrivening, tour competitors will be happy to take your customers who have no clue what you are saying.
Accessibility ConcernsLect 3, P.17

Your Responsibility

The Disability Discrimination Act does not require that web pages be restricted only to plain black and white Arial text, however, you must supply an effective, accessible alternative unless this is not reasonably possible.

It is technically feasible to remove many barriers to equal access for people in a way which does not detract from the usefulness or attractiveness of web pages to others. For example:

  • Provide a descriptive alt attribute in image tags.
    alt='cinema image' - Bad!
    alt='Young couple enjoying a 3D movie whilst eating popcorn' - Good!
  • Use a sensible amount of padding and margin around elements: not too little, not too much.
  • Color schemes should have good contrast. Do not create “rainbow” websites!
  • Supply a transcript or description for audio and video files, eg ABC 7.30 Report.
Lecture 3.2Lect 3, P.18

Part 2: Cascading Style Sheets

Cascading Style SheetsLect 3, P.19
  1. History of CSS
  2. Stylesheet Origins
  3. CSS Concepts
  4. Including CSS in a Web Document
  5. Cascading Nature of CSS
History of CSSLect 3, P.20

Structure v/s Presentation

In the very early days of the Web, the focus was on the delivery of information and content (ie scientific and engineering reports), there was little thought placed on styling content.

Various non-CSS techniques were tried to make Web pages look better:

  • Converting text to images.
  • Using images, empty tags, non-breaking white space for whitespace control and spacing.
  • Using tables for page layout.
  • Writing programs instead of using HTML.
  • Using style / presentation tags and attributes to change color, font, weight, borders and position.
  • Converting entire pages to images.

These techniques are bad!
Please do **NOT** use these ideas in your assignments!

Håkon Wium Lie, a W3C member and co-worker of Tim Berners-Lee, realised that styling would be an important consideration and was worried that the web might become a giant fax machine. He co-developed the first version of Cascading style sheets between 1994 and 1996.

History of CSSLect 3, P.21

Structure v/s Presentation

Mixing structure with presentation has long been considered bad programming practice and can create "spagetti" like code.

CSS makes it easy to organise all the presentation: positioning, white-space, padding, margin; font family, weight, size; colors used for text, background; hover states etc.

A single stylesheet (or a small number of stylesheets) can be applied to an entire website and create a uniform look and feel across all pages.

Designing a webpage to adapt to different devices (PC, tablet, phone etc) is made simpler using customised stylesheets for each type of device.

Client browsers, particularly those used by people with disabilities, can filter out irrelevant style if not included as HTML markup. For example, COLOR=RED is a deprecated style attribute that is not useful for a blind person's text reader or a search engine.

Stylesheet OriginsLect 3, P.22

Stylesheet Origins

Style sheets may have three different origins: user-agent, author, user.

  • The user-agent, ie the web browser manufacturer, must provide a default style sheet. This is usually black text on a white background, a larger bolder font for headings, simple dot points for lists, blue and purple underlines for hyperlinks. These styles are applied first, ie as a starting point.
  • The author, ie the developer, specifies style and stylesheets for a source document, defining a preferred presentation. This is the only area of CSS we have any control over and is the focus of this course. These styles are applied next.
  • The user, ie the client, may specify their own style sheet. For example, people with vision impairment will use a high contrast stylesheet. These styles are applied last.
Stylesheet OriginsLect 3, P.23

User-Agent v/s Author Styles

We will look at embeded stylesheets shortly, but for demonstration purposes, the following webpage contains an embedded stylesheet that removes the default user-agent styles in the browser you are using and replaces them with one uniform author style.

To view the plain user-agent styles, delete all of the author style contained between the <style> tags in the <head> element in the text area below before clicking the "Try it" button.


Stylesheet OriginsLect 3, P.24

User Styles

Below is an example of what Google's home page looks like using a high contrast user stylesheet. User styles override all styles set down by the user-agent (the browser) and the author (the developer).

high contrast screenshot

It is important to make sure that your website always caters for people with vision difficulties. Do not assume the visually impaired will have access to their own stylesheet! Even knowledgable users will have to use un-customised computers periodically.

CSS ConceptsLect 3, P.25

A CSS Property

CSS properties are set by specifying a property and value pair, followed by a semi-colon:

property: value;

Examples (most effects are self-explanatory):

  • color: green; (text becomes green)
  • background-color: cyan;
  • font-size: xx-large;
  • text-align: center;
  • border: thick red dotted;
  • padding: 2px 10px;
CSS ConceptsLect 3, P.26

Selector, Property and Value

A selector in a style sheet contains one or more CSS properties within a pair of curly braces:

selector { property: value; ... }

Example (styles all paragraphs in a document):

p {
  color: green;
  background-color: khaki;
  font-size: 110%;
  text-align: center;
  width: 80%;
  border: thick red dotted;
  padding: 2px 10px;
}

All paragraphs would be styled like this, but to demonstrate the concept, only this paragraph is styled using a class selector (more about that later).

CSS ConceptsLect 3, P.27

Grouping

When several selectors share the same declarations, they may be grouped as a comma-separated list:

h1 {
  font-family: sans-serif;
}
h2 {
  font-family: sans-serif;
}
h3 {
  font-family: sans-serif;
}

Can be grouped like this:

h1, h2, h3 {
  font-family: sans-serif;
}

Each of the three largest heading elements will be styled with the plain "sans-serif" font.

CSS ConceptsLect 3, P.28

Styling id and class Elements

Styling an element with a particular id is possible using the # character and the id value:

#eOOOOO {
  color: red;
}
<p id='eOOOOO'>"Your" paragraph will have red text.</p>

"Your" paragraph will have red text.

Styling elements with a particular class is possible using the . character and the class value:

.strike {
  text-decoration: line-through;
}
<p class='strike'>This paragraph will be struck out.</p>

This paragraph will be struck out.

<p id='eOOOOO' class='strike'>Both styles are applied: red and struck out!</p>

Both styles are applied: red and struck out!

CSS ConceptsLect 3, P.29

Inherited & Initial Styles

Property values are normally inherited by child elements, but this is not true for all styles. More often than not, if it "makes sense", styles are inherited.

This paragraph text is green and a little larger, so to is this child <em> element as it has inherited these styles from its parent without any CSS declarations.

If you want to remove an unwanted inherited style. Use the initial declaration value to restore the style property to its initial unstyled value:

span { color: initial; font-size: initial; }

This paragraph text is green and a little larger, but this child <em> element has normal sized black text because these properties are set to initial.

If a property you want inherited is not inherited, you can force an element to inherit a style from the parent using the inherit declaration value. For example, to set <options> in a <select> box to the same color as the <div> that they are in, two sets of inheritance are required:

select, option { color: inherit; }

CSS ConceptsLect 3, P.30

Comments

You can have multi-line comments inside a CSS by placing comments between /* and */ markers.

/* Code sourced and adapted from:
w3schools.com/css/css_syntax.asp */
p {
  color: red;
  text-align: center;
}

Unfortunately, commonly used single line comments found in other languages are not supported in CSS:

// This doesn't work and will generate an error in CSS.
 # Same is true for this attempt at a single line comment.
CSS ConceptsLect 3, P.31

Browser Rendering Differences

wrong electrical plugInternet Explorer, Opera and Firefox were all guilty of ignoring the standard set out by the W3C and did things “their own way” before 2000.

But by 2010, adhering to W3C standards had made a comeback, thanks to competition from Safari and Chrome. Content today is being rendered more reliably in all browsers, but differences still exist.

Web browsers are constantly evolving and do not support all CSS3 styles, particularly the advanced CSS3 styles. To make sure advanced styles work effectively in the maximum number of browsers, a developer should add vendor-prefixed styles as a fall back, as not all users have access to the most up to date versions of the browser.

For example, when using the new flex layout style, it is advisable to include all vendor prefixes before the compliant version:

#element {
      -o-flex: 1; /* Opera */
     -ms-flex: 1; /* Microsoft */
    -moz-flex: 1; /* Firefox (Mozilla) */
 -webkit-flex: 1; /* Chrome and Safari */
         flex: 1; /* Fully compliant browsers! */

Even today, it is still important to check cross-browser compatibility of HTML and even simple CSS across a range of browsers before final deployment.

Including CSS in a Web DocumentLect 3, P.32

CSS - Locations

There are three ways of adding CSS information to your web page:

  • INLINE: no better than markup, avoid it!
  • EMBEDDED: applies to one page only.
  • EXTERNAL: applies to many pages, use it!
Including CSS in a Web DocumentLect 3, P.33

CSS: Inline

Style directives can be attached directly to a single HTML element using the style='...'attribute:

<p>The next paragraph will be styled using <strong>inline</strong> CSS:</p>
<p style='font-size: xx-large; font-weight: bold; color: red;'>
   Styled using inline style.
</p>

The next paragraph will be styled using inline CSS:

Styled using inline style.

Including CSS in a Web DocumentLect 3, P.34

CSS: Embedded

Style directives can be attached directly to a single page and apply to all HTML elements in that page.

The style sheet is embedded inside the <head> element of a document between <style> tags:

<head>
  ...
  <style>

  /* Style directives go here */

    p { color:red; }
    #eOOOOO { ... }
    ...
  /* End of stylesheet */

  </style>
  ...
</head>
Including CSS in a Web DocumentLect 3, P.35

CSS: External

The best way to include style into a web document is using external stylesheets in separate files. The recognised file extension for a stylesheet is .css.

The stylesheet is included inside the <head> element with a <link> element:

<head>
  ...
  <link rel='stylesheet' href='mystyle.css' type='text/css' />
  ...
</head>

This allows you to link common stylesheets to all of your pages and create a uniform look and feel across all webpages in your website.

For example, these slides include five external stylesheets:

Including CSS in a Web DocumentLect 3, P.36

CSS: Common Pitfalls

When you create an external stylesheet, just write simple declarations inside that file. Do not embed them inside <style> tags:

<style> ← Don't put this tag in a .css file
  h1 { font-weight: bold; }
  p { font-size: 12pt; }
  span { color: red; }
</style> ← Don't put this tag in a .css file
      

Avoid embedded stylesheets when developing a consistant look and feel across multiple website pages. Embedded stylesheets are helpful for developing and page specific styling only.

Inline style is helpful when testing a single element's style during development, avoid using inline style on production servers as it is hard to maintain.

<p style='...'>Try not to use inline style ...</p>

Cascading Nature of CSSLect 3, P.37

Style Conflicts

Often two or more style selectors will exist as candidates to style a particular page element and so a browser needs to follow rules to make a decision as to which style to apply. For example:

* { color:red; }
Will render all text red.

p { color:orange; }
Will render all paragraph text orange.

.approved { color:green; }
Will render text in all elements of class "approved" green.

#eOOOOO { color:blue; }
Will render text in your unique element blue.

Question: What color will the text be in the element below?Answers are on the next slide!

<p class='approved' id='eOOOOO'>What color will I be?</p>

Cascading Nature of CSSLect 3, P.38

Competing CSS Selectors

As a rule, the "winning" style is determined by how specific the selector is, ie the more precise the selector, the more likely the style will be applied, for example:

* { color: red; }
Very general: All text will be red as a starting point.

p { color: orange; }
Somewhat precise: All paragraph text will become orange, text outside paragraphs stays red.

.approved { color: green; }
Quite precise: Text in class='approved' elements will be rendered green.

#eOOOOO { color: blue; }
Precise: One element is specified, so the element's text will be rendered blue.

Cascading Nature of CSSLect 3, P.39

Specificity Calculation

Specifically, the specificity calculation works like this:

  • 🥇 The declaration with the most ids wins.
  • 🥈 If there's a tie, the declaration with the most classes, pseudo classes and attributes wins.
  • 🥉 If there's another tie, the declaration with the most elements and pseudo elements wins.
  • 🎽 If all declarations seem to be equal, the selector that was found last is applied.

In an absolute emergency (eg if it is 3.55am and you have a 4am deadline), there is a overriding delaration you can use: the !important declaration will give the style precedence over all other selectors, for example:

* { color: purple !important; }
Override: Ignore every other style, make all the text purple!

Links to a visually friendly calculator and the exact W3C rules for specificity are below:

https://www.w3.org/TR/css3-selectors/#specificity
https://specificity.keegan.st/

Welcome!Lect 4, P.1

Web Programming
COSC2413 / 2426 / 2453

Lecture 4 - CSS 2

Lecture 4.1Lect 4, P.2

Part 1: Advanced Selectors & Color

Cascading Style SheetsLect 4, P.3
  1. CSS Contextual Selectors
  2. CSS Pseudo Selectors
  3. CSS Advanced Selectors
  4. Color Models
Contextual SelectorsLect 4, P.4

Descendent Selectors

Contextual or Combinator selectors allow us to select smaller groups of elements rather than styling all elements of a particular type.

The descendent selector starts with the topmost element and is followed by one or more descendent elements. For example:

nav a { color: red; }

All <a>s inside a <nav> element have red text color.

main a { color: green; }

All <a>s inside a <main> element have green text.

main li em { color: purple; }

All <em>s inside <li> elements inside the <main> element will have a purple text.

In these slides, the code examples are colored* by nested spans:

code { color: blue; }
code span { color: red; }
code span span { color: green; }

*Colors are approximate, we will look at colors in more detail shortly!

Contextual SelectorsLect 4, P.5

Direct Descendent Selectors

We can also select direct descendents, that is just the direct child elements using the > character instead of a single space:

p > em { color: red; }

Will style ...

<p><em>this element</em></p>

... but not ...

<p><strong><em>this element</em></strong></p>

... because it is a child of the <strong> element and a grandchild of the <p> element.

Contextual SelectorsLect 4, P.6

Sibling Selectors

We can select elements that come after a sibling element using the ~ character:

pre ~ p { color: saddlebrown; }

This paragraph, unlike the first paragraph, comes after a <pre> element and so the text is styled with saddlebrown color.

As does this paragraph and would any other paragraph that follows.

This <div> element misses out on the styling though :-( .
Contextual SelectorsLect 4, P.7

Adjacent Selectors

We can also select an element that directly follows another element using the + character:

p + p { color: purple; }
p + p + p { color: red; }

This paragraph won't be styled because it follows a <pre> element.

This paragraph will have purple text because it follows a paragraph.

This paragraph follows two paragraphs, so the "more specific" adjacent selector is applied and text will be red.

This paragraph also follows two paragraphs, so text will be red, unless a more specific adjacent selector is present.

Pseudo SelectorsLect 4, P.8

Pseudo Class

Pseudo class selectors select elements depending on their state.

The : character is re-used to separate the element from the state. Make sure you don't use a space!

selector:state { property: value; }
Pseudo SelectorsLect 4, P.9

Styling Hyperlinks

Arguably the most common example of pseudo class styling is to style hyperlinks to indicate whether the link has been visited before, and to respond to user & mouse events.

For example, both unvisited and visited links in the main part of these slides are styled with a darker green color:

a:link, a:visited {
  color: darkgreen;
}

And when a link has a mouse hovering over it, or when the link is active (ie being clicked), or when a link has the focus, it will be with a normal (lighter than dark) green color:

a:hover, a:active, a:focus {
  color: green;
}

Please Note: Most touch screens cannot detect a finger-based hover state.

Pseudo SelectorsLect 4, P.10

Styling Position

Pseudo class selectors can also select elements depending on where they are located in the document. For example, a first, a last, an 'nth' or every ‘nth’, odd and even elements (useful for "striped" table rows).

li:first-child { ... }
li:last-child { ... }
li:nth-child(7) { ... } ← 7th list item
li:nth-child(2n) { ... } ← even numbered items
li:nth-child(2n+1) { ... } ← odd numbered items

Pseudo SelectorsLect 4, P.11

Pseudo Elements

What we have seen are pseudo classes, that is where pseudo style is applied to an entire element based on its state.

There are times where we apply pseudo style to an element and in doing so we create a new sub-element. These sub-elements are called pseudo elements.

Developers should use two colons in CSS3 :: when designating a pseudo element selector, but this was unnecessary in previous versions of CSS:

selector::sub-element { property: value; }

Why the developers of CSS3 made a decision to create a distinction between pseudo classes and pseudo elements is a puzzling question, especially when it was not required before. Most browsers are smart enough and kind enough to render pseudo element styles when only one colon is used. Hopefully this decision will be reversed in a later version of CSS.

Pseudo SelectorsLect 4, P.12

First line and First letter

To style the first line of a paragraph use ::first-line:

p::first-line {
  color: darkcyan;
  font-style: italic;
  font-size: 120%;
}

Why the developers of CSS3 made a decision to create a distinction between pseudo classes and pseudo elements is a puzzling question, especially when it was not required before. Most browsers are smart enough and kind enough to render pseudo element styles when only one colon is used. Hopefully this decision will be reversed in a later version of CSS.

To style the first letter of a paragraph use ::first-letter:

p::first-letter {
  color: darkcyan;
  font-size: 200%;
}

Why the developers of CSS3 made a decision to create a distinction between pseudo classes and pseudo elements is a puzzling question, especially when it was not required before. Most browsers are smart enough and kind enough to render pseudo element styles when only one colon is used. Hopefully this decision will be reversed in a later version of CSS.

Pseudo SelectorsLect 4, P.13

Selection

To change the selected text color in a paragraph, use ::selection:

p::selection { 
  color: rgba(0,0,0,0);
}

Try selecting text in this paragraph. Can you see it disappearing? Do you think this style will stop people copying your work?

We will look at rgba(...) color later in the lecture.

Pseudo SelectorsLect 4, P.14

Before and After, plus Content and Url

To insert content before and after a paragraph, use ::before, ::after and content: " ... ":

p::before, p::after { 
  content: " \" "; 
  color: darkcyan;
  font-weight: bold;
  font-size: 150%;
}

The opening and closing quotes are inserted using CSS.

If using meta characters such as quote characters in content, escape the character or unicode hex sequence with a \ character.

p::after { 
  content: " \2764 "; 
  color: darkred;
  font-weight: bold;
  font-size: 150%;
}

This paragraph uses CSS to end with a dark red heart ...

Finally, content such as an image can be imported using url(...):

p::before { 
  content: url('shapeRMIT.png');
}
Advanced SelectorsLect 4, P.15

Attribute Selectors

Elements can be styled by looking at their attributes. This is done using square brackets:

selector [ attribute ] {  ...  }

For example: input[required] { ... } will style input fields with the required attibute set so that users know they are important fields that must be filled in.

You can also look at the value of the attribute using an operator and optional quotes. For example:

input [type='text'] styles just the inputs that are text boxes.

a [target='_blank'] styles hyperlinks that will open in a new page.

a [href^='http'] styles external hyperlinks, ie hyperlinks that begin with the characters 'http'.

a [href*='~eOOOOO'] styles your website hyperlinks, ie hyperlinks that contain the characters '~eOOOOO'.

img [alt='duck'] styles images that contain a whole word in the alt attribute (ie duck will be styled, but ducks will not).

Advanced SelectorsLect 4, P.16

HTML5 State Selectors

More pseudo states were introduced in HTML5 to make styling form elements easier, particularly form elements. For example:

input:invalid, select:invalid styles input and select elements that have invalid selections.

The search box in these slides has an invalid style. Can you work out what it is and when it is triggered?One character is invalid but zero characters or more than one character is valid. Background becomes red when invalid.

input:valid, select:valid ie the opposite of above, styles input and select elements that have valid selections.

input:checked styles radio buttons and checkboxes that have been selected. Will style future elements that implement the checked attribute too.

input [type='number']:out-of-range styles number inputs with values outside the min and max range. There is also a new :in-range pseudo selector you can use.

Color ModelsLect 4, P.17

How Humans See Color

WhereRainbowRises

one octave on piano keyboard represented with keys colored from colors of the rainbow
Humans are not very good at seeing colors. For those who understand music and frequency concepts, the rainbow in the photograph on the left represents just one octave of color on the elecro-magnetic spectrum, illustrated in the graphic on the right. Birds and insects see a wider and more colorful rainbow than humans.

three piano keyboard keys representing human visible colors of the rainbow
Not only that, even though we humans think that we can see all of these colors, we can only see three of these colors: red, green and dark blue (indigo), ie the primary colors, illustrated in the image on the right (see image right), and less if we are colorblind.

All other colors on the rainbow, ie orange, yellow, cyan and violet, can be created (or "spoofed") by a combination of these three primary colors.

All other colors and shades are not on the rainbow, eg grey, white, pink, brown and purple. These are "made up" by our brains when we see real colors mixed together.

Color ModelsLect 4, P.18

Fooling the Human Brain

iPhone 4s placed under a microscope
iPhone 4s viewed under a microscope

It is easy to fool ourselves into thinking we are seeing a full color spectrum. Stadium screens, televisions, computer monitors and projectors, touch pads and smart phone screens can be built by putting down a close-knit grid of three repeating red, green and blue lights.

Each group of three lights, or channels, form a picture element, otherwise known as a pixel.

In the images left, we are looking at a white iPhone 4S screen through a microscope and we can see that there are no "white" pixels, just thin red green and blue LEDs that form square shaped pixels.

On the next slide we will look at a very simple Red Green Blue or RGB model that allows 16 different intensities in each channel, producing 4,096 different colors.

Values are hexadecimal (ie 0, 1, 2, ... 9, A, B, C, D, E, F).

Color ModelsLect 4, P.19

Pixel Color Simulator

The following simulator modifies the background-color of various div elements to simulate changes to a single pixel and overall screen color:

#000
#000
#000



#000

div { background-color: #RGB; }

The 3 div / rectangles on the left represent the 3 channels that make up each pixel. The rounded div / rectangle on the bottom represents the unmagnified iPhone screen. Between the two are range inputs / sliders that increase the brightness of the LEDs using Javascript and jQuery.

Try to match the following ridiculously named colors with the iPhone screen and note their hex value.

AquamarineBurlywoodDarkgoldenrodDimgrayHotpinkThistle

If you have some form of color blindness, please work with some else and share your perception of color. All developers need to know what color combinations do not work for those with color blindess.

Using #RGBA notation, you can set the alpha channel which gives your element 16 levels of transparency:

  • 0 = fully transparent (ie invisible)
  • 1, 2, 3, ... C, D, E = 14 levels of translucency
  • F = fully opaque (ie the default).
Color ModelsLect 4, P.20

21st Century Color

color picker with eyedrop toolIn the inspector (image right), you can examine an element's color with great precision. Most browsers will also let you select colors on screen with an eyedropper tool. A color logo can be sampled to create a coherent color palette.

Notice that the colors are represented in a more modern #RRGGBB and #RRGGBBAA formats. This model offers 256 intensity levels in each channel, producing over 16.7 million colors and shades (not counting translucency of course):

  • 7F16 =  7 x16 + 16 = 12710 (half power)
  • FF16 = 16 x16 + 16 = 25510 (full power)
  • D416 = 13 x16 +  4 = 21210 (~83% power)

Most humans cannot detect such small incremental changes in each channel. Can you see any color differences below?

#80F0E0#70E0D0#71E1D1.............#7FEFDF#80F0E0#70E0D0

In CSS3, a more user friendly color system was introduced to allow decimal or percentage numbers:

color: rgb(255,255,0);creates yellow text.

color: rgb(100%,0%,100%);creates purple text.

The inspector lets you know how to generate a color in any of these models.

Color ModelsLect 4, P.21

Hue Saturation Lightness Model

A more intuitive way of selecting colors is to first pick the color or hue. Hue is a number between 0 and 360 and represents the angle on the color wheel in degrees (below right). All of these colors are "on the rainbow", except for magenta (ie purple) and rose.

RBG color wheel
What hue value is red? [ ]
What hue value is yellow? [ ]
What hue value is cyan? [ ]

Once the hue is selected, we then select a percentage of how saturated it is (0% = grey, washed out; 100% = vibrant, strong color) and how light it is (0% = black, 50% = pure, 100% = white).

selector { color: hsl(270, 100%, 50%); )

The above produces a strong vibrant violet text color.

The following simulator modifies the background-colorof various div elements using the HSL color model:

Color ModelsLect 4, P.22

Hue Saturation Lightness Model

This time the range inputs control hue, saturation and lightness.

rgb(0,0,0)
rgb(0,0,0)
rgb(0,0,0)



hsl(0,0%,0%)

div { background-color: hsl(hue, sat, light); }

Activity 1: Adjust just the top two sliders. What colors can you create?Just Black. Without light, there is no color.
Activity 2: Set the bottom slider to full and adjust just the top two sliders. What colors can you create? Just White. Too much light washes out all color.
Activity 3: Set the middle slider to 100%, the bottom slider to 50% and adjust just the top slider. What colors can you create? These colors should be "rainbow" colors (plus magenta and rose). You will notice that the LEDs levels fluctuate between 0 and 255.
Activity 4: Set both the middle and bottom sliders to 50% and adjust just the top slider. What colors can you create? These colors are similar to Activity 3, except that the colors are not as intense or saturated. They are shades of the saturated colors we saw before and you will notice that the LEDs levels only fluctuate between 64 and 191.
Activity 5: Set the middle slider to 50% and the bottom slider to 90% and adjust just the top slider. What colors can you create? These colors are similar to Activity 3, except that they are a very light pastel shade. You will notice that the LEDs are almost on full power, fluctuating between 217 and 242.

Again, if you have some form of color blindness, please work with some else and share your perception of color.

Color ModelsLect 4, P.23

Transparency, Opacity and Alpha

Transparency is a computer intensive operation and was introduced in CSS3. The browser must keep a record of what objects are laid out below a transparent element with transparency (eg the body and html elements) and perform a color calculation for each pixel.

The term alpha and opacity mean the same thing but have the opposite meaning of transparency. Alpha can be declared as part of the rgba() and hsla() color models.

For example, these slides have a slight transparency, allowing the background to show through.

section > header { background-color: hsla(0, 85%, 90%, 0.85); }

Light pink with 15% transparency.

section > section { background-color: rgba(255, 255, 255, 0.9); }

White with 10% transparency, ie less transparent than the slide header.

Opacity can be declared independently of color and can be applied to other elements such as the <img> element.

img.watermark { opacity: 0.05; }

Will make all images of class 'watermark' 95% transparent.

Lecture 4.2Lect 4, P.24

Part 2: Styling Text & Borders, Understanding the Box Model

Cascading Style SheetsLect 4, P.25
  1. CSS Text Styling
  2. CSS Text Alignment
  3. CSS Box Model
  4. CSS Compact Declaration
CSS Text StylingLect 4, P.26

Font Family

To render text with a particular font, we use the font-family declaration. Multiple fonts can be declared, separated with commas. Quotation marks are optional, but are required for fonts with spaces in the name.

font-family: firstchoice, "second choice", lastchoice;

eg font-family: "Times New Roman", Times, serif;

A list of fonts is supplied so that if the client does not have the particular font we want pre-installed, text can be rendered in alternative more general fonts. The last font in a list should be the most general and be one of the following:

  • serif: A font with curly ends like this one.
  • sans-serif: A font without curly ends like this one.
  • monospace: A font with equal width characters like this one.

Font sizing is generally based on the height of a font. As you can see, different fonts have different letter widths and spacing, so alternative fonts can affect layout.

CSS Text StylingLect 4, P.27

Supplying Fonts

In CSS3, we can provide the client with the actual font to avoid subtle layout changes with a @font-face declaration. We provide a name for the font we will be using in stylesheets and the location of the font.

@font-face {
  font-family: startrek;
  src: url("fonts/Star_Trek_future.ttf");
}
...
<p style='font-family: startrek;'>Now I can use the Star Trek font.</p>

Now I can use the Star Trek font.

This can cause copyright issues, so make sure that you have sufficient rights. There are many free fonts available for commerical and non-commercial use. For example, in these slides I have used dafont.com to source the Star Trek and Museo fonts used in headings.

CSS Text StylingLect 4, P.28

Web Fonts

Google has created a resource of hosted free web fonts at fonts.google.com. Whenever you use these fonts, the client will request the font directly from google, ie you do not have to host these font files directly.

You can include the font using a <link> element in the <head> element

<link href='//fonts.googleapis.com/css?family=Indie+Flower' rel='stylesheet' type='text/css'>
<span style='font-family: "Indie Flower";'>Now I can use this linked indie flower font.</span>

Now I can use the imported indie flower font.

NB: When you go to Google's quick use instructions, you will see 'https://' at the start of their links.

Servers and browsers often have security concerns when mixing 'http://' and 'https://' resources in one page, resulting in blocked content and no fonts. To solve this problem, use '//' as shown above which allow the server and browser to select the best transmission protocol.

CSS Text StylingLect 4, P.29

Font Size

The size of a font can be set using the font-size property. Some units (pt, px, cm, mm) are absolute and do not change, others are relative and their final size is determined by the size of their ancestor elements (em, %, rem) or the size of the viewport / screen (vw, vh, vmin, vmax).

font-size: 20px;

There are also absolute and relative size words: small, medium, large, smaller, larger. If you love lazy clothing size labels, these are for you! ← NB: sarcasm

Below is a series of nested divs with fonts of equal unit size. To change the font-sizes, make a selection from this select box:

Outer Div.
Middle Div
Inner Div

These slides use relative font-size units as much as possible so that text can be resized in the navigation menu.

screenshot of navigation magnifying slider

CSS Text StylingLect 4, P.30

Font Style and Weight

Fonts can be given normal, italic, oblique styles using the font-style property.

p { font-style: italic; }

To change the font-style of just this span, make a selection from this select box:

Font weight can be "fine-tuned" using the font-weight property by providing words such as normal, bold, lighter, bolder or by providing a number between 100 and 900, but ending in '00' (ie it's just nine numbers and not all fonts will have 9 distinct weights).

p { font-weight: bold; }

To change the font-weight of just this span, make a selection from this select box:

CSS Text StylingLect 4, P.31

Line Height, Letter and Word Spacing

The height of a line can be adjusted using line-height property. Default line-height varies from font to font, but most fonts have a default height around 1.2 or 120%, leaving a 20% gap between lines.

p { line-height: normal; }

This slider will set the line spacing on this slide between 0 and 5.

Distance between letters can be adjusted using letter-spacing property. Although letter spacing varies from font to font, the browser recognises 0 as the default letter spacing. Positive values increase space, negative values decrease space.

p { letter-spacing: normal; }

This slider will set the letter spacing on this slide between -3em and 3em.

Distance between words can be adjusted using word-spacing property. Although letter spacing varies from font to font, the browser recognises 0 as the default letter spacing. Positive values increase space, negative values decrease space.

p { word-spacing: normal; }

This slider will set the word spacing on this slide between -3em and 3em.

CSS Text StylingLect 4, P.32

Text Decoration

Text can be given none, underline, overline, line-through styles using the text-decoration property.

p { text-decoration: underline; }

Why do we call it text-decoration and not font-decoration? That's a really good question ...

To change the text-decoration of just this span, make a selection from this select box:

CSS Text AlignmentLect 4, P.33

Horizontal Alignment

Text can be horizontally aligned initial, left, right, center, justify using the text-align property.

div { text-align: initial; }

To change the alignment of the text in this resizable div, make a selection from this select box:

Most of you should be familiar with left and right alignment, but are you just as familiar with the inital and justify options? What do they do? Why are they there? I'm sure that some of you know the answers already and can see that this is just more paragraph padding text, but let me describe those two properties in more detail and in an unordered list so you can see what happens to bullet points:

  • Initial: Text will be left aligned for languages that are written left to right (ltr) and right aligned for languages that are written right to left (rtl).
  • Justify: Text will be lined up neatly left and right with stretched spaces between words. The last line has 'initial' alignment and spaces will not be stretched.
CSS Text AlignmentLect 4, P.34

Vertical Alignment

Inline elements within a block (eg spans, small images) can be vertically aligned using the vertical-align property. It has many "fine-tuning" options to remove small spaces, but it is not as powerful as the block-level text-align property above. One practical application is to align images with inline text, eg logos.

img { vertical-align: middle; }

To align the image with the text below, make a selection from this select box:

School of Science at rmit orb RMIT University

CSS Text AlignmentLect 4, P.35

Text Indentation

The first line of a text-block (eg a paragraph) can be indented using the text-indent property.

p { text-indent: 1em; }

To indent or outdent the first line of text in this paragraph, make a selection from the select box that is located at the end of this paragraph, ie after all of these words which are only here to pad out this paragraph and make sure it flows onto two or more lines:

CSS Text AlignmentLect 4, P.36

Floating Content

css is awesome mug, with text escaping assigned boundariesWithin a block element, such as a paragraph or div, we can float an element such as an image to the left or right (but not center) and allow text to flow around it. In this example, images are floated left and text flows around and to the right.

img.mug { float: left; }

css is awesome mug, with text escaping assigned boundariesUnfortunately, what starts off as a nice effect can quickly go wrong! It's not just text that flows, all following content flows including other floating elements. Resize browser window if layout issues are not obvious.

Around 99% of page layout catastophies are caused by uncleared float styles on logos, navigation links etc. Use this style sparingly!

css is awesome mug, with text escaping assigned boundariesOne way to "stop the floats" is to assign an element after the floating element a clear style which can have values left, right, both where both clears left and right sides together.

div, blockquote { clear: both };

css is awesome mug, with text escaping assigned boundariesAlternatively, assign the parent element an overflow style to stop it from collapsing.

div, blockquote { overflow: auto };
Slide Options Attach clear: both styles to div and blockquote elements.
Attach overflow: auto styles to parent div elements.
Remove mug images.
CSS Box ModelLect 4, P.37

Box Dimensions

Every page element is considered to be a rectangular "box" and is rendered in an appropriate place on the screen. this applies to both block and inline elements.

Each box has internal content area, surrounded by padding to keep it away from the border. Finally, there is some margin to keep it away from the parent element's sides.

#demoboxmodel1 {
  width: 200px;
  height: 100px;
  padding: 20px;
  border: 10px #B63 ridge;
  margin: 1em;
}
...
<div id='demoboxmodel1'>Text inside demoboxmodel1</div>
Text inside demoboxmodel1
CSS Box ModelLect 4, P.38

Box Dimensions Example

Below is a screenshot of RMIT's balloon and the inspector's graphical rendition of its box model dimensions. It has been placed inside a larger box with geen dotted outline so you can see the margin clearly.

RMIT Balloon picture and inspector

Right-click on the image above and use the inspector to discover how wide or thick the following properties are. NB: width means actual content width:

width: [ ]
padding: [ ]
border: [ ]
margin: [ ]
Red Box: [ ]
CSS Box ModelLect 4, P.39

Absolute v/s Relative Sizes

How absolute sizes (px, cm, etc) are applied to the box properties is clear, but how relative sizes (%, em etc) are applied is less clear and varies. The style properties of the paragraphs below can be adjusted:

Set width:
Set height:
Set padding:
Set border:
Set margin:

width: Relative to parent element's width.

height: Relative to the parent element's height, but only if the immediate parent element has been explicitly sized.

padding: Relative to the parent element's width. All 4 sides will have the same thickness.

border: Has no inherited or percentage options. All 4 sides will have the same thickness if using em or rem units.

margin: Relative to the parent element's width with one difference: left and right margins of sibling elements will add, but top and bottom margins will collapse. This means horizontal spacing will be double that of vertical spacing. You can see this with the red boxes above. Just resize the window so that they flow onto two lines.

CSS Box ModelLect 4, P.40

Box Sizing Model

The box sizing model sets the content width to the width property. As padding and border are added, the box gets wider.

When using relative width, eg percentage sizes, the content is resized to be the same size as the parent's content. This makes layout design difficult when using relative sizes. For example:

#demoboxmodel2 {
  width: 100%;
  padding: 20px;
  border-width: 10px;
}

These properties will create a box 60px wider than the parent. This means 60px of the content is outside the parent's content area, more if margin is added.

In CSS3 a new property box-sizing was introduced which has content-box, border-box values. The content-box setting is still the default, but border-box sets the outside (ie border) to be the width and shrinks the content to fit.

div {
  ... same as above
  box-sizing: border-box;
}
The border-box setting reduces the width so that it fits neatly inside the parent element, as long as the child element has no margin!
CSS Box ModelLect 4, P.41

Calc function

In CSS3, the need for developers to calculate relative widths was recognised. Please note: Spaces are required inside the calc() function.

In the next example, we will add a 30px margin to the child element. We will then need to reduce the child width by 2 x 30px = 60px.

#demoboxmodel4 {
  margin: 30px;
  width: calc(100% - 2 * 30px);
  padding: 20px;
  border-width: 10px;
  box-sizing: border-box;
}

The calc function has reduced the box width to compensate for its margin. It is centered neatly inside the parent element.

CSS Box ModelLect 4, P.42

Min and Max Suffixes, auto margin

Many dimension styles also have a min- and a max- option that can be used in conjunction with proportionate dimensions, for example percentages.

#demoboxmodel5 {
  width: 50%;
  min-width: 300px;
  max-width: 600px;
}
This demo box will resize to be 50% of it's parent's width (ie the slide), but will never be wider than 600px or narrower than than 300px.

Finally, a box can be aligned left, right and centered if left and right margin dimensions are set to auto.

.boxcenter {
  margin-left: auto;
  margin-right: auto;
}

CSS Compact DeclarationsLect 4, P.43

Setting Multiple Dimensions (1)

Most dimension styles can be set using individual top, right, bottom, left settings, or by setting many at once. For example:

element {
  padding-top: 10px;
  padding-right: 10px;
  padding-bottom: 10px;
  padding-left: 10px;
}

Can be set with one declaration:

element {
  padding: 10px;
}

The same rule applies to the element's margin and border-width. Replace the word padding with the word margin or border-width.

CSS Compact DeclarationsLect 4, P.44

Setting Multiple Dimensions (2)

Sometimes we want our vertical margin to be different to our horizontal margin. For example:

element {
  margin-top: 10px;
  margin-right: 20px;
  margin-bottom: 10px;
  margin-left: 20px;
}

Two values will set the vertical sides, then the horizontal sides:

element {
  margin: 10px 20px;
}

The same rule applies to the element's padding and border-width. Replace the word margin with the word padding or border-width.

CSS Compact DeclarationsLect 4, P.45

Setting Multiple Dimensions (3 & 4)

Three values set the top, then the sides, then the bottom

element {
  border-top-width: 10px;
  border-right-width: 20px;
  border-bottom-width: 30px;
  border-left-width: 20px;
}

Becomes:

element {
  border-width: 10px 20px 30px;
}

Four values set the dimensions in clockwise order: top, right, bottom, left:

element {
  border-width: 12px 3px 6px 9px;
}
CSS Compact DeclarationsLect 4, P.46

Setting Border Color, Style and Width

Individual dimension rules apply to the border-color, and the border-style properties. Border-style has solid, dotted, dashed; groove, ridge; inset, outset; none, hidden values. For example:

element {
  border-top-color: orange;
  border-right-style: dotted;
}

But it is also possible to combine color, border & style if combining a single style of each. For example:

element {
  border: dotted orange 1px;
}

The above declaration will style all 4 sides with the same style, color and thickness, instead of making 12 individual declarations.

Welcome!Lect 5, P.1

Web Programming
COSC2413 / 2426 / 2453

Lecture 5 - CSS 3

Lecture 5.1Lect 5, P.2

Part 1: Layout Styling

Layout StylingLect 5, P.3
  1. CSS Position
  2. CSS Layout
  3. CSS Flex Layout
  4. CSS Grid Layout
  5. CSS Media Queries
CSS PositionLect 5, P.4

Static and Custom Position

In previous examples we have seen that elements are laid out in the same order that they appear in the document. This order is termed the "normal document flow" and the default positioning style is called static.

div {
  position: static;
}

However, we can position elements so that they are:

  • relative, which is like static, but the element can be moved relative to its original position.
  • absolute, which will position the element relative to the root HTML element, or an ancestor element that has non-static position. This element will scroll with the page.
  • fixed, which will position the element relative to the browser window. This element won't scroll with the page.
  • sticky, which allows the content to scroll when in view but "sticks" to the top or bottom of the parent container if the user scrolls too far, eg the navigation bar in these slides.
  • initial, which restores the stylesheet setting.
  • inherit, which takes on its parent setting.

Tip: Absolute and fixed styles will take the element out of the normal flow, so you may need to add margin and padding to ensure content clears these absolute and fixed elements.

CSS PositionLect 5, P.5

Top, Bottom, Left, Right

In order to move non-static elements, we need to specify how far to move them. These attributes are distances, so the usual px, %, em etc units can be used.

top: 5px;
bottom: 5em;
left: 5%;
right: 5vw;

Note that you just need to pick one or two of these: top and bottom control vertical placement (ie don't chose both); left and right control horizontal placement (ie don't chose both).

Adjust this span element's position

CSS PositionLect 5, P.6

Sticky positioning

Sticky positioning, position: sticky is a recent addition that combines static and fixed position styles, a feature previously possible only with javascript programming. It is fully supported in most modern browsers.

The images in the div element below are "sticky", they scroll with the page but stay onscreen within its parent's boundaries when top, bottom, left and right styles are introduced.

Modify top and bottom styles:

Scroll down ...

to ...

see ...

more ...

S
Ti
C
K
Y


Dont stop!

Keep going ...

the example isn't ...

finished yet ...





Ok, we are done!
CSS PositionLect 5, P.7

Z-Index

To arrange non-static positioned elements in 3D, elements need to have a z-index integer value. The higher the number, the more "on top" it is, with 0 being the default value. Values can also be negative if you want elements to be hidden behind static elements.

div.card {
  z-index: 0;
}

Each of the following draggable cards has a z-index (printed on the card).

Can you find the z-index: -1 card?

-1
0
1
2
3
4
5
6
7
8
9
CSS LayoutLect 5, P.8

Display Style

The display style provides a large range and growing number of different layout styles. These include:

  • inline, block, inline-block, run-in,
  • table, inline-table, table-row, table-cell,
  • none, initial, inherit,
  • list-element,
  • flex, inline-flex, grid, inline-grid.

eg display: block; displays an element as a block.

CSS LayoutLect 5, P.9

Block v/s Inline

Block elements and Inline elements can have their display setting changed using the display style:

nav li {
  display: inline;
}

Turns list elements inside a nav element into inline elements.

aside a {
  display: block;
}

Turns hyperlinks inside an aside element into block elements.

CSS LayoutLect 5, P.10

Inline Block

Content inside inline elements can split onto two lines, and block elements are put on their own line. Inline-Blocks allow an element to keep its internal layout fixed as a block but leaves it free to "float" along with content in its parent element as if it is inline "on the outside". For example, in this paragraph, there are a few <spans> that can be changed into block and inline-block elements.

span {
  display: inline-block;
}

Change spans in the top paragraph to

Handy Tip: Hyperlinks styled as inline-blocks in a horizontal navigation bar makes sure that the link text does not break across lines:

nav a {
  display: inline-block;
}
CSS LayoutLect 5, P.11

Display v/s Visibility

There is a difference between display: none; where the element is removed from the layout and visibility: hidden; where the element is made invisible but space for the element is not removed.

span { display: none; }
span { visibility: hidden; }

The display style of the text inside this span can be changed here and the visibility style of the text inside this span can be changed here

CSS Flex LayoutLect 5, P.12

Flex Display

Before the flex layout model was created in CSS3, a simple, intuitive and dependable layout model was difficult to create without using <table> elements which had good height and width resizing "built in".

Any logical area that has elements that conform to a flex layout will need a parent or containing element with the display: flex; style.

<div style='display: flex;'> ... child elements go here ... </div>

By default, the width and height of child elements will be adjusted as evenly as possible to fit on one line inside the parent flex element.

Change CSS style to display:

The width of this child element has been set to 80%, height is unset.
The width of this child element has been set to 80%, height is unset.
... me too ...
... ditto ...
The width of this child element has been set to 80%, height is unset.
CSS Flex LayoutLect 5, P.13

Flex wrap

The child elements of a flex element can retain their widths and flow onto multiple lines. Set the parent flex element's flex-wrap: wrap; style will shrink and grow to fit the height and width of the parent container

<div style='... flex-wrap: wrap;'> ... child elements go here ... </div>

In this case, the cell heights on each line will be kept the same (ie some rows may have taller and shorter child elements)

Change CSS style to flex-wrap:

The width of this child element has been set to 40%, height is unset.
... tall when wrapped ...
... short when wrapped ...
... short when wrapped ...
... tall when wrapped ...
The width of this child element has been set to 40%, height is unset.
The width of this child element has been set to 40%, height is unset.
CSS Flex LayoutLect 5, P.14

Flex horizontal alignment and spacing

When child elements of a no-wrap flex element do not fit neatly on a line, the alignment and spacing of elements can be adjusted. Set the parent's justify-content style.

<div style='... flex-wrap: nowrap; justify-content: flex-start;'>
  <div style='width: 30%'>The width of this child element has been set to 30%, height is unset.</div>
  ...
  <div style='width: 34%'>The width of this child element has been set to 34%, height is unset.</div>
</div>

Change CSS style to justify-content:

The width of this child element has been set to 30%, height is unset.
The width of this child element has been set to 30%, height is unset.
The width of this child element has been set to 30%, height is unset.
The width of this child element has been set to 32%, height is unset.
The width of this child element has been set to 32%, height is unset.
The width of this child element has been set to 32%, height is unset.
The width of this child element has been set to 34%, height is unset.
The width of this child element has been set to 34%, height is unset.
CSS Flex LayoutLect 5, P.15

Flex vertical alignment and spacing

Child elements of a flex element are stretched to fit the vertical space by default, but this can be changed. Set the parent's align-items to a different style than the default and the child elements natural heights are restored.

<div style='... align-items: stretch;'> ... child elements go here ... </div>

When child elements are of different sizes, the vertical spacing and alignment styling that you are looking for can be catered for.

Change CSS styles to align-items: and flex-wrap:

The width of this child element has been set to 20%, height is unset.
The width of this child element has been set to 25%, height is unset.
The width of this child element has been set to 30%, height is unset.
The width of this child element has been set to 35%, height is unset.
The width of this child element has been set to 40%, height is unset.
CSS Flex LayoutLect 5, P.16

Flex vertical alignment and spacing: align-content

When child elements span multiple lines and you want to retain a common height , a similar set of alignment and spacing options are available. Set the parent's align-content to a different style than the default and the child elements natural heights are restored.

<div style='... align-content: content;'> ... child elements go here ... </div>

Change CSS style to align-content:

The width of this child element has been set to 10vw, height is unset.
The width of this child element has been set to 15vw, height is unset.
The width of this child element has been set to 20vw, height is unset.
The width of this child element has been set to 25vw, height is unset.
The width of this child element has been set to 30vw, height is unset.
The width of this child element has been set to 35vw, height is unset.
The width of this child element has been set to 40vw, height is unset.
The width of this child element has been set to 45vw, height is unset.
CSS Flex LayoutLect 5, P.17

Flex growth

The width of flexible child elements, ie elements with no fixed width, can be set in proportion to one another. This space is calculated after any non-flexible child elements have been accomodated.

Set each of the child element's flex style with one number, the higher the number the larger the share of the parent's remaining width will be assigned.

<div style='display: flex;'>
  <div style='width: 150px;'>My width is 150px ... </div>
  <div style='flex: 0;'>My width is 0 share of 6 ... </div>
  <div style='flex: 1;'>My width is 1 share of 6 ... </div>
  <div style='flex: 2;'>My width is 2 shares of 6 ... </div>
  <div style='flex: 3;'>My width is 3 shares of 6 ... </div>
</div>
My width is 150px ...
My width is 0 share of 6 (1+2+3==6).
My width is 1 share of 6 (1+2+3==6).
My width is 2 shares of 6 (1+2+3==6)
My width is 3 shares of 6 (1+2+3==6)

A minimum width is usually intelligently calculated to accommodate content.

CSS Flex LayoutLect 5, P.18

Flex control

There is more to the child flex style, you can supply up to 3 numbers to control:

  • the way in which the child element grows and shrinks
  • minimum and maximum sizing
  • resizing with a box-size or content-size focus
flex: flex-grow flex-shrink flex-basis;

The differences are quite subtle and difficult to demonstrate here, the "right" combination of flex parameters for an application will vary considerably.

Trulli
Image taken from: https://www.w3.org/TR/css-flexbox-1/images/rel-vs-abs-flex.svg
CSS Flex LayoutLect 5, P.19

Flex order

By default, the order in which the child elements correspond to where they appear in the code. Flex allows us to change the layout order so that child elements can be placed differently to suit a screen layout without adjusting the HTML code.

order: ##;

In the example below, the <aside> has a fixed width and appears before the <main> and <nav> in the HTML code, but it is placed after these elements on the screen.

As long as there is sufficient room for the child elements, the <main> element will be 5 times wider than the <nav> element.

<header>
<aside>
<div> <header> </div>
<div style='display:flex; >
  <div style='order: 3; width: 150px;'>
    <aside>
  </div>
  <div style='order: 2; flex: 5;'>
    <main>
  </div>
  <div style='order: 1; flex: 1;'>
    <nav>
  </div>
</div>
<div> <footer> </div>
<nav>
<footer>
The content of these flex themed slides owe much to these more comprehensive tutorials.
They are highly recommended if you want to be fully familiar with all flexbox styles, tricks and tips.
https://css-tricks.com/snippets/css/a-guide-to-flexbox
https://www.w3schools.com/css/css3_flexbox.asp
CSS GridLect 5, P.20

Grid Layout

One criticism of the flex model is that it controls sizing and alignment in only one direction. If you want a two dimensional layout, the grid model may be a better choice.

<div style='display: grid;'>

The grid style also has an inline-block variant.

<div style='display: inline-grid;'>

Spacing between child elements or "cells" can be controlled individually or together in the parent element with these grid-gap styles.

row-gap: 10px;
column-gap: 20px;
gap: 10px 20px;
CSS GridLect 5, P.21

Grid columns and rows

The number and width of columns can be set in the parent element with the grid-template-columns style. Widths can be fixed, proportional or fractionally calculated. The code below gives us four differently sized columns:

grid-template-columns: 200px 1fr 2fr 15vw;

The number and height of rows can be set in the parent element with the grid-template-rows style. Heights can be fixed, proportional or fractionally calculated. The code below gives us four differently sized rows:

grid-template-rows: 100px 3fr 4fr 15vh;
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F

Display above grid as .

CSS GridLect 5, P.22

Grid alignment

The content inside child elements or "cells" can be aligned horizontally with justify-self and vertically with align-self styles.

Set the justify-self: and align-self: styles.

1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
0

Display above grid as .

CSS GridLect 5, P.23

Cell Spanning

Child elements or "cells" can be made to span rows and columns with grid-column, grid-row and grid-area styles.

The first value(s) is (are) needed to specify where the cells are to be placed, the second value(s) is (are) needed to specify where to end OR how many cells to span.

Cells 1, 2 and 3 have been made to span multiple rows, columns and areas below, other cells reflow onto newly created rows.

<div style='grid-row: 1 / span 4;'>1</div>
<div style='grid-column: 2 / span 3;'>2</div>;
<div style='grid-area: 2 / 2 / 6 / 4 ;'>3</div>;
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
0

Display above grid as .

CSS GridLect 5, P.24

Grid template

There is another type of grid styling which moves more of the structuring out of the HTML and into the CSS. First we assign the page elements we want to arrange in a grid grid-area names. In this example, we are looking at a body element's contents.

body > header { grid-area: hd; }
body > nav    { grid-area: nv; }
body > main   { grid-area: mn; }
body > aside  { grid-area: ad; }
body > footer { grid-area: ft; }

Next we assign the element names places inside a container's grid-template-areas. In the example below we place the named elements into a 3 x 3 grid inside the body element.

body {
  display: grid;
  grid-template-areas:
    'hd hd hd'
    'nv mn ad'
    'nv ft ft';
}

A very helpful and inspiring grid tutorial from Morten Rand-Hendriksen demonstrating how this approach can make your code clean and free from unecessary containers can be found here: https://www.youtube.com/watch?v=txZq7Laz7_4

The content of these grid themed slides owe much to these more comprehensive tutorials.
They are highly recommended if you want to be fully familiar with all flexbox styles, tricks and tips.
https://css-tricks.com/snippets/css/complete-guide-grid
https://www.w3schools.com/css/css_grid_item.asp
CSS Media QueriesLect 5, P.25

Screen size adaption

The media query selector allows us to apply different styles to different media (eg screens, printers, etc). In particular, it can be applied to resize widths of elements based on different screen sizes.

In the example below, a "mobile first" approach is taken with all panel widths set to 100% by default, forming a single column view. As the screen gets larger, see min-width values, the panels are resized so that they fit into two columns and finally three columns.

.mq-panels {
  display:inline-block;
  box-sizing: border-box;
  width:calc(100% / 1);
}

@media only screen and (min-width: 700px) {
  .mq-panels { width: calc(100% / 2); }
}
@media only screen and (min-width: 1000px) {
  .mq-panels { width: calc(100% / 3); }
}
1
2
3
4
5
6
CSS Media QueriesLect 5, P.26

Printer styling

Another useful feature is to restyle a page so that it is "printer friendly" when a user prints the page. Things to consider are:

  • Should some elements be removed, eg navigation, footer
  • Should some elements avoid page breaks inside, eg images, paragraphs
  • Should some elements be re-sized to fit onto A4, eg articles
@media print {
  header, footer {
    display: none;
  }
  p, img {
    page-break-inside: avoid;
  }
}
@media print and (orientation: portrait) {
  main article {
    min-height: 277mm;
  }
}
Lecture 5.2Lect 5, P.27

Part 2: Advanced Styling

Advanced StyleLect 5, P.28
  1. CSS Background Images
  2. CSS Background Gradients
  3. CSS Corners
  4. CSS Shadows
  5. CSS Transitions
  6. CSS Transforms
  7. CSS Variables
CSS Background ImagesLect 5, P.29

Background Images

Background images can be included using the background-image style which takes a url() value. The default setting is to repeat the background to cover the background.

div {
  background-image: url('parchment.jpg');
}
Resizable

Images with transparency are rendered above any flat background-color of the element. A compact declaration is used to set both below:

div {
  background: #FF9 url('rmit-orb-ghost.png');
}

Change the background color of the demo below:

Resizeable
CSS Background ImagesLect 5, P.30

Background Repeating and Position

Background repeating can be turned off by using the background-repeat style which takes values initial, repeat-x, repeat-y, no-repeat:

div {
  background-repeat: no-repeat;
}

Background images can be fixed using the background-position style which takes values left, right, center, top, bottom or numeric values.

div {
  background-position: center;
}
  • If using 1 word: The image will be placed there and centered in the other direction.
  • If using 2 words: The image will be placed in the desired vertical and horizontal placement. Make sure you specify a vertical and a horizontal position!

Change the repeating style of the demo below:

Change the background position in the demo below:

Resizeable
CSS Background ImagesLect 5, P.31

Background Size and Origin

The size of a background image can be controlled with the background-size style which takes values cover, contain, inital or numeric values such as percentages, pixels etc. If only one numeric value is provided, the width is set and the height is resized in the correct proportion.

div {
  background-size: cover;
}

Change the background size in the demo below:

When background-size is combined with background-position, we can change the resize focus point of an image. For example, if you would like the background to focus on the word "IS" in the "CSS is Awesome" box on the mug, it is located 55% to the right and 60% down from the top left corner.

Change the background focus point (ie background-position) in the demo below:

Resizable
CSS Background ImagesLect 5, P.32

Background Compact Declaration

If declaring many background styles in one compact declaration, the order is advisable and a / must be used to separate position from size. This compact declaration combines color, url, position and size into one:

div {
  background: #393 url('css-is-awesome.png') 55% 60% / cover no-repeat;
}

Below is a very tiny mug for you to resize:

CSS Background ImagesLect 5, P.33

Multiple Background Images

Why stop at one? Multiple background images can be placed in a single element, for example in these slides ...

RMIT cresent orb fragment + RMIT steps orb fragment + abstract art background = Combined background images

html {
  background-image:
    url('app/img/orb-cres.png'),
    url('app/img/orb-step.png'),
    url('app/img/abstract.jpg');
  background-repeat: no-repeat, no-repeat, no-repeat;
  background-attachment: fixed, fixed, fixed;
  background-position: left, right, center;
  background-size: 17vw, 17vw, cover;
}

Note that images declared later (eg abstract image) are placed under images declared earlier (eg orb fragment images).

CSS Background GradientsLect 5, P.34

Linear Color Gradient

We have already seen the simple flat background color declaration:

element { background-color: white; }

But we can also create color gradients for the background. The linear color gradient style needs a comma delimited list of parameters; a direction followed by a list of colors to blend:

p {
  background: linear-gradient(left, red, orange, yellow, green, cyan, blue, violet);
}

This paragraph background should have a rainbow starting with red on the left and violet on the right.

Here is a less vibrant example of using one opaque color and a semi-transparent color.

p {
  background: linear-gradient(top, hsla(180,10,50,1), hsla(180,100,50,0));
}

This paragraph background should have a solid cyan color starting at the top and fading downwards.

CSS Background GradientsLect 5, P.35

Tilted Color Gradients

Instead of specifying the incoming side, we can replace it with an angle. The angle is a little counter-intuitive: 180deg and top are equivalent.

ul { background: linear-gradient( 23deg, ...); }

Change the angle here:

  • 0deg: Bottom
  • 45deg: Bottom Left
  • 90deg: Left
  • 135deg: Top Left
  • 180deg: Top
  • 225deg: Top Right
  • 270deg: Right
  • 315deg: Bottom Right
  • 360deg: Bottom (again!)

NB: Only the compliant browser style is being updated. Non-compliant browsers will see a static vendor gradient instead.

CSS Background GradientsLect 5, P.36

Repeating Color Gradients

Gradients can be used to set up using the repeating-linear-gradient style. It is very similar to the previous style, except that colors after the first color have stop point numbers, ie the point where the color stops. These numbers can take be relative sizes (eg percentages) or absolute sizes (eg pixels) depending on what overall effect you want. In this example, a horizontal curtain effect is created with 10 folds, independent of the element width:

div {
  background: repeating-linear-gradient(270deg, #A00, #F00 5%, #A00 10%);
}
Resizable

To get "hard" stripes, put in extra copies of the colors with zero width. This removes the color blending effect between different colors. Note fixed size option used below.

div {
  background: repeating-linear-gradient(315deg, #A00 0px, #A00 10px, #F00 10px, #F00 20px);
}
Resizable
CSS Background GradientsLect 5, P.37

Radial Color Gradients

Radial gradients start at the center of an element and spread outwards to the edges. It takes a list of colors.

p {
  background: radial-gradient(red, white);
}
Resizable

If you want the gradient to stop at the sides rather than the corners, add the word closest-side:

p {
  background: radial-gradient(closest-side, red, white);
}
Resizable

If you want the gradient to have a cropped circular shape, add the word 'circle':

p {
  background: radial-gradient(circle, red, white);
}
Resizable
CSS Background GradientsLect 5, P.38

Repeating Color Radial Gradients

Radial gradients can also repeat using the repeating-radial-gradient style. In this example, a cloud like effect is created with 5 rings, independent of the element width:

div {
  background: repeating-radial-gradient( red, white 10%, red 20%);
}
Resizable

To get "hard" stripes, put in extra copies of the colors with zero width. This removes the color blending effect between different colors. Note circle and fixed size options used below.

div {
  background: repeating-radial-gradient( circle, red, red 20px, white 20px, white 40px);
}
Resizable
CSS CornersLect 5, P.39

Border Radius

Each corner can be curved with individual border-radius declarations or using a compact declaration as per the dimension rules we have seen earlier.

div {
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
  border-bottom-right-radius: 10px;
  border-bottom-left-radius: 10px;
}
div { border-radius: 10px; }
Make sure you put in extra padding!

When supplying multiple values in a compact declaration, the top-left corner is always first, but remaining order differs.

Adjust corners on box above:
CSS CornersLect 5, P.40

Round and Oval Elements

Values can be static (eg pixels) or relative (eg percentages).

div { border-radius: 50% }
RESIZABLE
50% = Circle or Oval
CSS ShadowsLect 5, P.41

Box and Text Shadow (or Glow)

rmit orb image“ No piece of art can ever be complete without drop shadows ”

- no one ever

Drop shadows (darker colors) or glows (lighter colors) can be applied to:

  • Inline and block elements using the box-shadow property
  • Text using the text-shadow property
  #demoshadow {  box-shadow: 1px 1px 3px 2px #333; }
#demoshadow p { text-shadow: 1px 1px 2px     #CC9; }
  • The first 2 numbers control the direction of the shadow. In this example, the box and text shadows are pushed right and down by 1 pixel.
  • The 3rd number controls the size of the 'blur' of shadow/glow (ie the fuzzy part). In this example the box shadow is 1 pixel larger than the text shadow.
  • The 4th optional number controls the size of the shadow/glow (ie the strong part). Only box elements have this option.
  • The last item indicates the color of the glow / shadow. In this example, the box-shadow is dark grey and the text-shadow is a dark yellow to match the text color.
CSS ShadowsLect 5, P.42

Inset and Image Shadow (or Glow)

rmit orb image“ A glow is just a shadow in a lighter shade ”

- every Disney prince and princess ever

The box-shadow property has one final option. Insert the word inset and the shadow appears inside the box.

#demoinsetshadow { box-shadow: inset 1px 1px 3px 2px #333; }

To give images with transparency a shadow or glow, use the filter: drop-shadow() style:

 img {  filter: drop-shadow( 1px 1px 4px #fff ); }

Like the text-shadow style, the first two numbers control the direction of the shadow, the third number controls the blur, and the final number controls the color.

For advanced users: The filter style can also modify opacity, color and contrast; invert, blur and enhance images. You don't need Photoshop to make simple modifications anymore!

CSS ShadowsLect 5, P.43

Inset and Image Shadow (or Glow) Example

rmit orb image“ Play with the shadow settings ”

- web programming staff

Shadow Settings { }

box-shadow: 0px 0px 0px 0px #000000;
text-shadow: 0px 0px 0px #000000;
filter: drop-shadow(0px 0px 0px #000000);
CSS ShadowsLect 5, P.44

Combined Highlight and Shadow

☁ Stylish Logo ☁

By combining two text-shadows, a highlight and a shadow, text can be made to look very 3 dimensional. Multiple shadows are separated by a comma.

#demoshadow3 p {
  text-shadow:
    -1px -1px  2px rgba(255, 255, 255,  1 ),
     6px  3px  3px rgba( 0 ,  0 ,  0 , 0.7);
}
  • The highlight is a white "glow" shadow coming from the bottom right corner.
  • The shadow is a translucent black shadow which allows the background color to come through.
CSS TransitionsLect 5, P.45

Transition period

Whenever a new visual style is applied to an element, the default visual change is immediate, for example a :hover state change.

A visual transition from one style to another over a period of time can be introduced using the transition style declaration. In the following example we add a 1 second style transition for all navigation link styles by adding transition to the contextual selector.

nav a {
  color: yellow;
  background-color: black;
  transition: 1s;
}

If the :hover state has different styles, each style will transit over a period of 1 second.

nav a:hover {
  color: black;
  background-color: yellow;
}

Sample Nav Link 1

CSS TransitionsLect 5, P.46

Transition selection and delay

To add different visual transitions to different properties, we can specify which style is to transit and how long the transition should take; each style and timing should be separated by commas. In this example, we speed up the background-color change.

nav a {
  ...
  transition: background-color 0.5s, color 1s;
}

Sample Nav Link 2

We can also introduce a delay to the transition using the transition-delay delaration. In the next example all transitions last 0.5s and are delayed by 0.5s.

nav a:hover {
  ...
  transition: 0.5s;
  transition-delay: 0.5s;
}

Sample Nav Link 3

CSS TransformsLect 5, P.47

2D Transforms

Elements can be rotated and translated in two dimensions using the transform CSS delaration. Multiple transforms can be specified using spaces to separate each transform.

h1 {
  transform: translateY(30px) rotate(4deg);
}
h1 + p {
  transform: translate(20px, -20px) rotate(-4deg);
}

By default, the origin or "pivot point", the point around which rotation occurs, is set to the center of the element. This position can be changed by setting the transform-origin CSS declaration

transform-origin:  50%  50%; /* Center (default) */
transform-origin:   0%   0%; /* Top left corner */
transform-origin: 100%   0%; /* Top right corner */
transform-origin:   0% 100%; /* Bottom left corner */
transform-origin: 100% 100%; /* Bottom right corner */
CSS TransformsLect 5, P.48

3D Transforms

Elements can also be rotated and translated in three dimensions using the transform CSS delaration. Translations need an extra z coordinate and rotations require an axis as well as an angle.

In order to have an effective 3D effect, a perspective declaration should be supplied, ie how far an imaginary viewer is away from the screen, and a perspective-origin, ie the position where the viewer is in front of the element being transformed.

#screen {
  ...
  perspective: 200px; /* Viewer 200px away from screen */
  perspective-origin: 50% 0%; /* Viewer centered at base looking up */
}
#story {
  transform: rotateX(15deg); /* Left / right axis of rotation */
  transform-origin: bottom;; /* Base is fixed, top falls back */
}
CSS TransformsLect 5, P.49

Animated card-flip example (1)

One useful application of 3D transforms is to generate a double sided card that flips when hovered over. Let's start with a simple nested structure: a parent element containing 2 child elements, ie a front side and a back side.

<div class='card3D'>
  <div>FRONT</div>
  <div>BACK</div>
</div>

Let's apply some basic styling so that all three elements are visually distinct.

div.card3D {
  border: dotted black thin;
  background-color: #ddd;
  box-sizing: border-box;
}
div.card3D > div:nth-child(1) {
  border: 4px red groove;
}
div.card3D > div:nth-child(2) {
  border: 4px blue groove;
}

FRONT
BACK
CSS TransformsLect 5, P.50

Animated card-flip example (2)

Next let's add padding and set dimensions for all three elements, make sure that overflowing content stays in the parent element.

div.card3D {
  height: 300px;
  width: 200px;
  padding: 5px;
  overflow: auto;
}
div.card3D > div {
  height: calc(100% - 10px);
  width: calc(100% - 10px);
  box-sizing: border-box;
  padding: 5px 10px;
}

FRONT
BACK
CSS TransformsLect 5, P.51

Animated card-flip example (3)

Next step is to place both sides in the same place and on top of each other. Let's put some relative positioning on the parent and absolute positioning on the children.

div.card3D {
  position: relative;
}
div.card3D > div {
  position: absolute;
}

FRONT
BACK

The FRONT and BACK are now the right size and on top of each other, removing the unwanted scroll bar from the parent element in the process.

CSS TransformsLect 5, P.52

Animated card-flip example (4)

Let's put 3D rotations on each child with transformY() (ie we are rotating around the top / bottom axis). Whilst we are doing this, let's add some deliberately overflowing content to the back side and set its overflow style to auto.

div.card3D > div:nth-child(1){
  transform: rotateY(0deg);
}
div.card3D > div:nth-child(2){
  transform: rotateY(180deg);
  overflow: auto;
}

FRONT
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
End of BACK

Note that a scroll bar appears on the back side element.

CSS TransformsLect 5, P.53

Animated card-flip example (5)

Some :hover state styles would be helpful with transition delay too. The hover state will apply to the parent but the children will be styled, ie rotated by a further 180 degrees.

Another 3D transform style that will help us is backface-visibility, we can hide the child that faces away from us, the BACK side will be drawn on top of the FRONT side if not used.

NB: At time of writing, -webkit-backface-visibility is also needed in some browsers.

div.card3D > div {
  transition: 4s;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;

}
div.card3D:hover > div:nth-child(1) {
  transform: rotateY(180deg);
}
div.card3D:hover > div:nth-child(2) {
  transform: rotateY(360deg);
}

FRONT
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
BACK
End of BACK

And our preparation work is done! These cards are now ready to have content placed on each side and be styled.

Styling tips: 1) the parent element does not need to have a border or background, that is just scaffolding to help us see better; 2) a transition time of 4 seconds may be a little large (hint hint).

CSS VariablesLect 5, P.54

CSS Var() function

Most modern browsers support CSS variables, that is values for use and reuse inside a stylesheet. Value names must begin with the prefix --.

The example below creates a variable that has scope inside the root html element and all child elements. Note that values are NOT in quotes.

html { // or :root { ... }
  --brand-colour: #FACADE;
  --frame-effect: 6px ridge;
}

These values can be referenced in the stylesheet with the var() function.

nav a:hover {
  background-color: var(--brand-colour); // ie #FACADE
}
...
main aside {
  border:  var(--frame-effect) var(--brand-colour); // ie 6px ridge #FACADE
}

A second parameter can be provided as a fallback value in older browsers, circumventing the ease-of-maintenance feature that var() is meant to bring.

border:  var(--frame-effect, 6px ridge) var(--brand-colour, #FACADE);
Welcome!Lect 6, P.1

Web Programming
COSC2413 / 2426 / 2453

Lecture 6 - Javascript 1

Lecture 6.1Lect 6, P.2

Part 1: Javascript, Client Side Programming

Javascript - Client Side ProgrammingLect 6, P.3
  1. Introduction to Javascript
  2. Javascript Elements
  3. Operators
Introduction to JavascriptLect 6, P.4

What is JavaScript?

JavaScript is a scripting language which allows you to add interactivity to your web pages.

Originally developed by Brendan Eich at Netscape in 1995 under the names Mocha, LiveScript, then Javascript.

In the late 1990s and early 2000s, work to create a universal standard called ECMA script was stalled by Javascript’s popularity and competition from Microsoft’s jScript and Adobe’s Action Script.

Introduction to JavascriptLect 6, P.5

Don’t Get Confused!

JavaScript and Java have vaguely similar syntax, but are two completely different languages:

  • Java is a full-featured compiled programming language developed by Sun Microsystems.
  • JavaScript was developed by Netscape and was renamed "Javascript" as part of a licensing agreement with Sun Microsystems.

In 2006, Brendan Eich offered his opinion about Javascript being superseded by ECMAscript:

Some insist on using .es, but .es is not likely to become popular. ECMAscript was always an unwanted trade name that sounds like a skin disease.

Today, Javascript is the default client-side scripting language in HTML5

Introduction to JavascriptLect 6, P.6

What does JavaScript do?

JavaScript is a client-side scripting language, that is, it runs on the client machine, typically, in your web browser!

JavaScript is interpreted (evaluated line by line as it is run).

When a page loads or unloads, or as a user interacts with controls or any elements on a web page, an event is generated and an event-handler can run some code or call a javascript function.

Like CSS, javascript can be:

  • Written inline to run on the fly.
  • Embedded into a page (usually the head element).
  • <script> ... your javascript code here ... </script>
  • Stored in an External file, which can be linked to many pages (no <script> tags required in this case).
  • <script src="myScript.js"></script>

Some browsers will not have javascript enabled. You should put in a helpful message for these users (ie a prompt to run it on or alternative content

<noscript> ... helpful message for those without javascript enabled ... </noscript>
Introduction to JavascriptLect 6, P.7

What can I use JavaScript for?

Typical uses of JavaScript include:

  • Form validation
  • Pop-up boxes
  • Opening a new browser window (or several)
  • User behavior tracking (eg Google Analytics)
  • Games and Animation
  • Banner advertising
  • Simple calculators (home loan, blood alcohol)
  • Generating AJAX requests to the server

You have already seen a few examples in these slides:

  • Cute Kitten: interacting with the kitten activates audio elements.
  • Quiz Boxes: selecting an answer activates helpful (or snide) feedback.
  • RGB & HSL sliders: adjusting the slider changes the background color of elements, simulating a pixel channel or screen color change.
  • Menu Search: makes any slide with your phrase visible and hides all other slides.
  • Font Adjust: makes the <main> element font and child element fonts larger and smaller (ie most if not all fonts in the slides).

Why not use the search feature to find some of those slides? Just remember to clear the search field and you will be returned here ... ok, near here (still working on that).

Introduction to JavascriptLect 6, P.8

JavaScript Example

In this example:

  • The external javascript file tools.js is included with a script tag. Many HTML documents can include this file, so code that will be reused can be placed here.
  • A function called displayDate() is embedded in the <head> element and can be called anywhere in this page (and only this page.
  • Some inline javascript prints out the current year, with a <noscript> fallback.
Question: In the code below, what is printed when javascript is unavailable?Have a look for a reference to death and 70 years.

Javascript ElementsLect 6, P.9

Statement Blocks

A block of statements starts and ends with curly braces { ... }. Statement blocks can be nested inside other statement blocks

if(isHappy == true) 
{
  alert("I’m happy!");
  var answer = confirm("Are you happy?");
  if (answer == true) 
    document.write("You are happy too.");
}

Many languages use the curly braces, although Python is one of a few languages that relies on indentation to set statement blocks.

Javascript ElementsLect 6, P.10

Comments

To put in comments, javascript allows short comments that occur on one line or at the end of a line. These are denoted with //:

// This is a comment on one line or the end of a line

Or block comments that begin with /* and end with */:

/* This is a comment 
   on more than
   one line */
Javascript ElementsLect 6, P.11

Identifiers

Identifiers are the names of your variables, functions, arrays and objects. They must start with a letter or underscore and can contain letters and digits 0–9. Identifiers should be meaningful.

These are bad:

var a1 = 5; 
var array4Something = ['Morning','Afternoon','Evening'] 
function x3() { ... } 

These are good:

var numAttempts = 5; 
var daySegments = ['Morning','Afternoon','Evening'] 
function evaluateAttempt() { ... } 

Identifiers are unique within a page. Make sure that you don't do this, unless you like infinite loops and fast spinning computer fans:

for (var i=10; i<12; i++) {
  for (var i=0; i<2; i++) {
    console.log(i); 
  }
  console.log(i);
}
Javascript ElementsLect 6, P.12

Data Types

Javascript is a weakly typed language. When declaring a new variable or constant, it will pick what type it thinks best. You should use the following keywords.

  • var to create a new global variable (no scope limit within code).
  • let to create a new local variable (scope exists just for the current code block).
  • const to create an unchangable global constant (no scope limit within code).
Variable / Constant Types:
Number: integer, float, etc
String: a group of 0, 1 or more text characters
Boolean: true or false
Object: an array, object or unfortunately null:
Function: a variable can refer to a function, that is a block of code
Undefined: if it doesn't exist or is not set
var aNumber = 5;
var aString = '5';
let anotherString = "5";
const goldenRatioNumber =  1.61803399;
var aBoolean = true;
let anObject = [1,2,3,4,5];
var aFunction = function sayHello() { ... };
let aStudentObject = {id:'eOOOOO', type:'Ok I guess', ... };

We will look at objects and arrays in more detail next week.

Javascript ElementsLect 6, P.13

User Functions

Javascript has many inbuilt functions, and developers can write their own functions too.

Functions contain a sub-program or sub-routine that will not run until called. Functions can be called by other functions and by event handlers, such as when a page loads or when a user generated an event by interacting with the page. In an earlier slide, we saw a canvas object track a users mouse position and place virtual paint onto itself.

You can pass optional parameters, or an event object that is generated by the page element that called the function.

Good programming tip: A function should return something useful (eg a value or sting) or it should return a boolean (ie true or false) to let the caller know that the function executed successfully or failed.

function suitableFunctionName ( optional parameters ) {
  // code goes here
  // last line: return something, true or false
}
Javascript ElementsLect 6, P.14

Development: Logging and Alerting

context menu, inspect developer area Unlike Java and C, if there are any "compiler" errors, a user is not alerted in an obvious way; javascript will just stop running.

Modern day browsers have a developer area (Safari: you must enable developer mode in preferences) that can be accessed when right clicking in the browser and selecting "inspect" or "inspect element". Errors can be seen in the Console area.

To print an error to the console without halting the code execution, call the console.log() function. For example, if you click on this paragraph, a message will be logged to the console.

Sometimes you will want debug whilst halting the code execution. You can do this by calling the alert() function. For example, if you click on this paragraph, an alert box will pop up.

OperatorsLect 6, P.15

Math Operators

Math operators allow you to perform arithmetic operations on variables that are a type of number:

Basic Maths:
+ add / plus
- subtract / minus
* multiply / times
/ divide / ... share?
% modulus / remainder
var what_is = 19 {operator} 5;
What is 95? [ ]
What is 24? [ ]
What is 14? [ ]
What is 4? [ ]
What is 3.8? [ ]

Most languages also have an exponent operator, but javascript does not. Instead it has a Math library that allows you to perform more complex mathematical operations, for example:

var tenCubed = Math.pow(10,3);
OperatorsLect 6, P.16

Grouping Operations into a Block

For those unaware of PEMDAS, the order of operations is not always left to right and multiple operations in one statement can produce an unwanted result. For example:

$whatIs105 = 7 + 3 * 10 + 5;

will produce 42 and not 105. This is because the order of operations performs the later * operation before the earlier + operation.

To ensure that the operations are done in our desired left to right order, we must use parentheses (ie the 'P' in PEMDAS) to wrap the section we want evaluated first. Operations contained inside parenthesis have precedence over operations outside parenthesis.

$whatIs105 = ( 7 + 3 ) * 10 + 5;

For more information on the numbers 42 and 105, please visit https://en.wikipedia.org/wiki/42_(number) and https://en.wikipedia.org/wiki/105_(number)

OperatorsLect 6, P.17

Math Shortcut Operators

Most programming languages support shortcut operators when the variable is part of the operation. For example:

what_is = what_is + 5; is the same as what_is += 5;

And the same pattern works for -=, *=, /= and %=.

When adding or subtracting 1 from a variable:

what_is = what_is + 1; is the same as what_is++; (incrementing)

what_is = what_is - 1; is the same as what_is--; (decrementing)

OperatorsLect 6, P.18

Post & Pre Increment

There is a subtle difference between += and =+, and ++what_is and whatis++. When assigning or printing a variable in a statement block or a loop (we will look at loops soon), when the variable is updated is different. For example:

what_is = 0;
while(what_is < 5)
  alert(what_is++);
  
what_is = 0;
while(what_is < 5)
  alert(++what_is);

As you can see, when you alert:

  • whatis++: what_is is shown first and incremented by 1 afterwards (post-increment),
  • ++whatis: what_is is incremented by 1 first and shown afterwards (pre-increment).
OperatorsLect 6, P.19

String Operator(s)

Javascript allows you to join strings together using the string concatenation operator +:

var helloWorld = 'Hello' + ' ' + 'World!'

There are many string properties and functions built into javascript string objects which can be accessed using the . character. Here are a few examples:

Explore:
aString.length returns length of the string
aString.charAt(posn) returns the character found at a particular position
aString.indexOf(subString) returns position of subString within aString (or -1 if not a substring)
aString.includes(subString) similar to indexOf(), only a boolean true/false is returned
Manipulate:
aString.trim() returns a string with whitespace removed from both ends of the string
aString.toUpperCase() returns an uppercase version of the string
Disect:
aString.substr(start, num) returns a substring from specified position, extracting num characters
aString.split(delimiter) returns an array of strings split on a particular delimiter (ie character or substring)

There is even a concat() function if your keyboard doesn't have any working + keys on it:

helloWorld = 'Hello'.concat(' ').concat('World!')
OperatorsLect 6, P.20

Logical Operators

Javascript has three logical operators:

  • apples && oranges or apples and oranges
    true is returned if both are true, else false is returned.
  • apples || oranges or apples or oranges
    true is returned if either is true, else false is returned.
  • !apples
    true is returned if apples is false, else false is returned.
Evaluate !(!apples or !oranges) in another way [ ]
OperatorsLect 6, P.21

Comparison Operators

To test for equality or inequality of values:

  • 5 == 5
  • 5 != 4
  • 5 == "5"

To test for equality or inequality of values AND type:

  • 5 === 5
  • 5 !== "5"

And of course < (less than), <= (less than or equal), > (greater than), >= (greater than or equal)

OperatorsLect 6, P.22

Bitwise Operators

For specialist applications such as those involving flag checks, you can operate directly on the bits of 32 bit number variables. A 32 bit number is returned.

  • apples & oranges
    Compare each bit from both variables, return a 1 if both bits are 1, 0 otherwise.
  • apples | oranges
    Compare each bit from both variables, return a 1 if either bit is 1, 0 otherwise.
  • apples ^ oranges
    Compare each bit from both variables, return a 1 if bits are different, 0 if they are the same.
  • ~ apples
    Flip each bit, ie return a 1 if the bit is 0 and 0 if the bit is 1.
  • apples << n
    Move the bits to the left n times and return a number that is larger (value is doubled with each shift).
  • apples >> n
    Move the bits to the right n times and return a number that is smaller (value is halved with no remainder with each shift).

Here is an example, only the last 8 bits are shown:

     105 ^ 42       // is the same as
01101001 ^ 00101010 // evaluates to
     01000011       // is the same as
        67          // returned answer :-)
This is an advanced topic and won't be covered in detail in this course.
You won't need these in an eCommerce website for example!
OperatorsLect 6, P.23

Ternary Operator

Many languages offer a ternary operator that will return one of two values depending on the outcome of a test.

test ? true : false 

For example:

var whenDoes = ( 1==2 ? 'always' : 'never' )

This is a mini if - (then) - else statement. The above operator can we re-written as:

var whenDoes;
  if ( 1==2 ) { // '?' part
    whenDoes='always';
  } else {    // ':' part
    whenDoes='never';  
  }
OperatorsLect 6, P.24

The typeof operator

Javascript provides a typeof operator that checks a variable's type and returns a string describing its type. Often knowing a variable's type is required to branch code execution, particularly recursive and "tree walking" code.

var whatTypeAreYou = typeof aVariable;

What will be returned when testing the following variables?

typeof "";'string'
typeof 5;'number'
typeof 5.0;'number' (again). Javascript does not differentiate a float from an integer
typeof function () {} ;'function'. A variable can reference a function!
typeof wtv;'undefined' as the variable has not been created.

We will now create the variable wtv: var wtv;

typeof wtv;'undefined' as the variable has not been set.

We will now set the variable wtv: wtv = null;

typeof wtv;'object', which many believe is a mistake or fault in the standard.
typeof [3, 1, 4];'object', as any array is considered to be an object.
typeof typeof [3, 1, 4];'string', as the string 'object' is returned by the first typeof operator and passed to the second typeof operator.
OperatorsLect 6, P.25

Type Conversion Functions

At some point, you will need to convert a variable from one type to another, for example:

"5" + "3" = "53"; // not 8

You can use the following built-in javascript functions:

var aNumber = Number(aString);
var aString = String(aNumber);
var aFloat  = parseFloat(anInt);
var anInt   = parseInt(aFloat);

To get 8:

var eight = Number("5") + Number("3");
Lecture 6.2Lect 6, P.26

Part 2: Structures, Objects & Events

Structures, Objects & EventsLect 6, P.27
  1. Control Structures
  2. Handling Events
  3. Built In Objects
  4. Document Object Model (DOM)
  5. Form Validation
Control StructuresLect 6, P.28

Controlling Program Flow

Control structures help you control the flow of your program. In addition, we have structures which allow us to repeat actions. These are called loops.

if - then - else
This block allows us to make a decision and the else is optional.
switch - case - break
Similar to if - then - else block, more efficient when checking a single variable for many different values.
while and do - while
A simple loop that performs a condition check and allows the block to repeat
for and for - in
Similar to while loop, only incrementing is built in to the condition check
Control StructuresLect 6, P.29

Simple If Then Else

This block can be simple, with an optional else clause:

if ( condition check ) {
  // code to execute if condition evaluates to true
} 

and

if ( condition check ) {
  // code to execute if condition is true
} else {
  // code to execute if condition is false
} 
Control StructuresLect 6, P.30

Nested If Then Else

Blocks can be nested inside each other when performing more than one check:

if ( first condition check ) {
  // code to execute if first condition is true
} else if ( second condition check ) {
  // code to execute if only second condition is true
} else {
  // code to execute if both conditions are false
}

and

if ( first condition check ) {
  if ( second condition check ) {
    // code to execute if both conditions are true
  } else  {
    // code to execute if only first condition is true
  }
} else { 
  // code to execute if first condition is false
}

When performing more than two checks, code can become complex and it is very easy to mis-nest the blocks and get an incorrect outcome.

Control StructuresLect 6, P.31

Switch Case Block

This block is suitable when testing a variable for multiple values. Each mini "case-block" must be terminated with a break statement or it will run into the next case. An optional default option is to be run if no value is listed in the block:

switch ( aVariable ) {
  case value 1:
    // code to execute a variable has value #1
    break; 
  case value 2:
    // code to execute a variable has value #2
    break; 
  ...
  case value 105:
    // code to execute a variable has value #105
    break; 
  default:
    // code to execute if value not listed
}
Control StructuresLect 6, P.32

Run-on Switch Case Block

If the same code is to be executed for a set of values, the break statement can be ommitted to allow "run-on" execution.

switch ( dayName ) {
  case "Monday":
  case "Tuesday":
  case "Wednesday":
  case "Thursday":
  case "Friday":
    dayType = "Weekday";
    break; 
  case "Saturday":
  case "Sunday":
    dayType = "Weekend";
    break; 
  default:
    dayType = "Invalid";
}

Select Day:

These blocks can be nested when checking multiple values, but code can become very complex very quickly.

Control StructuresLect 6, P.33

While and Do - While Loops

A while loop will perform a check and run code if the check is returned true. The loop should be designed so the condition being checked changes in the loop. For example:

var sum1to99 = 0;
var count = 1;      
var stopCount = 100;      
while ( count < stopCount ) {
  sum1to99 += count;
  count++;
}

will add up all of the numbers from 1 to 99 and stop when count is incremented past 99.

A do - while loop is very similar except that the check is performed at the end of each loop, not the start. That is, you are guarenteed to execute the code in the loop at least once:

var sum1to99 = 0;
var count = 1;      
var stopCount = 100;      
do {
  sum1to99 += count;
  count++;
} while ( count < stopCount )
Control StructuresLect 6, P.34

For Loops

For loops combine an incrementer and a condition check into one area:

var stopCount = 100;
for ( var count = 1; count < stopCount; count++ ) {
  sum1to99 += count;
}

The incrementor can go up or down, or even increment in an exotic way. For example, to compute the natural note frequencies in an octave:

var oA = 440;
for ( var freq = oA; freq < oA*2; freq *= Math.pow(2,1/12) ) {
  var oscillator = audioCtx.createOscillator();
  oscillator.type = 'sawtooth';
  oscillator.frequency.value = freq;
  ...
}

Control StructuresLect 6, P.35

For Loops

For loops are particularly useful when processing each element inside an indexed array, for example when building up a response string to print out day names and what type of day it is:

var weekDays = ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Funday','Sunday'];
var dayMessage = '';

for ( var dayNum = 0; dayNum < weekDays.length; dayNum++ ) {
  dayMessage = weekDays[dayNum] + ' is a ';
  switch ( weekDays[dayNum] ) {
    case "Monday":
      dayMessage += 'hateful ';
    case "Tuesday":
    case "Wednesday":
    case "Thursday":
    case "Friday":
      dayMessage += 'week day';
      break; 
    case "Saturday":
    case "Sunday":
      dayMessage += 'weekend day';
      break; 
    default:
      dayMessage += '... what day is that?';
  }
  document.write(dayMessage + '<br>');
}

We will look at the for - in loop next week when we cover arrays.

Handling EventsLect 6, P.36

Events and Event Handlers

Events are actions that occur in a web browser (or other user agent). By convention, event handler attributes begin with the word on (see below).

Practically every element in a webpage can respond to an event, although load and unload events are restricted to <body>, <img> and multimedia elements.

<body onload='/* code to run when page loads */'>

The most common events to implement are to detect and respond to user interaction with the mouse and keyboard.

For example, to attach a mouse click event handler to this paragraph, add a new attribute called onclick and write a short code snippet inside, eg

<p onclick='alert("Mouse click detected");'>
  For example ... snippet inside, eg
</p>
Handling EventsLect 6, P.37

Objects: this and event

Javascript will recognise two words "by default" as references to objects involved with the generation of an event.

  • this: a reference to the originating element, ie from where the event was generated.
  • event: a reference to a more comprehensive event object created when the event was generated.

For example, when you click on this paragraph which has the id "thisevent", information about this paragraph will be presented in the alert box and information about the mouse event will be logged to the console.

<p id='thisevent' onclick='alert(this.id+": "+this.innerHTML); console.log(event);'>
  For example ... snippet inside, eg
</p>

The event object generated by an event contains a great deal of information including:

  • event.type: What type of event has been generated.
  • event.target: The originating element (equivalent to this above).
  • event.currentTarget: The calling element
  • event.clientX, event.screenY, event.pageX, event.pageYThe various locations of a click event, ie relative to the window, screen and page.
  • event.target.innerHTML: The content of a paired item (eg a paragraph or list item).
  • event.target.value: the value attribute of an element, ie most form elements.
Handling EventsLect 6, P.38

Event Handling Functions

To make HTML code more managable, you can set the event handler to call a function instead. For example, if you click on this paragraph or this child em element inside this paragraph, a function called inspectEvent() will run and log the event information to the console:

<p id='inspectEventDemo' onclick='inspectEvent();'>To make ... to the console:</p>
function inspectEvent() { 
  alert('Event of type "'+'event.type'+'" detected:\n- '
  +event.target.id+' (target = element that was clicked)\n- '
  +event.currentTarget.id+' (currentTarget = element making the call)\nView the console for more information');
  console.log(event);
}

NB: Whilst this is a reserved word and cannot be accidentally declared as a variable, event is a variable that can be over-written. That said, javascript will treat the word event as a "de-facto" reserved word, so you can refer to the generated event inside a function "auto-magically" as we can see in the example above.

Handling EventsLect 6, P.39

Mouse Events

The following list items will generate events that log information to the console. Each list item calls the inspectEvent() function we saw earlier.

  • click: A simple primary mouse button detection event.
  • dblclick: As above, but a double click detection event.
  • mousedown: When any mouse button is pressed and which mouse button can be determined from a passed event.
  • mouseup: When a mouse button is released.
  • mouseover: When the pointer enters an element.
  • mouseout: When the pointer leaves an element.
  • mousemove: When the pointer is moved, its position can be determined from a passed event. You may wish to disable further alert boxes!
Handling EventsLect 6, P.40

Keyboard and Related Events

Elements that accept user input, such as text boxes, textareas etc can handle keyboard and events below.

  • When a keyboard key is pressed, but not ALT, CMD, CTRL, ESC, FN, SHIFT, TAB keys etc).
  • As above, but any key; specifically when pressed down.
  • When any key is released.
  • When an element loses the focus.
  • When the field loses the focus and when the contents have been changed.
  • A new HTML5 event that is better designed and detects input events across a wider range of elements and devices (eg touch screens).
  • When a selection has been made inside the element - look for selectionStart and selectionEnd inside target!
  • When an element gets the focus - only one element can have the focus warning: this produces an infinite loop, test this one last!

Other elements, such as select boxes, radio buttons and checkboxes don't respond to keyboard events, but do respond to many of the other events above.

Handling EventsLect 6, P.41

Form Validation Event

When a user attempts to submit form data to a processing script, a submit event is generated and can be handled by a form's onsubmit handler.

Any function that returns false will block submission of form data and not submit, saving the server the trouble of having to process invalid form data.

<form action='...' method='...' onsubmit='return formCheck()'>

The return keyword is very important and essential to block submission!

We will look at an example of a form validation script shortly.

Built In ObjectsLect 6, P.42

Introduction

To carry out more complex JavaScript actions, we can take advantage of javascript's built-in objects. We have already seen the Math, Number and Date objects and some of their methods:

if ( isNaN(total) ) 
  alert("That's not a number");
else 
  alert('You owe $' + total.toFixed(2));
document.write('The time is ' + Date.now());

We will look at the RegExp object and its methods in detail shortly.

Built In ObjectsLect 6, P.43

Browser Object Model (BOM)

Many properties of the user's browser is available to a developer. They are grouped under the Window object:

  • Document: contains references to all elements in the page. We will look at this object in great detail shortly.
  • History: contains a list and count of the users visited urls.
  • Navigator: contains information on the browser, such as vendor, version, platform, geolocation etc.
  • Location: contains information about the server that is serving the current page such as name, protocol etc.
  • Screen: contains information about the user's screen such as size, orientation, color depth etc.

Click on the above elements to log them to the console!

Built In ObjectsLect 6, P.44

Accessing BOM

BOM objects properties and methods are structured in a branching tree-like structure. That is, some methods and properties are located inside other properties. All can be accessed using standard object referencing notation or by treating the object as an associative array:

alert(screen.width);
alert(screen['width']);
alert(screen.orientation.angle);
alert(screen['orientation']['angle']);

Many of the properties can be modified, as this fun website demonstrates: http://stewd.io/pong/.

window.open();
...
window.moveTo( xPos, yPos );
...
window.close();

Whilst some programming is performed using jQuery (a compact version of javascript), windows are opened, moved in response to keyUp events (arrow keys) and closed when going off screen.

Document ObjectLect 6, P.45

Document Object Model (DOM)

The document object is a map of all the elements on your page. For example, the following returns a tree like structure of all the elements in the webpage <body> element:

console.log(document.body);

To access the <main> element, ie the 3rd 4th element in the <body> element, you need to look at the children of the body element:

console.log(document.body.children[3]);

To access the 8th element inside the <main> (ie this lecture series on javascript), and its id, you need:

console.log(document.body.children[3].children[7]);
console.log(document.body.children[3].children[7].id);

Hopefully, you can appreciate that this is a very complicated and unmanagable way of referencing elements. Should the document ever change (Edit: Lol, it did recently!), the elements will be re-ordered and references to them will be incorrect.

Document ObjectLect 6, P.46

getElementById() Function

The document object has a method to find an element with a particular id. You can reference the lecture 6 slides in the following way:

document.getElementById('slides-lecture-6');

This is why it is important that elements never share the same id!

In particular, you will be looking for form elements and their values in your assignments. By giving your form elements an id as well as a name attribute means that javascript can access the element. Let us assume that a form element with id s1-qty contains the quantity of season 1 boxsets:

var s1-qty = document.getElementById('s1-qty').value;

Let us assume that a span with id s1-subTotal is where we need to put the season 1 subtotal, formatted to 2 decimal places:

document.getElementById('s1-subTotal').innerHTML = (s1-qty * s1-price).toFixed(2);
Document ObjectLect 6, P.47

Attributes: Name and Id

Form elements usually have a name and an id attribute.

  • name: For form submission. If there is no name, it will not be sent to the server in a form request.
  • id: For javascript manipulation. If there is no id, javascript will have trouble finding it.

Usually the names and ids are the same in form elements:

<input type='...' id='fname' name='fname' />

However, with radio buttons in the same group, names are not unique, so different ids must be used:

<input type='radio' name='gender' id='m-gender' value='male' />
<input type='radio' name='gender' id='f-gender' value='female' />
<input type='radio' name='gender' id='o-gender' value='other' />
Document ObjectLect 6, P.48

getElementsByTagName() Function

The document object has a method to find all elements with a particular tag name. You can find all the image elements in a page in the following way and they will be returned as an indexed array:

var allImgs = document.getElementsByTagName('img');

There are many examples of pages that pre-load all images with this script or something similar.

Document ObjectLect 6, P.49

getElementsByClassName() Function

The document object has a method to find all elements with a particular class name. You can find all the elements of a particular class in a page in the following way and they will be returned as an indexed array:

var allErrors = document.getElementsByClassName('error');

By selecting all elements on the page that have the class 'error', we can show or hide them.

Document ObjectLect 6, P.50

querySelector() and querySelectorAll() Functions

These two functions take a CSS selector string as a parameter and elements are selected in the same way that CSS declarations select elements. This makes them very useful and more powerful than the ones we have seen so far.

  • The querySelector() returns a single element, ie only the first if more than one match exists.
  • The querySelectorAll() returns an indexed array of elements, even if there is only one match.

How can we use these two query-selector functions in place of these simple selectors below:

document.getElementById('slides-lecture-6'); (a single lecture element with an id) document.querySelector('#slides-lecture-6');
document.getElementsByTagName('img'); (an array of image elements) document.querySelectorAll('img');
document.getElementsByClassName('errors'); (an array of error message elements) document.querySelectorAll('.errors');

What makes these selectors particularly powerful is that CSS selectors can use contextual, pseudo, attribute, etc. selectors to target a complex set of elements. For example, what does the following selector select?

document.querySelectorAll('#lecture-6 .key .qna'); This selector will look inside lecture-6 for just the "key" slides and return any of these "question / answer" elements that appear on those slides. As this "qna" element is not on a key slide, it will not be selected.
Form ValidationLect 6, P.51

Blocking Submission

When a user submits a form we’d like to make sure they have filled out fields correctly client side so that the server is not bothered by invalid requests.

If the user has filled the form incorrectly, we should indicate the error to the user and specifying the correct format of the input. HTML5’s new type and pattern attributes have made a lot of this redundant (now "built in" to the browser).

For this example, we are going to create a registration form for the "Project Steve" website:

http://www.skeptical-science.com/science/project-steve

Form ValidationLect 6, P.52

Accessing Form Elements

Open and examine the following website as we step through the following slides:

http://titan.csit.rmit.edu.au/~e54061/wp/ProjectSteve.html

You will observe that the form has:

  • A text field: name='name'
  • Radio buttons: name='scientist'
  • A PDF file: name='signDoc'
  • A submit button: // no name

In the form tag, you can see that the form:

  • Submits data to processing.php: action='.../processing.php'
  • Uses the post method: method='post'
  • Runs javascript whenever an onsubmit event is generated: onsubmit='return formValidate();'
  • Places the server response in a new tab (or window): target='_blank'
Form ValidationLect 6, P.53

Field and Sub-Functions in Example

There are a number of sub-fuctions present in this example:

  • getid(): Developer is very lazy and wishes to avoid typing "document.getElementById()" all the time.
  • clearErrors(): This function looks for all spans of class "error", makes them invisible and resets any form fields to a normal style.
  • nameCheck(): Checks that the name is "Steve", or sets an error message and styles the invalid name field if not.
  • scientistCheck(): Checks that the scientist button is selected, or sets an error message and styles the invalid file field if not.
  • fileNameCheck(): Checks that there is a filename and that it is has a .pdf extension, or sets an error message and styles the invalid file field if not.

Note that each "field function" nameCheck(), scientistCheck(), fileNameCheck() returns true if the field contains valid user input or false if not. This helps the calling function to determine success or failure and perform a complete form validation.

Form ValidationLect 6, P.54

Form Validation Function in Example

One "master" form validation function formValidate() first calls clearErrors() to reset any error messages and field styles, even if there aren't any, then calls each of the field functions in turn.

Each time a "field function" returns false, an error counter is incremented. If the error count is zero, submission of form data is allowed; however, if the error count is greater than zero, form submission to the server is blocked and the user is asked to correct their errors.

Finally, this function retirns true or false to the onsubmit event handler, which will either allow or block the form submission.

Form ValidationLect 6, P.55

Final Notes and Advice

By breaking up a complex task into a master function and a number of sub functions, code can be kept neat and managable.

Eventually, a true or false must "bubble up" to the form’s onsubmit event handler. This will either allow or block submission of the form (default is to allow).

When programming, it is unlikely you will get everything right the first time, so you will need to debug your code!

  • alert(message) is good for halting the program and printing something you want to check (don’t use in large loops)
  • console.log(message) is good for logging more complex messages without halting the program.
  • Having target="_blank" directs the output from the server to a new tab, so you can inspect both the form and the server's response page at the same time.

When everything is working, remove these debugging aids so that users are not bothered with ugly alert boxes, or console.logs; and so that the server response replaces the content of the form page when submission is sucessful.

Welcome!Lect 7, P.1

Web Programming
COSC2413 / 2426 / 2453

Lecture 7 - Javascript 2

Lecture 7.1Lect 7, P.2

Part 1: Advanced Event Handling, Regular Expressions

Javascript - Client Side ProgrammingLect 7, P.3
  1. Event Handling Redux
  2. Regular Expressions
Event Handling ReduxLect 7, P.4

Assigning Event Handlers

Previously, we saw that a JavaScript event handler can be set by adding an HTML attribute to an element.

<input type='button' id='price' value='Calculate' onclick='calculatePrice();' />

When the above button is clicked by a user, the function calculatePrice() is called.

There are two additional ways for setting event handlers:

  • DOM event handlers
  • Event listeners
Event Handling ReduxLect 7, P.5

DOM Event Handlers

DOM event handlers attach a function directly to an element using javascript so that the HTML can be kept free from event handler assignment:

<input type='button' id='price2' value='Calculate 2' onclick='calculatePrice2()' />
var myButton = document.getElementById("price2");
myButton.onclick = calculatePrice2;

This code assigns the function calculatePrice2 to an element with the id price2

Notice that:

  • No parentheses are added to the function name.
  • Only one function can be assigned to each event handler (ie "click") using this method.

When assigning event handlers, the code should be placed at the end of the webpage, ie after the page has been loaded and the DOM has been constructed. For this reason, external javascript files that assign event handlers to HTML elements in these slides have been placed after the <footer>element rather than in the <head> element.

Screenshot of console demonstrating js files being placed after the footer

Event Handling ReduxLect 7, P.6

Event Listeners

Event listeners are another way of adding event handling functionality to a web page. They are more flexible than DOM event handlers, and allow multiple event handlers of the same type to be added to an element (eg 2 click events).

Simply call the addEventListener() method again on the same element to add another handling function.

<input type='button' id='price3' value='Calculate' />
var myButton = document.getElementById("price3");
myButton.addEventListener("click", calculatePrice); 
myButton.addEventListener("click", calculatePrice2); 

This code assigns the functions calculatePrice AND calculatePrice2 to an element with the id price3

Notice that:

  • The event name does not use the "on" prefix.
  • No parentheses are added to the function name.
  • Multiple functions can be assigned to each event handler (ie "click") using this method.
Event Handling ReduxLect 7, P.7

Event Propagation and Flow

HTML elements may be nested inside other elements, for example, a span inside a div.

<div id='ef-div'>
  <span id='ef-span'>Click me!</span>
</div>
...
document.getElementById("ef-div").addEventListener("click", inspectEvent); 
document.getElementById("ef-span").addEventListener("click", inspectEvent);
Click Me!

When a click event is registered on the inner span, a click event is also registered on the outer div. The order in which events are handled is called event flow and by default starts with the innermost element and propagates up through the object tree.

Note that the event originating element (event.target) is not always the same as the event calling element (this or event.currentTarget).

  • Event bubbling (default) means that the event starts at the originating element, and "bubbles up", triggering any event listeners that have been attached to ancestor elements.
  • Event capturing means that the event starts at the highest element (usually the Document or Window object) and "tunnels down" towards the originating element, triggering any event listeners that have been attached to descendent elements.

The direction of propagation can be changed by setting an optional useCapture parameter to true.

var mySpan = document.getElementById("ef-span");
mySpan.addEventListener("click", tunnelDownInstead, true); 
Event Handling ReduxLect 7, P.8

Event Propagation Prevention

Event propagation is not always desired. Ideally you should avoid nesting elements that respond to events, but if this is not posible, you can call the passed event's stopImmediatePropagation() method inside the function.

function bubbleUp(event) {
  // function code goes here
  event.stopImmediatePropagation();
}

Sometimes you will want to prevent default functionality, for example, making sure mousewheel events on the lecture 2 kitten image does not scroll the browser window. This can be achieved by calling the passed event's preventDefault() method at the end of the function.

document.getElementById("cuteKitten").addEventListener("wheel", function(eP) {
  document.getElementById("purr").play();
  eP.preventDefault(); // no window scrolling!;
});

Notice here that the event object is being passed as a parameter and that the name chan be changed. This is fine, and many programmers choose not to rely on javascript's treatment of event as a de-facto reserved word.

Event Handling ReduxLect 7, P.9

Timing Events

You can trigger events to run once or periodically using the window's setTimeout() and setInterval() functions.

For example, the code below sets up a timer called fireworksTimer to run a function called fireworks() once, 5 seconds after being triggered.

var fireworksTimer = setTimeout(fireworks, 5000);

And this example sets up a timer called emojiTimer to run a function called animateEmoji continuously, every 500 milliseconds after being triggered.

var emojiTimer = setInterval(animateEmoji, 500);

If you want to stop the events, you can do so by clearing the timers using the window's timeout function (better be quick with those fireworks!).

clearTimeout(fireworksTimer);
clearTimeout(emojiTimer);
Event Handling ReduxLect 7, P.10

Timing Toggle Example

You can "play and pause" a continuously playing event. First put a play/pause emoji in a span with the id emoji like this ⏯️.

... like this <span id="emoji">⏯️</span>.

Next, assign an event handler to call animateEmojiToggle() when it is clicked.

document.getElementById("emoji").onclick=animateEmojiToggle;

The animateEmojiToggle function below sets and clears a timer called emojiTimer that controls the running of a function called animateEmoji. The emojiTimer timer will either be a number (when animateEmoji is running) or undefined (when animateEmoji is not running).

function animateEmojiToggle() {
  emojiTimer = (typeof emojiTimer == "number")
    ? clearInterval(emojiTimer)
    : setInterval(animateEmoji, 500);
}

Finally, we need some variables and an emoji animation function called animateEmojito update the span's content every 500ms.

var emjInc=1, emjInd=0;
var emojis=['🙁','😐','🙂','😃','😆','🤣'];

function animateEmoji() {
  document.getElementById("emoji").innerHTML = emojis[emjInd];
  if (emjInd>=emojis.length-1) emjInc=-1;
    else if (emjInd<=0)        emjInc=1;
  emjInd+=emjInc;
}
Regular ExpressionsLect 7, P.11

Introduction

Regular expressions (regexes) allow us to write patterns (sequences of characters) that then be searched for in strings, allowing us to avoid complex string manipulation.

In lecture 6, we used Javascript to perform a complex validation on two text fields

  • Name = Steve {space} {something}
  • Filename = {something} {dot} pdf

Example

To match {start} Steve {space} {letters & spaces} {end}, we use the following regular expression:

^Steve [a-zA-Z ]+$

To match {start} {letters & numbers} {dot} pdf {end}, we use the following regular expression:

^[a-zA-Z0-9]+\.pdf$

Regular ExpressionsLect 7, P.12

HTML5 pattern attribute

In HTML5, a new pattern attribute was introduced for text based input elements. We can supply a regular expression pattern for the browser to check against. Note that this pattern attribute only performs whole string checks, so ^ and $ are not needed - more on this later!

<input type='text' pattern='Steve [a-zA-Z ]+'>

In addition, a new pseudo style :invalid can be set to style invalid inputs, for example just inputs with a specified pattern attribute.

input[pattern]:invalid {
  border:2px red solid;
  background-color:#fee;
}

HTML5 Pattern Example

Full Name:

What happens when the field is blank?No "invalid" state is detected. This may be a glitch as the pattern is not matched, but to fix this, just add a required attribute. The downside is that the field will always be red when blank, eg on first load.
What happens when your name is not Steve?The field is red as the pattern is expecting a Steve.
What happens when your name is just Steve?The field is red as the pattern is expecting a space and at least one letter for a surname.
What happens when your name is Steven?The field is red as the pattern is expecting a space after "Steve".
Regular ExpressionsLect 7, P.13

Javascript

In javascript, the ends of the regex are marked by the / character by default and not quote characters.

When testing a string, we create a regex object and call its test method.

var patt = /^Steve [a-zA-Z ]+$/;
if (patt.test(name)) 
  // set friendly message
else
  // set error message

Javascript Regex Example

Full Name:

We can also replace part of a string with the string's replace method to correct a user's input when they leave the field.

var patt = /^(Stephen|Steven|Stephanie|Stephan|Stefanie)$/;
name.replace(patt,"Steve");

Javascript Replace Example

Full Name:

Regular ExpressionsLect 7, P.14

Start & End Anchors

In the previous examples, we can see that the characters:

  • ^ matches the start of a string.
  • $ matches the end of a string.

In combination, ^ and $ match the whole string.

Examples:

  • ^Stephen matches "Stephen Strange" but not "Doctor Stephen Strange".
  • ^Stephen$ matches "Stephen" but not "Stephen Strange" or "Doctor Stephen Strange".

Checkpoint - Consider Two Strings:

  1. "cause the players gonna play, play, play, play, play"
  2. "and the haters gonna hate, hate, hate, hate, hate"
Does /^cause/ match the above strings?(1) begins with "cause" so there is a match. There is no match for string (2).
Does /y$/ match the above strings?(1) ends with "y" so there is a match. There is no match for string (2).
Does /$e/ match the above strings?No match. At best, it may match a string with the substring "$e" somewhere inside.
Regular ExpressionsLect 7, P.15

Character Sets

To match one of a set of characters, specify them in square brackets [].

Some examples:

  • [aeiou] matches a single lower-case vowel.
  • [a-z] matches a single lower-case character between ‘a’ and ‘z’.
  • [A-Za-z0-9] matches a single alphanumeric character.
  • [-a-z] matches a single hyphen or lower-case letter.

Checkpoint - Consider Two Strings:

  1. "cause the players gonna play, play, play, play, play"
  2. "and the haters gonna hate, hate, hate, hate, hate"
Does /p[rl]ayer/ match the above strings?(1) contains the word "player" so there is a match. There is no match for string (2), but if a "prayer" was present, there would be a match.
Regular ExpressionsLect 7, P.16

Negated Matching

To "not match" or "match not", we re-use the ^ character inside the square brackets, for example [^0-9] matches a string if no digits are present.

It's unfortunate that the caret character is reused for a different meaning/purpose here. This is what happens when you let geeks code without proper supervision!

Checkpoint - Consider Two Strings:

  1. "cause the players gonna play, play, play, play, play"
  2. "and the haters gonna hate, hate, hate, hate, hate"
Does /[^a-z]h/ match the above strings?(2) contains the word "hater" and the letter 'h' is preceded by a space character, so there is a match. There is no match for string (1) as the only letter 'h' is preceded by the letter 't'.
Regular ExpressionsLect 7, P.17

Simple Quantifiers

To quantify occurrences, use:

  • * zero or more
  • ? zero or one
  • + one or more

For example:

  • [aeiou]* matches 0 or more vowels.
  • [aeiou]? matches 0 or 1 vowels.
  • [aeiou]+ matches 1 or more vowels.
What does /colou?r/ match?This will match any string with the word "color" or "colour" in it, but not "colouur" or "colouuur" etc.
Regular ExpressionsLect 7, P.18

Range Quantifiers

To quantify custom number or range of occurrences, we use the curly braces { } and a comma:

  • {0,} zero or more.
  • {0,1} zero or one.
  • {1,} one or more.
  • {2} two, no more and no less!
  • {3,4} three or four.
  • {5,20} between five and twenty.
  • {100,} 100 or more.

Checkpoint - Consider Two Strings:

  1. "cause the players gonna play, play, play, play, play"
  2. "and the haters gonna hate, hate, hate, hate, hate"
Does /n{2}/ match the above strings?In this example, both (1) and (2) contain the word "gonna" so both strings match.
Does /hate,{3}/ match the above strings?This is a bit of a trick question! (2) contains 5 "hate"s in a row, but no "hate" has 3 commas after it, so the is no match. (1) doesn't match because it does not contain any "hate,,," either.
Does /hated*/ match the above strings?This is also a bit of a trick question! Both (1) and (2) do not contain the word "hated" BUT we are looking for 0 or more occurences of the letter "d" that follows the word "hate", so (2) matches and (1) does not.
Many words are spelt or spelled differently in USA leaning countries and UK leaning countries. For example, are you enrolled or enroled in Web Programming? Write a regex that matches both cases.No answers for this one, this is left to the reader as an exercise ... I"M KIDDING! ... the answer is /enrol{1,2}ed/.
Regular ExpressionsLect 7, P.19

Meta Characters

Some characters have special meaning and are called meta characters. Some of the following we have seen already: ^$*?+-[]{}()|/ and one we haven't: . which matches any character.

To match the literal version of a meta character, we need to escape it first with the escape character: \. If it is not obvious, the backslash character is also a meta character.

  • \** matches the * character literally, zero or more times.
  • \?? matches the ? character literally, zero or one time.
  • \++ matches the + character literally, one or more times.
  • \.. matches the . character literally, followed by any character.
  • \\ matches the \ character, literally.
  • \/ matches the / character, literally.
How would you match a url string that begins with "https://"?This regex is a bit messy, but necessary, as the / character marks the ends of the regex. You will need to use /^https:\/\//
Regular ExpressionsLect 7, P.20

Escaping Literal Characters

Most characters have no special meaning and are called literal characters. For example, /Steve Jobs/ matches "Steve Jobs" - even the space character is a literal character!

However, when escaped, some literal characters become meta characters and have meaning:

  • \n matches the new line character.
  • \t matches the tab character.
  • \d matches any digit, \D matches any non-digit.
  • \w matches any word char, \W matches any non-word char.
  • \s matches any whitespace character, \S matches any non-whitespace character.

Checkpoint - Consider Two Strings:

  1. "cause the players gonna play, play, play, play, play"
  2. "and the haters gonna hate, hate, hate, hate, hate"
Does /\D{6} / match the above strings?Both strings match as there are plenty of places where 6 non-digits can be found in a row.
Does / .h. / match the above strings?Both strings match as there is one place in each string where a three letter word exists with 'h' in the center? Can you find it? What can the word be?
Does /^[^a-z]*.ause/ match the above strings?This is a bit of a trick question! Initially, we are looking for something at the beginning of a string that isn't a lowercase letter, BUT 0 times is fine, so we can ignore that part. This leaves us to look for a string that begins with any character (eg "c", "😋", anything!) followed by "ause", so string (1) matches and string (2) does not.
Regular ExpressionsLect 7, P.21

Grouping and Branching

You can put parts (or atoms) of a pattern in parentheses () to form complete parts of a longer expression.

What will /(very ){1,2}/ match?This will match a string that contains "very " and "very very ".

The pipe character | allows choices or options.

What will /\.((com)|(edu)|(org)|(net))$/ match?This will match a string that ends with a ".", followed by com", "edu", "org" OR "net".
What will /(fruit|vampire) bat/ match?This will match a string that contains "fruit bat", "vampire bat" but not "cricket bat".

Checkpoint - Consider Two Strings:

  1. "cause the players gonna play, play, play, play, play"
  2. "and the haters gonna hate, hate, hate, hate, hate"
Does /(p|l|a|y){2}/ match the above strings?Update: This answer was corrected on 17th June 2017 - Thanks go to Samuel and Shichao for spotting the error. In this example, string (1) passes because there are many places where the letters in the set {p,l,a,y} are followed by another letter in the same set. String (2) fails because there are no places where two letters from the set occur next to each other. If we changed the regex to /(p|l|a|n){2}/, both strings would match because of the "nn" in "gonna" and a matching sequece can be found in the word and.
Does /(hate, ){3}/ match the above strings?String (2) will match because of the repeated phrase "hate, ". String (1) won't match.
Does /(play, ){5}/ match the above strings?This is a bit of a trick question! In this example, (2) fails, but (1) also fails because there are only 4 instances of "play, " in a row. To match this string, use /(play, ){4}play/.
Regular ExpressionsLect 7, P.22

Modifiers

Regexps can also take special modifiers after the closing delimiter.

  • /[a-z]/i makes the search case insensitive.
  • /[a-z]/x ignores whitespace inside the string.
  • /[a-z]/g searches globally, ie it doesn't stop at the first match.
  • /[a-z]/m searches on multiple lines, good for searching documents, not just single lines.
  • /[a-z]/ixgm does all 4!
Regular ExpressionsLect 7, P.23

Worked Example - Email

The following regex is intended to detect an email address:

/^[a-zA-Z0-9_\-.]+@[a-zA-Z0-9\-.]+$/

Just to let you know, . is a meta character outside square brackets, but inside it does not need to be escaped. Some browsers will fail if you "do the right thing" and escape it like this \..

  • ^ start of string anchor.
  • [a-zA-Z0-9_\-.]+ any of these characters inside [] one or more times.
  • @ the literal "at" character, once.
  • [a-zA-Z0-9\-.]+ any of these characters inside [] one or more times.
  • $ end of string anchor.
How good is this regex? Any problems?This regex is not bad, but it will allow ".@." for example. Many good, many bad, and the length is not always a good indicator of robustness. Make sure that your chosen regex does not block people, especially those that work in museums: http://archives.icom.museum/musedoma/naming.html.
Regular ExpressionsLect 7, P.24

Look Ahead

Regexs can also "look ahead" and the meta-sequence ?= is used to do this.

Normally a regex search moves the search position forwards one way, capturing characters as it goes; but a look ahead allows the search position to return for a second or third search with no character capturing.

  • x(?=y) matches "x", but only if it is followed by "y". It does not capture "xy".
  • /be(?= not)/ matches "be" but only the ones that are followed by " not". It does not capture "be not".

To perform a password strength check in a single regex, we can make use of look ahead. The following regex is used to check for a mix of character sets and a minimum string length.

/^(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(.{8,})$/

Password:

Can you work out what it is and how it works?

The first three terms are look aheads and return to the start of the string. We look for anything 0 or more times, followed by ...

  1. (?=.*\d) a digit somewhere
  2. (?=.*[A-Z]) an uppercase char somewhere
  3. (?=.*[a-z]) a lowercase char somewhere

If any of these look aheads fail, the regex match fails BUT if all three pass, a final whole string check is made: (.{8,}) looks for 8 or more characters.

Regular ExpressionsLect 7, P.25

POSIX Classes

There are some predefined classes (called POSIX classes) that can be convenient (and sometimes make code more clear!).

NB: They are not supported in Javascript, but are supported in PHP!

  • [[:digit:]] digit character
  • [[:upper:]] uppercase character
  • [[:lower:]] lower character
  • [[:alnum:]] alpha-numeric character
  • [[:punct:]] punctuation character
  • [[:space:]] whitespace character (space, tab, line-break, …)
Can you write a regex that makes sure a string (ie a password) contains at least one uppercase char, one lowercase char, one punctuation character and one digit?

This is a complicated task for a single regex as we will have to "look ahead" for each case. An easier solution is to test the string 4 times (ie use 4 regexes) and if any fail, then the whole test fails.

To get you started, /[[:punct:]]/ will match a string with at least one digit character BUT ... javascript does not support POSIX so you will have to smash out the keyboard ... and make sure you escape the meta characters ... erm ... no solution, this is left to the reader as an exercise - damn you javascript!

Regular ExpressionsLect 7, P.26

Resources

Tests and explains how your regex works:
https://regex101.com/

A concise single page summary:
http://www.cheatography.com/davechild/cheat-sheets/regular-expressions/

W3Schools:
http://www.w3schools.com/jsref/jsref_regexp_test.asp
http://www.w3schools.com/tags/att_input_pattern.asp

Lecture 7.2Lect 7, P.27

Part 2: Arrays, Objects, Web Storage

Javascript - Client Side ProgrammingLect 7, P.28
  1. Indexed Arrays (1D)
  2. Indexed Arrays (2D)
  3. Objects - Associative Arrays
  4. HTML5 Web Storage
  5. Example of localStorage
Indexed Arrays (1D)Lect 7, P.29

Simple Indexed Arrays

Simple indexed arrays are good for storing data, for example a simple shopping list.

  1. Milk
  2. Bread
  3. Chicken
  4. Peas
  5. Chocolate
  6. more Chocolate

They are indexed numerically, starting at element 0.

var shopList = [
  "Milk", 
  "Bread",
  "Chicken",
  "Peas",
  "Chocolate",
  "more Chocolate"
];

This code can be written on one line!

Arrays (1D)Lect 7, P.30

Accessing and Iterating

Individual elements can be accessed using their index:

var fifthElement = shopList[4]; // Chocolate is the fifth element!
shopList[3] = "Spam";  // who needs peas anyway?

To get the length of an indexed array, you can access its length property.

var howLong = shopList.length;  // ie 6

To iterate over an array, a for loop is often used. For example, to create an ordered list from an array, use the following code.

document.write('<ol>');
for (var i=0; i<shopList.length; i++)
{
  document.write('<li>'+shopList[i]+'</li>');
}
document.write('</ol>');
Indexed Arrays (2D)Lect 7, P.31

Table-like Arrays

Sometimes a single dimension (simple list) is not sufficient enough to store data - if it were, we would not need spreadsheets!

A spreadsheet is a good example of a 2 dimensional array. It has data that is split into cells in rows and columns and makes for a more useful shopping experience.

ProductQtyUnit PricePrice
Milk12.002.00
Bread13.003.00
Chicken17.007.00
Peas5000.015.00
Chocolate74.0028.00

A 2D array is really a 1D array where each element is array. With that in mind, this is how create a new 2D array:

var shopTable = [
  ["Product","Qty","Unit Price","Price"],
  ["Milk", "1", "2.00", "2.00"],
  ["Bread", "1", "3.00", "3.00"],
  ["Chicken", "1", "7.00", "7.00"],
  ["Peas", "500", "0.01", "5.00"],
  ["Chocolate", "7", "4.00", "28.00"] 
];
Indexed Arrays (2D)Lect 7, P.32

Accessing and Iterating

Individual elements in a 2D indexed array can be accessed using two indexes (first row, then column):

var milkPrice = shopList[1][3]; // second row, last column
shopList[3][0] = "Spam"; // Don't feel like chicken tonight

To get the number of rows, we need to access the length property of the array.

var numRows = shopTable.length // ie 6

To get the number of columns (assuming all sub-arrays are the same size), we need to access the length property of one of the sub arrays (eg the first one).

var numCols = shopTable[0].length // ie 4

To iterate over a 2D array, two for loops are often used. For example, to create a table from the 2D array, use the following code.

document.write('<table>');
for (var row=0; row<shopTable.length; row++)
{
  document.write('<tr>');
  for (var col=0; col<shopTable[row].length; col++)
  {
    document.write('<td>'+shopTable[row][col]+'</td>');
  }
  document.write('</tr>');
}
document.write('</table>');
Objects - Associative ArraysLect 7, P.33

Rethinking the Indexing Method

While numbered indexes are convenient, they are also limiting in some situations. In the previous example, it is not clear what the data in each cell of the array relates to.

var peaQty = shopTable[4][1] // not very intuitive ...

How much nicer would it be if we could use just ask the array for what we wanted?

var peaQty = shopTable['Pea']['Qty'] // this would be cool!

Objects allow us to use named keys in place of a numeric index. An object can therefore be used as an associative array.

Objects - Associative ArraysLect 7, P.34

Creating an Object

When creating objects, we use JSON (Javascript Object Notation). We need to bring in the colon : character to separate a key from its value, and for an array of key / values pairs we use braces {} instead of square brackets [].

var shopObject = {
   Milk: {
    Qty: "1",
    UnitPrice: "2.00",
    Price: "2.00"   
   },
   Bread: {
    Qty: "1",
    UnitPrice: "3.00",
    Price: "3.00"   
   }, 
   
   //... repeat for Chicken and Peas ...
   
   Chocolate: {
    Qty: "7",
    UnitPrice: "4.00",
    Price: "28.00"   
   }
};

Both of the following statements update the object / associative array:

shopObject['Bread']['Qty'] = "2"; // Associative array syntax
shopObject.Bread.Qty = "2"; // Object syntax

And we can add new items if we wish:

shopObject['Icecream']['Qty'] = "2"; // Associative array syntax
shopObject.Icecream.Qty = "2"; // Object syntax
Objects - Associative ArraysLect 7, P.35

For-In Loop

A standard for loop can iterate over a numeric indexed array, but how do you iterate over an associative array?

for (var row="Milk"; row<="Chocolate" ; row++) { 
  for (var col='Qty'; col<='Price' ; col++) {
    document.write(shopObject[row][col]);  
  }
}
// Trust me, the computer is totally confused!

Javascript provides with a for in loop to handle objects. The iterator is automatically assigned the key on each loop:

for (var row in shopObject) { 
  for (var col in shopObject[row]) {
    document.write(shopObject[row][col]);  
  }
}
// Everything works!

We are no longer constrained by integer keys, starting at 0!

Objects - Associative ArraysLect 7, P.36

Mixing Indexed Arrays and Objects

In truth, there is still a need for indexed arrays, for example a shopping receipt is an indexed array and contains objects as array elements.

var shopReceipt = [
  {
    Product: "Milk",
    Qty: "1",
    UnitPrice: "2.00",
    Price: "2.00"   
  },
  {
    Product: "Chocolate", 
    Qty: "20",
    UnitPrice: "4.00",
    Price: "80.00"   
  } 
];
// Not the healthiest shop visit ...

In this example, the product is no longer the row key, but rather part of each receipt item (ie another column). The following definition list writes out each purchased item in a <dt> element and each of the properties in <dd> elements.

document.write('<dl>');
for (var row=0; row<shopReceipt.length; row++) 
{
  document.write('<dt>Item #'+(row+1)+':</dt>');
  for (var col in shopReceipt[row])
  {
    document.write('<dd>'+col+': '+shopReceipt[row][col]+'<dd>');
  }
}
document.write('</dl>');
HTML5 Web StorageLect 7, P.37

Storing Data Client Side

HTTP is a stateless protocol. This means that once a client has sent a request to a server, and the server has responded by sending the requested information, the connection is terminated, and the server forgets everything about the client/user.

However, it can be vital to maintain state for interactive web applications. We will now look at client side storage, ie what is stored in your web browser.

In Chrome, view the developer console and navigate to Application. You should see this:

screenshot of application area in console

HTML5 Web StorageLect 7, P.38

Cookies

Cookies are small pieces of information that are stored on a client's machine, to store information about the user. A cookie is a name - value pair, such as:

name = "Steve Gates"

By default cookies are deleted when the browser is closed, but they can also be given a set expiry time (persistent cookies).

Javascript has always been able to set cookies on the client's machine to remember information about each particular user, but HTML5 saw an upgrade to the size and security of client side storage, called Web Storage, and is a better way of storing information client side.

We will look more at cookies in lecture 12

HTML5 Web StorageLect 7, P.39

Web Storage

There are two types of Web Storage objects:

  • sessionStorage is temporarily stored on the client's machine and is automatically erased when the user leaves your website. For Pixar fans, remember how Dory's memory keeps getting wiped every time she swims away from Marlin near the start of Finding Nemo.
  • localStorage is stored persistently on the client's machine and can be retrieved when the use re-visits your website at a later date. For Pixar fans fans, remember when Dory has a "total recall" moment when she meets Nemo near the end of Finding Nemo.

In all cases (cookies, sessionStorage and localStorage), client side information is stored as pairs of keys and values.

  • Cookies are always sent to the server, whether the server needs them or not.
  • Web storage data is only sent to the server programmatically, i.e. when the developer decides that the server needs it.
HTML5 Web StorageLect 7, P.40

Setting a key / value pair

Use the setItem() method to set web storage data, for example a persistent name, phone number, and today's coffee order:

if (typeof(Storage) !== 'undefined') {
  localStorage.setItem('name','Alice Liddell');
  localStorage.setItem('phone','0400 000 000');
  sessionStorage.setItem('coffee','Latte');
} else {
  // Sorry - you'll have to code using cookies!
}
Please Note: All values stored in cookies and web storage are in string format.
You must convert variable, eg numbers and booleans, when storing or retrieving them.
HTML5 Web StorageLect 7, P.41

Getting a key / value pair

Use the getItem() method to retrieve Web Storage data, for example a persistent name, phone number, and today's coffee order:

var name, phone, coffee;
if (typeof(Storage) !== 'undefined') {
  name = localStorage.getItem('name');
  phone = localStorage.getItem('phone');
  coffee = sessionStorage.getItem('coffee');
} else {
  // Sorry - you'll have to code using cookies!
}
HTML5 Web StorageLect 7, P.42

Deleting Web Storage Data

Use the removeItem() method to unset Web Storage data:

var name, phone, coffee;
if (typeof(Storage) !== 'undefined') {
  localStorage.removeItem('name');
}

Or reset all data:

localStorage.clear(); // just localStorage
sessionStorage.clear(); // just sessionStorage
Storage.clear(); // both!
HTML5 Web StorageLect 7, P.43

Alternative Notation

The two web storage objects can be set and accessed using array and object notation:

localStorage.name = "Bob D'Builder";
localStorage['name'] = "Bob D'Builder";

var coffee = sessionStorage.coffee;
var coffee = sessionStorage['coffee'];
Example of localStorageLect 7, P.44

What's on Your Machine?

These lecture slides use localStorage to remember which slide sets you have open.

At the moment, this website has stored the following keys and values in your localStorage object:

Example of localStorageLect 7, P.45

Slide Interaction

When you click "Instructions" in the top menu, an item in localStorage called slides-instructions is either set to either "false" or "true":

if (document.getElementById('instructions').checked)
{
  localStorage['slides-instructions']='true';
  // code to make instructions visible
} else {
  localStorage['slides-instructions']='false';
  // code to make instructions invisible  
}

In a similar fashion, when you return to the website after an absence, localStorage is checked and the instructions checkbox is either set or unset to the same state that you left it in:

if (localStorage['slides-instructions']=='false') {
  document.getElementById('instructions').checked=false;
  // code to make instructions invisible  
} else { 
  document.getElementById('instructions').checked=true;
  // code to make instructions visible
}
Example of localStorageLect 7, P.46

Remember Me!

Fields can be pre-filled, for example in the case of a "remember me" type of application:

if (localStorage.remember == 'true') {
  document.getElementById('name').value = localStorage.name;
  document.getElementById('phone').value = localStorage.phone;
}

The user can be forgotten if the box is unchecked:

if (document.getElementById('remember').checked !== true) {
  localStorage.removeItem('name');
  localStorage.removeItem('phone');
}
// or localStorage.clear(); if not storing anything else in localStorage
Welcome!Lect 8, P.1

Web Programming
COSC2413 / 2426 / 2453

Lecture 8 - PHP 1

Lecture 8Lect 8, P.2
  1. PHP Basics
  2. String and String Functions
  3. Functions
  4. Includes and Modules
  5. Error Reporting
PHP BasicsLect 8, P.3

History of PHP

Created in 1994 by Rasmus Lerdorf, originally Personal Home Page", renamed in 1997 to PHP: Hypertext Preprocesor".

It is a server side programming language (i.e. it runs on the server), built from C and C++. The language grew "organically", with features and naming conventions that often feel "bolted on". it is not unual to find multiple functions that are aliases of each other and do the same job.

With the release of PHP 7 in 2015, there has been a culture shift to make PHP more robust with fixed typing options.

You also need to realize that there is consistency. It is just consistency from a different angle."
- Ramus Lerdorf, Jan 2014

A PHP file usually contains a mix of PHP and HTML code, but it can contain no PHP code and still function correctly.

PHP code will be located inside PHP tags <?php ?> (code instructions) or <?= ?> (variable or function values).

PHP BasicsLect 8, P.4

PHP Usage

Some popular sites that use PHP are

  • Wikipedia
  • Facebook
  • Yahoo!
  • Wordpress
  • Tumblr
  • Baidu

https://w3techs.com/technologies/overview/programming_language/all

PHP BasicsLect 8, P.5

Client - Server Architecture

Unlike javascript, PHP does not interact with the user "in real time" and all PHP code is executed before it leaves the server. Only HTML, CSS and Javascript remain when a PHP script page is finished running.

Clients connect via Internet to a Server

  1. Server receives a request for a PHP file, often with GET, POST, COOKIE information to process.
  2. Server loads PHP file, sends file to the PHP engine
  3. PHP engine makes decisions, prepares a response or arranges a redirection to another page.
  4. Once the process is complete, server delivers a response back to the client with HTML, CSS & Javascript.
  5. Client receives response, builds a new page, runs javascript.
PHP BasicsLect 8, P.6

PHP Example

As outlined earlier, the PHP engine looks for PHP code located inside PHP tags inside a PHP file.

The following example will demonstrate the echo and date functions, and the short tag value output.

<html>
  <head>
    <title>Hello World</title>
  </head>
  <body>
  <?php
    echo "<h1>Hello world!</h1>";
    echo "<p>The time is " . date("g:i a") . "</p>";
  ?>
  <p>Your RMIT id is <?= $_SESSION['PHP_AUTH_USER'] ?>.</p>
  </body>
</html>

This code is "run" and turned into HTML.

...
  <h1>Hello world!</h1>
  <p>The time is 5:52 pm</p>
  <p>Your RMIT id is eOOOOO.</p>
...
View the page source. Can you see the PHP code? [ ]
PHP BasicsLect 8, P.7

PHP Identifiers

PHP allows you to create variables, and define constants.

$radius = 4; // variable, can change
define("TAU", 6.2831853); // constant
$circumference = TAU * $radius;
$radius = 2; 
$circumference = TAU * $radius;
  • By convention, contants are written in uppercase.
  • All variable names start with a dollar sign, eg: $name, $age
  • Variables are case sensitive, eg: $name and $Name are different variables
  • Variable names consist of letters, numbers, underscores
  • Variable names cannot start with a digit, eg: $1direction is an invalid name but $direction1 is a valid name
PHP BasicsLect 8, P.8

PHP Types

Types include: Boolean, Integer, Float/Double, String, Array and Object (for classes). Like javascript, PHP is a weakly typed language.

Constant types are automatically set when created (defined) and do not change but variables are not a fixed type and can change during runtime by PHP, depending on the context in which the variable is used.

Re-assigning values will "recast" the variable to a new type if needed

$age = 15; // $age is an integer
$age = "fifteen"; // now a string

The default behaviour usually does what you expect, but types can also be explicitly cast if needed

$age = (string) 15; // still a string
PHP BasicsLect 8, P.9

PHP Comments

Comments throughout your code will help you and other developers understand your thought processes later. PHP allows ...

# A comment on a single line

// A comment on a single line

$a=5; // A comment after a statement

/* A block comment or multiple comments
   that span more than one line */

Comments can also be used to temporarily hide page content. One thing to consider is HTML comments can be seen by everyone in the source code, eg

<!-- Hey Alice, this stupid client of ours wants us to fix up some
petty alignment issue ... just get it done and we can get out of here!
- Bob. -->

Whereas PHP comments can't ...

<?php /* Hey Bob, please use PHP comments, we don't want
the whole world reading this stuff. I'll talk to the client tomorrow. 
- Alice. */ ?>
PHP BasicsLect 8, P.10

PHP Operators

PHP operators are very similar to other programming languages (e.g. Javascript)

+ - / * % (...) // ie the usual arithmetic operators

echo 105 % 10;  // remainder is 5

String concatenation uses the . char instead of the + char:

$helloworld = "Hello" . "World";

Assignment operators also have their short-cut variations

= += -= *= /= ++ -- .=

$hello .= " ".$world; // $hello now has a space and $world at end
PHP BasicsLect 8, P.11

PHP Operators

Comparison operators include equality and identical comparators

 == > < >= <= != === !==

if(5 !=  5.0) echo "Not equal";
if(5 !== 5.0) echo "Not identical";

Logical operators have a few bonus natural language operators:

true false && and || or xor !

(!$a && !$b) == !($a || $b) // always!
PHP BasicsLect 8, P.12

PHP Operator Precedence

|| and && are the same as or and and but the former have a higher precendece, higher than the assignment operators =, +=, -= etc.

$bool = false || true; // equivalent to $bool = (false || true), ie $bool is true.
$bool = false or true; // equivalent to ($bool = false) or true, ie $bool is false.

It is wise to use parentheses to make code both clear and unambiguous.

http://php.net/manual/en/language.operators.precedence.php

Note that PHP uses "shortcut evaluation" for logical comparisons

(x || y) // if x is true, the second part y is not evaluated
(x && y) // if x is false, the second part y is not evaluated
PHP BasicsLect 8, P.13

PHP identifiers

When creating name value pairs in an associative array, use => (fat arrow).

$student = [
  "sid" => "s1234567",
  "name" => "Alice Liddell",
  "quality" => "meh"
];

When accessing a class method or traversing an object tree, use -> (thin arrow).

$xmlDoc -> saveXML();
(More on these later…)
PHP BasicsLect 8, P.14

PHP Loops

PHP has loops that are very similar to javascript syntax, although to find the length of an array we must count() the array elements

for ($i=0; $i<count($items); $i++) {
  ... 
}

while (boolean) {
 ... 
}

do { 
  ... 
} while (boolean)

PHP has a "for in" like loop to iterate through an associative array, but the syntax is a little different.

foreach ($array as $key => $value) {
  echo  "Element" . $key . " has the value " . $value . " or " . $array[$key];
}

As you can see above, we can use $value or $array[$key] to reference the array element's value.

PHP BasicsLect 8, P.15

PHP Switch Case

Like Javascript, PHP has a switch case block which can replace a series of cumbersome nested if-then-else blocks.

switch ($letter) {
  case "A": ... break;
  case "B": ... break;
  case "C": ... break;
  ...
  default: ... break;
}

Note: The default case is optional and will run if no cases have been matched.

PHP BasicsLect 8, P.16

PHP Ternary Operator

Like Javascript, PHP offers a ternary operator which uses the ? and : characters to create a shorthand "if-then-else" block.

// test ? true case : false case;

$a = ($b == $c) ? $d : $e;
... is equivalent to writing ...
if ($b == $c) {
  $a = $d;
} else {
  $a = $e;
}
PHP BasicsLect 8, P.17

Checkpoint

Consider the following variables:

$int = 5;
$float = 5.0;

What will be returned by the following statements?

($int = $float) ? "Yes" : "No";
"Yes" or "No"?

This is a tricky one. The answer is "Yes" but in general either "Yes" or "No" can be returned.

The value in $float is assigned to $int, changing its type and value to 5.0. This value 5.0 is passed as a boolean, ie a true, but if $float was originally 0.0, "No" would be returned. This is a very easy mistake to make when programming in weakly typed languages.

($int == $float) ? "true" : "false";
"true" or "false"?

"True". 5 has the same value as 5.0.

($int === $float) ? "true" : "false";
"true" or "false"?

"False". Even though 5 has the same value as 5.0, they are different variable types. The === and !== operators are used to make sure non-boolean variables are not re-cast as booleans.

Strings and String FunctionsLect 8, P.18

PHP Strings

You can create a string, i.e. a sequence of characters, using single or double quotes.

PHP offers a neat feature: content enclosed in in single quotes ' is interpreted literally whereas content enclosed in double quotes " allow characters to be parsed, eg meta characters are converted and variable substitution is carried out.

Consider the following strings:

$love = 'I love you';
$greeting1 = 'Hello World,\n$love';
$greeting2 = "Hello World,\n$love";

What is printed in each case?

echo $greeting1;

Hello World,\n$love

echo $greeting2;

Hello World,
I love you

Strings and String FunctionsLect 8, P.19

Disambiguating Variable Names

Whilst the double quotes parsing feature is handy, there will be times where PHP will need help disambiguating variable names for example.

$memory = 4;
echo "My computer has $memoryGB of RAM";

The problem is that the variable $memoryGB is passed and has not been defined. We need to find a way to separate the variable name $memory from the substring 'GB'.

We could cheat and use a space, but PHP allows us to delimit variable names by wrapping them inside curly braces {}.

echo "My computer has {$memory}GB of RAM";

This also works for complex variables such as arrays and objects, more about that later ...

Strings and String FunctionsLect 8, P.20

Escape Sequences

We have seen escape sequences that have meaning before. Here are a few examples:

\t - tab
\n - newline
\s - a space
\r - carriage return
\r\n - A Microsoft™ carriage return (required in old dot matrix printers)
\$ - $ in a double quoted string
\" - " in a double-quoted string
\' - ' in a single-quoted string

https://www.youtube.com/watch?v=nEdeZkBG14w

Strings and String FunctionsLect 8, P.21

PHP String Blocks

You can create a large multi-line string in a block using:

  • Heredoc syntax (with parsing, like double quotes)
  • Nowdoc syntax (no parsing, like single quotes)

In both cases, <<< (the operator) and a pair of identifiers, text of the developer's chosing, mark or delimit a large sequence of characters.

Heredoc Example ("YOLO")

$meta=<<<"YOLO"
  <p>This is a multi-line string</p>
  <p>That renders line breaks</p>
  <p>And to be clear, the value of \$love is $love</p>
YOLO; 

Nowdoc Example ('STARWARS')

$meta=<<<'STARWARS'
  <p>This is a multi-line string</p>
  <p>That renders line breaks</p>
  <p>And to be clear, $love will be written literally as '$love'.</p>
STARWARS; 

Note: the closing identifier must be on it's own line with no indentation (ie no leading spaces or tabs).

Strings and String FunctionsLect 8, P.22

Trimming Whitespace

When handling stored data or user input data, there is a possibility that unwanted whitespace can be present on either side of the string. PHP has three trim functions, trim(), ltrim() and rtrim(). Consider the following 'bloated' string:

What is printed by the following functions?

$bloated="   Hello   ";
echo trim($bloated);

Just "Hello" - both leading (left) and trailing (right) space is removed.

echo rtrim($bloated);

"   Hello" - leading space is retained but trailing space is removed.

echo ltrim($bloated);

"Hello   " - leading space is removed but trailing space is retained.

Strings and String FunctionsLect 8, P.23

HTML Sanitisation / Conversion

One issue when accepting user input is protecting the server against cross site or and injection injection attacks.

For example, if a user enters <script> /* insert malicious code here */ </script> into a blog textarea and this content is stored untreated in a database, that code will be recalled and run in another user's browser. Consider the following code:

$html = '<script>prompt("Your session has expired. Re-enter your password.");</script>';

The htmlspecialchars() function turns all html characters into htmlentities:

What does $encode = htmlspecialchars($html); return?

&lt;script&gt;prompt(&quot;Your session has expired. Re-enter your password.&quot;);&lt;/script&gt;

The reverse function decodes encoded data, for example:

What does $decode = htmlspecialchars_decode($encode); return?

The original HTML / Javascript!

These functions are not just for sanitising data. Websites such as https://w3schools.com and https://codepen.io accept code as input and will need to deactivate it for storage and re-activate it in a try-it editor later.

Strings and String FunctionsLect 8, P.24

PHP Newline Conversion

When reading from a file, newline characters \n are not displayed as line breaks in HTML. PHP Provides a function called nl2br() that changes \n, \r or a combined \r\n sequence into <br>.

$textFromFile = "Mac \r Unix \n Microsoft \r\n -cheers";
$html = nl2br($textFromFile);
What is stored in $html?

Mac <br> Unix <br> Microsoft <br> -cheers

Sadly, there is no br2nl() function, but it is not difficult to create one with the PHP regular expression replacement function preg_replace().

function br2nl($string='', $nl="\n") {
  return preg_replace('/<br>/g', $nl, $string);
}

We will look at regular expressions in PHP soon.

Strings and String FunctionsLect 8, P.25

PHP Letter Case Conversion

We can change the case of all letters in a string to either uppercase or lowercase using the strtoupper() and strtolower() functions.

What is returned?

strtoupper("you are shouting!");

YOU ARE SHOUTING!

strtolower("I'M NOT SHOUTING!");

i'm not shouting!

We can make the first letter of a string or each word uppercase with ucfirst() and ucwords() functions. These are useful for formatting sloppy text entered by customers for use in SMSs, receipts or delivery labels etc.

What is returned?

ucfirst("i c U l8R Ok?");

I c u l8r ok?

ucwords("1 rmIt st, melbOurnE viC 3000");

1 Rmit St, Melbourne Vic 3000

Strings and String FunctionsLect 8, P.26

PHP Substrings

We can look for the position of a sub-string (a needle) within a larger string (haystack) using strpos() (case sensitive) or stripos() (case insensitive).

$position = strpos($haystack, $needle);

In both cases, if the sub-string is found, the position (starting at 0) is returned and if the sub-string is not found, false (boolean) is returned.

What is displayed in the following examples?

echo strpos("Elephant","E");

0 is printed because 'E' is found at the start of the string.

echo strpos("Elephant","e");

2 is printed because 'e' is found at the third position in the string.

echo stripos("Elephant","e");

0 is printed as 'e' & 'E' are considered the same character in a case insensitive search.

echo strpos("Elephant","Zebra");

false should be printed, but don't rely on PHP to print 'false'.

Strings and String FunctionsLect 8, P.27

PHP Substring Checkpoint

Consider the following code example:

$E = "Elephant";
$e = "E";
$where = strpos($E, $e);
if( $where == false )
  echo "There is no $e in $E";
else
  echo "$e found at position $where in $E";
What is printed to the screen?

You might think that 'E' is found at position 0 in Elephant is the answer, but this is displayed instead:

There is no E in Elephant

0 (int) has the same value as false (boolean). We need to use the identity comparator:

if( $where === false ) { ... }

Strings and String FunctionsLect 8, P.28

Comparing Strings Lexicographically

Two strings can be compared lexicographically using the functions strcmp() and strncmp(), which will return:

  • a negative result if string1 is less than string2
  • a positive result if string1 is greater than string2
  • 0 if the strings are equal
if (strcmp($a, $b) < 0)
  echo "You will find $a before $b in the dictionary.";
else if (strcmp($a, $b) > 0)
  echo "You will find $b before $a in the dictionary.";
else
  echo "The two strings are the same.";

What is displayed in the following examples?

echo strcmp("adele","taytay");

-19 is printed [ord("a")=97; ord("t")=116;]

echo strcmp("taytay","adele");

19 is printed (see above example, only reversed)

echo strcmp("adele","adele");

0 is printed as the two strings are equal.

echo strncmp("adele","adelaide", 4);

A "bait and switch" question: the answer is 0 because the alternative strncmp function allows us to compare just the first part of the string, in this case the first 4 characters specified in a third parameter.

Strings and String FunctionsLect 8, P.29

Replacing Substrings

In a large string, or in an array, we can change all occurrences of one substring with another substring using the str_replace() function:

echo str_replace("fork", "spork", $userInput);

Can you think of a similar application where you might want to replace character sequences with other character sequences?

Strings and String FunctionsLect 8, P.30

Formatted Printing

Printing floating point numbers as a string can result in ugly output. For example, a split bills calculator that divides the total price by the number of people at the table:

$bill = 100;
$people = 3;
$each = $bill / $people;
print "Your bill is \$$bill, or \$$each each";
What is printed?

Your bill is $100, or $33.3333333333301 each

The printf() function allows us to format floats as strings without altering (ie rounding) the original values. References to the format of each variable are present in the string, which is followed by a list of variables to format.

printf("Your bill is $%1.2f, or $%1.2f each", $bill, $each);
What is printed?

Your bill is $100.00, or $33.33 each

Strings and String FunctionsLect 8, P.31

Formatted Printing Detail

A variable is formatted as a string in the following way, for example a float formatting pattern %1.2f:

  • % = start of format string.
  • 1 = minimum size string will take up, 1 space (but can expand).
  • .2 = precision of float, 2 decimal places.
  • f = variable type, eg floats in this case.

The format of conversion specifications is: %[padding_character][-][width][.precision][type]

  • The padding character can be used to pad with zeros (rather than spaces). You may need to use ' to escape the character if it is not a space or 0.
  • The minus symbol, if included, means left-justify (the default is right-justify).
  • The width specifies the minimum field width.
  • The precision specifies the number of places after the decimal point.
  • The type specifies the data type to print as: s string, f float, d decimal, x hexadecimal number.

Other variable types can be formatted with printf(), for example strings can be padded with spaces or dashes etc to line up in columns.

Strings and String FunctionsLect 8, P.32

Formatted Printing Examples

What would the following examples produce?

printf("%9s\n","hey!");
     hey!
printf("%-9s\n","hey!");
hey!     
printf("%9.3f\n",3.14159265359);
    3.142
printf("%09.3f\n",3.14159265359);
00003.142
printf("%'-9.3f\n",3.14159265359);
----3.142
printf("%'--9.3f\n",3.14159265359);
3.142----
FunctionsLect 8, P.33

User Defined Functions

As in other programming languages, functions allow related statements to be grouped together, enabling the creation of reusable code, and making code maintenance easier.

Declared with the keyword function, optional arguments are specified in parentheses

function emphasise($string) {
  echo "<em>" . $string . "</em>";
}
What does emphasise("Hello World"); print?
Hello World

A parameter can be given a default value and be made "optional"

function emphasise($string="An example") {
  echo "<em>" . $string . "</em>";
}
What does emphasise(); print?
An example
FunctionsLect 8, P.34

User Defined Functions

Values can be returned using the return keyword. Both parameter and return value types don't need to be declared.

function divide($num, $den) {
  return ($den == 0) ?
    "Denominator can't be zero" :
    ($num / $den);
}
What does $res = divide(10, 4); return?
(float) 2.5
What does $res = divide(10, 2); return?
(int) 5
What does $res = divide(10, 0); return?
(string) Denominator can't be zero
FunctionsLect 8, P.35

Variable Scope

Variables used in a PHP function only have scope within the function body. If you need to access a variable outside the function, you need to use the keyword global to declare the variable global within the function.

Tip: This programming practice should be avoided whenever possible!

$temp = 25;
function globalWarming() {
  global $temp;
  $temp += 0.25;
}

globalWarming();
echo "Global temperature is now {$temp}&deg;C";
What is printed?
Global temperature variable is now 25.25°C
FunctionsLect 8, P.36

Passing Parameters by Reference

Parameters are passed by value as default. This means that PHP creates a new local variable with the passed value which is discarded when the function run is complete.

To pass by reference, use an ampersand & before the parameter in the function declaration. PHP creates a pointer to where the original variable is stored in memory is passed.

function localWarming(&$temp) {
  $temp += 0.25;
}

$localTemp = 25;
localWarming($localTemp);
echo "Local temperature is now {$localTemp}&deg;C";
What is printed?
Local temperature is now 25.25°C
Includes and ModulesLect 8, P.37

PHP Include and Require Functions

PHP allows us to include the contents of another file. There are 4 functions:

  • include() includes the contents of a file and generates a warning if the file is unavailable and continues the execution. External files can be included any number of times.
  • include_once() is the same as the above, but PHP keeps a track of files already included and will not include the same file twice.
  • require() includes the contents of a file and generates an error if the file is unavailable and stops the execution. External files can be included any number of times.
  • require_once() is the same as the above, but PHP keeps a track of files already included and will not include the same file twice.

As a rule, if the file is useful but not needed, use an include function, otherwise use a require function.

include_once("weatherinfo.php");
require_once("tools.php");
Includes and ModulesLect 8, P.38

PHP Modules

The individual pages of a website often contain large sections of repeated code. Any changes to the sitewide layout and look, ie "template" changes, must be made on every page and small mistakes will lead to inconsistencies.

page source code classification of shared and unshared code

Shared content can be moved out to modules so that a sitewide or template change can be made in one place rather than many places.

We will put all of this code into a file called "tools.php" and include it in all pages with require_once("tools.php") near the top of each file.

Includes and ModulesLect 8, P.39

PHP Top Module

All of the code above <main> can be moved to a function, as long as you supply a page title as a parameter to the function.

function top_module($pageTitle) {
  $html = <<<"OUTPUT"
<!DOCTYPE html>
<html>
  ...
  <title>$pageTitle</title>
  ...
    </nav>
    <main>
OUTPUT;
  echo $html;
}

Call this function at the right place in your file with a page title as follows:

top_module("Welcome to Bob's Garage");
Includes and ModulesLect 8, P.40

PHP End Module

All of the code below <main> can be moved to another function.

function end_module() {
  $html = <<<"OUTPUT"
    </main>
    <footer>
    ...
  </body>
</html>
OUTPUT;
  echo $html;
}

Call this function at the right place in your file as follows:

end_module();

Once this is done, the only remaining HTML in your file should be the content inside the <main> element.

An example of this conversion can be found in the secured examples area mini-website. Have a look at the footer in each page, you can see that the source code has been greatly reduced.

Error ReportingLect 8, P.41

PHP Levels of Error

Error reporting is controlled using the error_reporting() function.

During the development of a project, it is sensible to have error reporting turned on because you want your developers and managers to know if there are any issues or possible problems.

Once development is finished and the project moves to a production server, it is sensible to turn error reporting off because you do not want customers and hackers to see if there are any issues, assuming that some escaped detection and still exist.

There are currently 14 different error levels, but three common ones are:

  • E_NOTICE is something minor that won't cause a problem, but is considered an example of bad programming practice by some types of people (you know who you are ...).
  • E_WARNING is something significant that should be fixed, but won't stop execution.
  • E_ERROR is something serious enough to halt code execution.

What level of error reporting is achieved by the following?

error_reporting(0);
No errors are reported, 0 represents a byte with all the bits set to zero / off.
error_reporting(E_ALL);
All errors, E_ALL or 32767 represents a byte with all the required bits set to one / on.
error_reporting(E_ERROR | E_WARNING | E_PARSE);
PHP is using a bitwise operator to set and unset particular flags. Some errors, ie a moderate level of error reporting. Of all the possible bits, just 3 are set to one / on with all remaining bits set to zero / off.
For example, this will not detect a E_DEPRECATED or 8192 error. This means that your code works now, but it will stop working in the near future.
Welcome!Lect 9, P.1

Web Programming
COSC2413 / 2426 / 2453

Lecture 9 - PHP 2

Lecture 9Lect 9, P.2
  1. Arrays and Objects
  2. Super Globals
  3. Processing Form Data
  4. Processing Form Example
  5. Form Data validation
Arrays and ObjectsLect 9, P.3

Arrays

PHP supports indexed arrays and formally supports associative arrays, which allows us to create data structures (ie objects) to house data.

Indexed Array Creation

$array1 = ['A', 'B', 'C'];
$array2 = array('A', 'B', 'C');
$array3[0] = 'A';
$array3[1] = 'B';
$array3[2] = 'C';

Associative Array Creation

$assoc1 = ['A' => 'Apple', 'B' => 'Bear', 'C' => 'Chair'];
$assoc2 = array('A' => 'Apple', 'B' => 'Bear', 'C' => 'Chair');
$assoc3['A'] = 'Apple';
$assoc3['B'] = 'Bear';
$assoc3['C'] = 'Chair';

Javascript has rudimentary classes and also allows you to create objects "on the fly". PHP supports classes, so you can create objects in a more formal fashion.

Classes won't be formally covered in this course, but if it is something you want to look at and need assistance with, let your teaching staff know.

Arrays and ObjectsLect 9, P.4

Accessing Arrays

Syntax in PHP is very similar to javascript syntax and extends to multi-dimensional arrays. In the following indexed arrays, which elements are accessed and printed?

echo $array1D[3];

The 4th element of the one dimensional array.

echo $table2D[3][4];

The element in the 4th row and 5th column in the two dimensional array / table.

echo $cube3D[3][4][5];

The element in the 4th table, 5th row and 6th column inside the three dimensional array / cube.
If this is at the limit of your comprehension, you are not alone. Not everyone has been assimilated by the Borg!

In the following associative arrays, which elements are accessed and printed?

echo $students['eOOOOO'];

A "tree-dimensional" chunk of data (eg an object) that is related to a student with the id 'eOOOOO' ... you perhaps?

echo $students['eOOOOO']['courses']['current'];

A branch of data that contain information to all the courses you are currently enrolled in.

echo $students['eOOOOO']['courses']['current']['COSC1234']['assignments']['A1']

A "leaf" of information: your recent assignment 1 result in the course COSC1234.

Although this is an extreme example, hopefully you can appreciate that storing data in multi-dimensional associative arrays is more like storing data in a tree-like structure. At some point the branches will stop and a leaf of data will be reached.

Try not to set up multiple variables and multiple 1D arrays to store data as you will end up with an unmanageable mound of "variable spagetti". Combine all related data into a sensible structure (or object) and data management becomes easier.

Arrays and ObjectsLect 9, P.5

Iterating through indexed arrays

For loops are an efficient way of iterating through an array, but the while loop is equally as effective. The for loop syntax is very similar to javascript's loop, but you must employ the function count()to count the number of elements in an array first.

A simple indexed array

$arrLen = count($arr);
for( $i=0; $i<$arrLen; $i++ ) {
  echo $arr[$i];
}

A 3D indexed array

$numTables = count($cubeArr);
for( $table=0; $table<$numTables; $table++ ) {
  $numRows = count($cubeArr[$table]);
  for( $row=0; $row<$numRows; $row++ ) {
    $numCols = count($cubeArr[$table][$row]);
    for( $col=0; $col<$numCols; $col++ ) {
      echo $cubeArr[$table][$row][$col];
    }
  }
}

Tip: To improve execution time, count the number of elements in the array first. The count() function takes time to run, so you only want it to run once, and is not a simple variable like javascript's .length property.

Arrays and ObjectsLect 9, P.6

Iterating through associative arrays

PHP has a foreach loop. it is similar to javascript's syntax and has a feature: the key and value is extracted on each iteration. This means that there is no need for an increasing string of square brackets with a key inside.

A simple associative array

foreach( $students as $sID => $student ) {
  echo $student['firstname']; // same as $students[$sID]['firstname']
}

A "tree-like" associative array

foreach( $students as $sID => $student ) {
  echo "<h2>$sID: {$student['firstname']}</h2>";
  foreach( $student['courses']['current'] as $cID => $course ) {
    echo "<h3>$cID: {$course['title']}</h3>";
    echo "<ul>";
    foreach( $course['assignments'] as $aID => $result ) {
      echo "<li>$aID: $result</li>";
      /* Typing $result is the same as typing:
         $students[$sID]['courses']['current'][$cID]['assignments'][$aID] */
    }
    echo "</ul>";
  }
}

The above code will echo out:

  • All of the student's IDs and first names in <h2> tags.
  • All of the student's course codes and course names in <h3> tags.
  • All of the student's assignment name and results in <li> elements.
Arrays and ObjectsLect 9, P.7

Adding and appending to Arrays

By default, the foreach loop will create a copy of the associative array. If you want to modify the values in the array (rather than a copy of the array), use the & character to reference the array elements

foreach ($assocArr as $key => &$value){
  $value = 'something new';
}

Appending to an Array

Appending to an indexed array is simple, just use the square brackets[]:

$indexArr[]='D'; // 'D' is appended to the end of the array

Appending a new element to an associative array is also simple, just specify a new key / value pair:

$indexArr['D']='Deer'; // 'Deer' is added to the array with the key 'D'

Look up the array_push() function too, if you like typing ...

Arrays and ObjectsLect 9, P.8

Printing an Entire Array or Object

The functions print_r() and var_dump() will print out all elements in an array or object in a structured view, even nested arrays (eg a JSON object).

An optional true parameter will cause the function to return the output as a string rather than to print it.

print_r($indexArr);
/* Prints:
   Array
   (
      [0] => A
      [1] => B
      [2] => C
      [3] => D
   )
*/
print_r($assocArr);
/* Prints:
   Array
   (
      [A] => Apple
      [B] => Bear
      [C] => Chair
      [D] => Deer
   )
*/
$output = print_r($assocArr, true);
/* $output contains:
   Array
   (
      [A] => Apple
      [B] => Bear
      [C] => Chair
      [D] => Deer
   )
*/

Tip: When debugging, wrap the output in <pre> tags when outputting to the screen.

Arrays and ObjectsLect 9, P.9

Merging Two Arrays

The functions merge() will merge two arrays.

  • Indexed arrays will be reindexed and no data will be lost.
  • Associative arrays will lose data if duplicate keys exist.

You can merge an indexed and an assocative array, whether you should is another matter!

$dontDoThisArray = array_merge($indexArr,$assocArr);
/* Array contents are now:
   Array
   (
      [A] => Apple
      [B] => Bear
      [C] => Chair
      [D] => Deer
      [0] => A
      [1] => B
      [2] => C
      [3] => D
   )
*/
Arrays and ObjectsLect 9, P.10

Sorting Arrays

There are many different functions that sort arrays.

Indexed (i.e. indices stay fixed)

  • sort() sorts by value, ascending
  • rsort() sorts by value, descending

Associative (i.e. keys move with the value ):

  • ksort() sorts by key, ascending
  • krsort() sorts by key, descending
  • asort() sorts by value, ascending
  • arsort() sorts by value, descending

Indexed and Associative

  • array_keys() takes an associative array, returns a simple indexed array containing all the keys of the array.
  • array_values() takes either an indexed or associative array, returns a simple indexed array containing all the values of the array. This function is useful for re-indexing an indexed array that has gaps caused by unsetting array elements before hand.
Arrays and ObjectsLect 9, P.11

Manipulating Arrays

PHP has a vast library of functions for manipulating and querying arrays.

Removing element(s) from an array

array_splice($indexArr,4,1); // 1 = just remove the 5th element.
unset($assocArr['E']); // Element with key 'E' is removed.

Checking array contents

in_array($value,$indexArr); // returns true or false if $value exists
key_exists($key,$assocArr); // returns true or false if $key exists

"Deck of cards" like functions

shuffle($arr); // Elements are shuffled like a deck of cards;
array_rand($arr,$num); // pick $num random elements from $arr array
array_reverse($arr); // reverse order of array, ie first becomes last etc.

There are many other array functions. As a general rule: "If you can think of it, PHP has an array manipulation function for it." (see http://php.net/manual/en/ref.array.php for more information).

Arrays and ObjectsLect 9, P.12

Form Arrays

A form will submit name and value data. Typically this is straightforward, but sometimes we want data to be submitted as an array, for example an array of checkbox values. To achieve this, we need to add square brackets [] to the end of an input field's name attribute.

What will be submited by the following forms?

<input type='checkbox' name='extras' ... />
Will submit only the last selected box value.
<input type='checkbox' name='extras[]' ... />
Will submit all selected box values.
<select multiple name='extras' ... />
Will submit only the last combo box value.
<select multiple name='extras[]' ... />
Will submit all selected combo box values.
Arrays and ObjectsLect 9, P.13

Form Arrays

For complex forms, we can take arrays one step further and tie logically related form elements together into a multi-dimensional array.

Name a possible value for the following "Pizza shop" items:

<input type=radio name='pizza[size]' ... />
Small, medium, large, family, ...
<input type=radio name='pizza[base]' ... />
Thin, thick, cheesy crust, ...
<input type=checkbox name='pizza[extras][]' ... />
pineapple and/or anchovies and/or bacon ...
<input type=checkbox name='pizza[extras][cheese]' ... />
double or triple or vegan ...

Each pizza order will be submitted in one associative array (more on this soon).

Super GlobalsLect 9, P.14

Super Global Arrays

PHP provides a number of server-side "built in" variables that are always available. Each takes the form of an associative array, e.g.

  • $_SERVER, $_ENV,
  • $_GET, $_POST, $_COOKIE, $_REQUEST,
  • $_SESSION,
  • $_FILES.

http://php.net/manual/en/language.variables.superglobals.php
Coreteaching Superglobals

Super GlobalsLect 9, P.15

$_SERVER array

Server related information is located in $_SERVER array.

Some information is unique to the server:

What is the name of the server?
It's called titan.csit.rmit.edu.au.
What is the server's IP addess?
It's internal IP address is 10.118.128.3.
What webserver software is it running?
It's running Apache.

Other information is unique to the user

Who are you?
You are .
What is your password?
Don't worry, this is not in the $_SERVER array.
What is your IP address?
You are making requests from 52.15.92.58 on port 59069.
Super GlobalsLect 9, P.16

$_ENV Array

$_ENV is another superglobal array that allows variables to be created as part of a multi-process request, ie when parent and child processes are invoked as part of one request.

This is an advanced topic and we won't be using $_ENV in this course.

Super GlobalsLect 9, P.17

$_GET Array

When a user submits name / value data from a form using the get method, the data is sent as part of the URL in the request.

<form action='processing.php' method='get'> ... </form>

The $_GET array will be populated with that data. To try this for yourself, create a processing script inside your wp directory called 'processing.php' and put two lines of code inside:

<h3>$_GET contains:</h3>
<pre><?php print_r($_GET); ?></pre>

Set the action and method of one of your forms to this script and see what happens when you press submit!

Super GlobalsLect 9, P.18

$_POST Array

When a user submits name / value data from a form using the post method, the data is sent as part of the body of the request.

<form action='processing.php' method='post'> ... </form>

The $_POST array will be populated with that data. To try this for yourself, add these lines to your processing script 'processing.php':

$post = print_r($_POST, true);
echo "<h3>\$_POST contains:</h3>
<pre>
  $post
</pre>";

Change the method of the form your are modifying and see what happens when you press submit!

Super GlobalsLect 9, P.19

$_COOKIE Array

hello kitty backpack ad
Based on your purchase history
we know you want this!

Both javascript and a webserver can store data on the user's machine in the form of name / value pairs. These are called "cookies" and are always sent to the server in the body of each request.

Only cookies belonging to a particular website are sent, assuming that the browser has not been hacked or compromised. However many online advertising agencies are able to work around this restriction (legally of course) and insert content based on your purchases from other websites using cookies that have been left on your machine in other websites.

For this reason, localStorage and webStorage are seen as more secure ways to store needed data on users machines as web storage data is not always sent.

To see what cookies have been stored on our machine from this website, add two more lines to your processing script 'processing.php':

<h3>$_COOKIE contains:</h3>
<pre><?php print_r($_COOKIE); ?></pre>

Tip: PHP tracks a user's logged in status and identity using a cookie called PHPSESSID. Look after that cookie, if anyone else gets it, they can hijack your session and pretend to be you!

Super GlobalsLect 9, P.20

$_REQUEST Array

The $_REQUEST array contains all combined request information from $_GET, $_POST and $_COOKIE in one place

  • Advantage: convenient if request method not important. Good for sloppy coders.
  • Disadvantage: If elements have same name, information will be over written. Encourages sloppy coders.

To see which variable is in $_REQUEST when there is a conflict, modify your form action to processing.php?buy=hello-kitty-backpack and create a submit button with the name buy and the value goodbye-kitty-backpack.

Add two more lines to your processing script 'processing.php':

<h3>$_REQUEST contains:</h3>
<pre><?php print_r($_REQUEST); ?></pre>
Super GlobalsLect 9, P.21

$_FILES array

When a user uploads a file (or many files) an array of files is sent to the server. Each file has the following properties:

  • name: e.g. "myscreenshot.png
  • type: e.g. "image/png"
  • error: e.g. 0 is ok, 3 is partial upload
  • size: how many bytes it takes up
  • tmp_name: a temporary name where the file is saved temporarily.

Once a file has been checked for size, type etc, it can be moved to a more permanent place. Checking the file extension is a quick way of making sure no easily executable files have been uploaded (eg files with a '.exe' extension that contain malware).

In the Coreteaching Superglobals page, there is a testing form that submits GET, POST and FILES data to the server. Have a play and verify that you understand what is happening at each step.

Super GlobalsLect 9, P.22

$_SESSION Array

The $_SESSION array is a private store of information for each user accessing the server and is stored server-side, ie where users and third parties can't access it.

Each user has their own array, so if there are 100 users browsing the website, there will be 100 session arrays. When coding, you can be sure that the content of the array relates exclusivly to the user accessing the page.

We will look at the SESSION array in more detail next week.

Processing Form DataLect 9, P.23

A Restaurant Analogy

The processing of receiving a user request and preparing a response page is very similar to what happens inside a restaurant kitchen:

A Chef

  • Receives an order & instructions.
  • Checks order, makes sure it makes sense and ingredients are available.
  • Rejects invalid order, states problems, asks for a valid order.
  • Prepares a dish using ingredients.
  • A cooked dish leaves the kitchen.
  • Floor staff at the client's table adds pepper, parmesan 'in real time".

A Webserver

  • Receives a request & form data
  • Checks request data, makes sure it makes sense and resources are available.
  • Rejects invalid request, places error messages in response page.
  • Prepares a page using PHP.
  • HTML page leaves the server.
  • Javascript on the client's machine interacts with the user "in real time".
Processing Form DataLect 9, P.24

The Webserver's Workflow

  • When a server receives a request, the client will have sent GET or POST information to the server from a form.
  • Form data (i.e. request data) allows the server to prepare a custom dynamic page for the client using PHP
  • The server has no further involvement once all the PHP has been converted into HTML, and the page leaves the server.
  • The server waits for the next request (i.e. the next request / form submission)

For this reason, it is wise to process as much POST and GET data at the top of a PHP file, before starting to output HTML.

If you start printing HTML before all request data has been processed and the logical flow has been created, you may run into problems.

This would be like a chef starting to cook a dish without knowing what all the ingredients and instructions for preparation are.

Processing Form DataLect 9, P.25

Tracking Input Errors

During input validation, you can track user input errors using a boolean, eg

$errorsFound = false;
...
if (!isset($_POST["name"])) {
  $nameError = "Name cannot be blank";
  $errorsFound = true;
}
...
...
if (!$errorsFound)
  $message = "Here are your results ...";
else
  $message = "There are errors in your form";
Processing Form DataLect 9, P.26

Tracking Input Errors

Using a counter does allow you to track how many errors have been detected, eg

$errorsCount = 0;
...
if (!isset($_POST["name"]) {
  $nameError = "Name cannot be blank";
  $errorsCount++;
}
...
...
if ($errorsCount == 0)
  $message = "Here are your results ...";
else
  $message = "There are $errorsCount errors in your form";
Processing Form DataLect 9, P.27

Page Redirection

PHP allows you to invisibly redirect a user's request uing the header() function.

This must be done before any HTML has been written. For example in the original processing page, we can redirect any user that comes to the page without POST data:

if(count($_POST) <= 0) {
  header("Location: bmi-form.php");
} else {
  // POST data processing and message printing code goes here
}

It is possible to create a "processing only" script that outputs no HTML and redirects the user to different pages:

if(empty($_POST)) {
  header("Location: bmi-form.php");
} else {
  // POST data processing here, no HTML output
  if ($errorsFound) {
    header("Location: bmi-form.php");
  } else {
    header("Location: bmi-result.php");
  }
}
Processing Form DataLect 9, P.28

Page Redirection

A PHP script can be just a processing script (i.e. does some calculation, writes to a file, etc.) that outputs no HTML, and redirects users to a success page or back to the referring page:

  // Data processing code goes here
  if ($errorsFound)
    header("Location: " . $_SERVER["HTTP_REFERER"]);
  else
    header("Location: success.php"); 

You can also redirect to error pages, e.g. "page not found":

  if ($didnt_enter_secret_code)
    header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found");
  else {
    // Show secret stuff
  }
Processing Form ExampleLect 9, P.29

Body Mass Index (BMI) Calculator

We are going to look at three pages that use the POST method. The pages rely on a semi-scientific formular that calcuates a persons fitness with the following equation:

BMI = weight_in_kg / (height_in_m)²

http://en.wikipedia.org/wiki/Body_mass_index

  1. A static form page that collects and sends height and weight information.
  2. A dynamic processing page that calculates a Body Mass Index (BMI) or prints a message if invalid data is entered.
  3. A combined form and processing page that does both tasks.

We will look at the first two pages that work in tandem, then we will look at the third page that combines the first two pages into one.

Processing Form ExampleLect 9, P.30

Analysis

The BMI example has separate pages for the collection and processing of data. There are some issues:

  • Users have to swap back and forth, especially if they have made a mistake.
  • Users can reach the processing page. This page should not be accessed directly
  • Usability is poor, not user friendly

Usability will be improved by combining the form and processing pages into one page.

Processing Form ExampleLect 9, P.31

Body Mass Index (BMI) Calculator v2

We need to see things from the server's point of view, how should the server behave when requests for the third script arrive?

First time, no POST data is present to process

  1. Print out standard message and form.

Subsequent times, when invalid POST data is received

  1. Print out standard message and form.
  2. Pre-fill input fields with the previous user entries.
  3. Print out error messages next to input fields.

Subsequent times, valid POST data is received

  1. Print out results in message area.
  2. Reprint submitted data into the inputs, or not (your choice).
Processing Form ExampleLect 9, P.32

Body Mass Index (BMI) Calculator v2

If this was a restaurant ...

First time, no order to process

  1. Give the customers a food & drink menu.

Subsequent times, order not valid

  1. Tell the customer which items aren't on the menu.
  2. Ask the customer to re-order from the menu.

Subsequent times, order valid.

  1. Prepare the customer's order.
  2. Deliver the customer's order.
Processing Form ExampleLect 9, P.33

Body Mass Index (BMI) Calculator v2

A combined version resembling both previous versions can be found here: combined script.

By setting the form's action attribute to the same script and rewriting the script, the new version will appear to the user to be the same page:

If you look carefully, you will see that there is a page refresh after submitting. The faster and closer the server, the less obvious this refresh will be.

Some things to note:

  • All of the form processing code is at the top of the page before any HTML is outputted.
  • Variables are created to act as flags, hold messages, error messages etc. This is unlike Javascript where interactive code may be scattered throughout the page.
  • HTML is only outputted when all of the Request data has been processed.
  • All processing happens on server, before a page is created and delivered to the client. No PHP code is returned to the client, only HTML, Javascript, CSS code etc.
Form Data ValidationLect 9, P.34

Validating User Input

1950s grocery store, woman is checking out groceries and being served by a man. Woman claims purchases comes to a dollar, man incorrectly assumes the customer is rightIn a previous lecture we saw that certain types of form data can be trusted (product codes, quatity etc) but other types should not (pricing in particular).

Streamlining the form input entry process, locking down input options and using javacript to perform rudimentary checks makes sure that "honest" users don't submit faulty data solves most of the problem, but we also need to protect the server from what "dishonest" users can do:

  • Disabling Javascript (ie both honest and dishonest users).
  • Going into the browser inspector, changing field names and values.
  • Creating their own pages and scripts to submit data to your server.
  • Putting code into inputs (javascript, SQL code etc) to be stored and run on your server in order to manipulate your database or launch a cross site scripting (XSS) attack.
  • Uploading files that contain malevolent code.

Most examples can be prevented just by treating the user input. We will look at a few examples, but this topic will be covered in more detail in other courses.

Form Data ValidationLect 9, P.35

Cross site scripting (XXS) attack

Javascript prompt box falsly claiming that the user's session has expired and asking for login credentialsWhen another user comes to a page that loads the previous user's blog post, the script is run and this second user can be tricked into thinking that this script is part of the website's normal process.

This kind of attack can occur when a user enters javascript into a text area, such as a blog post, that is stored by the server "raw", ie without being inspected and processed.

Form Data ValidationLect 9, P.36

SQL Injection Attack

This kind of attack can occur when a user enters quotes and SQL code into a text area, such as a blog post, that is stored by the server into a database "raw:, ie without being inspected first.

Comic taken from XKCD: Mother on phone to school who has lost their students table from their database owing to non-sanitised input of her son's unusual name.
Taken from https://xkcd.com/327 with permission

When the string is being processed for storage in the database, the script component can run and augment the database. this may be code to remove data or exploit weaknesses in order to gain access to the data.

Form Data ValidationLect 9, P.37

Input sanitisation

As outlined, these attacks are caused by unescaped characters from user input.

Cross site scripting fix

Convert tags in string to html entities, e.g.
<script> becomes &lt;script&gt;.

Or remove the tags entirely, eg
<script>... code ...</script> becomes ... code ....

SQL Injection fix

Escape quotation characters, e.g.
Tom"; delete all databases becomes Tom\"; delete all databases

^^ Or use prepared statements (not covered in this course)

Form Data ValidationLect 9, P.38

String Treating Functions

PHP offers many encoding and decoding html entity functions to "deactivate" dangerous user input. These functions are similar but there are some subtle differences and flags can be used to fine-tune behavior.

  • htmlentities()
  • html_entity_decode() (inverse of above)
  • htmlspecialchars()
  • htmlspecialchars_decode() (inverse of above)

If you are sure that you want to remove all tags rather than encode them, you can use the strip_tags() function instead.

If you would like to know more about the problems touched on, the videos below explain each issue in more detail:

https://www.youtube.com/watch?v=L5l9lSnNMxg
https://www.youtube.com/watch?v=_jKylhJtPmI
https://www.youtube.com/watch?v=vRBihr41JTo

Form Data ValidationLect 9, P.39

Validating and Sanitising Function

Common validation tasks can be performed using the filter_var() function with different flags.

  • Validation, returning true or false
  • Sanitising, cleaning up a string or array

What do the following versions do?

filter_var($email, FILTER_VALIDATE_EMAIL);

The function will return true if the string $email conforms to an email address. It will return false if it does not.

filter_var($numSeats, FILTER_VALIDATE_INT);

The function will return true if the string $numSeats conforms to an integer. It will return false if it does not.

filter_var($url, FILTER_VALIDATE_URL)

The function will return true if the string $url conforms to a url. It will return false if it does not.

Form Data ValidationLect 9, P.40

Validating and Sanitising Flags

Using a different flag, the filter_var() function can be used to sanitize a string, i.e. strip out or escape offending characters.

if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
  $errorCount++;
  $cleanEmail=filter_var($email, FILTER_SANITIZE_EMAIL);
  $emailError="Did you want to type $cleanEmail?";
}
What is the above function doing?

The FILTER_VALIDATE_EMAIL flag is used on the first line and a true or false will be returned.

If the test returns false, the number of errors detected is incremented and the string is examined a second time with the function BUT this time the FILTER_SANITIZE_EMAIL flag is used, which will return a 'cleaned up' string

Essentially, when the server detects a bad email address, it presents a "best guess" back to the user.

Welcome!Lect 10, P.1

Web Programming
COSC2413 / 2426 / 2453

Lecture 10 - PHP 3

Lecture 10Lect 10, P.2
  1. PHP Regular Expressions
  2. Maintaining State
  3. File Handling
  4. Handling Delimited Data
PHP Regular ExpressionsLect 10, P.3

PHP Regular Expression Support

PHP used to support two types of regular expression syntax, but modern PHP only supports one type:

  • PCRE: Perl flavour, supported version, use it.
  • POSIX: Unix flavour, deprecated in PHP 5.3, removed in PHP 7.

You only need to learn the PCRE version in this course, but you may find yourself upgrading or maintaining an old website that uses the POSIX syntax.

Unlike javascript, PHP requires patterns to be both quoted and delimited. That said, PHP allows you to use an alternative delimiter if / is inconvenient:

$pattern1 = "/^https:\/\//"; // Hard to read, the "/\"s look like mountains.
$pattern2 = "#^https://#";   // Easier to read, no mountains.
$pattern3 = "\^https://\";   // Don't do this, you have lost the ability to escape characters!
PHP Regular ExpressionsLect 10, P.4

PHP preg_match

The preg_match() function takes a pattern and a string as parameters and returns true or false, e.g.

if ( preg_match("/^Steve[ ].*$/", $name) ){
  // code for those called Steve.
} else {
  // code for those NOT called Steve.
}

As long as the string $name starts with "Steve", the function will return true.

PHP Regular ExpressionsLect 10, P.5

PHP preg_replace

The preg_replace() function takes a pattern, a replacement string, and a subject string as parameters. Any sub-strings within the subject string matching the pattern will be replaced with the replacement string, e.g.

$patt="/(Stephen|Stephanie)/";
$repl="Steve";
$subj="Stephen and Stephanie rock!";
echo preg_replace($patt, $repl, $subj);
What is printed above and why?

Two substrings "Stephen" and "Stephanie" will be replaced with the string "Steve", so the printed string will be "Steve and Steve rock!".

Tip: For advanced users only, this function also allows the subject and pattern parameters to be arrays of strings. Several checks can be combined into one when using this feature.

PHP Regular ExpressionsLect 10, P.6

PHP Atomic Matches

We can also use atomic matches, usually found in parethesis () to form part of the replacement string. Each atom detected is assigned a reference $1, $2 ... etc. in the order it is found in the pattern string. Consider the following code:

$date="December 23rd 2024";
$patt="/(\w+) (\d+\w*) (\d{2,4})/";
$repl="$2 $1 $3"; // swap month and day
echo preg_replace($patt, $repl, $date);
What is printed above and why?

This example reverses the month and day in a U.S. style date and prints it out as 23rd December 2024.

  • $1 contains the (\w+), ie the name of the month
  • $2 contains the (\d+\w*), ie the day number with optional 'th' or 'st' etc.
  • $3 contains the (\d{2,4}), ie the 2 or 4 digit year.
PHP Regular ExpressionsLect 10, P.7

PHP Valid Date Regex

Write a regular expression to detect a valid date ...

  • 1/1/15
  • 1/01/2015
  • 31/12/2015

... and reject an invalid date.

  • 31/13/2015 (There is no 13th month)
  • 31/9/15 (30 days hath September ...)
  • 29/02/2015 (2015 was not a leap year)
  • 10/10/1582 (Pope Gregory cancelled this date)
Maintaining StateLect 10, P.8

Identifying Users

Diagram of Client and Server requests and responses for home page and cart pageA server receives requests from many users. When logged into a webserver (eg Google Drive, Facebook, your bank etc), the server is able to distinguish your requests from other user requests, for example:

  • Anyone on the Internet
  • RMIT students on campus
  • Housemates
  • People sharing a computer or laptop.
  • Separate browser windows on your machine.

HTTP has no built-in way of carrying state from page to page.

This means that when a user clicks a link on page 1 and moves to page 2, the server has no way of knowing if it is the same user.

This is fine for downloading static hypertext files (i.e. "browsing the web", visiting a home page) but it is very problematic when we want to provide an application-style interface and server dynamic hypertext (i.e. when shopping, visiting a cart page).

Maintaining StateLect 10, P.9

How does a webserver know it's you?

Falero Luis Ricardo Lily Fairy 1888How is this done? Is there a magic session fairy that looks after all of this? What can be used to determine the identity of a user?

My IP address, ie where I make requests from?

A first guess is to check the IP address of the user, for example your request to this server came from 52.15.92.58 which is near SUBURB isn't it?

Not a bad idea, but unfortunately many other users make requests from "subnets" inside larger organisations (e.g. RMIT Campus, your internet at home), so many users share a "public" IP addresses.

Can we give each user their own private port number to use and track them that way?

This is also a good idea. Your initial request for this page using the HTTPS protocol came though on port 443, but the server responded to your request on port 59069. It would not be hard to get each user to stick with a port number.

Unfortunately this approach alone would be susceptible to port hijacking as there are only 65,535 possible port numbers, even if it is just your housemate that is spoofing your IP address and port number.

Can we store secret information unique to each user?

This is how PHP currently works, for example your current session id is ............. (middle digits obscured for security reasons). See https://titan.csit.rmit.edu.au/~e54061/secure/superglobals.php for full detail of your client-side and server-side session ids.

Tip: If nothing is showing above, that means the server hasn't received your cookies yet, refresh the page and your session cookie will be shown.

Maintaining StateLect 10, P.10

Transmission of Session ID

Diagram of Client and Server requests and responses for home page and cart page with session id cookieIn each user's browser, a unique session id is created, stored as a cookie named PHPSESSID on the client's machine. This cookie is transmitted to the server on each request.

PHP uses this information to re-identify each user on each request and allows the developer to feel confident that the response will be customised and delivered to the right person.

If cookies are disabled on the user's machine, PHP will embed the session ID into the URL as a fallback transmission method. This is not secure or ideal, but it's better than nothing.

This means that you can have multiple browsers open on your machine and the server will recognise requests from each browser as requests from separate users.

Maintaining StateLect 10, P.11

PHP Session Duration

Sessions do expire (timeout):

  • If a user is inactive for a period of 1440 seconds (24 minutes), the session will expire.
  • Servers can be configured to have shorter sessions (e.g. banks) and longer sessions (e.g. coreteaching servers).
  • A user with an expired session will usually have to log in again.
  • Cookie propagation improves process: the session cookie will be destroyed when the user closes the browser. It is not unusual for sessions to "come back to life" (internet cafe users beware!).

These timeout periods can be adjusted on the server side in PHP configuration files (e.g. php.ini):

session.cookie_lifetime = 0
session.gc_maxlifetime = 1440
Maintaining StateLect 10, P.12

Session Re-activation

Many websites, including banks, will have a "remember me" checkbox option, but only the username is stored. The user will still have to enter (or re-enter) a password to create a new session profile and log in.

However, many websites (e.g. Facebook, Gmail, Twitter...) have a "remember me" checkbox option that allows a complete authentication bypass, i.e. the user does not need to enter a password to create a new session profile and log in.

Login information stored in "long life" cookies are sent to the server, and a new session is created. This gives the user the illusion that they had not been logged out, even if their device has been switched off, etc.

Of course, such a "remember me" setting is only as secure as access to your client device is ...

Maintaining StateLect 10, P.13

$_SESSION array

The server keeps store of information unique to each user serverside inside a personalised $_SESSION superglobal array. If there are 100 users accessing the server, there will be (up to) 100 unique $_SESSION arrays and no user has access to another user's session data.

When you write code that refers to this array, you can be assured that the data present in this array is particular to each user.

Applications such as maintaining a shopping cart or serving content to logged in users can be supported. For example:

$_SESSION["cart"]["P01"] = $_POST["P01"];
What does the above code do?

This "hard coded" code adds a quantity of items with the product code P01 that is present in the POST array (ie that has been submitted via a web form) to a serverside shopping cart like variable in the SESSION array. There are more efficient ways of adding all the POST data to the SESSION, but this is a good starting point.

foreach ($_SESSION["cart"] as $productID => $quantity) {
  // print out the quantity of each product ordered
}
What does the above code do?

The foreach loop extracts the cart branch into a series of productIDs (keys) and quantities (values). A shopping cart summary can be constructed using this code.

if (isset($_SESSION["user"])) {
  // print out information available only to those "logged in"
}
What does the above code do?

The if block checks to see if there is a user branch inside the session. If so, content intended only for users who are "logged in" can be shown.

Maintaining StateLect 10, P.14

Modifying $_SESSION array

In PHP a session is started (or "resumed") using the session_start() function. Without this function, a page will not have access to the user's session array, which is an easy mistake to make.

<?php session_start(); ?>

Session information, unique to each user, is easily stored in the $_SESSION superglobal array. For example, a login script can set up a user information branch in the session once authenticated.

$_SESSION["user"]["firstname"] = "Alice";
$_SESSION["user"]["lastname"] = "Liddell";
$_SESSION["user"]["email"] = "alice@wonder.land";

Session information can be easily removed with the PHP function unset(), for example a user can be logged out by removing the user information branch ...

unset($_SESSION["user"]); // removes ALL of Alice's personal details

... and a cart can be emptied by removing the cart branch.

unset($_SESSION["cart"]); // removes ALL of Alice's shopping items
Maintaining StateLect 10, P.15

Cookies

Diagram of Client and Server requests and responses with cookie transmissionCookies are variables that are stored on the client's machine, and can be set using client side or server side code.

As discussed, PHP sessions make use of cookies (by default), but you may want to set or manipulate cookies directly for other reasons.

In the past, cookies were the only way of storing data long term client side, but it is recommended to store data in localStorage and webStorage in modern web applications.

Maintaining StateLect 10, P.16

PHP setcookie()

To set a cookie on the client's machine, use PHP's setcookie() function. The function takes three parameters, a name, a value and an expiry time, which represents the number of seconds that will have elapsed since midnight 1st January 1970 (currently 1734936752 seconds).

What do the following code samples do?

setcookie('firstname', 'Alice', 0);

A cookie with the name firstname and value Alice is created.

The 0 lets the browser know that this cookie is to expire at the end of the session.

In other words, this is a session cookie.

setcookie('firstname', 'Alice', time()+3600);

A cookie with the name firstname and value Alice is created.

The time()+3600 lets the browser know that this cookie is set to expire whenever "now" is (see top), plus 3600 more seconds.

In other words, this cookie will expire in an hour.

setcookie('firstname', 'Alice', time()+60*60*24*30);

A cookie with the name firstname and value Alice is created.

The time()+60*60*24*30 lets the browser know that this cookie is set to expire whenever "now" is (see top), plus ... let me get my calculator out ... tappity ... tappity ... tap tap tap ... 2592000 seconds.

But if you look closely at those numbers, it should be obvious that the cookie will expire in 30 days.

setcookie('firstname', 'Alice', 1);

A cookie with the name firstname and value Alice is created and 1 lets the browser know that this cookie expired one second past midnight 1st January 1970.

In other words, this is a quick way to destroy a cookie.

Maintaining StateLect 10, P.17

$_COOKIE array

Once the server receives a copy of the client's cookies, they are stored in an array on the server called $_COOKIE. These should be read only and changing them does not affect the client's cookies, eg.

$_COOKIE["firstname"] = "Bob";

Only changes the server's copies of the client's cookies, not the actual cookies stored on the client's machine.

session_start();
setcookie("firstname", "Bob", time()+3600);
$_SESSION["user"]["firstname"]= "Bob";
// some more code ...
echo $_SESSION["user"]["firstname"];
echo $_COOKIE["firstname"];
What does the above code do?

PHP starts or resumes the session, prepares a cookie for transmission to the client, sets a firstname variable in the $_SESSION array.

After "some other code" is executed ...

PHP saves a cookie to the client's machine and prints the $_SESSION value "Bob" to the screen.

If a cookie with the value "firstname" was transmitted to the server on the previous request, its value from $_COOKIE is printed BUT it is not guarenteed to be "Bob".

If the client refreshes the page (ie makes another request), then the value of the $_COOKIE variable will become "Bob".

File HandlingLect 10, P.18

Long Term Data Storage

Session handling functionality is convenient for handling data while a user is active. However, to maintain data in the longer term, we need to use persistent storage.

Two main storage options are:

  • A database
  • A file

A relational database management system (RDBMS) is a software system designed to efficiently store and retrieve data that provides better support for transaction management and data integrity.

PHP offers functionality for interacting with RDBMSs, but this is an advanced topic and is covered in detail in follow-on courses such as Web Database Applications and Database Concepts.

For this reason, we will focus just on file handling, i.e. reading from and writing to files.

File HandlingLect 10, P.19

Storing data in files

Storing data in a text file is conceptually similar to typing a text document in an editor (vi, notepad++, ...) and saving it. In our scripts, we therefore typically need to:

  • Open a file
  • Lock a file (ie restrict access)
  • Read from a file
  • Write to a file
  • Unlock a file (ie restore access)
  • Close the file

PHP supports the creating and deleting of files, but RMIT University has imposed certain security restrictions on the Coreteaching servers, so you must create the file first and set permissions to 606 (ie read-write for you (the user) and read-write for the PHP and the world.

Once this is done, yout PHP scripts can modify the content of the file.

File HandlingLect 10, P.20

Storing data in files

Data can be stored in files in a "flat file" format, ie where the content is unstructured and undescribed, or in a more structured format where content is structured and described.

The following file formats range from no structure or description to:

  • Plain text, unstructured (eg a 'notepad' memo)
  • HTML (eg a shopping receipt, but with information stored inside semantic elements)
  • Plain text, with delimiters (eg a spreadsheet with a row and/or column of headings)
  • JSON and XML (eg text stored in a tree-like data structure)

The term "flat file" usually refers to formats that are pure text or, whereas formats that contain markup.

File HandlingLect 10, P.21

File Loading and Manipulation

You can load and manipulate a file in two main ways.

  1. One shot, i.e. load the entire file into memory, manipulate the content, write the whole file back.
    • Benefit: easier access to file content
    • Disadvantage: memory intensive, all file data is held in memory.
  2. Step through, i.e. read one line at a time into memory and manipulate it.
    • Benefit: less memory intensive, more flexible
    • Disadvantage: harder to program, easy to leave files open and block file access to other processes.

Tip: If manipulating a file, it is often easier and more time efficient to read what you need into memory, manipulate the data then write back to the file.

File HandlingLect 10, P.22

Reading from a (flat) file

To read an entire file into memory "in one shot" as an indexed array of lines, use the PHP file() function.

$lines = file($filename);
echo "<ol>";
foreach($lines as $line)
  echo "<li>$line</li>";
echo "</ol>";
What does the above code do?

PHP finds a file in the current directory with the name stored in the variable $filename and opens it for reading.

The file() function extracts each line and places the content into the array $lines. Once the end of the file is reached, the file will be closed. If there are 50 lines in the file, $lines will have 50 elements.

The rest of the code creates an <ol> block with each line inside an <li> element. A for loop could be used here just as easily, but the author likes the simplicity of foreach loops.

An example of this can be found in the footer of each file located in the secure directory.

https://titan.csit.rmit.edu.au/~e54061/secure

Alternatively, to read an entire file into memory as a single string, use the file_get_contents() function.

File HandlingLect 10, P.23

Writing to a (flat) file

To write out to a file from memory "in one shot", use the PHP file_put_contents() function.

if ( $numBytes = file_put_contents($filename, $linesOrBigString) )
  echo "File Saved, $numBytes bytes written.";
else
  echo "File Access Error. Does $filename exist and have 606 permissions?";
What does the above code do?

PHP finds a file in the current directory with the name stored in the variable $filename and attempts to open it for writing.

The file_put_contents() function is quite clever: if $linesOrBigString is a simple string, the string will be written BUT if it is an array of lines, it will write each array element and put a \n character on the end so that the file will contain a list of lines. Once complete, a confirmation message with the new file size will be written.

If any problems arise with opening the file or writing to the file, the function will return false and a failure message will be written. Usually insufficient file and/or directory writing permissions are to blame (hint hint).

When writing to a file, you should place an exclusive lock the file with a LOCK_EX flag so that no other process can access it during the writing.

file_put_contents($filename, $linesOrBigString, LOCK_EX);

It is also possible to append data to a file with a FILE_APPEND flag.

file_put_contents($filename, $moreLinesOrBigString, LOCK_EX | FILE_APPEND);
File HandlingLect 10, P.24

Reading a file line by line

Reading a file one line at a time offers greater flexibility, but you need to use a combination of several functions.

  • fopen() opens the file and creates a "file pointer" or handler
  • flock() locks a file to restrict or prevent access to others.
  • fgets() gets a single line.
  • flock() also unlocks a file to restore access.
  • fclose() closes a file.

We can also manipulate the file pointer position.

  • ftell() gets the file pointer's position.
  • fseek() moves the file pointer.
  • rewind() moves the file pointer to start.
File HandlingLect 10, P.25

Reading, Writing, Appending

A file can be opened in different modes.

  • r reading, file contents are unaffected.
  • w writing, previous file contents are erased.
  • a appending, previous file contents are preserved, new content is added to the end of the file.

Modes can be combined (eg r+, w+, and a+). The a+ option is particularly useful as you can read from the file without affecting the writing position, new content is appended to the end of the file.

Tip: Generally, it is sensible not to open a file for more than one purpose, unless you sure that you know what you are doing, as you may accidentally alter or erase the file contents.

File HandlingLect 10, P.26

Locking

More than one user can access a file at any one time, so when reading from or writing to a file, it is important to anticipate what other users might be doing.

The function flock() augments access of other users during file operations.

  • LOCK_SH Shared or "read only" lock. Others can read but not write, useful when reading from a file or when writing and you are sure changes you are making are not significant.
  • LOCK_EX Exclusive or "write" lock. Others have no access, useful when when writing to a file and partial changes will affect data integrity.
  • LOCK_UN Unlock or remove lock. Access restrictions for others are removed.

Tip: When using an exclusive lock, optimise your code to keep the file locked for as short a time as possible, and don't forget to unlock the file when done!

File HandlingLect 10, P.27

Example: Reading Line by Line

When reading from a text file, use the r mode of fopen().

Place a shared lock on the file using flock() so that other processes can read from but not write to the file whilst reading.

if( ($fp = fopen($filename, "r")) && flock($fp, LOCK_SH) !== false ) {
  echo "<ol>";
  while( ($line = fgets($fp)) !== false )
    echo "<li>$line</li>";
  flock($fp, LOCK_UN);
  fclose($fp);
  echo "</ol>";
} else {
  echo "File unavailable, check file or check back later.";
}
What does the above code do?

When PHP finds a file in the current directory with the name stored in the variable $filename, opens it for reading and returns an active file pointer to $fp so that more file operations can be made on the file.

The flock() function locks the file in shared mode, meaning others can read from it but noone can write to it. This is because the developer doesn't want the file contents to changed by another process during the read.

The fgets() function extracts one line at a time and places the content into the variable $line. Once the end of the file is reached, the fgets() function returns false which terminates the while loop, the file is unlocked by flock() and file will be closed with the fclose() function.

The rest of the code creates an <ol> block with each line inside an <li> element. It differs from the "one shot" code in that only one line of the file is in short term memory at any one time BUT the file is open for longer and may cause concurrency issues if manipulated by other processes whilst open.

Note that the file opening and closing statements are placed as close together as possible.

File HandlingLect 10, P.28

Writing to a file

When writing to a text file, the w mode of fopen() will remove any existing lines, so make sure you actually intend to reset or empty the file first!

Place an exclusive lock on the file using the PHP function flock() so that other processes can't read from nor write to the file whilst writing.

if( ($fp = fopen($filename,"w")) && flock($fp, LOCK_EX)) !== false ) {
  fwrite($fp, "Here is the first line\n");
  fwrite($fp, "Here is the second line\n");
  flock($fp, LOCK_UN);
  fclose($fp);
}
What does the above code do?

PHP finds a file in the current directory with the name stored in the variable $filename, opens it for writing, erasing the file contents, and returns an active file pointer to $fp so that more file operations can be made on the file.

The flock() function locks the file in exclusive mode. Other processes cannot read from or write to the file whilst this process is running.

The fwrite() function inserts one string at a time. Not that we have to add a line feed character\n to the end of each string as this function does not assume we wish to write lines to the file.

Once the 2 lines have been written, the file is unlocked by flock() and file will be closed with the fclose() function.

File HandlingLect 10, P.29

Appending to a file

When writing to a text file, the a mode of fopen() will leave existing lines alone and add new lines to the end of the file.

if( ($fp = fopen($filename, "a")) && flock($fp, LOCK_EX) !== false ) {
  fwrite($fp, "Here is a new line\n");
  fwrite($fp, "Here is another new line\n");
  flock($fp, LOCK_UN);
  fclose($fp);
}
What does the above code do?

PHP finds a file in the current directory with the name stored in the variable $filename, opens it for appending, preserving the file contents, and returns an active file pointer to $fp so that more file operations can be made on the file.

The flock() function locks the file in shared mode, meaning others can read from it but noone can write to it. This is because the developer has made a decision it is ok for other processes to read data during the append, a decision that may or may not be correct.

The fwrite() function appends one line at a time. We have to add a line feed character\n if we want lines as this function does not assume we are writing one line at a time.

Once the 2 lines have been appended, the file is unlocked by flock() and file will be closed with the fclose() function.

Handling Delimited DataLect 10, P.30

Delimited files

A delimited file is still a flat file, but each line contains "cells", each separated by a delimiter.

A spreadsheet is a good example of a 2D delimited file, with rows separated by a new line character \n, \r, or \r\n; and separated into columns by a character such as tab \t or comma ,.

We will look at PHP's dedicated spreadsheet handling functions shortly, but let's look at a more general case where cells inside the file are delimited with | characters and records/rows are delimited with \n characters.

Joe|Bloggs|s3457535|CSIT|2015\n
Jane|Doe|s8645753|Physics|2013\n
Fred|Simms|s3543574|CSIT|2014\n
Handling Delimited DataLect 10, P.31

PHP explode function

A single string that has delimiter characters can be split up and placed into an array using the PHP explode() function. The first parameter is the delimiter character and the second parameter is the string to split up.

if( ($fp = fopen($filename, "r")) && flock($fp, LOCK_SH) !== false ) {
  while( ($line = fgets($fp)) !== false )
    $records[] = explode("|", $line);
  flock($fp, LOCK_UN);
  fclose($fp);
  echo "<p>{$records[1][2]}</p>";
}
What does the above code do?

Hopefully you should understand the file operations from the previous slide examples, but to get started, an array variable $records is created and will eventually reference a 2D array.

The while loop reads a line from the file and appends it to $records array BUT ...

... before that happens, the explode() function converts the line into an array of cells, for example on the first loop the array ['Joe','Bloggs','s3457535','CSIT','2015'] will be appended to $records.

Once the file is closed, a single cell from the 2D array is printed to the screen. In this case, [1] refers to the second line and [2] refers to the third cell, ie s8645753.

Handling Delimited DataLect 10, P.32

PHP implode function

Elements in an array can be turned into a single string with delimiter characters using the PHP implode() function. The first parameter is the delimiter character and the second parameter is the array to merge.

$records;
if( ($fp = fopen($filename, "a")) && flock($fp, LOCK_EX) !== false ) {;
  foreach($records as $record)
    fwrite($fp,implode("|", $record)."\n");
  flock($fp, LOCK_UN);
  fclose($fp);
}
What does the above code do?

To begin with, the array variable $records is assumed to be a 2D array populated by the code on the previous slide.

The foreach loop selects a single record array from the $records array and writes it to the file BUT ...

... before that happens, the implode() function converts the record array into an single string with delimiting characters, for example on the first loop the string "Joe|Bloggs|s3457535|CSIT|2015\n" will be appended to the file.

Handling Delimited DataLect 10, P.33

RCF4180 CSV Format Standard

One of the problems with delimited data is anticipating delimiting characters as part of the data. Also, there are times when you want to have line feed inside a data cell, how will you know whether this is data or the end of a row?

The RCF4180 CSV Format Standard outlines formatting rules for data and structure characters that we should be aware of:

  • , is a delimiter character that separates cells on a single line. Its purpose is the same as the | character we saw in earlier examples.
  • " is an optional enclosure character that wraps around cell content. These must be used when a comma or line feed, delimiter and enclosure characters are present within a cell.
    For example the comma and line feed characters in the cell "some data,\n and some more data in the same cell" when wrapped in quotes will be interpreted as data and not as structure.
  • " must also be used to "escape" a double quote character, for example she said ""I do"" and he said ""cool bananas"" will be interpreted as she said "I do" and he said "cool bananas"
  • \ is the escape character and must be used when turning a literal character into a meta character within a cell. For example the literal characters t and n can be turned into the meta characters tab \t and line-feed \n respectively.

As you can imagine, coding for all these eventualities can be taxing for your average developer!

Handling Delimited DataLect 10, P.34

PHP Spreadsheet Handling Functions

PHP has created two functions to handle the reading fgetcsv() and writing fputcsv() of plain text to a csv spreadsheet. These functions look after all the formatting "edge cases" when reading and writing data, so we can concentrate on developing.

We will examine the following csv file when using these functions:

First Name,Last Name,Student ID,School,Enrolled\n
"Robert""); Drop TABLE Students-- ?\n",Bloggs,s3457535,CSIT,2015\n
Jane,Doe,s8645753,Physics,2013\n
Fred,Simms,s3543574,CSIT,2014\n

See https://xkcd.com/327/ for more information on this "edge case".

Handling Delimited DataLect 10, P.35

PHP fgetcsv() function

The fgetcsv() function reads one line of an open file at a time and returns an array of cells OR false if the end of the file is reached.

One extra parameter that is needed is length which indicates the maximum number of characters on a line to read. Luckily the default value is 0, which means unlimited, ie the whole line.

Examine the following file reading code:

if( ($fp = fopen($filename, "r")) && flock($fp, LOCK_SH) !== false ) {
  $headings = fgetcsv($fp);
  while( ($aLineOfCells = fgetcsv($fp)) !== false )
    $records[] = $aLineOfCells;
  flock($fp, LOCK_UN);
  fclose($fp);
  echo "<p>{$headings[3];}</p>";
  echo "<p>{$records[0][0]}</p>";
}
What does the above code do?

PHP finds the csv file opens it for reading, puts a shared lock on the file.

The first line of a csv file usually contains headings, so if a developer is sure that this is the case, an array of heading cells can be placed inside a $headings variable.

The while loop will read each line of the file and will have no problems interpeting characters in the first cell "literally". An array of cells will be appended to the variable $records. Note that there is no need to put any code inside the while loop!

When the file is read, the file is unlocked and closed. Two cells are printed, the first is a heading cell containing School and the second is a record cell containing Robert""); Drop TABLE Students-- ?\n

As you can see, the record cell contains a few characters that would be difficult to process using explode() and implode() functions.

Handling Delimited DataLect 10, P.36

PHP fputcsv() function

The fputcsv() function takes an array of cells and writes it to one line of an open file.

Examine the following file writing code:

if( ($fp = fopen($filename, "w")) && flock($fp, LOCK_EX) !== false ) {;
  fputcsv($fp, $headings);
  foreach ($records as $record)
    fputcsv($fp, $record);
  flock($fp, LOCK_UN);
  fclose($fp);
}
What does the above code do?

PHP finds the csv file opens it for writing, puts an exclusive lock on the file.

The first line written to the csv file is the 1D array $headings.
It is unlikely that any escape or enclosing characters will be used as the heading cell data is usually uncomplicated by customer input.

The foreach loop will read each record array inside the 2D $records array.
Only the first line must contain quotes and escape characters to conform to the RCF4180 standard.

When the file writing is complete, the file is unlocked and closed.

This is a "first time" run, ie when the file is being created for the first time. Usually you would be appending data to the file and not writing a headings row.

Handling Delimited DataLect 10, P.37

PHP fgetcsv() and fputcsv() options

An added bonus of the fgetcsv() and fputcsv() functions is that the delimiter, enclosure and escape characters can be changed.

For example, to read from a tab delimited file (ie where tabs are used instead of commas) you can specify a tab \t character. Make sure you specify the length (ie 0 if reading the whole line) and put the tab character in double quotes:

if( ($fp = fopen($filename, "r")) && flock($fp, LOCK_SH) !== false ) {
  $headings = fgetcsv($fp, 0, "\t");
  while( ($aLineOfCells = fgetcsv($fp, 0, "\t")) !== false )
    $records[] = $aLineOfCells;
  flock($fp, LOCK_UN);
  fclose($fp);
}

And to append to a tab delimited file, just the \t character is required:

if( ($fp = fopen($filename,"a")) && flock($fp, LOCK_EX) !== false ) {
  // Note: Appending assumes headings are already present!
  foreach ($records as $record)
    fputcsv($fp, $record, "\t");
  flock($fp, LOCK_UN);
  fclose($fp)
};
Welcome!Lect 11, P.1

Web Programming
COSC2413 / 2426 / 2453

Lecture 11 - PHP 4

Lecture 11Lect 11, P.2
  1. Error Reporting and Handling
  2. Log In and Out Example
  3. Server Configuration
  4. PHP and the OS
  5. PHP and the CLI
  6. Final Slide!
Error Reporting and HandlingLect 11, P.3

Error Checking

Error handling is an important part of creating scripts and web applications.

If your code lacks error checking, your program may look very unprofessional to users and will be open to security risks from hackers.

As discussed in a previous lecture, when developing it is sensible to have error reporting on and once development is finished it is sensible to turn it off.

Some of the ways to handle errors are:

  • During development, halting execution near the problem areas using the PHP exit() and die() functions.
  • Using try-catch blocks where an error is anticipated and needs to be handled.
  • Customising error handlers to replace the generic default error.
  • Triggering errors if an error has not occured but a parameter has an unwanted value (eg out of range error).
Error Reporting and HandlingLect 11, P.4

PHP exit() and die()

The PHP functions exit() and die() are equivalent and take an optional message string as a parameter. Execution is halted and the message, if supplied, is printed to the screen.

exit(); // Not very informative
exit("An error has occurred. Exiting!");
die("AARRRGG!! I love being dramatic!!");

This approach is good for immediate debugging, but is not suitable for the end user experience on a production server.

if( !file_exists("") ) {
  exit("File not found on line 145: customers.txt. Hope you weren't buying anything ...");
} else {
  $file = fopen("customers.txt, "r");
  // rest of code here
Error Reporting and HandlingLect 11, P.5

Try Catch Block

A more elegant way of handling errors is to try code, catch errors and throw exceptions in a try catch block.

try {
  if ($a == 0)
    throw new Exception ("Can't divide by 0");
  return $b / $a;
} catch (Exception $e) {
  return "Exception: ".$e->getMessage();
}
Error Reporting and HandlingLect 11, P.6

Triggering Errors

Sometimes we will want to trigger an error to trap those very persistent bugs. We can do this using the PHP function trigger_error() which takes two paramaters, an error message and an error number (ie a level or flag) of our choosing if the default value E_USER_NOTICE is insufficient.

$a = 0;
if ($a = 5) {
  trigger_error("Why is \$a equal to $a? AARRGG!!?", E_USER_ERROR);
}
Error Reporting and HandlingLect 11, P.7

Custom Error Handlers

You can write your own custom error handlers and override the default error handling in PHP with the set_error_handler() function.

This function takes the name of your custom function as a parameter and your custom error function should anticipate two parameters, an error number $errnum, and an error message $errmsg, both automagically supplied by PHP's error handling machinary.

function myConsoleLog($errnum, $errmsg) {
  echo
  "<script>
     console.log('PHP Error #$errnum: $errmsg');
   </script>";
}
...
set_error_handler("myConsoleLog");
What does the above code do?

A function called myConsoleLogis created which echoes out a script tag as part of the response message to the client when called.

When the error handler is set to this function AND when an error occurs, this function is called rather than the default error handler function.

Errors that are generated in PHP are now logged to the browser's console, in otherwords, this is equivalent to calling the console.log

function in javascript.

You can restore the previous error handler (e.g. default) by using the PHP restore_error_handler() function.

Error Reporting and HandlingLect 11, P.8

Error Logging

By default, PHP sends an error log to the server’s logging system (or a file, depending on how the error_log configuration is set). When error reporting is turned off to the public on a production server, errors can still be monitored by website administrators.

The PHP error_log() takes a message parameter and a number of optional parameters if wanting to do more than just log errors to the default error file. These optional parameters are message_type, destination and extra_headers.

Imagine that an error log message is generated when too many bookings for a particular cinema session has been made. What will the following code examples do?

error_log("$day $time session is full\n");

The error message is logged to the default error log file.

error_log("$day $time session is full\n", 3, "/var/tmp/eOOOOO-errors.log");

The error message is logged to a custom log file. This is useful for individual developers or small teams working on a larger project wanting to keep related error logs in one place.

When appending to a custom log file, message_type must be set to 3.

error_log("$day $time session is full\n", 1, "bookings@silverado.com.au");

The error message is sent to the email addresss e-mail address bookings@silverado.com.au. Emailing is a more efficient way of alerting someone responsible to a problem quickly.

When sending an email, message_type must be set to 1 and if a more stylish email needs to be generated, extra_headers can be set up and included in the email.

Log In and Out ExampleLect 11, P.9

Introduction

The next few slides will look at creating a simple log in and log out script that is present on every page as part of a "topModule" script.

This is currently implemented as part of the secured area examples.

https://titan.csit.rmit.edu.au/~e54061/secure

We will need to create two "sibling" forms, each submitting to a processing script called logIO.php with a submit button with the name logIO:

<form action="logIO.php">
  ...
  ...
  <button name="logIO"> ... </button>
</form>
Log In and Out ExampleLect 11, P.10

Sibling Forms Detail

A very trimmed down version of both forms are below to get you started. Many form elements and field attributes you would expect to see are either missing or slightly mangled.

Log In Version:

<form action="logIO.php">
  <label>Sign in as</label>
  <input type=text name=fname>
  <button name=logIO>Log In</button>
</form>

Log Out Version:

<form action="logIO.php">
  <span>Logged in as <?= $_SESSION["user"]["fname"] ?><span>
  <button name=logIO>Log Out</button>
</form>
Log In and Out ExampleLect 11, P.11

Display Logic: SESSION check

In order to decide which form to display in the topModule function, we will check to see if a variable called $_SESSION['user'] exists:

session_start();
...
if (isset($_SESSION["user"])) {
  // show logout version
} else {
  // show login version
}
...

It is left to the reader to complete this step.

Tip: If you are duplicating form code, you are doing it wrong not quite right!

Log In and Out ExampleLect 11, P.12

Processing Logic: SESSION and POST check

A very trimmed down processing script called logIO.php is below.

Only a submit button name is checked. Your script should check more than just one form field.

  session_start();
// User should only get here if a logIO button is clicked
  if (isset($_POST["logIO"])) {
// If user is currently logged in, log them out
    if (isset($_SESSION["user"])) {
      unset($_SESSION["user"]);
// User not logged in, make sure fname field is not blank.
    } else if (!empty($_POST["fname"])) {
// Log the user in, make sure fname is clean.
      $_SESSION["user"]["fname"] = htmlentities($_POST["fname"], ENT_QUOTES);
    }
// Transfer user back to the referring page
    header("Location: ".$_SERVER["HTTP_REFERER"]);
  } else {
// User got here by not clicking a logIO button, forward them "silently" to the home page.
    header("Location: index.php");
  }
Server ConfigurationLect 11, P.13

Configuration Stages

A server can be configured (or reconfigured) at various stages.

  • Compile Time, ie when the server is being built, created or updated. If it is not obvious, the maximum number of configuration options is available at this stage.
  • Restart Time, ie when the server is to be restarted some time after being built or created. This allows for a sizeable but smaller number of server configuration options.
  • Run Time, ie when PHP scripts on the server modify configuration settings "on the fly". If it is not obvious, the smallest number of configuration options is available at this stage.
Server ConfigurationLect 11, P.14

Compile Time Configuration

A server can be configured at compile time, i.e. when creating or building the server.

When PHP is first compiled (from its source code), several configuration options need to be considered.

Most common options include which APIs should be enabled (or not).

For example, the MySQLi API (to include support functions to access and manipulate the mySQL database) needs to be enabled at compile-time. A list of extensions can be found here:

https://php.net/manual/en/extensions.alphabetical.php

Server ConfigurationLect 11, P.15

Start / Restart Time Configuration

Run-time options can also be set by modifying the php.ini configuration file. On the coreteaching servers, the file is located at /etc/php.ini and can be opened for reading using a text editor.

This file is read when PHP starts up, i.e. after the server is started / restarted, and new settings are applied.

Normally you can see a list of current settings using the phpinfo() function but this has been disabled on the coreteaching servers for security reasons. Equivalently, use php -i from the command-line to see these settings.

Server ConfigurationLect 11, P.16

Example php.ini settings

Some important settings in php.ini to improve performance and guard against malicious users are:

  • memory_limit: the maximum memory, in bytes, that a script is allowed to allocate.
  • max_execution_time: the amount of time, in seconds, that a script is allowed to run for before being terminated.
  • precision: the number of digits displayed by default for floating-point numbers.
  • post_max_size: the maximum size of post data that can be received.
  • file_uploads: whether to allow HTML file uploads.
  • disable_functions: a list of disabled functions, eg phpinfo()

Coreteaching's php.ini file can be found in the /etc directory.

Server ConfigurationLect 11, P.17

Run Time Configuration

Some (i.e. not all) of the configuration settings in the php.ini file can be modified within a script using the ini_set() function. This function takes two parameters, a name and a value, eg:

ini_set("display_errors", "1");

The new configuration settings will be applied when the function is called and maintained until the script is finished.

Server ConfigurationLect 11, P.18

File Uploads and Email

Allowing users to upload their own files (eg photos, resumes etc) is a popular feature but poses security risks if malware is uploaded.

File uploads can be disallowed completely, for example the coreteaching servers have disabled file uploads, but more reasonable restrictions can be taken such as placing limits on the number and size of files uploaded.

Allowing email creation via webforms using the PHP mail() function is also a popular feature but if header information is programmed badly, it can cause your server to be blacklisted by other servers guarding against spam email servers.

For this reason, mail() is disabled on the Coreteaching servers, but as a general rule, make sure that your scripts encode headers so that email is seen to be sent from same domain name that the server is actually running on.

PHP and the OSLect 11, P.19

Interacting with the Operating System

PHP includes a range of functions that allow direct interaction with the Operating System (OS).

The PHP system() function takes a command as a parameter and an optional return_var variable to indicate the return status. It executes the system command and returns the last line of output or false if the command failed to run.

echo system("ls"); // displays the last line of the directory listing (ls) command

The PHP exec() function is similar to to system(), except that it takes an optional output array parameter and will append to this array all lines of output from the system command. It also returns the last line of output or false if the command failed to run.

$output = array();
system("ls -al", $output);
foreach($output as $line)
  echo "$line\n"; // displays all lines of the directory listing (ls) command

Using these functions can be handy in a controlled environment, but on a public web server it may be desirable to disable such functions for security reasons.

PHP and the OSLect 11, P.20

Escape Shell Arguments

Imagine that the following code accepts user input $_GET['directory'] to determine which directory to list.

$dir = $_GET["directory"];
echo "<p>The contents of the directory $dir are:</p>";
echo exec("ls $dir");

What happens when the contents of $_GET['directory'] are:

wp

The directory wp is listed.

wp; rm *

The wp is listed, but all files inside the directory are removed as the command rm * is also run.

If accepting user input for system call functions, you should use the escapeshellarg() function. This function makes sure all strings are enclosed in single quotes and any single quotes inside are escaped, making the argument a single safe string.

$dir = escapeshellarg($_GET["directory"]);
echo "<p>The contents of the directory $dir are:</p>";
echo exec("ls $dir");

This time, the function will merely fail to find the directory 'wp; rm *'.

PHP and the CLILect 11, P.21

Run PHP from the Command Line

Aside from being invoked by a web server, PHP can also be run from the command-line.

In other words, in addition to "web programming", you have now learned a new general-purpose scripting language

There are two ways to use the PHP CLI

  1. Invoke the PHP executable with the -f flag:
    % php -f your_script_file.php
  2. Alternatively, to run your script like a "stand-alone" application, add the following as the first line inside your script file:
    #!/path/to/php -f
    You then also need to give your script appropriate permissions to run (e.g. 700 if you will be the one running it)
PHP and the CLILect 11, P.22

CLI Variables

Two CLI-specific variables make it easy to integrate interactivity with the command-line:

  1. $argc is automatically set to the number of arguments received on the command line.
  2. $argv is an array containing the arguments passed to the script
    $argv[0] is the name of the script, $argv[1] is the first argument passed, etc.

Imagine that the following code is contained in a file called simplegrep.php and has been given appropriate permissions 700:

#!/usr/bin/php -f
<?php
if ($argc != 3)
   die("Usage: {$argv[0]} pattern filename\n");

if (!$content = file($argv[2]))
   die("Unable to open file {$argv[2]}\n");

$pattern = "/" . $argv[1] . "/";
foreach($content as $num => $line)
   if(preg_match($pattern, $line))
      echo $num+1 . ": $line";
?>

Explain what happens, and why, when a user types the following at the command line:

% ./simplegrep.php

The number of elements in the array $argc are checked to make sure 3 are passed. The script fails as only one is supplied, so a helpful "how to use" message is printed to the screen.

% ./simplegrep.php simplegrep.php

The number of elements in the array $argc are checked to make sure 3 are passed. The script fails again as only two are supplied, so a helpful "how to use" message is printed to the screen.

% ./simplegrep.php die simplegrep.php

The number of elements in the array $argc are checked to make sure 3 are passed. Three are supplied, so the script proceeds to the next step.

If the filename contained in $argv[2] cannot be read, the script fails and a "unable to open file" message is printed to the screen. Luckily we know that simplegrep.php exists as it is the script file, so the script proceeds to the next step.

The $argv[1] parameter is assumed to be a regular expression and only the lines in the opened file that match the pattern are printed to the screen with a line number printed in front. In this case, only lines that contain the word die are listed, ie lines 4 and 7

Final SlideLect 11, P.23

And There's More ...

As you begin to develop more complex applications with PHP, remember that it comes with an extensive set of libraries and built-in functions

  • Credit-card processing
  • Cryptography
  • Text Processing
  • Web Services

And lots more! Check https://php.net