Introduction to Modern Web Development

Rune Johan Borgli

Steven Alexander Hicks

Overview

HTML5

CSS

Javascript

Layout

Visuals

Functionality

Frameworks

Tools

Communication

Webpack

Websockets

Ajax

Bootstrap

React

HTML

Tag-based programming

Static layout for web pages

Served by web-servers

Core of the web-site

HTML example

<nav class="navbar navbar-dark" style="background-color: #1aa8b2;">
  <div class="container">
    <a class="navbar-brand mb-0 h1 d-none d-sm-block" href="">
      <img src="assets/brand/OhmIcon.png" width="32" height="32" class="d-inline-block align-top" alt=""/>
      Ohminator Documentation
    </a>
    <a class="navbar-brand mb-0 h1 d-block d-sm-none" href="">
      <img src="assets/brand/OhmIcon.png" width="32" height="32" class="d-inline-block align-top" alt=""/>
      Ohminator Docs
    </a>
    <div class="btn-group d-lg-none">
      <button type="button" class="btn btn-light dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        Menu
      </button>
      <div class="dropdown-menu dropdown-menu-right" id="dm" role="tablist" style="left: initial; right: 0;">
        <a class="dropdown-item active" id="menu-summary-list" href="#list-summary" aria-controls="summary">Summary</a>
        <a class="dropdown-item" id="menu-audio-list"  href="#list-audio" aria-controls="audio">Audio</a>
        <a class="dropdown-item" href="#list-intro" aria-controls="intro">Intro</a>
        <a class="dropdown-item" href="#list-util" aria-controls="util">Util</a>
        <a class="dropdown-item" href="#list-other" aria-controls="other">Other</a>
        <a class="dropdown-item" href="#list-wow" aria-controls="wow">WoW</a>
        <a class="dropdown-item" href="#list-team" aria-controls="team">Team</a>
      </div>
    </div>
  </div>
</nav>

CSS

Complements HTML with customized visuals

Uses HTML classes, tags and IDs for changing an element's appearance

Is loaded in the HTML

Uses a hierarchical system for applying changes to elements

Is usually written using CSS compilers such as Sass

CSS example

.overlay {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background-color: rgba(255, 255, 255, 0.9);
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
      -ms-flex-direction: row;
          flex-direction: row;
  color: #555;
  border-radius: 3px;
}

.overlay .l-text {
  font-size: 24px;
  margin-top: 15px;
  margin-bottom: 10px;
  margin-left: 10px;
  display: block;
  -webkit-margin-before: 1em;
  -webkit-margin-after: 1em;
}

Javascript

Adds advanced functionality to your site

Scripting language

Handles everything from rendering, history, communication ect.

Many frameworks to choose from and several versions

Javascript example

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
        navigator.serviceWorker.register('sw.js').then(function(registration) {
            // Registration was successful
            console.log('ServiceWorker registration successful with scope: ', registration.scope);
        }, function(err) {
            // registration failed :(
            console.log('ServiceWorker registration failed: ', err);
        });
    });
}

ES6+

Imports

Simple Static Webpage

Content Delivery Network (CDN)

Loads resources such as CSS and Javascript from external sources

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

    <!-- DataTables CSS -->
    <link rel="stylesheet" href="https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css">
    <link rel="stylesheet" href="https://cdn.datatables.net/fixedheader/3.1.5/css/fixedHeader.dataTables.min.css">

    <title>Hyperparameter Optimizer</title>
  </head>
  <body>
    <div id="root"></div>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>

    <!-- React -->
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

    <!-- React-router -->
    <script src="https://unpkg.com/react-router-dom/umd/react-router-dom.min.js"></script>

    <!-- Babel -->
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

    <!-- DataTables -->
    <script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap4.min.js"></script>
    <script src="https://cdn.datatables.net/fixedheader/3.1.5/js/dataTables.fixedHeader.min.js"></script>

    <script type="text/babel" src="js/experiment_overview.js"></script>
    <script type="text/babel" src="js/model_summary.js"></script>

    <!-- Optimizer GUI -->
    <script type="text/babel" src="js/index.js"></script>
  </body>
</html>

CSS Libraries

Bootstrap

CSS Libraries

Bulma

Single Page Application

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>Saga</title>
    <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>
ReactDOM.render(<App />, document.getElementById('root'));
class App extends Component {
  render() {
    return (
      <Router>
        <Saga/>
      </Router>
    );
  }
}

Webpack

Create React App

npx create-react-app my-app
cd my-app
npm start

Package Managers

Node.js' package manger called npm is the most used

Yarn

npm install react
npm install bootstrap

React

Virtual DOM

Components

Props

Children

State

React example

