Search code examples
google-drive-realtime-api

Realtime API - how to render collaborative lists?


I've been trying recently to make a web app using Google Realtime API. However, I'm stuck on pretty basic things, while trying to implement collaborative lists. Here's a code example I've found (https://realtimeplayground.appspot.com/):

var app = {};

function onInitialize (model) {
  var collaborativeList = model.createList();
  collaborativeList.pushAll(['Cat', 'Dog', 'Sheep', 'Chicken']);
  model.getRoot().set('demo_list', collaborativeList);
}

function onFileLoaded (doc) {
  app.doc = doc;
  app.listDemo = doc.getModel().getRoot().get('demo_list');
  setup();
}

function setup () {
  app.listDemo.addEventListener(
    gapi.drive.realtime.EventType.VALUES_ADDED,
    onListChange);
  app.listDemo.addEventListener(
    gapi.drive.realtime.EventType.VALUES_REMOVED,
    onListChange);
  app.listDemo.addEventListener(
    gapi.drive.realtime.EventType.VALUES_SET,
    onListChange);
}

function onListChange (evt) {
  // Update the UI, etc.
}

My problem is that I don't know how to bind those list elements to the DOM objects or even render them. Nothing I've tried so far seems to work. Can somebody tell me please how to connect those elements to the UI?


Solution

  • You could display the information from the collaborative list in a series of div elements. Let's say your html contained a div like this:

    <div class='animal-list'></div>
    

    Then you could define your event handler functions like this:

    // add divs for the entries that are already in the list to begin with
    function onFileLoaded (document) {
      // get the collaborative list
      var list = document.getModel().getRoot().get('demo_list');
      // get the div element containing the list
      var listElement = document.querySelector('.animal-list');
      // for each value in the list, create a div and insert into the list div
      for (var i = 0; i < list.length; i++) {
        // create the div element
        var newElement = document.createElement('div');
        // set the text to the animal name
        newElement.innerHTML = list.get(i);
        // append to the list div
        listElement.appendChild(newElement);
      }
      // call setup to add event handlers
      setup();
    }
    
    function setup () {
      // add different handler for each event type
      app.listDemo.addEventListener(
        gapi.drive.realtime.EventType.VALUES_ADDED,
        onValuesAdded);
      app.listDemo.addEventListener(
        gapi.drive.realtime.EventType.VALUES_REMOVED,
        onValuesRemoved);
      app.listDemo.addEventListener(
        gapi.drive.realtime.EventType.VALUES_SET,
        onValuesSet);
    }
    
    // when values are added, add a div for each to the list div
    function onValuesAdded(event) {
        // get the div element containing the list
        var listElement = document.querySelector('.animal-list');
        // beforeChild is false if we the values are at the end of the list,
        // otherwise, it is the child div that the new values will be inserted before
        var beforeChild = false;
        if (event.index < event.target.length) {
            beforeChild = listElement.childNodes[event.index];
        }
        // for each inserted value, create a div and insert into the list div
        for (var i = 0; i < event.values.length; i++) {
            // create the div element
            var newElement = document.createElement('div');
            // set the text to the animal name
            newElement.innerHTML = event.values[i];
            if (beforeChild) {
                // insert into the list div at the correct place
                listElement.insertBefore(listElement.childNodes[event.index]);
            } else {
                // append to the list div
                listElement.appendChild(newElement);
            }
        }
    }
    
    // remove the divs from the ui corresponding to the entries removed from the list
    function onValuesRemoved(event) {
        // get the div element containing the list
        var listElement = document.querySelector('.animal-list');
        // remove the divs
        for (var i = 0; i < event.values.length; i++) {
             listElement.removeChild(listElement.childNodes[event.index]);
        }
    }
    
    function onValuesSet (evt) {
        // get the div element containing the list
        var listElement = document.querySelector('.animal-list');
        // for each set value, set the text of the div to the new value
        for (var i = 0; i < event.newValues.length; i++) {
            // set the text to the animal name
            listElement.childNodes[event.index + i].innerHTML = event.newValues[i];
        }
    }