Effective solution to map names with groups - javascript

I have some staff names. Each staff can be in different groups. Say staff names are N1, N2, and N3, and group names are G1, and G2.
I need to show in a webpage which staff belongs which group (sorting by groups). E.g. G1 contains N1 and N2.
Also I need to show (when another button is clicked) for each staff what are the groups they belongs to. E.g. N1 belongs to G1 and G2.
What is the effective way to do this in a webpage?

I have create an object with staffname as key and groupsArray as value;
Others must be self-explanatory; Hope this helps
let staffsArray = ["N1","N2","N3"];
staffs = [{
"N1" : ["G1","G2","G3"]
},{
"N2" : ["G1"]
},
{
"N3" : ["G3"]
},
{
"N4" : ["G2","G3"]
}]
window.onload = appendStaffsToDropDown();
function appendStaffsToDropDown() {
staffsArray.map((staffName) => {
let staffNameDiv = document.createElement("option");
let x = document.createElement("OPTION");
x.setAttribute("value", staffName);
let t = document.createTextNode(staffName);
x.appendChild(t);
document.getElementById("staffDropDown").appendChild(x)
});
displayStaffDetails();
}
function displayStaffDetails() {
staffsArray.map((staffName) => {
staffs.map((staffObject) => {
if(staffObject[staffName] != undefined) {
let parentDiv = document.getElementById('staffDetails');
let staffNameDiv = document.createElement("div");
let staffNameContent = document.createTextNode("staffName :" + staffName);
staffNameDiv.appendChild(staffNameContent);
parentDiv.appendChild(staffNameDiv)
let staffGroupDiv = document.createElement("div");
let staffGroupContent = document.createTextNode("StaffGroup :" + staffObject[staffName]);
staffGroupDiv.appendChild(staffGroupContent);
parentDiv.appendChild(staffGroupDiv)
}
});
});
}
document.getElementById("staffDropDown").onchange = function () {
let staffName = document.getElementById("staffDropDown").value;
var filteredDetails = document.getElementById("filteredDetails");
while (filteredDetails.firstChild) {
filteredDetails.removeChild(filteredDetails.firstChild);
}
staffs.map((staffObject) => {
if(staffObject[staffName] != undefined) {
let parentDiv = document.getElementById('filteredDetails');
let staffNameDiv = document.createElement("div");
let staffNameContent = document.createTextNode("staffName :" + staffName);
staffNameDiv.appendChild(staffNameContent);
parentDiv.appendChild(staffNameDiv)
let staffGroupDiv = document.createElement("div");
let staffGroupContent = document.createTextNode("StaffGroup :" + staffObject[staffName]);
staffGroupDiv.appendChild(staffGroupContent);
parentDiv.appendChild(staffGroupDiv)
document.getElementById("staffDetails").style.display = 'none';
}
});
}
<div id="staffDetails">
</div>
<select id="staffDropDown">
<option>Select Staffs</option>
</select>
<button>
Filter groups
</button>
<div id="filteredDetails">
</div>

Related

URL is produced each radio click, how to stop

