Is there a way to simplify this snippet? - javascript

const navTitle = document.querySelectorAll(".nav-sec");
const subTitle = document.querySelector(".subtitle");
const artTexts = document.querySelectorAll(".art-text");
const sectionTitles = document.querySelectorAll(".section_title");
const footerContent = document.querySelector(".footer_content");
const projectsTitle = document.querySelectorAll(".title-project");
const projectsDescription = document.querySelectorAll(".desc-project");
const aboutTitle = document.querySelectorAll(".about_title");
const contactContent = document.querySelector(".contact_content");
const aboutContent = document.querySelectorAll(".about_content");
btnLang.addEventListener("click", () => {
const attr = (btnEnglish.classList.contains("hiddden") ? btnPortuguese : btnEnglish).getAttribute("language");
navTitle.forEach((el, index) => (el.textContent = data[attr].navbar[index]));
sectionTitles.forEach((title, index) => (title.textContent = data[attr].navbar[index]));
projectsTitle.forEach((project_titles, index) => (project_titles.textContent = data[attr].project_titles[index]));
projectsDescription.forEach((project_description, index) => (project_description.textContent = data[attr].project_description[index]));
aboutTitle.forEach((about_title, index) => (about_title.textContent = data[attr].about_title[index]));
aboutContent.forEach((about_content, index) => (about_content.textContent = data[attr].about_content[index]));
contactContent.textContent = data[attr].contact_content;
subTitle.textContent = data[attr].subtitle;
footerContent.textContent = data[attr].footer_content;
});
I'm a benninger and I know that when you are repeating yourself too much, you can probably simplify things. But how can I approach something like this code? DRY ftw.

Assuming you have the same number of array elements in data as matching elements in the DOM, one approach is to use an array of selectors, each of which is tied to the associated property name on the data. Iterate over the selectors and language properties, then loop over each element matching the selector to assign the same index from the language property.
const selectorsByLangProp = [
['navbar', '.nav-sec'],
['navbar', '.section_title'],
['project_titles', '.title-project'],
['project_description', '.desc-project'],
['about_title', '.about_title'],
['about_content', '.about_content'],
];
btnLang.addEventListener("click", () => {
const attr = (btnEnglish.classList.contains("hiddden") ? btnPortuguese : btnEnglish).getAttribute("language");
const langData = data[attr];
for (const [langProp, selector] of selectorsByLangProp) {
document.querySelectorAll(selector).forEach((elm, i) => {
elm.textContent = langData[langProp][i];
});
}
contactContent.textContent = langData.contact_content;
subTitle.textContent = langData.subtitle;
footerContent.textContent = langData.footer_content;
});
For larger, complicated pages, a nicer approach to this sort of thing would be to construct the HTML directly from the data, instead of having separate selectors and properties. For example, with React, one might be able to do something similar to the following:
const Page = ({ langData }) => (<>
<div>{langData.subTitle}</div>
{
langData.sections.map((sectionData) => (
<section>
<div>{sectionData.project_title}</div>
<div>{sectionData.project_description}</div>
</section>
))
}
<footer>{langData.contact_content} {langData.footer_content}</footer>
</>);
(That isn't working code, but it's an example of what implementing this sort of thing could look like)

Related

Changing elements to lowercase issues

I'm building a dynamic list of trees that starts with Oak, Pine, Aspen, Bald Cypress.
Which includes a button to add a 'Redwood' tree to the end of the list, and a 'Pear' tree to the start of the list.
I then included a button that onclick would change the strings to lowercase but I can't seem to get it right. I know the push() method will add the lowercase strings to the end of the list but I can't figure out how to get rid of the old strings with uppercase letters, and it also keeps adding more items to the list when the button is pushed again. I also tried the map method, however it did not seem to work unless created a new variable.
const trees = ['Oak', 'Pine', 'Aspen', 'Bald Cypress']
const listTrees = () => {
let treeList = ''
trees.forEach(tree => {
//console.log(tree)
treeList += `${tree} <br>`
})
displayResults.innerHTML = `${treeList} <span>${trees.length} elements
long</span>`
}
listTrees()
* ------adding redwood to the end ------------*/
document.querySelector('#add_redwood').onclick = () => {
trees.push('Redwood')
listTrees()
}
/* --------------------adding a pear to the start ----------------------*/
document.querySelector('#add_pear').onclick = () => {
trees.unshift('Pear')
listTrees()
}
document.querySelector('#lowerTrees').onclick = () => {
trees.forEach(tree => {
trees.push(tree.toLowerCase())
})
listTrees()
}
Simply declare trees with let instead of const then reassign it. There is no reason for you to keep the original array reference in this case. Then you can use map(). You can also use map() for listTrees().
const displayResults = document.querySelector("#displayResults");
let trees = ['Oak', 'Pine', 'Aspen', 'Bald Cypress']
const listTrees = () => {
let treeList = trees.map(tree => `${tree}<br>`).join("");
displayResults.innerHTML = `${treeList} <span>${trees.length} elements long</span>`
}
listTrees()
/* ------adding redwood to the end------------ */
document.querySelector('#add_redwood').onclick = () => {
trees.push('Redwood')
listTrees()
}
/* --------------------adding a pear to the start ----------------------*/
document.querySelector('#add_pear').onclick = () => {
trees.unshift('Pear')
listTrees()
}
document.querySelector('#lowerTrees').onclick = () => {
trees = trees.map(tree => tree.toLowerCase());
listTrees();
}
<button id="add_redwood">Add Redwood</button>
<button id="add_pear">Add Pear</button>
<button id="lowerTrees">Lower Trees</button>
<div id="displayResults"></div>
If you really want to keep tree as const, use a regular for loop to change each element one by one instead.
for(let i = 0; i < trees.length; i++)
{
trees[i] = trees[i].toLowerCase();
}
Because you have to reassign lowercased values to HTML
document.querySelector('#lowerTrees').onclick = () => {
trees.forEach(tree => {
trees.push(tree.toLowerCase())
})
listTrees()
}

