How can I print out HTML markup based on an object hierarchy? - javascript

I have a customer list of over 200 on a flat site! I thought perhaps a Javascript object might be good here as it'll enable me to print out the HTML structure dynamically. Is there a way I can quickly build the HTML structure using an object or similar?
<ul class="main-list">
<li class="customer {{SEX}}">
<a href="{{URL}}">
<div>{{Name}}</div>
<img src="/img/{{PATH}}>
</a>
</li>
</ul>
Users: {
1: {
SEX: "male",
URL: "https://google.com",
NAME: "John Smith",
PATH: "/john.jpg"
},
2: {
SEX: "female",
URL: "https://url.com",
NAME: "Emily Smith",
PATH: "/emily.jpg"
},
{
.. so on ..
}
}
How would I be able to loop over the Users object in my markup that prints out the above HTML structure into the main-list div?

const users= {
1: {
SEX: "male",
URL: "https://google.com",
NAME: "John Smith",
PATH: "/john.jpg"
},
2: {
SEX: "female",
URL: "https://url.com",
NAME: "Emily Smith",
PATH: "/emily.jpg"
},
};
const container = document.getElementById('container');
const html = Object.values(users).reduce( (acc, {SEX, URL, NAME, PATH}) => {
return acc + `<div class="customer $SEX}">`
+ `<a href="${URL}">`
+ `<div>${NAME}</div>`
+ `<img src="/img/${PATH}" />`
+ '</a>'
+ '/<div>'
}, '');
container.innerHTML = html;
<div id='container'>
</div>

function makeHTML(obj) {
for(key in obj) {
const item = obj[key]
return `
<div class="customer ${item.SEX}">
<a href="${item.URL}">
<div>{${item.NAME}</div>
<img src="/img/${item.PATH}>
</a>
</div>
`
}
}
usage:
makeHTML(Users); // Returns HTML as string

Like this
I changed to an array
const users = [
{
SEX: "male",
URL: "https://google.com",
NAME: "John Smith",
PATH: "/john.jpg"
},
{
SEX: "female",
URL: "https://url.com",
NAME: "Emily Smith",
PATH: "/emily.jpg"
}
]
const html = users.map(user => `<div class="customer ${user.SEX}">
<a href="${user.URL}">
<div>${user.NAME}</div>
<img src="/img/${user.PATH}>
</a>
</div>`)
document.getElementById("main-list").innerHTML += html.join("")
<div id="main-list"></dov>

Related

Loops inside react components leading to rendering of sub components

I have a data as below
myArr = [
{
"Sl.No": "n1",
company: "ABC",
Name: "Sam",
Designation: "Architect",
Salary: "100",
},
{
"Sl.No": "n2",
company: "ABC",
Name: "Bill",
Designation: "Engineer",
Salary: "200",
},
{
"Sl.No": "n3",
company: "ABC",
Name: "Jill",
Designation: "HR",
Salary: "300",
},
{
"Sl.No": "n4",
company: "XYZ",
Name: "Bill",
Designation: "Engineer",
Salary: "250",
},
{
"Sl.No": "n5",
company: "XYZ",
Name: "Tom",
Designation: "Mechanic",
Salary: "150",
},
{
"Sl.No": "n6",
company: "LMN",
Name: "Tom",
Designation: "Mechanic",
Salary: "150",
},
];
I want to create a react app which shows the data as below. Nothing but listing the employees & their designations under the name of the company.
The boxes on the right are number of doses of vaccine taken (data comes from somewhere else)
I have the components set-up like so
Inside App.js
I have left out importing the components , css & all that for simplcity
export const App = () => {
return (
<div className=app}>
<CompanyInfo />
</div>
);
}
Inside CompanyInfo.js
export const CompanyInfo= () => {
let companies= [...new Set(myArr.map((item) => item.company))];
const renderingComponents = (company: string, index: number) => {
return (
<Fragment key={index}>
<p className="company-name">{company}</p>
<div className="category-employees">
<CompanyEmployee toggled={toggled} />
</div>
;
</Fragment>
);
};
return (
<div className=company-info}>
{companies.map((item, index) => renderingComponents(item, index))}
</div>
);
}
So far, so good, I can render the titles of all the companies & I have hardcoded the CompanyEmployee to see if it populates within every company & it does. However, I want CompanyEmployee to be dynamic & I am not able to figure our how to pass the company related info to the components (that data will have info of all the company employees) and then map the CompanyEmployee component on that data.
Inside CompanyEmployee.js
Please note that this is like a wrapper for 2 components
export const CompanyEmployee= () => {
return (
<div className=ce}>
<EmployeePrimaryDetails />
<EmployeeVacDetails />
</div>
);
}
Inside EmployeePrimaryDetails.js
export const EmployeePrimaryDetails= (props) => {
return (
<div className=epd>
<span className="name">{props.Name}</span>
<span className="designation">{props.Designation}</span>
</div>
);
}
Can anyone guide me on how I render EmployeePrimaryDetails.js for each employee of the company?
I tried to do a for of, forEach, map in the renderingComponents function of CompanyInfo itself but when I try that I get the Typescript error "Expression Expected" (I am using typescript with React in my project).
Any help is appreciated.
Inside renderingComponents function you can say:
const filteredList = myArr.filter(employee => employee.company === company);
filteredList.map(employee => (<CompanyEmployee employee={employee} toggled={toggled} />));
Resulting in this:
const renderingComponents = (company: string, index: number) => {
const filteredList = myArr.filter(employee => employee.company === company);
return (
<Fragment key={index}>
<p className="company-name">{company}</p>
<div className="category-employees">
{filteredList.map(employee => (<CompanyEmployee employee={employee} toggled={toggled} />))}
</div>
;
</Fragment>
);
};
So in CompanyEmployee component you can destructure the data you need.

