20: Filter Todos

Show filtering todos.

  1. Add CSS to hide filtered todo item in <style>.
  2. Add visibility property into x-state.
  3. Add changeVisibility invocation to controller element by x-invocations directive.
  4. Set dataset to <ul> to hide by x-bind:data-filter directive.
  5. Add click event listener to root <ul> of filter links by x-on:click directive. It calls changeVisibility invocation.
  6. Set x-bind:class directive to filter links for show selected design.

  <link
    rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/todomvc-app-css@2.1.2/index.css"
  >
  
  <style>
    [data-filter="active"] > .completed {
      display: none;
    }

    [data-filter="completed"] > :not(.completed) {
      display: none;
    }
  </style>
  

<body>
  <section class="todoapp"
    x-state="{
      todos: [],
      editingTodoIndex: -1,
      visibility: 'all',
    }"

      clearCompleted (_, payload, meta) {
        this.todos = this.todos.filter(todo => !todo.completed)
      },
      changeVisibility (_, payload, meta) {
        const hash =meta._.$._.attr('href')
        if (!hash) {
          return
        }

        this.visibility = hash.substring(2)
      },
    }"



  ::>

    <section class="main">

      <ul class="todo-list"
        x-each="todo, index in todos"
        :data-filter="this.visibility"
      >

      </ul>
    </section>
    <footer class="footer">

      <ul class="filters"
        @click.prevent="changeVisibility"
      >
        <li><a href="#/all" class="selected":class="{selected: visibility == 'all'}">All</a></li>
        <li><a href="#/active" :class="{selected: visibility == 'active'}">Active</a></li>
        <li><a href="#/completed" :class="{selected: visibility == 'completed'}">Completed</a></li>
      </ul>

    </footer>
  </section>
</body>
</html>