<style>
.scrollable pre {
    overflow-y: auto;
    max-height: 40em;
    -webkit-overflow-scrolling: touch;
}
</style>

<div class="intro">
<p>
This example demonstrates how to create a todo list app using the <a href="../model/index.html">Model</a>, <a href="../model-list/index.html">Model List</a>, and <a href="../view/index.html">View</a> components. The example also includes a custom sync layer that stores the todo items in `localStorage` (in browsers that support it).
</p>
</div>

<div class="example">
{{>app-todo-css}}
{{>app-todo-html}}
{{>app-todo-templates}}
{{>app-todo-js}}
</div>

<h2>Disclaimer</h2>

<p>
Ironically, this example complexifies a very simple application in order to demonstrate concepts you might actually use to simplify a complex application. In reality, this little todo app is so conceptually simple that it probably doesn't need to be broken into discrete components, but its inherent conceptual simplicity makes it convenient for explaining how models, model lists, and views work.
</p>

<p>
In other words, this example is not meant to be a recommendation for how to implement a todo app; it's meant to be a demonstration of how models and views fit together to define application logic. Also, our lawyers advised us that we were legally required to provide a todo example, so we had no choice in the matter. I swear.
</p>

<p>
For a slightly more realistic use case demonstrating how the App Framework can make a complex task simpler instead of a simple task more complex, take a look at the <a href="app-contributors.html">GitHub Contributors</a> example.
</p>

<h2>HTML</h2>

<p>First we'll create the HTML shell for our todo app.</p>

```
{{>app-todo-html}}
```

<p>We'll also add some invisible HTML templates to the page, which will be used to render our views later.</p>

<p>By putting this template HTML inside a `<script>` element with `type="text/x-template"`, we ensure that the browser will ignore it because it doesn't recognize the `text/x-template` type. We can then retrieve the contents of the element to get a convenient template string.</p>

<p>This is generally a more maintainable way of embedding templates than storing them in JavaScript strings, but there's no requirement that you use this technique.</p>

```
{{>app-todo-templates}}
```

<h2>CSS</h2>

<p>Next, some CSS to make the todo list look pretty.</p>

<div class="scrollable">
```
{{>app-todo-css}}
```
</div>

<h2>JavaScript</h2>

<p>Our todo app will consist of five main parts:</p>

<ol>
    <li><p>A `TodoModel` class, which extends `Y.Model`. Each instance of this class will represent the data for a single todo item.</p></li>
    <li><p>A `TodoList` class, which extends `Y.ModelList`. There will be a single instance of this class to contain all the `TodoModel` instances in the todo list.</p></li>
    <li><p>A `TodoAppView` class that extends `Y.View` and acts as a view controller for the entire app.</p></li>
    <li><p>A `TodoView` class, which extends `Y.View`. Each instance of this class will represent the visual content and control the interactions for a single todo item.</p></li>
    <li><p>A `localStorage`-based sync layer that will be used by the `TodoModel` and `TodoList` classes to save and load todo items using `localStorage`.</p></li>
</ol>

<p>All of these things will live inside the following YUI instance:</p>

```
{{>js-yui-seed}}
{{>app-todo-js-yui-start}}
    // ... Add the code from the following sections here! ...
{{>app-todo-js-yui-end}}
```

<h3>TodoModel</h3>

<p>The `TodoModel` class extends `Y.Model` and customizes it to use a `localStorage` sync provider (the source for that is in the [[#LocalStorageSync]] section below) and to provide attributes and methods useful for todo items.</p>

```
{{>app-todo-js-todo}}
```

<h3>TodoList</h3>

<p>The `TodoList` class extends `Y.ModelList` and customizes it to hold a list of `TodoModel` instances, and to provide some convenience methods for getting information about the todo items in the list.</p>

```
{{>app-todo-js-todolist}}
```

<h3>TodoAppView</h3>

<p>The `TodoAppView` class extends `Y.View` and customizes it to represent the main shell of the application, including the new item input field and the list of todo items.</p>

<p>This class also takes care of initializing a `TodoList` instance and creating and rendering a `TodoView` instance for each todo item when the list is initially loaded or reset.</p>

<div class="scrollable">
```
{{>app-todo-js-app-view}}
```
</div>

<h3>TodoView</h3>

<p>The `TodoView` class extends `Y.View` and customizes it to represent the content of a single todo item in the list. It also handles DOM events on the item to allow it to be edited and removed from the list.</p>

<div class="scrollable">
```
{{>app-todo-js-todo-view}}
```
</div>

<h3>LocalStorageSync</h3>

<p>This is a simple factory function that returns a `sync()` function that can be used as a sync layer for either a Model or a ModelList instance. The `TodoModel` and `TodoList` instances above use it to save and load items.</p>

<div class="scrollable">
```
{{>app-todo-js-localstorage-sync}}
```
</div>

<h3>Initializing the App</h3>

<p>Finally, all we have to do is instantiate a new `TodoAppView` to set everything in motion and bring our todo list into existence.</p>

```
{{>app-todo-js-init}}
```

<h2>Complete Example Source</h2>

```
{{>app-todo-css}}
{{>app-todo-html}}
{{>app-todo-templates}}
{{>js-yui-seed}}
{{>app-todo-js}}
```
