ToDo-List Javascript

Hello, I wanted to add this todolist in my App. https://jsfiddle.net/ayoisaiah/1uL24kxb/9/?utm_source=website&utm_medium=embed&utm_campaign=1uL24kxb

When im added the Javascript i have this error:
(I think my javascript is on the wrong place, where do i put it so it works and loads right?
Sorry for all the questions :smiley: Thank you in advance!

app.js:102 Uncaught TypeError: Cannot read property ‘addEventListener’ of null
at eval (app.js:102)
at Module…/src/js/app.js (app.js:4821)
at webpack_require (app.js:726)
at fn (app.js:101)
at eval (webpack:///multi_(:8080/webpack)-dev-server/client?:3:18)
at Object.0 (app.js:5000)
at webpack_require (app.js:726)
at app.js:793
at app.js:796

My Todo.html:

<template>

<div class="page" data-name="about">

  <div class="navbar">

    <div class="navbar-bg"></div>

    <div class="navbar-inner sliding">

      <div class="left">

        <a href="#" class="link back">

          <i class="icon icon-back"></i>

          <span class="if-not-md"></span>

        </a>

      </div>

      <div class="title">To-Do</div>

    </div>

  </div>

  <div class="page-content">

    <div class="container">

      <h1 class="app-title">todos</h1>

      <ul class="todo-list js-todo-list"></ul>

      <div class="empty-state">

        <h2 class="empty-state__title">Add your first todo</h2>

        <p class="empty-state__description">What do you want to get done today?</p>

      </div>

      <form class="js-form">

        <input autofocus type="text" aria-label="Enter a new todo item" placeholder="E.g. Build a web app" class="js-todo-input">

      </form>

    </div>

  </div>

</div>

</template>

<script>

export default {};

</script>

My App.js:

import $$ from ‘dom7’;

import Framework7 from ‘framework7/framework7.esm.bundle.js’;

// Import F7 Styles

import ‘framework7/css/framework7.bundle.css’;

// Import Icons and App Custom Styles

import ‘…/css/icons.css’;

import ‘…/css/app.css’;

// Import Cordova APIs

import cordovaApp from ‘./cordova-app.js’;

// Import Routes

import routes from ‘./routes.js’;

// Import main app component

import App from ‘…/app.f7.html’;

var app = new Framework7({

root: ‘#app’, // App root element

component: App, // App main component

id: ‘io.framework7.jetztZEIT’, // App bundle ID

name: ‘jetztZEIT’, // App name

theme: ‘auto’, // Automatic theme detection

// App routes

routes: routes,

// Register service worker

serviceWorker: Framework7.device.cordova ? {} : {

path: '/service-worker.js',

},

// Input settings

input: {

scrollIntoViewOnFocus: Framework7.device.cordova && !Framework7.device.electron,

scrollIntoViewCentered: Framework7.device.cordova && !Framework7.device.electron,

},

// Cordova Statusbar settings

statusbar: {

iosOverlaysWebView: true,

androidOverlaysWebView: false,

},

on: {

init: function () {

  var f7 = this;

  if (f7.device.cordova) {

    // Init cordova APIs (see cordova-app.js)

    cordovaApp.init(f7);

  }

},

},

});

let todoItems = [];

function addTodo(text) {

const todo = {

text,

checked: false,

id: Date.now(),

};

todoItems.push(todo);

const list = document.querySelector(’.js-todo-list’);

list.insertAdjacentHTML(‘beforeend’, `

<li class="todo-item" data-key="${todo.id}">

  <input id="${todo.id}" type="checkbox"/>

  <label for="${todo.id}" class="tick js-tick"></label>

  <span>${todo.text}</span>

  <button class="delete-todo js-delete-todo">

    <svg><use href="#delete-icon"></use></svg>

  </button>

</li>

`);

}

function toggleDone(key) {

const index = todoItems.findIndex(item => item.id === Number(key));

todoItems[index].checked = !todoItems[index].checked;

const item = document.querySelector([data-key='${key}']);

if (todoItems[index].checked) {

item.classList.add('done');

} else {

item.classList.remove('done');

}

}

function deleteTodo(key) {

todoItems = todoItems.filter(item => item.id !== Number(key));

const item = document.querySelector([data-key='${key}']);

item.remove();

const list = document.querySelector(’.js-todo-list’);

if (todoItems.length === 0) list.innerHTML = ‘’;

}

const form = document.querySelector(’.js-form’);

form.addEventListener(‘submit’, event => {

event.preventDefault();

const input = document.querySelector(’.js-todo-input’);

const text = input.value.trim();

if (text !== ‘’) {

addTodo(text);

input.value = '';

input.focus();

}

});

const list = document.querySelector(’.js-todo-list’);

list.addEventListener(‘click’, event => {

if (event.target.classList.contains(‘js-tick’)) {

const itemKey = event.target.parentElement.dataset.key;

toggleDone(itemKey);

}

if (event.target.classList.contains(‘js-delete-todo’)) {

const itemKey = event.target.parentElement.dataset.key;

deleteTodo(itemKey);

}

});

you arw mixing things. From your code i see you use components, but use app.js to put you js. Put all your component related js in the component:
this is just an example, change it to your needs
Todo.html:

<template>
  <div class="page" data-name="about">
    <div class="navbar">
      <div class="navbar-bg"></div>
      <div class="navbar-inner sliding">
        <div class="left">
          <a href="#" class="link back">
            <i class="icon icon-back"></i>
            <span class="if-not-md"></span>
          </a>
        </div>
        <div class="title">To-Do</div>
      </div>
    </div>
    <div class="page-content">
      <div class="container block">
        <h1 class="app-title">todos</h1>
        {{#if todos.length}}
        <div class="list simple-list">
          <ul class="todo-list js-todo-list">
            {{#each todos}}
              <li>
                {{this}}
              </li>
            {{/each}
          </ul>
        </div>
        {{else}}
        <div class="empty-state">
          <h2 class="empty-state__title">Add your first todo</h2>
          <p class="empty-state__description">What do you want to get done today?</p>
        </div>
        {{/if}}
      </div>
      <div class="block">
        <form class="js-form" @submit='addTodo'>
          <input autofocus type="text" aria-label="Enter a new todo item" placeholder="E.g. Build a web app" class="js-todo-input">
        </form>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'TodoList',
  data () {
    return {
      todos: []
    }
  },
  methods: {
    addTodo (e) {
      e.preventDefault()
      this.$setState({
        todos: [
          ...this.todos,
          this.$dom7('.js-form').find('input').val()
        ]
      })
      this.$dom7('.js-form').find('input').val('')
    }
  }
}
</script>

2 Likes

So should i add all JS related things as a component? Or whats the difference?

I prefer using component. But it depends what you like/want.

2 Likes