Javascript - checkbox reading value from array of objects - javascript

I need to get my checkboxes in todo list read from object in array if task is complete or not. And stay checked when they're complete and unchecked or not.
const todos = [
{
id: 1,
title: 'Nakupit',
description: 'Mlieko, syr, vajcia',
completed: false,
},
{
id: 2,
title: 'Umyt auto',
description: '+ povysavat',
completed: true,
},
]
This is the array and i tried on checkbox something like this. And variations, unable to get it work and changing array or value from array making checkbox ,checked, if complete
toDoCheckbox.addEventListener('click', () => {
if (toDoCheckbox.checked = true) {
return todos.completed === true
} else {
return todos.completed === false
}
});
Can anyone help with it?

You can modify the todos state by looking it up by its id and flipping its completed status.
I added the button to request re-rendering. This will re-build the checkboxes using the current state.
const todos = [{
id: 1,
title: 'Nakupit',
description: 'Mlieko, syr, vajcia',
completed: false,
}, {
id: 2,
title: 'Umyt auto',
description: '+ povysavat',
completed: true,
}]
const main = () => {
const btn = document.querySelector('.btn-render')
btn.addEventListener('click', reRender)
renderTodos()
}
const reRender = (e) => {
renderTodos()
}
const onCheck = (e) => {
const id = parseInt(e.currentTarget.dataset.id, 10)
const found = todos.find(todo => todo.id === id)
if (found) {
found.completed = !found.completed // Flip status
}
}
const renderTodos = () => {
const container = document.querySelector('.container')
container.innerHTML = '' // Clear
todos.forEach(todo => {
let wrapper = document.createElement('div')
let label = document.createElement('label')
let checkbox = document.createElement('input')
wrapper.classList.add('checkbox-wrapper')
label.textContent = todo.title
checkbox.type = 'checkbox'
checkbox.checked = todo.completed
checkbox.dataset.id = todo.id
checkbox.addEventListener('change', onCheck)
wrapper.appendChild(label)
wrapper.appendChild(checkbox)
container.appendChild(wrapper)
})
}
main()
.checkbox-wrapper label {
display: inline-block;
width: 6em;
}
<div class="container"></div>
<br />
<button class="btn-render">Re-render</button>

Related

Quasar QSelect is not opening when performing AJAX call