Finally found an anchor code that puts a clickable URL where I want it, however the onclick of the radio buttons writes the URL for each click.
I need the URL to replace / reset the previous selection on each radio click so only 1 URL is ever showing - i will eventually have about 30 radio buttons - each will produce a different URL.
var roomNo = ""
var phoneNo = ""
var guestPin = ""
var roomLink = ""
var createLinkNode1 = ""
var createLinkNode2 = ""
var link369 = 'https://join.meet.video.justice.gov.uk/';
var link453 = 'https://join.meet.video.justice.gov.uk/';
function H369() {
document.getElementById("roomNo").innerHTML = "CVP Room: " + "HMCTS369";
document.getElementById("phoneNo").innerHTML = "Telephone Number: " + "02920 ";
document.getElementById("guestPin").innerHTML = "Guest Pin Number: " + "4444";
document.getElementById("roomLink").innerHTML = "<b>" + "Full Clickable URL Link: " + "</b>";
createLinkNode1(link369, document.body);
function createLinkNode1(url, parent) {
const linkTextNode = document.createTextNode(url);
const linkNode = document.createElement('a');
linkNode.href = url;
linkNode.appendChild(linkTextNode);
parent.appendChild(linkNode);
}
}
function H453() {
document.getElementById("roomNo").innerHTML = "CVP Room: " + "HMCTS453";
document.getElementById("phoneNo").innerHTML = "Telephone Number: " + "02920";
document.getElementById("guestPin").innerHTML = "Guest Pin Number: " + "5555";
document.getElementById("roomLink").innerHTML = "<b>" + "Full Clickable URL Link: " + "</b>";
createLinkNode2(link453, document.body);
function createLinkNode2(url, parent) {
const linkTextNode = document.createTextNode(url);
const linkNode = document.createElement('a');
linkNode.href = url;
linkNode.appendChild(linkTextNode);
parent.appendChild(linkNode);
}
}
<html>
<body>
<input type="radio" name="CVPRoom" onclick = "H369()">HMCTS369</br>
<input type="radio" name="CVPRoom" onclick = "H453()">HMCTS453</br>
<p id="demo"></p>
<p id="demo2"></p>
<p id="demo3"></p>
<div id="roomNo"></div>
<div id="phoneNo"></div>
<div id="guestPin"></div>
<div id="roomLink"></div>
<script src="CVPScripts.js">
</script>
</body>
</html>
I had it working on my previous code version, but the anchor would put the URL at the bottom of the HTML so was useless - stupidly overwrote the code so no example to demo
I suggest you delegate and create an object to hold the values
Then you are much more DRY (Don't Repeat Yourself)
I additionally use template literals
const radioContainer = document.getElementById("radioContainer");
const linkBase = 'https://join.meet.video.justice.gov.uk/HMCTS/#/';
const emailBase = '#meet.video.justice.gov.uk';
const output = document.getElementById("output");
const rooms = {
"hmcts369": {
"telephone": "02920 376411",
"guestPin": "4444"
},
"hmcts453": {
"telephone": "02920 376400",
"guestPin": "5555"
}
};
// create the room radios
radioContainer.innerHTML = Object
.keys(rooms)
.map(key => `<label><input type="radio" name="CVPRoom" />${key.toUpperCase()}</label>`).join("<br/>");
radioContainer.addEventListener("click", function(e) { // click anywhere in the label to select and show the details
const tgt = e.target.closest("label");
if (!tgt) return
const thisRoom = tgt.textContent.trim();
const thisRoomKey = thisRoom.toLowerCase();
const details = rooms[thisRoomKey];
if (!details) {
alert(`Sorry, room ${thisRoom} not found`);
return;
}
const href = `${linkBase}?conference=${thisRoomKey}${emailBase}`; //
output.innerHTML = `<div id="roomNo">CVP Room: ${thisRoom}</div>
<div id="phoneNo">Telephone Number: ${details.telephone}</div>
<div id="guestPin>Guest Pin Number: ${details.guestPin}</div>
<div id="roomLink"><b>Full Clickable URL Link</b></div>`;
})
<div id="radioContainer"></div>
<div id="output"></div>
Note the URL is not a truly valid URL with the /#/ in the middle.
If you have a better URL, you can do
const linkBase = new URL('https://join.meet.video.justice.gov.uk/HMCTS/#/'); // invalid URL - fix it and we can use the URL API
linkBase.searchParams.set("conference", `${thisRoomKey}${emailBase}`); // set the conference parameter
const href = linkBase.toString(); // get the URL
Here is a version that does not manipulate the DOM but just changes the text and attributes
const radioContainer = document.getElementById("radioContainer");
const linkBase = 'https://join.meet.video.justice.gov.uk/HMCTS/#/';
const emailBase = '#meet.video.justice.gov.uk';
const output = document.getElementById("output");
const roomNo = document.getElementById("roomNo");
const phoneNo = document.getElementById("phoneNo");
const guestPin = document.getElementById("guestPin");
const roomLink = document.getElementById("roomLink");
const rooms = {
"hmcts369": {
"telephone": "02920 376411",
"guestPin": "4444"
},
"hmcts453": {
"telephone": "02920 376400",
"guestPin": "5555"
}
};
// create the room radios
radioContainer.innerHTML = Object
.keys(rooms)
.map(key => `<label><input type="radio" name="CVPRoom" />${key.toUpperCase()}</label>`).join("<br/>");
radioContainer.addEventListener("click", function(e) { // click anywhere in the label to select and show the details
const tgt = e.target.closest("label");
if (!tgt) return
output.hidden = true;
const thisRoom = tgt.textContent.trim();
const thisRoomKey = thisRoom.toLowerCase();
const details = rooms[thisRoomKey];
if (!details) {
alert(`Sorry, room ${thisRoom} not found`);
return;
}
const href = `${linkBase}?conference=${thisRoomKey}${emailBase}`; //
roomNo.textContent = thisRoom;
phoneNo.textContent = details.telephone;
guestPin.textContent = details.guestPin;
roomLink.href = href;
output.hidden = false;
})
<div id="radioContainer"></div>
<div id="output" hidden>
<div>CVP Room: <span id="roomNo"></span></div>
<div>Telephone Number: <span id="phoneNo"></span></div>
<div>Guest Pin Number: <span id="guestPin"></span></div>
<div><a id="roomLink" href=""><b>Full Clickable URL Link</b></a></div>
</div>
The best way is create a object with the data, and not repeat functions that do the same thing. Create one function for each functionality and pass the data from the object to the functions.
Check this:
let conferences = [
{
id: "369",
input: {
name : "CVPRoom",
value: "HMCTS369"
},
info: {
room: "HMCTS369",
phone: "02920 376411",
pin: "4444",
link: "https://join.meet.video.justice.gov.uk/HMCTS/#/?conference=hmcts369#meet.video.justice.gov.uk"
}
},
{
id: "453",
input: {
name : "CVPRoom",
value: "HMCTS453"
},
info: {
room: "HMCTS453",
phone: "02920 376400",
pin: "5555"
}
}
]
let divInputs = document.querySelector('#inputs')
let divData = document.querySelector('#data')
conferences.forEach( c => {
let label = document.createElement('label')
let radio = document.createElement('input')
radio.setAttribute('type', 'radio')
radio.value = c.input.value
radio.name = c.input.name
radio.id = c.id
radio.addEventListener( 'change', e=>{
changeData( c )
} )
label.appendChild(radio)
label.appendChild( document.createTextNode( c.input.value ) )
divInputs.appendChild( label )
} )
function changeData( conferenceData ){
while( divData.hasChildNodes() ){
divData.removeChild( divData.firstChild )
}
let divRoom = document.createElement('div')
divRoom.appendChild(document.createTextNode(`CVP Room: ${conferenceData.info.room}`))
divData.appendChild( divRoom )
let divPhone = document.createElement('div')
divPhone.appendChild(document.createTextNode(`Telephone Number: ${conferenceData.info.phone}`))
divData.appendChild( divPhone )
let divPin = document.createElement('div')
divPin.appendChild(document.createTextNode(`Guest Pin Number: ${conferenceData.info.pin}`))
divData.appendChild( divPin )
let aLink = document.createElement('a')
aLink.appendChild(document.createTextNode('Full Clickable Link'))
aLink.href = `https://join.meet.video.justice.gov.uk/HMCTS/#/?conference=${conferenceData.info.room.toLowerCase()}#meet.video.justice.gov.uk`
divData.appendChild( aLink )
}
<html>
<body>
<div id="inputs">
</div>
<div id="data">
</div>
</body>
</html>

Conditional statement limiting the number of displayed elements

I'm having trouble implementing the logic that will limit me from adding the same items to my shopping list. When the item is the same, I just want to display the quantity with the existing item.
<div class="pizzas">
</div>
<div class="shoppingCart">
<p class="totalPrice">Hungry? order our pizzas</p>
</div>
// js
fetch("https://raw.githubusercontent.com/alexsimkovich/patronage/main/api/data.json")
.then(data => data.json())
.then(data => {
let valueCurrency = 0;
data.forEach(element => {
const shoppingCart = document.querySelector(".shoppingCart");
const pizzas = document.querySelector(".pizzas");
const box = document.createElement("div");
const img = document.createElement("img");
const title = document.createElement("h3");
const ingredients = document.createElement("p");
const price = document.createElement("h4");
const btn = document.createElement("button");
const totalPrice = document.querySelector(".totalPrice");
box.className = "box";
ingredients.className = "ingredients"
btn.className = "btn";
img.src = element.image;
img.className = "img";
title.innerHTML = element.title;
ingredients.innerHTML = element.ingredients;
price.innerHTML = element.price.toFixed(2) + " zł";
btn.innerHTML = "Dodaj do koszyka";
box.appendChild(img);
box.appendChild(title);
box.appendChild(ingredients);
box.appendChild(price);
box.appendChild(btn);
pizzas.appendChild(box);
btn.addEventListener("click", (e) => {
valueCurrency = valueCurrency + element.price;
const pizza = document.createElement("div");
pizza.className = "pizzaList";
const pizzasList = document.createElement("li");
const pizzaPrice = document.createElement("p");
const btnRemove = document.createElement("button");
btnRemove.innerText = "X";
pizzasList.innerText = title.textContent;
pizzaPrice.innerText = price.textContent;
pizza.appendChild(pizzasList);
pizza.appendChild(pizzaPrice);
pizza.appendChild(btnRemove);
totalPrice.innerText = "Całkowita cena: " + valueCurrency.toFixed(2);
if(pizzasList.innerText === pizzasList.innerText)
{
// don't add another item to the list
// just add +1 to existing element
}
else
{
// add an item to the list
shoppingCart.prepend(pizza);
}
btnRemove.addEventListener("click", (e) => {
pizza.remove();
valueCurrency = valueCurrency - element.price;
totalPrice.innerText = "Całkowita cena: " + valueCurrency.toFixed(2);
})
})
});
})
.catch(err => console.log(err));
My problem is exactly in the conditional statement, I don't know exactly how to implement the counting of the same pizzas option.
Thank you in advance for your help.
Since you are using html elements for this, what you can do is to use a data-attribute in your pizza element and increment it each time you need.
Something like:
if(pizzasList === pizzasList)
{
pizza.dataset.total = Number(pizza.dataset.total) + 1;
}
else
{
pizza.dataset.total = 1;
shoppingCart.prepend(pizza);
}
Then just use pizza.dataset.total to retieve the total number of repetitions.

Keep Todo Results after browser refreshing

I created a todo app to add and remove tasks on the page.
however i would like to keep todo results when browser refreshed .
Is that possible to make this like storing data on db or any storage to save these results?
any idea to make this to save data ??
Now I posted the complete code hereee! because i cant posted code here before
let menu = document.querySelector(".bs");
let btn1 = document.querySelector(".btn");
let btn2 = document.querySelector(".btn3");
let irp = document.querySelector(".date");
let inp = document.querySelector(".input");
let bsd = document.querySelector(".sss");
let brs = document.querySelector(".marker");
let addBr = () => {
btn1.addEventListener("click", addBr);
let br = document.createElement("DIV");
let dd = document.createElement("H1");
dd.innerHTML = (inp.value);
br.className = "red";
var bn = document.createElement("H1");
bn.innerHTML = (irp.value);
menu.appendChild(br);
br.appendChild(dd);
br.appendChild(bn);
if( inp.value == "") {
br.remove();
}
else {
menu.appendChild(br);
}
if( irp.value == "") {
dd.innerHTML = "Albenis";
}
else {
menu.appendChild(br);
}
let ttt = document.createElement("BUTTON");
ttt.className = "marker";
ttt.innerHTML = "Remove";
br.appendChild(ttt);
// This is the important change. Part of creating the .ttt element
// is setting up its event listeners!
ttt.addEventListener('click', () => br.remove());
};
btn1.addEventListener("click", addBr);
// Call `addBr` once to add the initial element
addBr();
<html>
<body>
<div class="bs">
<input type="text" class="input">
<input type="date" class="date">
<button class="btn">
Add
</button>
</div>
</body>
</html>
TL;DR: use localStorage to read the items at page load and write the items when they change, like in the final version
To keep your todo entries, you need to store it in a Database. This can be either a local database in the website like localStorage. Or you need to build a backend which is connected to a Database and send and load the Data from there.
localStorage example:
const items = [{ name: "My Todo" }, { name: "My Todo 2" }];
const setItems = () => {
localStorage.setItem("items", JSON.stringify(items));
};
const getItems = () => {
return JSON.parse(localStorage.getItem("items"));
};
Including your code:
const getItems = () => {
return JSON.parse(localStorage.getItem("items"));
};
const items = getItems() || [];
const setItems = () => {
localStorage.setItem("items", JSON.stringify(items));
};
let addBr = (item) => {
let br = document.createElement("DIV");
let dd = document.createElement("H1");
dd.innerHTML = (item ? item.name : inp.value);
br.className = "red";
var bn = document.createElement("H1");
bn.innerHTML = (item ? item.name : irp.value);
if (!item) {
items.push({ name: inp.value });
setItems();
}
menu.appendChild(br);
br.appendChild(dd);
br.appendChild(bn);
if( inp.value == "") {
br.remove();
}
else {
menu.appendChild(br);
}
if( irp.value == "") {
dd.innerHTML = "Albenis";
}
else {
menu.appendChild(br);
}
let ttt = document.createElement("BUTTON");
ttt.className = "marker";
ttt.innerHTML = "Remove";
br.appendChild(ttt);
// This is the important change. Part of creating the .ttt element
// is setting up its event listeners!
ttt.addEventListener('click', () => br.remove());
};
for (const item of items) {
addBr(item);
}
btn1.addEventListener("click", () => addBr());

Javascript: group JSON objects using specific key

I have the following JSON object and wanted to merge them by OrderID, making the items into array of objects:
[
{
"OrderID":"999123",
"ItemCode":"TED-072",
"ItemQuantity":"1",
"ItemPrice":"74.95",
},
{
"OrderID":"999123",
"ItemCode":"DY-FBBO",
"ItemQuantity":"2",
"ItemName":"DOIY Foosball Bottle Opener > Red",
"ItemPrice":"34.95",
}
]
and I'm wondering how in Javascript to merge the items on the same order...like this:
[{
"OrderID": "999123",
"Items": [{
"ItemCode": "DY-FBBO",
"ItemQuantity": "2",
"ItemName": "DOIY Foosball Bottle Opener > Red",
"ItemPrice": "34.95"
}, {
"ItemCode": "TED-072",
"ItemQuantity": "1",
"ItemName": "Ted Baker Womens Manicure Set",
"ItemPrice": "74.95"
}]
}]
I suggest you use javascript library like underscorejs/lazyjs/lodash to solve this kind of thing.
Here is the example on using underscorejs:
var data = [{
"OrderID":"999123",
"ItemCode":"TED-072",
"ItemQuantity":"1",
"ItemPrice":"74.95",
}, {
"OrderID":"999123",
"ItemCode":"DY-FBBO",
"ItemQuantity":"2",
"ItemName":"DOIY Foosball Bottle Opener > Red",
"ItemPrice":"34.95",
}]
var result = _.chain(data).groupBy(function (e) {
return e.OrderID;
}).map(function (val, key) {
return {
OrderID: key,
Items: _.map(val, function (eachItem) {
delete eachItem.OrderID;
return eachItem;
})
};
}).value();
Working example:
var data = [{
"OrderID":"999123",
"ItemCode":"TED-072",
"ItemQuantity":"1",
"ItemPrice":"74.95",
}, {
"OrderID":"999123",
"ItemCode":"DY-FBBO",
"ItemQuantity":"2",
"ItemName":"DOIY Foosball Bottle Opener > Red",
"ItemPrice":"34.95",
}];
var result = _.chain(data).groupBy(function (e) {
return e.OrderID;
}).map(function (val, key) {
return {
OrderID: key,
Items: _.map(val, function (eachItem) {
delete eachItem.OrderID;
return eachItem;
})
};
}).value();
document.write(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
This should do what you want it to do, but it's rather a group function than a merge function :)
You can see the result in the browser console.
var items = [
{
"OrderID":"999123",
"ItemCode":"TED-072",
"ItemQuantity":"1",
"ItemPrice":"74.95",
},
{
"OrderID":"999123",
"ItemCode":"DY-FBBO",
"ItemQuantity":"2",
"ItemName":"DOIY Foosball Bottle Opener > Red",
"ItemPrice":"34.95",
}
];
function groupBy(ungrouped, groupByProperty) {
var result = [],
getGroup = function (arr, val, groupByProperty) {
var result, j, jlen;
for (j = 0, jlen = arr.length; j < jlen; j++) {
if (arr[j][groupByProperty] === val) {
result = arr[j];
break;
}
}
if (!result) {
result = {};
result.items = [];
result[groupByProperty] = val;
arr.push(result);
}
return result;
}, i, len, item;
for (i = 0, len = ungrouped.length; i < len; i++) {
item = getGroup(result, ungrouped[i][groupByProperty], groupByProperty);
delete ungrouped[i][groupByProperty];
item.items.push(ungrouped[i]);
}
return result;
}
var grouped = groupBy(items, 'OrderID');
document.getElementById('result').innerHTML = JSON.stringify(grouped);
console.log(grouped);
<div id="result"></div>
Lodash is a great Javascript Utility library that can help you in this case. Include the latest version of lodash in your code and group the objects like this:
var mergedOrders = _.groupBy(OriginalOrders, 'OrderID');
It seems you'll have to do a function that, for each entry, will check if it match
try this :
// your array is oldArr
var newArr = []
for (var i=0;i<oldArr.length;i++){
var found = false;
for(var j=0;j<newArr.length;j++){
if(oldArr[i]["OrderID"]==newArr[j]["OrderID"]){
newArr[j]["Items"].push(oldArr[i]);
found=true;
break;
}
if(!found){
newArr.push({"OrderID" : oldArr[i]["OrderID"], "Items" : oldArr[i]});
}
}
You need to loop and create new grouped objects according to your requirement.
For an easier approach I would suggest using jquery-linq
var qOrderIds = $.Enumerable.From(myArray).Select(function(item) { return item.OrderID; }).Distinct();
var groupedList = qOrderIds.Select(function(orderId) {
return {
OrderID: orderId,
Items : $.Enumerable.From(myArray).Where(function(item) { item.OrderID === orderId}).ToArray()
};
}).ToArray();
Thank you for all your answers.
I was able to attain my goal (maybe a bit dirty and not as beautiful as yours but it worked on my end). Hoping this might help others in the future:
function processJsonObj2(dataObj, cfg) {
var retVal = dataObj.reduce(function(x, y, i, array) {
if (x[cfg.colOrderId] === y[cfg.colOrderId]) {
var orderId = x[cfg.colOrderId];
var addressee = x[cfg.colAddressee];
var company = x[cfg.colCompany];
var addr1 = x[cfg.colAddress1];
var addr2 = x[cfg.colAddress2];
var suburb = x[cfg.colSuburb];
var state = x[cfg.colState];
var postcode = x[cfg.colPostcode];
var country = x[cfg.colCountry];
var orderMsg = x[cfg.colOrderMessage];
var carrier = x[cfg.colCarrier];
delete x[cfg.colOrderId];
delete y[cfg.colOrderId];
delete x[cfg.colAddressee];
delete y[cfg.colAddressee];
delete x[cfg.colCompany];
delete y[cfg.colCompany];
delete x[cfg.colAddress1];
delete y[cfg.colAddress1];
delete x[cfg.colAddress2];
delete y[cfg.colAddress2];
delete x[cfg.colSuburb];
delete y[cfg.colSuburb];
delete x[cfg.colState];
delete y[cfg.colState];
delete x[cfg.colPostcode];
delete y[cfg.colPostcode];
delete x[cfg.colCountry];
delete y[cfg.colCountry];
delete x[cfg.colOrderMessage];
delete y[cfg.colOrderMessage];
delete x[cfg.colCarrier];
delete y[cfg.colCarrier];
var orderObj = {};
orderObj[cfg.colOrderId] = orderId;
orderObj[cfg.colAddressee] = addressee;
orderObj[cfg.colCompany] = company;
orderObj[cfg.colAddress1] = addr1;
orderObj[cfg.colAddress2] = addr2;
orderObj[cfg.colSuburb] = suburb;
orderObj[cfg.colState] = state;
orderObj[cfg.colPostcode] = postcode;
orderObj[cfg.colCountry] = country;
orderObj[cfg.colOrderMessage] = orderMsg;
orderObj[cfg.colCarrier] = carrier;
orderObj["Items"] = [ x, y ];
return orderObj;
} else {
var orderId = x[cfg.colOrderId];
var addressee = x[cfg.colAddressee];
var company = x[cfg.colCompany];
var addr1 = x[cfg.colAddress1];
var addr2 = x[cfg.colAddress2];
var suburb = x[cfg.colSuburb];
var state = x[cfg.colState];
var postcode = x[cfg.colPostcode];
var country = x[cfg.colCountry];
var orderMsg = x[cfg.colOrderMessage];
var carrier = x[cfg.colCarrier];
var itemCode = x[cfg.colItemCode];
var itemQuantity = x[cfg.colItemQuantity];
var itemName = x[cfg.colItemName];
var itemPrice = x[cfg.colitemPrice];
var item = {};
item[cfg.colItemCode] = itemCode;
item[cfg.colItemQuantity] = itemQuantity;
item[cfg.colItemName] = itemName;
item[cfg.colItemPrice] = itemPrice;
var orderObj = {};
orderObj[cfg.colOrderId] = orderId;
orderObj[cfg.colAddressee] = addressee;
orderObj[cfg.colCompany] = company;
orderObj[cfg.colAddress1] = addr1;
orderObj[cfg.colAddress2] = addr2;
orderObj[cfg.colSuburb] = suburb;
orderObj[cfg.colState] = state;
orderObj[cfg.colPostcode] = postcode;
orderObj[cfg.colCountry] = country;
orderObj[cfg.colOrderMessage] = orderMsg;
orderObj[cfg.colCarrier] = carrier;
orderObj["Items"] = [ item ];
return orderObj;
}
});
return retVal;
}

Comma separated values: from strings to objects to list

I have 3 variables with strings containing comma separated values (I don't know how many) which I want to combine into jQuery objects.
"name1,name2,name3,nameN"
"value1,value2,value3,valueN"
"id1,id2,id3,idN"
to:
var item1 = { name: name1, value: value1, id: id1 };
var item2 = { name: name2, value: value2, id: id2 };
var item3 = { name: name3, value: value3, id: id3 };
var itemN = { name: nameN, value: valueN, id: idN };
To then iterate an operation over each item, for example to append a list:
<h3>items</h3>
<ul>
<li>item1</li>
<ul>
<li>value: <b>value1</b></li>
<li>id: <b>id1</b></li>
</ul>
[...]
<li>itemN</li>
<ul>
<li>value: <b>valueN</b></li>
<li>id: <b>idN</b></li>
</ul>
<ul>
What is the best way to do this?
You can build an array of your items like this:
var names = "name1,name2,name3,nameN";
var values = "value1,value2,value3,valueN";
var ids = "id1,id2,id3,idN";
var namesArray = names.split(",");
var valuesArray = values.split(",");
var idsArray = ids.split(",");
var item, items = [];
for (var i = 0; i < namesArray.length; i++) {
item = {};
item.name = namesArray[i];
item.value = valuesArray[i];
item.id = idsArray[i];
items.push(item);
}
Then, to build the HTML from that, you can do this:
var main = $("<ul>");
var str = "";
for (var i = 0; i < items.length; i++) {
str += "<li>" + items[i].name + "</li><ul><li>value: <b>" + items[i].value + "</b></li>";
str += "<li>id: <b>" + items[i].id + "</b></li></ul>";
}
main.html(str);
$(document.body).append("<h3>items</h3>")
$(document.body).append(main);
You can see it work here: http://jsfiddle.net/jfriend00/yWU3L/4/.
You may want to use the DOM for this.
Using innerHTML means having in-line HTML in your javascript. This breaks Seperations of concerns and leads to maintenance hell.
Live Example
var createListFragment = (function () {
function createItems(names,value,ids) {
var namesArray = names.split(",");
var valuesArray = value.split(",");
var idsArray = ids.split(",");
return namesArray.map(function (name, key) {
return {
name: name,
value: valuesArray[key],
id: idsArray[key]
}
});
}
function createLi(item) {
var itemLi = document.createElement("li");
itemLi.textContent = item.name;
var propertiesUl = document.createElement("ul");
itemLi.appendChild(propertiesUl);
var valueLi = document.createElement("li");
valueLi.appendChild(document.createTextNode("value: "));
var b = document.createElement("b");
b.textContent = item.value;
valueLi.appendChild(b);
propertiesUl.appendChild(valueLi);
var idLi = document.createElement("li");
idLi.appendChild(document.createTextNode("id: "));
var b = document.createElement("b");
b.textContent = item.id;
idLi.appendChild(b);
propertiesUl.appendChild(idLi);
return itemLi;
}
function createListFragment(names, values, ids) {
var items = createItems(names, values, ids);
var fragment = document.createDocumentFragment();
var h3 = document.createElement("h3");
h3.textContent = "items";
fragment.appendChild(h3);
var ul = document.createElement("ul");
fragment.appendChild(ul);
items.forEach(function (item) {
var li = createLi(item);
ul.appendChild(li);
});
return fragment;
}
return createListFragment;
})();
You may need a DOM-shim and ES5-shim for cross browser compliance.

Categories