Skip to content

Example app

To show how easy fetch(bible) is to use, here's a basic bible app created with a single file of plain HTML/CSS/JS. For a more complex example with a nicer UI you can also check out the web app and its source code.

 

html
<!DOCTYPE html>
<html>

<!-- Some basic meta and styles -->
<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1'>

    <!-- Include client CSS, normally done for bundled apps with:
        import '@gracious.tech/fetch-client/client.css'
    -->
    <link rel='stylesheet' href='./client.css'>

    <style>
        body {
            margin: 0;
        }
        input, select, button {
            border-style: none;
            background-color: #fff9;
            padding: 4px 8px;
            margin: 4px;
        }
        .toolbar {
            position: sticky;
            z-index: 1;
            top: 0;
            background-color: purple;
            padding: 6px;
            text-align: center
        }
        .content {
            padding: 20px;
        }
    </style>
</head>


<!-- A basic page structure for UI -->
<body>

    <div class='toolbar'>
        <select class='language'></select>
        <select class='translation'></select>
        <select class='book'></select>
        <select class='chapter'></select>
    </div>

    <!-- Scripture must be under class "fetch-bible" for styles -->
    <div class='content fetch-bible'></div>


    <script type='module'>


// NOW FOR THE APP...
// Normally this would be even simpler when using a JS framework
// but we'll use plain JS for sake of demonstration


// Import the fetch(bible) client
// Normally you would import from '@gracious.tech/fetch-client' rather than a static file
import {BibleClient} from './client.mjs'


// Locate UI elements
const select_language = self.document.querySelector('.language')
const select_translation = self.document.querySelector('.translation')
const select_book = self.document.querySelector('.book')
const select_chapter = self.document.querySelector('.chapter')
const div_content = self.document.querySelector('.content')


// Fetch collection
const client = new BibleClient()
const collection = await client.fetch_collection()


// Method for updating the content shown
async function update_content(){
    const book = await collection.fetch_book(
        select_translation.value,
        select_book.value,
    )
    div_content.innerHTML = book.get_chapter(select_chapter.value)
}



// Method for populating the language <select> element
function update_select_language(){
    const languages = collection.get_languages()
    update_options(select_language, languages.map(language => {
        return [
            language.code,
            `${language.local} (${language.english})`,
        ]
    }))
}


// Method for populating the translation <select> element
function update_select_translation(){
    const translations = collection.get_translations({
        language: select_language.value,
    })
    update_options(select_translation, translations.map(translation => {
        const name = translation.name_local || translation.name_english
        return [translation.id, `${name} (${translation.name_abbrev})`]
    }))
}



// Method for populating the book <select> element
function update_select_book(){
    const books = collection.get_books(select_translation.value)
    update_options(select_book, books.map(book => {
        return [book.id, `${book.name_local} (${book.name_english})`]
    }))
}


// Method for populating the chapter <select> element
function update_select_chapter(){
    const chapters = collection.get_chapters(select_book.value)
    update_options(select_chapter, chapters.map(c => [c, c]))
}



// Do initial update of dynamic UI elements
update_select_language()
update_select_translation()
update_select_book()
update_select_chapter()
update_content()


// Trigger updates for UI actions
select_language.addEventListener('change', () => {
    update_select_translation()
    update_select_book()
    update_select_chapter()
    update_content()
})
select_translation.addEventListener('change', () => {
    update_select_book()
    update_select_chapter()
    update_content()
})
select_book.addEventListener('change', () => {
    update_select_chapter()
    update_content()
})
select_chapter.addEventListener('change', () => {
    update_content()
})


// Util for updating the options of a <select> element
function update_options(element, items){
    element.innerHTML = ''  // Remove existing options
    for (const item of items){
        const option = self.document.createElement('option')
        option.value = item[0]
        option.label = item[1]
        element.appendChild(option)
    }
}


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