What method to use to access multiple objects in an array?

I'm new to javascript and still learning them.
So I was building a project where I want to display a multiple object, which I put it in an array, to the DOM.
I am not sure what method to use to access the object inside the array.
<div class="container">
<div class="hero">
<h2>List of Names</h2>
</div>
<ul class="name-list"></ul>
</div>
This is my js file:
const nameList = document.querySelector('.name-list');
//List of Names
const john = {
name: 'john',
car: 'fiat',
address: 'new york'
}
const mike = {
name: 'mike',
car: 'toyota',
address: 'sydney'
}
const greg = {
name: 'greg',
car: 'nissan',
address: 'melbourne'
}
//Store list of names in an array
const allNames = [
john,
mike,
greg
]
function displayName (){
//Not sure what methods to use to
return `
<li>
<p>Name: ${allNames.name}</p>
<p>Car: ${allNames.car}</p>
<p>Address: ${allNames.address}</p>
</li>
`
}
So I kind of want to display all the objects in the DOM.
Is it necessary to put the objects in the array first? What methods do I use to return a list in the file? Or do you know any easier methods to display all the objects in the DOM?
Thank you so much for the help.
Maybe you can try something like this :
function showNameList() {
const allNames = [
{
name: 'john',
car: 'fiat',
address: 'new york'
},
{
name: 'mike',
car: 'toyota',
address: 'sydney'
},
{
name: 'greg',
car: 'nissan',
address: 'melbourne'
}
]
var namelist = allNames.map(function (t, i) {
return `<b>Name : </b> ${t.name}<br/><b>Car : </b> ${t.car}<br/><b>Address : </b> ${t.address}<br/><br/>`;
})
document.getElementById('name-list').innerHTML =
'<li>' + namelist.join('</li><li>') + '</li>'
}
showNameList()
<div class="container">
<div class="hero">
<h2>List of Names</h2>
</div>
<ul id="name-list"></ul>
</div>
use map function to display them :
const values = allNames.map(item=>{
return(
<li>
<p>Name: ${item.name}</p>
<p>Car: ${item.car}</p>
<p>Address: ${item.address}</p>
</li>
)
})
<div class="container">
<div class="hero">
<h2>List of Names</h2>
</div>
<ul class="name-list">
{values}
</ul>
</div>

how to make a new div with jquery?

