how to add a element with href on li element? - javascript

i have a search system on my website it works but i can not click on items i search. its a simple script that creates li elements dephended on my search input but how can i add this elements a custom links? because if you can not click on item you searched that does not make any sense... i want to add this const people elements custom links.code:
const people = [
{name:'გადაარჩინე დედამიწა'},
{name:'ანტიმელა'},
{name:'mr.capsule'},
{name:'capsule battle royale'}
];
const list = document.getElementById('list');
function setlist (group) {
clearlist();
for (const person of group) {
const item = document.createElement("li");
item.classList.add("list-group-item");
const text = document.createTextNode(person.name);
item.appendChild(text);
list.appendChild(item);
}
if (group.length === 0) {
setnoresults();
}
}
function clearlist () {
while (list.firstChild) {
list.removeChild(list.firstChild);
}
}
function getrelevency (value, searchTerm) {
if (value === searchTerm) {
return 2;
}else if (value.startsWith(searchTerm)) {
return 1;
}else if (value.includes(searchTerm)) {
return 0;
}
}
function setnoresults () {
const item = document.createElement('li');
item.classList.add('list-group-item');
const text = document.createTextNode('შედეგები ვერ მოიძებნა... სცადეთ თავიდან');
item.appendChild(text);
list.appendChild(item);
}
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', (event) => {
let value = event.target.value;
if (value && value.trim().length > 0) {
value = value.trim().toLowerCase();
setlist(people.filter(person => {
return person.name.includes(value);
}).sort((personA, personB) => {
return getrelevency(personB.name, value) - getrelevency(personA.name, value);
}));
}else {
clearlist();
}
});

You should add it in setlist function.
function setlist (group) {
clearlist();
for (const person of group) {
const item = document.createElement("li");
item.classList.add("list-group-item");
const link = document.createElement("a");
link.href = "http://..."; // put here where the link should point
item.appendChild(link);
const text = document.createTextNode(person.name);
link.appendChild(text);
list.appendChild(item);
}
if (group.length === 0) {
setnoresults();
}
}

i got solution with this way checking what search input is and if its targeted search it will add a link on custom search. if statemant is doing everything!
function setlist (group) {
clearlist();
for (const person of group) {
const item = document.createElement("li");
item.classList.add("list-group-item");
if (person.name === "გადაარჩინე დედამიწა") {
const link = document.createElement("a");
link.href = "https://google.com"; // put here where the link should point
link.text = "გადაარჩინე დედამიწა"
item.appendChild(link);
}
const text = document.createTextNode(person.name);
item.appendChild(text);
list.appendChild(item);
}
if (group.length === 0) {
setnoresults();
}
}

Related

javascript function calling in loop

