Single Page App – Basic Templating Example

#5800

A basic 5 minute example of a vanilla JavaScript SPA

Below is the code for an example where we load a login page, dummy handle the response and go to a home page where we show fetched data.

Example HTML that loads the main.js file which includes our app view handler, as well as two template files, login.js and and home.js

				
					<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="main.js"></script>
    <script src="templates/login.js"></script>
    <script src="templates/home.js"></script>
</head>
<body>
    <div id="header"></div>
    <div id="content"></div>
</body>

</html>
				
			

Our view handler. I always default to app for new projects and package or attach all main methods to it.

Here we are defining an output method which will attempt to set default values if not passed, render the view to our defined content element and call a related script, all by calling app.output()

				
					const app = {

    template: [],
    content: false,
    output: (name, values = {}) => {
        if (typeof app.template[name].values === "function") {
            values = app.template[name].values(values)
        }
        if (typeof app.template[name].view === "function") {
            app.content.innerHTML = app.template[name].view(values)
        }
        if (typeof app.template[name].script === "function") {
            app.template[name].script(values)
        }
    },
}

window.addEventListener("load", () => {
    app.content = document.querySelector('#content')
    app.output('login')
})
				
			

Below are the login.js and home.js files to import.

The can optionally include the values method for handling default variables (see home.js), the view method which will return the html output to be rendered and the script method which is automatically called by output to run any related scripts.

Scripts can include initial functions to run and event handlers for things like login buttons.

				
					app.template.login = {

    view: (op = {}) => {
        return `
        <p>Login Here</p>
        <input name="email">
        <input name="password" type="password">
        <button id="login">Login</button>
        `
    },

    script: (op = {}) => {
        document.querySelector('#login').addEventListener('click', () => {
            //login check - assume passed for demo
            app.output('home', {name: 'Luke'})
        })
    }
}


				
			
				
					app.template.home = {

    values: (op = {}) => {
        return {
            name: 'User',
            ...op,
        }
    },

    view: (op = {}) => {
        return `Hello, ${op.name}!
        <div id="home"></div>
        `
    },

    script: (op = {}) => {
        let feed = document.querySelector('#home')
        feed.innerHTML = `Hi Loading...`

        //fetch home feed content
        setTimeout(() => {
            let output = ``
            output += `<ul>`
            for (let i = 0; i < 20; i++) {
                output += `<li>I am an item</li>`
            }
            output += `</ul>`

            //show home feed content
            feed.innerHTML = output
        }, 1000)

    }

}
				
			
Files

No files attached.

Work With Digitally Tailored

If you would like to implement, discuss or add to this project, please contact us.

License

Copyright 2019 - 2022 Digitally Tailored LTD

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.