Creating a Data persistence Timetable App

Hi, so don't be fooled by the title, this is actually a sort of Advance to-do App, I was thinking of what article i would be writing this month and decided to start a How I Built that App Series, please note this series will be very irregular. The App we would be building today was inspired by school as you might have guessed, and some of the concept we will be using includes local storage, classes, arrays and few others. below are images from the finished product.

timetable.png

ttl1.png

ttl3.png

ttl2.png

we wont be discussing about the design here only the JavaScript, i would be leaving a link below to the repo and the live site.

The First challenge in building an app like this, is where will i store my data, I considered using Firebase but then quickly realized how stupid that would be, given that most individuals change schedules so frequently, the cost of using Firebase could be too high, So i did what any other individual in my situation could do, i went to find the answer on google and guess what there was a solution and it was something called localStorage. in simple terms localStorage is a type of web storage that allows JavaScript sites and apps to store and access data right in the browser with no expiration date. This was just what i was looking for, but beware that localStorage saves the data internally meaning that the data in your app without a hosted database would only be available to you, if you wanted synchronicity across devices you would have to use a service like MongoDB atlas or any other hosted database you would prefer to use

The next step was what data structure would i use to store data in the localStorage, long story short i ended up using JSON. JSON is literally just an array with object within it and this was perfect for my use case given that each new subject on the timetable was going to be passed as an object.

    //Created a class so a new instance object can be call each time the save button is clicked
    class Tt {
    constructor(id, day, sub, tim, ) {
    return { id: id, day: day, sub: sub, tim: tim }
      }
    }


    // add an event listener to the save button event
    document.getElementById('save').addEventListener('click', function (e) {
      e.preventDefault()
      //gets the values
      const days = document.getElementById('days').value
      const TtSubject = document.getElementById('TtSubject').value
      const Ttime = document.getElementById('sumTime').innerText

      if (days == "" || TtSubject == "") { 
     document.getElementById('TtWarning').style.display = 'block' }
      else {

    //check for already existing value
    if (localStorage.getItem('timeTable') == null) {
      var id = 0
    } else {
      var id = JSON.parse(localStorage.getItem('timeTable')).length //uses the arrays length as an identifial
      // console.log(new Tt(days,TtSubject, Ttime))
    }


    // //push the new object/timetable input to the array
    // timeTable.push(new Tt(id, days, TtSubject, Ttime));
    const NEW = new Tt(id, days, TtSubject, Ttime)


    var addToLocalStorageArray = function (value) {
      // Get the existing data
      var existing = localStorage.getItem('timetable');
      // If no existing data, create an array
      // Otherwise, convert the localStorage string to an array
      if (localStorage.getItem('timeTable') == null) {
        existing = []
        // Add new data to localStorage Array
        existing.push(value);
        // Save back to localStorage
        localStorage.setItem('timeTable', JSON.stringify(existing));
      } else {
        existing = JSON.parse(localStorage.getItem('timeTable'));
        // Add new data to localStorage Array
        existing.push(value);
        // Save back to localStorage
        localStorage.setItem('timeTable', JSON.stringify(existing));
      }
    };
    addToLocalStorageArray(NEW)
      }

      location.reload()  
    })

The above code block basically explains the core functionality of the app. First create a Tt(short for timetable) class, then pass the values from the input boxes into new instances of the created class and after that check for the timeTable key on the localStorage this would return an array if the key exist else it would return undefined which would in turn trigger a response that would create an array, push the object into this newly created array, and then saves it back on to the localStorage.

Now that we have a way to save our objects, we would also need a way to delete them. This was done by creating a function that would receive the position of the object in the timeTable array as its parameter and then gets the timeTable key from the localStorage, using the splice method on the array it removes the desired object and then saves the array back into localStorage, the code is shown below

//react to the trash bin icon click 
document.getElementById('deleter').addEventListener('click', function (e) {
  if (e.target.tagName === 'I') {

    let delID = e.target.id
    console.log(delID)
    let upNEW = Ttable.splice(delID, 1)

    localStorage.setItem('timeTable', JSON.stringify(Ttable));
    deleter.innerHTML = ''
    console.log('done')
    Ttable.forEach(function (doc) {
      del(doc)
    })
  }
})

Finally we needed a way to display the contents of the localStorage on screen into appropriate timeTable cards, this was done by filtering the array according to days and then displaying the appropriate contents. the code is below

//Display appropiate content for each day
const Monday = Ttable.filter((days) => {
  return days.day == 'mon'
})

const Tuesday = Ttable.filter((days) => {
  return days.day == 'tue'
})

const Wednesday = Ttable.filter((days) => {
  return days.day == 'wed'
})

const Thursday = Ttable.filter((days) => {
  return days.day == 'thu'
})

const Friday = Ttable.filter((days) => {
  return days.day == 'fri'
})

const Saturday = Ttable.filter((days) => {
  return days.day == 'sat'
})

const Sunday = Ttable.filter((days) => {
  return days.day == 'sun'
})
//Display appropiate content for each day end

//Rendering array to DOM
Monday.forEach(function (doc) {
  mon(doc)
})

Tuesday.forEach(function (doc) {
  tue(doc)
})

Wednesday.forEach(function (doc) {
  wed(doc)
})

Thursday.forEach(function (doc) {
  thu(doc)
})

Friday.forEach(function (doc) {
  fri(doc)
})

Saturday.forEach(function (doc) {
  sat(doc)
})

Sunday.forEach(function (doc) {
  sun(doc)
})

//Rendering array to DOM end

//function to render
function mon(data) {
  const html = `
    <li>${data.sub} <span class="right">${data.tim}</span></li>          
    `;

  Tmon.innerHTML += html
}

function tue(data) {
  const html = `
    <li>${data.sub} <span class="right">${data.tim}</span></li>          
    `;

  Ttue.innerHTML += html
}

function wed(data) {
  const html = `
    <li>${data.sub} <span class="right">${data.tim}</span></li>          
    `;

  Twed.innerHTML += html
}

function thu(data) {
  const html = `
    <li>${data.sub} <span class="right">${data.tim}</span></li>          
    `;

  Tthu.innerHTML += html
}

function fri(data) {
  const html = `
    <li>${data.sub} <span class="right">${data.tim}</span></li>          
    `;

  Tfri.innerHTML += html
}

function sat(data) {
  const html = `
    <li>${data.sub} <span class="right">${data.tim}</span></li>          
    `;

  Tsat.innerHTML += html
}

function sun(data) {
  const html = `
    <li>${data.sub} <span class="right">${data.tim}</span></li>          
    `;

  Tsun.innerHTML += html
}

//function to render end

//react to the trash bin icon click 
document.getElementById('deleter').addEventListener('click', function (e) {
  if (e.target.tagName === 'I') {

    let delID = e.target.id
    console.log(delID)
    let upNEW = Ttable.splice(delID, 1)

    localStorage.setItem('timeTable', JSON.stringify(Ttable));
    deleter.innerHTML = ''
    console.log('done')
    Ttable.forEach(function (doc) {
      del(doc)
    })
  }
})

We have now finally come to the end of this article the links to the repo and website can be found below, i hope you had fun reading and you learnt something new, leave your comments below

No Comments Yet