I'm making a map using leaflet.js.
I made a function where user selects a country and it generates easybuttons with that selection with specific information.
The problem is when I select one country after another it creates more easybuttons and doesn't remove the previously created button.
Please check the image so you can know what the problem is.
function generateList() {
const list = document.querySelector('.dropdown-content');
countryList.sort(function (a, b) {
if (a.properties.country < b.properties.country) {
return -1;
}
if (a.properties.country > b.properties.country) {
return 1;
}
return 0;
});
countryList.forEach((country) => {
const a=document.createElement('a');
const p=document.createElement('p');
//flying to the country on user click on country
a.addEventListener('click', () => {
flyToStore(country);
const city=country.properties.city;
const currency1=country.properties.currency;
const contry=country.properties.country;
L.easyButton('fa-solid fa-cloud fa-lg',function (){
weatherdetails(city);
$('#weathermodal').modal('show');
}).addTo(myMap);
L.easyButton('fa fa-dollar fa-lg',function (){
currencyexchange(currency1);
$('#myModal').modal('show');
}).addTo(myMap);
L.easyButton('fa fa-info-circle fa-lg',function (){
moredetails(contry);
$('#detailsmodal').modal('show');
}).addTo(myMap);
});
a.classList.add('country-item');
countries=country.properties.country;
a.innerText =countries ;
//div.appendChild(p);
list.appendChild(p);
p.appendChild(a);
});
}
I think you need to hold a reference to that button instance. Then call your map removeControl it.
function generateList() {
const list = document.querySelector('.dropdown-content');
countryList.sort(function (a, b) {
if (a.properties.country < b.properties.country) {
return -1;
}
if (a.properties.country > b.properties.country) {
return 1;
}
return 0;
});
lastButton1 = null;
lastButton2 = null;
lastButton3 = null;
countryList.forEach((country) => {
const a = document.createElement('a');
const p = document.createElement('p');
//flying to the country on user click on country
a.addEventListener('click', () => {
if (lastButton1) {
myMap.removeControl(lastButton1);
myMap.removeControl(lastButton2);
myMap.removeControl(lastButton3);
lastButton1 = null
}
flyToStore(country);
const city = country.properties.city;
const currency1 = country.properties.currency;
const contry = country.properties.country;
lastButton1 = L.easyButton('fa-solid fa-cloud fa-lg', function () {
weatherdetails(city);
$('#weathermodal').modal('show');
})
lastButton2 = L.easyButton('fa fa-dollar fa-lg', function () {
currencyexchange(currency1);
$('#myModal').modal('show');
})
lastButton3 = L.easyButton('fa fa-info-circle fa-lg', function () {
moredetails(contry);
$('#detailsmodal').modal('show');
})
lastButton1.addTo(myMap);
lastButton2.addTo(myMap);
lastButton3.addTo(myMap);
});
a.classList.add('country-item');
countries = country.properties.country;
a.innerText = countries;
//div.appendChild(p);
list.appendChild(p);
p.appendChild(a);
});
}

How to delete specific item from local storage on click of button in todo app

How can i make a delete function that deletes the specific list from local storage when delete button is clicked and update the data. I am a beginner and i have no idea how i can make this happen. I have tried to look for solution by watching video but i couldn't find solution that i can understand.
let input = document.querySelector('input');
let btn = document.querySelector('button');
let ul = document.querySelector('ul');
let arr = getItem() || [];
arr.forEach(renderItem);
function addItem() {
let inVal = input.value;
if (inVal === '') return;
renderItem(inVal);
arr.push(inVal);
setItem(arr);
input.value = '';
input.focus();
}
btn.addEventListener('click', () => {
addItem();
});
window.addEventListener('keydown', e => {
if (e.key === 'Enter') {
addItem();
}
});
function renderItem(render) {
let li = document.createElement('li');
li.innerText = render;
let del = document.createElement('button');
del.innerText = 'delete';
del.setAttribute('class', 'delete');
li.append(del);
ul.append(li);
}
function setItem(set) {
localStorage.setItem('name', JSON.stringify(arr));
}
function getItem() {
let result = localStorage.getItem('name');
return JSON.parse(result);
}

Passing the Eventlistener to the correct function in JS

I have two buttons (each of them has a value which matches the id of a dish in the food menu) with two EventListeners. One button for adding something to a shopping cart and one button to remove something from the shopping cart. My problem is, that i cant figure out how to pass the Eventlistener to the correct class function. This is my code so far:
class Cart {
constructor() {
this.inhalt = [];
}
add(item) {
this.inhalt.push(item);
console.log(this.inhalt)
}
remove(item) {
for (let i = 0; i < this.inhalt.length; i++) {
if (this.inhalt[i].id === item.id) {
this.inhalt.splice(i, 1);
console.log(this.inhalt)
}
}
}
sum() {
let s = null;
this.inhalt.price.forEach(element => {
s += element
});
console.log(s)
}
}
const myCart = new Cart();
function getItem(type) {
let item = null;
for (let i=0; i<speisekarte.length; i++) {
if (speisekarte[i].id === this.value) {
item = speisekarte[i];
break;
}
}
if (type == "plus") {myCart.add(item)}
else if (type == "minus") {myCart.remove(item)};
}
let plus = document.querySelectorAll(".kaufen");
plus.forEach(el =>{
let type = "plus"; el.addEventListener("click", getItem(type));
});
let minus = document.querySelectorAll(".zurück");
minus.forEach(el =>{
let type = "minus"; el.addEventListener("click", getItem(type));
});
You shouldn't be calling the functions when registering the event listeners.
Instead of:
let plus = document.querySelectorAll(".kaufen");
plus.forEach(el =>{
let type = "plus"; el.addEventListener("click", getItem(type));
});
let minus = document.querySelectorAll(".zurück");
minus.forEach(el =>{
let type = "minus"; el.addEventListener("click", getItem(type));
});
Do this:
let plus = document.querySelectorAll(".kaufen");
plus.forEach(el =>{
el.addEventListener("click", () => getItem("plus"));
});
let minus = document.querySelectorAll(".zurück");
minus.forEach(el =>{
el.addEventListener("click", () => getItem("minus"));
});