I have been trying to create a simple auto complete using Quasar's select but I'm not sure if this is a bug or if I'm doing something wrong.
Problem
Whenever I click the QSelect component, it doesn't show the dropdown where I can pick the options from.
video of the problem
As soon as I click on the QSelect component, I make a request to fetch a list of 50 tags, then I populate the tags to my QSelect but the dropdown doesn't show.
Code
import type { PropType } from "vue";
import { defineComponent, h, ref } from "vue";
import type { TagCodec } from "#/services/api/resources/tags/codec";
import { list } from "#/services/api/resources/tags/actions";
import { QSelect } from "quasar";
export const TagAutoComplete = defineComponent({
name: "TagAutoComplete",
props: {
modelValue: { type: Array as PropType<TagCodec[]> },
},
emits: ["update:modelValue"],
setup(props, context) {
const loading = ref(false);
const tags = ref<TagCodec[]>([]);
// eslint-disable-next-line #typescript-eslint/ban-types
const onFilterTest = (val: string, doneFn: (update: Function) => void) => {
const parameters = val === "" ? {} : { title: val };
doneFn(async () => {
loading.value = true;
const response = await list(parameters);
if (val) {
const needle = val.toLowerCase();
tags.value = response.data.data.filter(
(tag) => tag.title.toLowerCase().indexOf(needle) > -1
);
} else {
tags.value = response.data.data;
}
loading.value = false;
});
};
const onInput = (values: TagCodec[]) => {
context.emit("update:modelValue", values);
};
return function render() {
return h(QSelect, {
modelValue: props.modelValue,
multiple: true,
options: tags.value,
dense: true,
optionLabel: "title",
optionValue: "id",
outlined: true,
useInput: true,
useChips: true,
placeholder: "Start typing to search",
onFilter: onFilterTest,
"onUpdate:modelValue": onInput,
loading: loading.value,
});
};
},
});
What I have tried
I have tried to use the several props that is available for the component but nothing seemed to work.
My understanding is that whenever we want to create an AJAX request using QSelect we should use the onFilter event emitted by QSelect and handle the case from there.
Questions
Is this the way to create a Quasar AJAX Autocomplete? (I have tried to search online but all the answers are in Quasar's forums that are currently returning BAD GATEWAY)
What am I doing wrong that it is not displaying the dropdown as soon as I click on the QSelect?
It seems updateFn may not allow being async. Shift the async action a level up to solve the issue.
const onFilterTest = async (val, update /* abort */) => {
const parameters = val === '' ? {} : { title: val };
loading.value = true;
const response = await list(parameters);
let list = response.data.data;
if (val) {
const needle = val.toLowerCase();
list = response.data.data.filter((x) => x.title.toLowerCase()
.includes(needle));
}
update(() => {
tags.value = list;
loading.value = false;
});
};
I tested it by the following code and mocked values.
// import type { PropType } from 'vue';
import { defineComponent, h, ref } from 'vue';
// import type { TagCodec } from "#/services/api/resources/tags/codec";
// import { list } from "#/services/api/resources/tags/actions";
import { QSelect } from 'quasar';
export const TagAutoComplete = defineComponent({
name: 'TagAutoComplete',
props: {
modelValue: { type: [] },
},
emits: ['update:modelValue'],
setup(props, context) {
const loading = ref(false);
const tags = ref([]);
const onFilterTest = async (val, update /* abort */) => {
// const parameters = val === '' ? {} : { title: val };
loading.value = true;
const response = await new Promise((resolve) => {
setTimeout(() => {
resolve({
data: {
data: [
{
id: 1,
title: 'Vue',
},
{
id: 2,
title: 'Vuex',
},
{
id: 3,
title: 'Nuxt',
},
{
id: 4,
title: 'SSR',
},
],
},
});
}, 3000);
});
let list = response.data.data;
if (val) {
const needle = val.toLowerCase();
list = response.data.data.filter((x) => x.title.toLowerCase()
.includes(needle));
}
update(() => {
tags.value = list;
loading.value = false;
});
};
const onInput = (values) => {
context.emit('update:modelValue', values);
};
return function render() {
return h(QSelect, {
modelValue: props.modelValue,
multiple: true,
options: tags.value,
dense: true,
optionLabel: 'title',
optionValue: 'id',
outlined: true,
useInput: true,
useChips: true,
placeholder: 'Start typing to search',
onFilter: onFilterTest,
'onUpdate:modelValue': onInput,
loading: loading.value,
});
};
},
});

javascript quiz how to give the answer array a default value?

I'm creating a quiz that requires every answer to be answered. The problem is that you should be able to skip questions if you don't have an answer. I'm trying to set a default answer everytime I press next so when I try to skip one I don't have to answer for it to have a value. The default value I want is each time the last value of my array.
next and previous question
SetQuestion(question) {
if (this.questionNumber >= 0) {
let oldAnswerButton = document.querySelectorAll('.filter_anwser');
// Deletes old question when the next question is clicked
for (let answerButton of oldAnswerButton) {
answerButton.style.display = 'none';
}
}
this.questionNumber = question;
let q = this.quiz[question];
// Check if your at the last question so the next button will stop being displayed.
if (this.questionNumber === Quiz.length - 1) {
this.nextbtn.style.display = 'none';
this.prevbtn.style.display = 'block';
this.resultbtn.style.display = 'grid';
} else if (this.questionNumber === 0) {
this.nextbtn.style.display = 'block';
this.prevbtn.style.display = 'none';
this.resultbtn.style.display = 'none';
} else {
this.nextbtn.style.display = 'block';
this.prevbtn.style.display = 'block';
this.resultbtn.style.display = 'none';
}
// Displays Question
this.questionName.textContent = q.questionText;
this.questionName.id = "questionID";
return q;
console.log(this.getLink())
console.log(this.tmp)
}
IntoArray() {
const UrlVar = new URLSearchParams(this.getLink())
this.UrlArray = [...UrlVar.entries()].map(([key, values]) => (
{[key]: values.split(",")}
)
);
}
NextQuestion() {
// let quizUrl = this.url[this.questionNumber];
let question = this.SetQuestion(this.questionNumber + 1);
let pre = question.prefix;
let prefixEqual = pre.replace('=', '');
let UrlArr = this.UrlArray;
let UrlKeys = UrlArr.flatMap(Object.keys)
let answers = question.chosenAnswer.slice(0, -1);
this.clicked = true;
// Displays answers of the questions
for (let y = 0; y < answers.length; y++) {
let item = answers[y];
// Display answer buttons
if (UrlKeys.includes(prefixEqual)) {
console.log("exists");
let btn = document.querySelector('button[value="' + item.id + '"]');
btn.style.display = 'block';
} else {
let btn = document.createElement('button');
btn.value = item.id;
btn.classList.add("filter_anwser", pre)
btn.id = 'answerbtn';
btn.textContent = item.name;
this.button.appendChild(btn);
}
// let quizUrl = control.url[control.questionNumber];
// // console.log(this.tmp);
// if (quizUrl === undefined) {
// quizUrl.push(question.prefix[y] + '');
// }
// if (quizUrl === undefined){
// this.tmp.push('');
// }
}
this.IntoArray();
}
PrevQuestion() {
let question = this.SetQuestion(this.questionNumber - 1);
let answers = question.chosenAnswer.slice(0, -1);
// Displays answers of the questions
for (let y = 0; y < answers.length; y++) {
let item = answers[y];
// Display answer buttons
let btn = document.querySelector('button[value="' + item.id + '"]');
btn.style.display = 'block';
}
this.IntoArray();
}
Link creator:
/**
* Returns the parameters for the URL.
*
* #returns {string}
*/
getLink() {
this.tmp = [];
for (let i = 0; i < this.url.length; i++) {
// Check if question is from the same quiz part and adds a , between chosen answers and add the right prefix at the beginning
if (this.url[i].length > 0) {
this.tmp.push("" + Quiz[i].prefix + this.url[i].join(","))
// console.log(this.url)
}
if (this.url[i].length === 0) {
this.tmp.push("");
}
}
/// If answers are from different quiz parts add a & between answers.
return "" + this.tmp.join("&");
// console.log(this.url[i].prefix);
};
Answer click event
control.button.addEventListener("click", function (e) {
const tgt = e.target;
control.clicked = true;
// clear the url array if there's nothing clicked
if (control.url.length === control.questionNumber) {
control.url.push([]);
}
let quizUrl = control.url[control.questionNumber];
// Check if a button is clicked. Changes color and adds value to the url array.
if (quizUrl.indexOf(tgt.value) === -1) {
quizUrl.push(tgt.value);
e.target.style.backgroundColor = "orange";
// Check if a button is clicked again. If clicked again changes color back and deletes value in the url array.
} else {
quizUrl.splice(quizUrl.indexOf(tgt.value), 1);
e.target.style.backgroundColor = "white";
}
console.log(control.getLink());
console.log(quizUrl)
})
array:
class QuizPart {
constructor(questionText, chosenAnswer, prefix, questionDescription) {
this.questionText = questionText;
this.chosenAnswer = chosenAnswer;
this.prefix = prefix;
this.questionDescription = questionDescription;
}
}
class ChosenAnswer {
constructor(id, name) {
this.id = id;
this.name = name;
}
}
let Quiz = [
new QuizPart('Whats your size?', [
new ChosenAnswer('6595', '41'),
new ChosenAnswer('6598', '42'),
new ChosenAnswer('6601', '43'),
new ChosenAnswer('', ''),
], 'bd_shoe_size_ids=',
'The size of your shoes is very important. If you have the wrong size, they wont fit.'),
new QuizPart('What color would you like?', [
new ChosenAnswer('6053', 'Red'),
new ChosenAnswer('6044', 'Blue'),
new ChosenAnswer('6056', 'Yellow'),
new ChosenAnswer('6048', 'Green'),
new ChosenAnswer('', ''),
], 'color_ids=',
'Color isn t that important, It looks good tho.'),
new QuizPart('What brand would you like?', [
new ChosenAnswer('5805', 'Adidas'),
new ChosenAnswer('5866', 'Nike'),
new ChosenAnswer('5875', 'Puma'),
new ChosenAnswer('', ''),
], 'manufacturer_ids=',
'Brand is less important. Its just your own preference'),
]
I tried giving the array's in link creator and my eventlistener a default value and replacing it when I get and actual value from one of my buttons, but it just doesn't work. Can anybody help me?
I understand, that it might be a bit far from what you expect for an answer - but why don't you have a look at a reactive tool, like Vue? It has all the tools that you might need for such a task, and maybe more:
the whole quiz can be abstracted to a simple array of objects (the questions)
next, prev, set default answer becomes a breeze
easy to extend (with questions)
simple to update (template, features, etc.)
Vue.component('QuizQuestion', {
props: ['data', 'selected'],
computed: {
valSelected: {
get() {
return this.selected
},
set(val) {
this.$emit('update:selected', val)
}
},
},
template: `
<div>
{{ data.text }}<br />
{{ data.description }}<br />
<div class="quiz-options">
<label
v-for="val in data.options"
:key="val[0]"
>
<input
type="radio"
:name="data.text"
:value="val"
v-model="valSelected"
/>
{{ val[1] }}
</label>
</div>
</div>
`
})
new Vue({
el: "#app",
computed: {
currentQuestion() {
return this.questions[this.current]
},
hasPrev() {
return !!this.current
},
hasNext() {
return this.current < this.questions.length - 1
},
},
data() {
return {
current: 0,
questions: [{
text: 'Whats your size?',
description: 'The size of your shoes is very important. If you have the wrong size, they wont fit.',
options: [
['6595', '41'],
['6598', '42'],
['6601', '43'],
['', ''],
],
selected: null,
}, {
text: 'What color would you like?',
description: 'Color isn\'t that important, It looks good tho.',
options: [
['6053', 'Red'],
['6044', 'Blue'],
['6056', 'Yellow'],
['6048', 'Green'],
['', ''],
],
selected: null,
}, {
text: 'What brand would you like?',
description: 'Brand is less important. Its just your own preference',
options: [
['5805', 'Adidas'],
['5866', 'Nike'],
['5875', 'Puma'],
['', ''],
],
selected: null,
}, ],
}
},
methods: {
selectDefault() {
this.questions[this.current] = {
...this.questions[this.current],
selected: this.questions[this.current].options.slice(-1)[0],
}
},
getPrev() {
if (this.hasPrev) {
if (!this.currentQuestion.selected) {
this.selectDefault()
}
this.current -= 1
}
},
getNext() {
if (this.hasNext) {
if (!this.currentQuestion.selected) {
this.selectDefault()
}
this.current += 1
}
},
},
template: `
<div>
<quiz-question
:data="currentQuestion"
:selected.sync="currentQuestion.selected"
/><br />
<button v-if="hasPrev" #click="getPrev">PREV</button>
<button v-if="hasNext" #click="getNext">NEXT</button>
<button v-if="!hasNext">RESULT</button>
</div>
`
})
.quiz-options {
display: flex;
flex-direction: column;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>
EDIT
But, if frameworks/libraries are not to be used, here's a more OOP approach:
class Quiz {
constructor(questions) {
this._current = 0
this._questions = questions
}
get current() {
return this._current
}
set current(val) {
this._current = val
}
get hasNext() {
return this.current < this.questions.length - 1
}
get hasPrev() {
return !!this.current
}
get questions() {
return this._questions
}
get next() {
this.current = this.hasNext ? this.current + 1 : this.current
return this.currentQuestion
}
get prev() {
this.current = this.hasPrev ? this.current - 1 : this.current
return this.currentQuestion
}
get currentQuestion() {
return this.questions[this.current]
}
}
class Question {
constructor({
text,
description,
options,
prefix,
}) {
this.text = text
this.desc = description
this.prefix = prefix
this._options = options.map(([key, val]) => ({
id: key,
value: [key, val],
selected: false,
}))
}
get options() {
return this._options
}
set options(newOptions) {
this._options = newOptions
}
get selected() {
return this.options.find(({
selected
}) => !!selected)
}
set selected(selectedVal) {
this.options = [...this.options.map(({
value: [key, val],
selected,
...rest
}) => {
return {
...rest,
value: [key, val],
selected: key === selectedVal
}
})]
}
get lastOption() {
return this.options.slice(-1)[0]
}
setDefault() {
if (!this.selected) {
this.selected = this.lastOption.id
}
}
}
const urlParser = (quiz) => {
return quiz.questions.map(({
prefix,
selected = {
value: ['']
}
}) => {
const s = selected.value[0] ? selected.value[0] : ''
return `${prefix}${s}`
}).join('&')
}
const qArr = [{
text: 'text1',
description: 'desc1',
options: [
['1_1', '11'],
['1_2', '12'],
['1_3', '13'],
],
prefix: 'prefix_1_',
},
{
text: 'text2',
description: 'desc2',
options: [
['2_1', '21'],
['2_2', '22'],
['2_3', '23'],
],
prefix: 'prefix_2_',
},
{
text: 'text3',
description: 'desc3',
options: [
['3_1', '31'],
['3_2', '32'],
['3_3', '33'],
],
prefix: 'prefix_3_',
},
]
const getOptionsHtml = ({
text,
options
}) => {
let html = ''
options.forEach(({
id,
value,
selected
}, i) => {
html += `
<label>
<input
class="question-input"
type="radio"
name="${text}"
value="${value[0]}"
${selected ? 'checked' : ''}
/>
${value[1]}
</label>
`
})
return html
}
const getSingleQuestionHtml = (q) => {
const optionsHtml = getOptionsHtml({
text: q.text,
options: q.options
})
return `
${q.text}<br />
${q.desc}<br />
${optionsHtml}
`
}
const registerEventHandlers = ({
container,
question
}) => {
const radioBtns = document.querySelectorAll('.question-input')
radioBtns.forEach((input, i) => {
input.addEventListener('change', function(e) {
question.selected = e.target.value
})
})
}
const updateHtml = ({
container,
question
}) => {
container.innerHTML = getSingleQuestionHtml(question)
registerEventHandlers({
container,
question
})
};
const updateContainer = (container) => (question) => updateHtml({
container,
question
});
const setElDisplay = ({
el,
display
}) => {
if (display) {
el.classList.add("d-inline-block")
el.classList.remove("d-none")
} else {
el.classList.remove("d-inline-block")
el.classList.add("d-none")
}
}
const updateBtnVisibility = ({
btnNext,
btnPrev,
btnResult,
quiz
}) => () => {
setElDisplay({
el: btnNext,
display: quiz.hasNext
})
setElDisplay({
el: btnResult,
display: !quiz.hasNext
})
setElDisplay({
el: btnPrev,
display: quiz.hasPrev
})
}
(function() {
const quiz = new Quiz(qArr.map(q => new Question(q)))
const container = document.getElementById('quiz-container')
updateQuizContainer = updateContainer(container)
updateQuizContainer(quiz.currentQuestion)
const btnPrev = document.getElementById('btn-prev')
const btnNext = document.getElementById('btn-next')
const btnResult = document.getElementById('btn-result')
const updateBtns = updateBtnVisibility({
btnPrev,
btnNext,
btnResult,
quiz
})
updateBtns()
btnPrev.addEventListener('click', function() {
if (quiz.hasPrev) {
quiz.currentQuestion.setDefault()
}
updateQuizContainer(quiz.prev)
updateBtns()
})
btnNext.addEventListener('click', () => {
if (quiz.hasNext) {
quiz.currentQuestion.setDefault()
}
updateQuizContainer(quiz.next)
updateBtns()
})
btnResult.addEventListener('click', function() {
quiz.currentQuestion.setDefault()
console.log(urlParser(quiz))
})
})();
.d-inline-block {
display: inline-block;
}
.d-none {
display: none;
}
<div id="quiz-container"></div>
<div id="quiz-controls">
<button id="btn-prev" class="d-inline-block">
PREV
</button>
<button id="btn-next" class="d-inline-block">
NEXT
</button>
<button id="btn-result" class="d-none">
RESULT
</button>
</div>
<div id="result"></div>

Check if userid matches one in the array

I'm attempting to check if a user's ID is in this array and if they are, also get the "text" from it.
Array:
const staff = [
{
user: '245569534218469376',
text: 'dev'
},
{
user: '294597887919128576',
text: 'loner'
}
];
I've tried if (staff.user.includes(msg.member.id)) (Which I didn't think was going to work, and didn't.)
const findUser = (users, id) => users.find(user => user.id === id)
const usersExample = [
{
id: '123456765',
text: 'sdfsdfsdsd'
},
{
id: '654345676',
text: 'fdgdgdg'
}
]
//////////////////
const user = findUser(usersExample, '123456765')
console.log(user && user.text)
The some method on an array is used to tell if an item meets a condition, it is similar to the find method but the find method returns the item where the some method return true or false.
const staff = [
{
user: '245569534218469376',
text: 'dev'
},
{
user: '294597887919128576',
text: 'loner'
}
];
const isStaff = (staff, id) => staff.some(s => s.user === id);
console.log(isStaff(staff, '123'));
console.log(isStaff(staff, '245569534218469376'));
You may try something like this:
const staff = [
{
user: '245569534218469376',
text: 'dev'
},
{
user: '294597887919128576',
text: 'loner'
}
];
let item = staff.find(item => item.user == '294597887919128576'); // msg.member.id
if (item) {
console.log(item.text);
}
One another way to do that is:
const inArray = (array, id) => array.filter(item => item.user === id).length >= 1;
const users = [
{
user: '245569534218469356',
text: 'foo'
}, {
user: '245564734218469376',
text: 'bar'
}, {
user: '246869534218469376',
text: 'baz'
}
];
console.log(inArray(users, '246869534218469376')); // true
console.log(inArray(users, '222479534218469376')); // false

Object removal with filter method in Javascript

I want to remove objects with javascript with the filter method. how can i do this.
objects:
Code:
let todos = [
{
id: 0,
title: "Javascript",
completed: false
},
{
id: 1,
title: "php",
completed: true
}
]
This method:
function removeElement(id) {
let checkRemove = confirm("are you sure");
if (checkRemove) {
let item = todos.find(item => item.id === id);
let index = todos.indexOf(item);
// todos.splice(index, 1);
let filtered = todos.filter(function(){
});
render();
}
return;
}
I took care of the problem using the following codes thank you
I solved the problem
function removeElement(id) {
let checkRemove = confirm("are you sore");
if (checkRemove) {
let item = todos.find(item => item.id === id);
todos = todos.filter(function(item) {
return item.id !== id;
});
console.log(todos);
render();
}
return;
}
const removeElement = (id) => confirm('are you sure') ? todos = todos.filter(item => item.id !== id) : todos;
let todos = [
{
id: 0,
title: "Javascript",
completed: false
},
{
id: 1,
title: "php",
completed: true
}
];
console.log(todos);
console.log(removeElement(1));
This should work:
function removeElement(id) {
let checkRemove = confirm("are you sure");
if (checkRemove){
//It return all other elements except the id you pass to removeElement Function
let filtered = todos.filter(item => item.id !== id);
render();
}
return;
}

How to remove elements from an array of objects

In a todo app I'm making, I want to remove the completed tasks by clicking on a button.
This is what I have in my body:
<div id="div-todo"></div>
<button id="hide-todo">Hide completed</button>
<script src="script.js"></script>
</body>
And this is my js code:
const todos = [
{
text: 'Learn HTML',
completed: true
},{
text: 'Learn CSS',
completed: true
},{
text: 'Learn Javascript',
completed: false
},{
text: 'Learn Nodejs',
completed: false
},{
text: 'Learn SQL',
completed: false
}
]
// renderring and printing tasks
const renderTodo = function (todos) {
const incompletedTodo = todos.filter(function (todo) {
return !todo.completed
})
//printing the h2 tag that containe the number of incompleted task
const summery = document.createElement('h2')
summery.textContent = `You have ${incompletedTodo.length} todos left. `
document.querySelector('#div-todo').appendChild(summery)
//printting all of tasks
todos.forEach(function (todo) {
const p = document.createElement('p')
p.textContent = todo.text
document.querySelector('#div-todo').appendChild(p)
})
// button setting
document.querySelector('#hide-todo').addEventListener('click',function (e) {
const completedTodo = todos.filter(function (todo) {
return todo.completed
})
e.target.textContent = 'Completed task is hide'
console.log(completedTodo)
})
}
renderTodo(todos)
I want to hide uncompleted task with a button, I even log the completedTodo variable, but I don't know how to remove them (I am new to JS).
The problem is that there is no 'real' connection between the objects in your todos array and the actual html elements. So though a task might be flagged as completed you don't know what paragraph element is displaying the task.
To make a connection, get all child elements of the parent element holding all your paragraphs (div-todo), check if it's text matches the text in your todos array and ultimately remove the whole paragraph element if the task is flagged as completed.
document.querySelector('#hide-todo').addEventListener('click', function(e) {
const completedTodo = todos.filter(function(todo) {
return todo.completed
})
e.target.textContent = 'Completed task is hide'
var myChild = document.getElementById("div-todo").childNodes;
for (var a = 0; a < myChild.length; a++) {
for (var b = 0; b < completedTodo.length; b++) {
if (myChild[a].textContent == completedTodo[b].text) {
myChild[a].parentNode.removeChild(myChild[a]);
}
}
}
})
Just assing incompleted task in to do.
const todos = [{
text: 'Learn HTML',
completed: true
},{
text: 'Learn CSS',
completed: true
},{
text: 'Learn Javascript',
completed: false
},{
text: 'Learn Nodejs',
completed: false
},{
text: 'Learn SQL',
completed: false
}]
// renderring and printing tasks
const renderTodo = function(todos){
const incompletedTodo = todos.filter(function (todo) {
return !todo.completed
})
//printing the h2 tag that containe the number of incompleted task
const summery = document.createElement('h2')
summery.textContent = `You have ${incompletedTodo.length} todos left. `
document.querySelector('#div-todo').appendChild(summery)
//printting all of tasks
todos.forEach(function (todo) {
const p = document.createElement('p')
p.textContent = todo.text
document.querySelector('#div-todo').appendChild(p)
})
// button setting
document.querySelector('#hide-todo').addEventListener('click',function (e){
const completedTodo = todos.filter(function (todo) {
return todo.completed
})
e.target.textContent = 'Completed task is hide'
$('#div-todo').html('');
incompletedTodo.forEach(function (todo) {
const p = document.createElement('p')
p.textContent = todo.text
document.querySelector('#div-todo').appendChild(p)
})
console.log(completedTodo)
})
}
renderTodo(todos)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div id="div-todo"></div>
<button id="hide-todo">Hide completed</button>
<script src="script.js"></script>
</body>

Categories