7

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?

1
  • At the very beginning, actually. I know I can use split, but then I find myself with arrays combining the same type values... Commented Nov 18, 2011 at 19:44

2 Answers 2

14

You can build an array of your items like this:

const names = "name1,name2,name3,nameN";
const values = "value1,value2,value3,valueN";
const ids = "id1,id2,id3,idN";

const namesArray = names.split(",");
const valuesArray = values.split(",");
const idsArray = ids.split(",");

const items = [];
for (let i = 0; i < namesArray.length; i++) {
    let 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:

const main = $("<ul>");
let str = "";
for (let item of items) {
    str += "<li>" + item.name + "</li><ul><li>value: <b>" + item.value + "</b></li>";
    str += "<li>id: <b>" + item.id + "</b></li></ul>";
}
main.html(str);
$(document.body).append("<h3>items</h3>")
$(document.body).append(main);

And, here in a snippet:

const names = "name1,name2,name3,nameN";
const values = "value1,value2,value3,valueN";
const ids = "id1,id2,id3,idN";

const namesArray = names.split(",");
const valuesArray = values.split(",");
const idsArray = ids.split(",");

const items = [];
for (let i = 0; i < namesArray.length; i++) {
  let item = {};
  item.name = namesArray[i];
  item.value = valuesArray[i];
  item.id = idsArray[i];
  items.push(item);
}

const main = $("<ul>");
let str = "";
for (let item of items) {
  str += "<li>" + item.name + "</li><ul><li>value: <b>" + item.value + "</b></li>";
  str += "<li>id: <b>" + item.id + "</b></li></ul>";
}
main.html(str);
$(document.body).append("<h3>items</h3>")
$(document.body).append(main);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Sign up to request clarification or add additional context in comments.

5 Comments

I just tried it. The "var item, items = [];" part wasn't working. I splitted in two lines but I end up with another problem: every value in the list is now "nameN, valueN, idN". I'll post the example right away.
I made one correction to the code and it's working here: jsfiddle.net/jfriend00/yWU3L/4.
I "fiddled" an example of your code: jsfiddle.net/yWU3L It's not working as intended... EDIT: i see! What was causing the problem?
Please see my correction both in my answer and in the fiddle I posted a link to in my previous comment.
What would be the proper way to do this now w/ ES6 ?
1

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.

6 Comments

This code has no less separation of concern than the innerHTML example. In either case, you're creating HTML via javascript so there is no separation of concern. I'd love to know why you think this code is more maintainable than the innerHTML version? In the innerHTML version, it's trivial to see what HTML is being created. In your version, you have to reverse-engineer the code to figure out what HTML is actually being created.
FYI, your HTML creation code is 31 lines vs. 8 lines for the innerHTML version. Length isn't a measure of goodness, but in this case, it is related to simplicity. Your code is just a lot more complex and requires an ES5 shim for cross-browser compatibility. This answer was designed for someone without a lot of javascript experience. Which answer do you think they will find quicker to understand, simpler to implement and easier to maintain?
I should add (for the benefit of other readers) that this conversation is related to what's going on in this answer: stackoverflow.com/questions/8190024/….
@jfriend00 I wouldn't argue that this code is "simpler", that would be silly. I would say that this is "doing it right". In the long run it's better to not think of HTML but think of nodes.
Hmmm, you say: "it's better to not think of HTML" when creating presentation in Javascript. It's hard to do, but you've rendered me speechless.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.