Create Html Tree view with native javascript / HTML

I need to create an HTML/CSS tree view as in the example from already created object using native javascript.
Please suggest,
BR
You could first build nested structure and then use recursive approach to also create html from that data where if the current element has children property you call the function again with that children array as a data parameter.
var data = [{"name":"container-1","type":"container","description":"container description"},{"name":"category-1","type":"category","parent":"container-1"},{"name":"grid-1","type":"grid","parent":"category-1"},{"name":"chart-1","type":"chart","parent":"category-1"},{"name":"container-2","type":"container"},{"name":"category-2","type":"category","parent":"container-2"},{"name":"category-3","type":"category","parent":"container-2"},{"name":"grid-2","type":"grid","parent":"category-2"},{"name":"chart-2","type":"chart","parent":"category-2"},{"name":"grid-3","type":"grid","parent":"category-3"}]
function toTree(data, pid = undefined) {
return data.reduce((r, e) => {
if (pid == e.parent) {
const obj = { ...e }
const children = toTree(data, e.name)
if (children.length) obj.children = children;
r.push(obj)
}
return r
}, [])
}
function toHtml(data, isRoot = true) {
const ul = document.createElement('ul')
if (!isRoot) {
ul.classList.add('hide')
}
data.forEach(e => {
let isVisible = isRoot;
const li = document.createElement('li')
const text = document.createElement('span')
const button = document.createElement('button')
if (e.children) {
button.textContent = '+'
li.appendChild(button)
}
text.textContent = e.name
li.appendChild(text)
if (e.children) {
const children = toHtml(e.children, false)
li.appendChild(children)
button.addEventListener('click', function() {
if (isRoot) {
isVisible = !isVisible
}
button.textContent = isVisible ? '+' : '-'
children.classList.toggle('hide')
if (!isRoot) {
isVisible = !isVisible
}
})
}
ul.appendChild(li)
})
return ul;
}
const tree = toTree(data)
const html = toHtml(tree)
document.body.appendChild(html)
.hide {
display: none;
}
button {
margin-right: 10px;
}

Select list filter json data

I want to do filtering from json by select list. now when I choose value from the select list, it gives selected products at the end of the list, and I want to show only those selected
function showContent(data) {
const contentBox = document.querySelector('#content__products');
const select = document.querySelector('.products__select');
data.map(function (product) {
return selectCat(product)
})
}
function selectCat(product) {
const select = document.querySelector('.products__select');
createProduct(product)
select.addEventListener('change',() => {
if(select.value == product.cat) {
createProduct(product);
}
})
}
function createProduct(product) {
const contentBox = document.querySelector('#product__list');
const element = prepareElement('div',['product__elem']);
const imageElement = prepareElement('img', ['product__img'], element);
const nameProd = prepareElement('p',['product__name'], element);
const catProd = prepareElement('p',['product__cat'], element);
contentBox.appendChild(element)
imageElement.setAttribute('src', product.img);
nameProd.innerText = product.name;
catProd.innerText = 'Category:' + ' ' + product.cat;
}
You can hide elements that don't match to your filter. In your code, I assume that you need to clean the container with products first.
function selectCat(product) {
const select = document.querySelector('.products__select');
createProduct(product)
select.addEventListener('change',() => {
var contentBox = document.getElementById('product__list');
while (contentBox.firstChild) {
contentBox.removeChild(contentBox.firstChild);
}
if(select.value == product.cat) {
createProduct(product);
}
})
}

Categories