okay so, I need to create a new div using jquery with the information of a first and last name that I loop from my array.. This is what I have so far, I was wondering if I could get some help on how to make it show up on my webpage. it needs to show up like:
hello firstname lastname
hello firstname lastname
hello firstname lastname
<div id="output"></div>
function names() {
var firstAndLast = [
{name: "jane", surname: "doe"},
{name: "john", surname: "leg"},
{name: "hunny", surname: "bun"}
];
var div = $("#output");
for (var i=0; i < firstAndLast.length; i++) {
}
var div1 = $("<div>").html("Hello name surname");
$("#names").append(div1);
Your code is almost there. The main issue is that you need to put the line of jQuery which creates the div and appends it within the for loop. In addition you can retrieve the name and surname from the objects in the array using the i variable to access them by index:
var $output = $("#output");
for (var i = 0; i < firstAndLast.length; i++) {
var div1 = $("<div>").html(`Hello ${firstAndLast[i].name} ${firstAndLast[i].surname}`);
$output.append(div1);
}
That being said, the most performant way to do this would be to use map() to build an array of HTML strings which you only append to the DOM once:
function names() {
let firstAndLast = [
{ name: "jane", surname: "doe" },
{ name: "john", surname: "leg" },
{ name: "hunny", surname: "bun" }
];
let html = firstAndLast.map(o => `<div>Hello ${o.name} ${o.surname}</div>`);
$("#output").append(html);
}
names();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="output"></div>
You can try something like this
function names() {
var firstAndLast = [{
name: "jane",
surname: "doe"
},
{
name: "john",
surname: "leg"
},
{
name: "hunny",
surname: "bun"
}
];
let _data = firstAndLast.reduce((acc, {
name,
surname
}) => {
acc += `hello <span>${name}</span> <span>${surname}</span><br>`
return acc;
}, "")
$("#output").html(_data);
}
names()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="output">
</div>

How do I split and Array into two parts based on type- Angular JS

I am trying to split an array into 2 types based on type: Buyer or Supplier. If you look at the last snippet, there is an array called newCompanies where there are company names with the type of company.
I am trying to get that company array data from local storage and I want to split them into 2 arrays so that I can have 2 types of listboxes. One is the Buyer listbpx and the other is supplier listbox.
Thanks in advance
var companies = JSON.parse(localStorage.getItem("newCompany"));
var splitted = companies.reduce(function(obj, item) {
if (obj[item.type] == null) {
obj[item.type] = [];
}
obj[item.type].push(item);
return obj;
}, {});
splitted.buyer;
splitted.supplier;
$scope.companies.push(splitted.supplier);
$scope.companies.push(splitted.buyer);
<div class="form-group">
<label class="control-label col-sm-2">Company</label>
<div class="col-sm-10" ng-class="{ 'has-error' : addForm.addCompany.$invalid && !addForm.addCompany.$pristine }">
<select class="form-control" name="addCompany"
placeholder="Select Company"
ng-options="company for company in companies"
ng-model="newUser.company" ng-required="true">
</select>
<span class="help-block" ng-show="addForm.addCompany.$invalid && !addForm.addCompany.$pristine">
Your Company is required.
</span>
</div>
</div>
var newCompany = [{
name: "Huawei", // -->COMPANY NAME
email: "Drath#yahoo.com",
phone: "123-123-1234",
owner: "Drath",
type: "buyer"
},
{
name: "Asus", // -->COMPANY NAME
email: "Vadar#yahoo.com",
phone: "999-123-8888",
owner: "Vadar",
type: "supplier"
},
{
name: "Acer", // -->COMPANY NAME
email: "Radal#yahoo.com",
phone: "676-989-8888",
owner: "Randall",
type: "supplier"
}
];
window.localStorage.setItem("newCompany", JSON.stringify(newCompany));
var newCompany = [{
name: "Huawei", // -->COMPANY NAME
email: "Drath#yahoo.com",
phone: "123-123-1234",
owner: "Drath",
type: "buyer"
},
{
name: "Asus", // -->COMPANY NAME
email: "Vadar#yahoo.com",
phone: "999-123-8888",
owner: "Vadar",
type: "supplier"
},
{
name: "Acer", // -->COMPANY NAME
email: "Radal#yahoo.com",
phone: "676-989-8888",
owner: "Randall",
type: "supplier"
}
];
let buyers = [], suppliers = [];
for (let company of newCompany) {
if (company.type === "buyer")
buyers.push(company);
else
suppliers.push(company);
}
console.log("Buyers:");
console.log(buyers);
console.log("Suppliers:");
console.log(suppliers);
With a reduce:
var companies = JSON.parse(window.localStorage.getItem('newCompany'));
var splitted = companies.reduce(function (obj, item) {
if (obj[item.type] == null) { obj[item.type] = []; }
obj[item.type].push(item);
return obj;
}, {});
Will result in splitted looking like this:
{
buyer: [{name: "Huawei", ... }],
supplier: [{name: "Asus", ... }, {name: "Acer", ... }]
}
And then grab the information from splitted:
splitted.buyer; // -> [{name: "Huawei", ... }]
splitted.supplier; // -> [{name: "Asus", ... }, {name: "Acer", ... }]
This has the additional benefit, that if you add a third "type" of company later, you won't have to change a single line of code.

Returning json object nightwatch.js

I want to execute json object like this from my html ul list like this
{name: "Nick", surname:"Kyrgios", age: "22", city: "Sydney"}, {....}, {....}
this is the html part
<html>
<ul>
<li class="user">
<div class="name">Nick</div>
<div class="surname">Kyrgios</div>
<div class="age">22</div>
<div class="city">Sydney</div>
</li>
<li class="user odd">
<div class="name">Nick</div>
<div class="surname">Kyrgios</div>
<div class="age">22</div>
<div class="city">Sydney</div>
</li>
</ul>
</html>
my nightwatch js file
browser.elements('css selector','ul li', function (result) {
els = result.value;
var i = 0;
els.forEach(function(el, j, elz){
browser.elementIdText(el.ELEMENT, function(text) {
console.log(text)
})
})
})
This will execute
{ state: 'success',
sessionId: 'cdfdda85-4348-4692-9ad0-2a5d10080a27',
hCode: 151444186,
value: 'Nick\nKyrgios\n22\nSydney',
class: 'org.openqa.selenium.remote.Response',
status: 0 }
{ state: 'success',
sessionId: 'cdfdda85-4348-4692-9ad0-2a5d10080a27',
hCode: 118749018,
value: 'Nick\nKyrgios\n22\nSydney',
class: 'org.openqa.selenium.remote.Response',
status: 0 }
The main question is how can I change it to normal json format like
{name: "Nick", surname:"Kyrgios", age: "22", city: "Sydney"}, {....}, {....}
Every time you run console.log - you are automatically getting a carriage return. Each call to console.log moves you down one line.
You should be appending the results to a string
var jsonString = "";
els.forEach(function(el,j,elz) {
browser.elementIdText(el.ELEMENT, function(text) {
jsonString += text;
})
console.log(jsonString);

Categories

Resources