Вы должны создавать новые <LI>
элементы и устанавливать их текстовое содержимое для имени задачи.
const btnAdd = document.querySelector('.btn-add')
const addTask = e => {
let txtTask = document.querySelector('.txt-task'),
task = txtTask.value.trim()
if (task) {
let li = document.createElement('li')
li.textContent = task
document.querySelector('.tasks').append(li)
txtTask.value = ''
}
}
btnAdd.addEventListener('click', addTask)
h1 { font-size: 1.25rem; }
h2, label { font-size: 1.00rem; }
<h1>Task Manager</h1>
<div>
<label>New Task</label>
<input class="txt-task" type="text" />
<button class="btn-add">Add</button>
</div>
<h2>Tasks</h2>
<ul class="tasks"></ul>
Приложение для рендеринга
Вот пример использования структуры данных списка и механизма рендеринга. Он имеет автоматическую сортировку и обнаружение повторяющихся записей.
const main = () => {
new TaskManager('.task-app', {
formConfig: {
fieldLabel: 'New Task',
buttonText: 'Add'
},
listConfig: {
autoSort: true
}
})
}
class TaskForm {
constructor(options) {
let opts = Object.assign({}, TaskForm.defaultOptions, options)
this.fieldLabel = opts.fieldLabel
this.buttonText = opts.buttonText
}
addEvents(target) {
target.querySelector('.btn-add').addEventListener('click', e => {
let txtTask = document.querySelector('.txt-task'),
task = txtTask.value.trim()
if (task) {
const addEvent = new CustomEvent('task-add', {
detail: txtTask.value
})
target.dispatchEvent(addEvent);
txtTask.value = ''
}
})
}
render() {
return `
<div>
<label>${this.fieldLabel}</label>
<input class="txt-task" type="text" />
<button class="btn-add">${this.buttonText}</button>
</div>
`
}
}
TaskForm.defaultOptions = {
fieldLabel: 'New Task',
buttonText: 'Add'
}
class TaskList {
constructor(options) {
this.tasks = []
let opts = Object.assign({}, TaskList.defaultOptions, options)
this.autoSort = opts.autoSort
}
addTask(task) {
if (!this.tasks.includes(task)) {
this.tasks.push(task)
if (this.autoSort) this.tasks.sort()
} else {
console.log(`Task "${task}" already exists.`)
}
}
addEvents(target) {
target.addEventListener('task-add', e => {
this.addTask(e.detail)
const addEvent = new CustomEvent('task-added')
target.dispatchEvent(addEvent);
e.stopImmediatePropagation()
})
}
render() {
return `
<ul>
${this.tasks.map(task => `<li>${task}</li>`).join('')}
</ul>
`
}
}
TaskList.defaultOptions = {
autoSort: false
}
class Mountable {
constructor(target, options) {
this.target = typeof target === 'string' ?
document.querySelector(target) : target
this.initialize(options)
this.update()
}
update() {
this.target.innerHTML = this.render()
this.afterRender()
}
}
class TaskManager extends Mountable {
constructor(target, options) {
super(target, options)
}
initialize(options) {
this.form = new TaskForm(options.formConfig)
this.taskList = new TaskList(options.listConfig)
}
afterRender() {
this.target.addEventListener('task-added', e => {
this.update()
e.stopImmediatePropagation()
})
this.form.addEvents(this.target)
this.taskList.addEvents(this.target)
}
render() {
return `
<h1>Task Manager</h1>
${this.form.render()}
<h2>Tasks</h2>
${this.taskList.render()}
`
}
}
main()
h1 { font-size: 1.25rem; }
h2, label { font-size: 1.00rem; }
<div class="task-app"></div>