How to compare 2 object in react JS and get the values

I have 2 state
console.log(this.state.tempWilayahUser)
console.log(this.state.wilayahUser)
how to get row when have same value of id_rt ?
You can use filter() function to achieve this. You can read the docs here.
const state1 = [];
const state2 = [];
const itemsWithIdRtFromState1 = state1.filter(item1 => {
return state2.filter(item2 => item2?.id_rt === item1?.id_rt)
});
const itemsWithIdRtFromState2 = state2.filter(item2 => {
return state1.filter(item1 => item1?.id_rt === item2?.id_rt)
});

How to generate HTML text with a for loop?

I have a list of expenses, I want to create a html code to iterate over all the expenses and show their name. I am not working with the DOM, I literally want to save the html code in a variable, so I can generate a pdf file with it.
This is what I tried:
lets say I have this array
const spents = [{expenseName: "Pizza"},{expenseName: "Home"}]
const testHtml = () => {
for(let i of spents) {
const title = `<h1>${i.expenseName}</h1>`
}
}
testHtml()
This is the result I want, something like:
htmlResult = "<h1>${i.expenseName}</h1> <h1>${i.expenseName}</h1>"
by the way, This is for a react native app.
I think this will work for you.
const spents = [{expenseName: "Pizza"},{expenseName: "Home"}]
const testHtml = () => {
let title = '';
for(let i of spents) {
title += `<h1>${i.expenseName}</h1>`
}
return title;
}
testHtml()
You could use Array.prototype.reduce().
const spents = [{
expenseName: "Pizza"
}, {
expenseName: "Home"
}];
const result = spents.reduce((prev, curr, index) => index === 0 ? curr.expenseName : `<h1>${prev}</h1> <h1>${curr.expenseName}</h1>`, '');
document.body.append(result);

My javascript code does not work with the result of work php

I have website on wordpress, and i use Search & Filter Pro plugin for filter my posts.
I need to sort filter fields by posts count.The plugin does not provide the necessary functionality, so I decided to use javascript to sort.
const getFilterFieldDepMeth = () => {
const container = document.querySelector(
".sf-field-taxonomy-deposit_methods ul"
);
const listField = container.querySelectorAll("li");
let arrayList = [];
listField.forEach((item) => {
arrayList.push(item);
});
const sortedListField = arrayList.sort((a, b) => {
const elem1 = parseInt(b.getAttribute("data-sf-count"));
const elem2 = parseInt(a.getAttribute("data-sf-count"));
return elem1 - elem2;
});
sortedListField.map((item) => {
container.appendChild(item);
});
};
getFilterFieldDepMeth();
The code works and can show the result anywhere but I can’t influence the DOM in the filter block. I also cannot delete filter fields.

How remove an element from array with Redux ? JavaScript

i wanted to remove an element from an array but i'm not getting, my code is:
const renderCount = state => {
const peopleHtml = state.filteredPeople.map(person => {
const personHtml = document.createElement('LI');
const personName = document.createTextNode(person.name);
const buttonDelete = document.createElement('Button');
const textOfButtonDelete = document.createTextNode('Delete');
buttonDelete.appendChild(textOfButtonDelete);
personHtml.appendChild(personName);
personHtml.appendChild(buttonDelete);
buttonDelete.onclick = function() {
return {...state,filteredPeople : state.filteredPeople.filter( (item, index) => index !=="Jean")}
}
return personHtml;
});
resultado.innerHTML = '';
peopleHtml.forEach(personHtml => resultado.appendChild(personHtml));
};
export default renderCount;
What the code makes?
He renders the elements of an array, 3 in 3. Each element of array have a button 'delete'and each time that i clicked that, a element get out off the screen.
The code and the button are: buttonDelete.onclick.....
Thanks and good afternoon.
This is not the right way to do in reactjs. React believe on Virtual DOM. Your states values and HTML elements will be talking with each other and you do not need to use appendChild or removeChild to update them , just update the state value. Some thing like below
render()
{
return (
<div>
<ul>
{this.state.filteredPeople.map(person => { =>
<li>
{person.name}
<button onClick={this.deleteme.bind(this,person.id)}>Delete</button>
</li>
)}
</ul>
</div>
);
}
deleteme(index){
let initial_val = this.state.contents.slice();
let obj_to_del= initial_val.find(person => person.id === id);
initial_val.remove(obj_to_del);
this.setState({people:initial_val});
}

Categories

Resources