let AppButton = (props) => {
  return (
    <article className={"media"}>
      <figure className={"media-left"}>
        <a href={props.link}>
          {props.icon ?
            <img src={props.icon}/>
            :
            <img src={"https://bulma.io/images/placeholders/64x64.png"} width={"64px"} height={"64px"}/>
          }
        </a>
      </figure>
      <div className="media-content">
        <div className="content">
          <p>
            <strong>{props.title}</strong>
            <br/>
            {props.text}
          </p>
        </div>
        <nav className="level is-mobile">

        </nav>
      </div>{/*
      <div className="media-right">
        <a href={props.link}>
          <span className="icon is-small"><i className="fas fa-play"></i></span>
        </a>
      </div>*/}
      {props.link && props.component &&
        <Route path={props.link} component={props.component}/>
      }
    </article>
  );
};

Websockets/AJAX

  • Update a web page without reloading the page
  • Request data from a server - after the page has loaded
  • Receive data from a server - after the page has loaded
  • Send data to a server - in the background

AJAX polls the endpoint and Websockets maintain a full duplex connection

Ajax is implemented by the Fetch API and most common

Websockets Example

startTraining() {
    let startTrainingRequest = {
        type: "request",
        request: {
            command: "start_optimization",
            parameters: {
                "hyperparameters": {
                    'models': this.options.models,
                    'blockOptimizers': this.options.blockOptimizers,
                    'tuneOptimizers': this.options.tuneOptimizers,
                    'optimizerParameters': this.options.optimizerParameters,
                    'blockOptimizerParameters': this.getParametersOfSelectedOptimizers(this.options.blockOptimizers),
                    'tuneOptimizerParameters': this.getParametersOfSelectedOptimizers(this.options.tuneOptimizers),
                    'delimitingLayer': this.options.delimitingLayer,
                    'sharedHyperparameters': this.options.sharedHyperparameters
                },
                "options": {
                    'numberOfGpus': this.options.numberOfGpus,
                    'evaluationMetric': this.options.evaluationMetric,
                    'initialDesign': this.options.initialDesign,
                    'maxIterations': this.options.maxIterations,
                    'batchSize': this.options.batchSize,
                    "dataset": this.options.dataset,
                    "testName": this.options.testName
                }
            }
        }
    };
    let ws = new WebSocket(WEBSOCKET_ADDRESS);
    ws.onmessage = (message) => {
        let response = JSON.parse(message.data);
        console.log(response);
        if (response.type === 'error') {
            this.setState({error: response.error});
            $('#errorMsg').collapse('show');
        } else {
            this.setState({testData: response.response.data});
        }
        ws.close();
    };
    ws.onopen = () => ws.send(JSON.stringify(startTrainingRequest));
}

JSON

{
    "objectId": "prKTTNWxHV",
    "gyldig_til": {
        "__type": "Date",
        "iso": "2018-12-10T00:00:00.000Z"
    },
    "publishedAt": {
        "__type": "Date",
        "iso": "2018-12-03T06:47:06.696Z"
    },
    "tekst": "Menu all Restaurants",
    "langBeskrivelse": "Expedition\r\n\r\nMonday: egg fuyan with tofu wok\r\n                  Fish fillet mussels sauce and potatoes\r\n                   Bean salad with olives and pesto rosatto\r\n                  Chef's soup of the day\r\nTuesday: chicken with pepper sauce and cream potatoes \r\n                 Vegetarian bulgur with vegetables\r\n                Noodles salad with shellfish\r\n               Chef's soup of the day\r\nWednesday: pork Thai panang\r\n                Falafel  in a Spanish sauce with potatoes\r\n                Lentils salad with avocado and strawberries\r\nThursday: Chicken in a jalapeno coriander saus\r\n                  Chiles sin carne\r\n                  Millionaire salad\r\n                  Chef's soup of the day\r\nFriday:   Fish and chips with remulade sauce \r\n                Chef's soup of the day\r\n                 Surprise me \r\n\r\nTransit week 49\r\nMonday:\r\nCrabstick salad\r\nChicken with curry sauce\r\nArtichoke soup\r\nTuesday:\r\nRatatouille salad\r\nVeggie cakes with roast potatoes\r\nTom kha soup\r\nWednesday:\r\nLentil salad with bacon\r\nFish curry\r\nSpicy bean soup\r\nThursday:\r\nPasta salad with smoked salmon\r\nTurkey meatloaf With mushroom sauce\r\nCorn soup\r\nFriday:\r\nFruit salad\r\nTomato soup\r\nKebab\r\n\r\n",
    "publisert": true,
    "is_tilbud": false,
    "kategoriId": "grTjT8pqzY",
    "kategori_navn": "ISS Restaurant",
    "kategori_channel": "ISSKantine-09a79",
    "globalFavoritt": false,
    "bilde": null,
    "thumb": null,
    "createdAt": "2018-12-03T06:47:06.787Z",
    "updatedAt": "2018-12-04T08:05:34.690Z",
    "pushed_once": true
}

Server

Apache

Nginx

Flask

Websockets

GitHub

Summary

Use create-react-app for webpack and easy React start

Use a CSS framework and make modifications of it for your own style

We recommend React as the go-to Javascript web framework

Make use of useful Javascript libraries for different functionality. There exists many, and you can get many of them through CDNs or npm package manager

Use AJAX calls or Websockets to load dynamic content

Thank you!

Web Development Basics

By borgli

Web Development Basics

  • 582