Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

An Annotated Remake Todos Web App

This is an example of how to build a simple todos web app with Remake, using only data attributes.

Parent template:

<h1>Todo list</h1>
<div 
  id="app" 
  data-o-save-deep="defaultSave"
  data-o-type="object"
>
  <div 
    class="todos"
    data-o-key="todos"
    data-o-type="list"
  >
    {% for todo in data.todos %}
      {% include "../../partials/todo/index.njk" %}
    {% endfor %}
  </div>
  <button
    class="todo__add-button"
    data-i-new="todo .todos"
  >Add Todo</button>
</div>
  • On line 4, we use the data-o-save-deep attribute. When the data on the page changes, this attribute is responsible for passing the data to the back-end as a nested object. Specifying defaultSave will automatically post all the data on the page to a /save endpoint.
  • On line 5, we use a data-o-type="object" attribute. This tells Remake that the data this element represents is an object.
  • On line 9, we use the data-o-key="todos" attribute. This will put all the data that's inside this element into a key named todos inside the parent object.
  • On line 10, we use a data-o-type="list" attribute. This tells Remake that this element represents an array. The children of this element will be wrapped in this array.
  • On line 12, we use a for loop from the Nunjucks templating language to iterate over the todos in our data.
  • On line 13, we render a partial for every item in the data.
  • On line 18, we use the data-i-new attribute with two arguments: todo and .todos. This tells Remake to create a new item on the page and add it to the page. The first arugment (todo) is the name of the partial to render on the back-end. This rendered partial will be passed back to the front-end. The second argument (.todos) is a selector that specifies where to append the rendered template.

Item template:

<div 
  class="todo__item"
  data-i-editable-with-remove="text(text-single-line)"
  data-o-type="object" 
  data-o-key-text="{{ todo.text }}"
  data-w-key-text="innerText"
>{{ todo.text }}</div>
  • On line 3, we use the data-i-editable-with-remove attribute. When an element with this attribute is clicked, an inline edit area will appear. The function-looking thing (text(text-single-line)) that's passed to this attribute is the data key you want to modify (i.e. text), along with the way you want to modify it (i.e. with a text-single-line input). There's also the altnernate data-i-editable attribute, which comes without a remove button.
  • On line 4, we use a data-o-type="object" attribute. This tells Remake that the data on this element is an object.
  • On line 5, we create a key on the current object using the data-o-key-text attribute. For this kind of attribute, everything after the data-o-key- part is the key name. And the value of the attribute is the value of the key. This attribute will serialize into something like: {text: ""}
  • On line 6, we use a data-w-key-text attribute. This attribute tells Remake to watch a matching data-o-key- attribute (i.e. data-o-key-text) and call a function whenever that data-o-key- attribute's value changes. If the value of the data-w-key- attribute is not a function that you defined, it will default to using its value as an element's property (e.g. innerHTML, value, src, href).
  • One line 7, we set this element's text to the starting value of the todo.

What does this code do?

  1. By attaching data to the DOM, we allow it to be automatically serialized and saved when the data changes. In this example, we save the entire page any time any of the data changes. In future examples, we can explore how to save to an id.
  2. A user can click on any todo in order to edit or remove it.
  3. When a saves their data, the todo's text will be updated and saved to the database.
  4. When a user wants to add a todo, it will be inserted after all the other todos and the page will be saved!

With just 28 lines of HTML, we have a fully functional web application! \(^ _ ^)/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.