JasonAizkalns
JasonAizkalns

Reputation: 20473

How to dynamically add items and attributes to HTML with javascript or jQuery referencing items from a csv or json file

I am trying to make the following bit of code easier to maintain. I am not a web developer so bear with me. I think the following approach is appropriate.

I would like to dynamically add content and attributes to an html file using either javascript or jQuery. The items could reside in a .csv or .json (or something else?) file.


Given content like this

<div class="filtr-container">

    <div class="col-12 col-sm-6 col-md-4 card filtr-item" data-category="cat-1" data-date="2018-02-09">
        <div class="card-inner-border box-shadow">
            <a href="address-1.html">
                <img class="card-img-top rounded-top" src="./images/image-1.jpg" alt="img-2-alt">
            </a>
            <div class="card-body">
                <h5 class="card-title">Title-1</h5>
                <p class="card-text card-desc">
                    This is a description for title-1 content.
                </p>
                <a href="address-1.html">
                    <button type="button" class="btn btn-sm btn-outline-secondary">View</button>
                </a>
                <p class="card-text">
                    <small class="text-muted">Last updated February 2, 2018</small>
                </p>
            </div>
        </div>
    </div>

    <div class="col-12 col-sm-6 col-md-4 card filtr-item" data-category="cat-2, cat-3" data-date="2018-02-14">
        <div class="card-inner-border box-shadow">
            <a href="address-2.html">
                <img class="card-img-top rounded-top" src="./images/image-2.jpg" alt="img-2-alt">
            </a>
            <div class="card-body">
                <h5 class="card-title">Title-2</h5>
                <p class="card-text card-desc">
                    Here is a long description for title-2 content.
                </p>
                <a href="address-2.html">
                    <button type="button" class="btn btn-sm btn-outline-secondary">View</button>
                </a>
                <p class="card-text">
                    <small class="text-muted">Last updated February 14, 2018</small>
                </p>
            </div>
        </div>
    </div>

    <!-- MANY MORE CARDS / ITEMS ... -->

</div> <!-- End of filtr-container -->

I think we could abstract the details into something like this (.csv)

item-id,title,description,categories,address,image,image-alt,update
1,Title-1,This is a description for title-1 content.,cat-1,address-1.html,image-1.jpg,img-1-alt,2018-02-09
2,Title-2,Here is a long description for title-2 content.,"cat-2, cat-2",address-2.html,image-2.jpg,img-2-alt,2018-02-14

What's a nice approach of attack for using `javascript` or `jQuery` to add this content from the `.csv` or `.json` file?

A few concerns:


To hopefully help make this feel less complicated, here's a picture with the highlighted elements that could be "referenced" from the .csv file.

Image highlighted referenced elements

To me this feels like:

  1. Read in the .csv file.
  2. For each item in the .csv file, append objects to $(".filtr-container") with the shell layout...

But I'm lost when it comes to the particulars or if that's an appropriate approach.

Upvotes: 0

Views: 222

Answers (2)

Randy Casburn
Randy Casburn

Reputation: 14175

You seem to be searching for template parsing. You can find many libraries that will ease this burden. In its simplest form, template parses carry out the steps in the following code. If you don't need the flexibility, power, features, etc. from a template parser library or full framework, you should consider not including the thousands of lines of code if all you want to accomplish is what is shown below.

Since you mentioned both JSON and CSV I've included the code to parse both. I'll leave the AJAX and date formatting magic to you. I don't think I populate the ID either, but this shows that more data than template attributes will work fine.

let template = document.getElementById('card-template').innerHTML;
let container = document.querySelector('.filtr-container');

// Do some ajax magic to get csv file
let csv = `item-id,title,description,categories,address,image,image-alt,update
1,Title-1,This is a description for title-1 content.,cat-1,address-1.html,https://via.placeholder.com/75,img-1-alt,2018-02-09
2,Title-2,Here is a long description for title-2 content.,cat-2 cat-2,address-2.html,https://via.placeholder.com/75,img-2-alt,2018-02-14`;

let csvLines = csv.split("\n");
let csvHeaders = csvLines.shift().split(',');
csvLines.forEach(line => {
  let parsed = template;
  let props = line.split(',');
  props.forEach((prop, idx) => {
    parsed = parsed.replace('{{' + csvHeaders[idx] + '}}', props[idx]);
  });
  container.innerHTML = container.innerHTML + parsed;
});

let json = `[{
  "item-id": "1",
  "title": "Title-1",
  "description": "This is a description for title-1 content.",
  "categories": "cat-1",
  "address": "address-1.html",
  "image": "https://via.placeholder.com/75",
  "image-alt": "img-1-alt",
  "update": "2018-02-09"
}, {
  "item-id": "2",
  "title": "Title-2",
  "description": "Here is a long description for title-2 content.",
  "categories": "cat-2 cat-2",
  "address": "address-2.html",
  "image": "https://via.placeholder.com/75",
  "image-alt": "img-2-alt",
  "update": "2018-02-14"
}]`;

let data = JSON.parse(json);
data.forEach(col => {
  let jParsed = template;
  for (prop in col) {
    jParsed = jParsed.replace('{{' + prop + '}}', col[prop]);
  }
  container.innerHTML = container.innerHTML + jParsed;
});
<div class="filtr-container">

  <script type="template" id="card-template">
    <div class="col-12 col-sm-6 col-md-4 card filtr-item" data-category="{{categories}}" data-date="{{date}}">
      <div class="card-inner-border box-shadow">
        <a href="{{address}}">
          <img class="card-img-top rounded-top" src="{{image}}" alt="{{image-alt}}">
        </a>
        <div class="card-body">
          <h5 class="card-title">{{title}}</h5>
          <p class="card-text card-desc">
            {{description}}
          </p>
          <a href="{{address}}">
            <button type="button" class="btn btn-sm btn-outline-secondary">View</button>
          </a>
          <p class="card-text">
            <small class="text-muted">Last updated {{update}}</small>
          </p>
        </div>
      </div>
    </div>
  </script>

Upvotes: 1

Saraband
Saraband

Reputation: 1590

This post might help you parse your CSV document. If your data lives in a JSON, you can use JSON.parse

Once you properly retrieved and parsed your data, it's a matter or rendering it to the DOM.

You can do it using the standard javascript library, JQuery or frameworks such as React or VueJS

Upvotes: 0

Related Questions