1
votes

Have received help previously when importing JSON data into a table but this time we need a responsive & flexible layout and are using a grid, div, p and CSS styling approach.

We are displaying thumbnail "cards" of the latest members to join/renew membership in our group - the number of cards can vary between 2-6 to be displayed at at time and can change frequently

When a user visits the web page we want the JSON data to populate the flexible responsive grid with the thumbnail cards.

The card data comes via a correctly formatted JSON file that is created and uploaded to the web site by a 3rd party app.

Data required to be used is:

  • Type
  • Year
  • Member Page URL
  • Member Image Url
  • Member Name
  • Member Group
  • Member Company
  • Member Classification
  • Ideally we want to either generate in the script or can import the alt text and the title text for each member image (not essential but would be a bonus)

The current hard coded displayed result looks like this: responsive hard coded result This is an example of the working hardcoded code:

<style type="text/css" media="all">
.newmembers {
    display: grid;
    grid-gap: 10px;
    grid-template-columns: repeat(auto-fit, minmax(155px,175px));
    grid-auto-rows: 370px;
    grid-auto-flow: dense;
    justify-content: center;
    padding: 10px 10px 10px;
    background-color: #c7c7c7;
}

.member {
    background: rgba(255, 213, 70, 0.3);
    border: 1px solid grey;
    text-align: center;
    border-radius: 4px;
    box-shadow: 3px 3px 3px grey;
}
.type {
    color: #1f7665;
    font-weight: 900;
    text-transform: uppercase;
    margin: 5px 5px 0px;
    text-align: center;
}
   .year {
    color: #1f7665;
    font-weight: bold;
    font-size: x-small;
    margin: 0px 0px 0px;
    text-align: center;
} 
.thumb {
    width: 85%;
    min-height: 160px;
    max-height: 160px;
    min-width: 160x;
    max-width: 160px;
    object-position: center top;
    -o-object-fit: cover;
    object-fit: cover;
    overflow: hidden;
    border: 5px solid #fff;
    border-radius: 4px;
    box-shadow: 5px 5px 5px grey;
    -webkit-filter: grayscale(100%);
    filter: grayscale(100%);
}

.thumb:hover {
    position:relative;
    top:5px;
    left:5px;
    background:#00CCCC;
    -webkit-filter: grayscale(10%);
    filter: grayscale(10%);
}

.membername {
    color: #1f7665;
    font-weight: 900;
    text-transform: uppercase;
    margin: 10px 0px 0px;
}

.group {
    color: #333333;
    font-weight: bold;
    margin: 0px 0px 5px;
}

.company {
    color: #333333;
    font-weight: normal;
    margin: 0px 0px 5px;
}

.classification {
    color: #333333;
    font-weight: bold;
    margin: 0px 0px 10px;
    font-size: x-small;
}

.info {
    margin: 10px;
}

</style>

<div class="newmembers">  

<!-- We want to populate a div like this 3,4,5 or 6 times with data from the correctly formated JSON file -->
<div class="member">
    <p class="type">* RENEWING *</p>
    <p class="year">Year: THREE</p>
        <a class="memurl" href="https://example.com/brownsville.html#59e5c8">
            <img class="thumb" 
                alt="MEMBER PROFILE: Andy Smith - Smithville, Andys Lawns, Gardening" 
                title="MEMBER PROFILE:&#013Andy Smith&#013Smithvile&#013Andys Laws&#013Gardening" 
                src="https://example.com/brownsville.html/u/#59e5c8.jpg"
            >
        </a>
    <p class="info">
        <p class="membername">Andy Smith</p>
        <p class="group">Smithville</p>
        <p class="company">Andys Lawns</p>
        <p class="classification">Gardening</p>
    </p>
</div>

<!-- We want to populate a div like this 3,4,5 or 6 times with data from the correctly formated JSON file -->
<div class="member">
    <p class="type">* RENEWING *</p>
    <p class="year">Year: FOUR</p>
        <a class="memurl" href="https://example.com/brownsville.html#5a2f86">
            <img class="thumb" 
                alt="MEMBER PROFILE: Dave Brown -  Brownville, Daves Paint, Paint" 
                title="MEMBER PROFILE:&#013Dave Brown&#013Brownville&#013Daves Paint&#013Paint" 
                src="https://example.com/u/5a2f86.jpg"
            >
        </a>
    <p class="info">
        <p class="membername">Dave Brown</p>
        <p class="group">Brownsville</p>
        <p class="company">Daves Paint</p>
        <p class="classification">Paint</p>
    </p>
</div>

<!-- more "member" divs here -->

</div>

Our JSON file will look like this but can be altered to whatever is required:

[
{ "type":"* RENEWING *", "year":"THREE", "memurl":"https://example.com/smithville.html#5a2f81", "memimgsrc":"https://example.com/smithville.html/u/#59e5c8.jpg", "membername":"Andy Smith","group":"Smithville","company":"Andys Lawn","classification":"Gardening" },
{ "type":"* RENEWING *", "year":"FOUR", "memurl":"https://example.com/brownsville.html#5a2f86", "memimgsrc":"https://example.com/brownsville.html/u/#5a2f86.jpg", "membername":"Dave Brown","group":"Brownsville","company":"Daves Paint","classification":"Paint" },
{ "type":"* NEW *", "year":"ONE", "memurl":"https://example.com/applegate.html#5b3a51", "memimgsrc":"https://example.com/applegate.html/u/#5b3a51.jpg", "membername":"May Apple","group":"Applegate","company":"Marys Conserves","classification":"Canning" }
];

We have used the following script to import data in to a table but how can we get this to work with the above example?

<!-- We have used this load to populate a table from JSON and it works perfect -->
<script>
    //first add an event listener for page load
    document.addEventListener( "DOMContentLoaded", get_json_data, false ); // get_json_data is the function name that will fire on page load

    //this function is in the event listener and will execute on page load
    function get_json_data(){
        // Relative URL of external json file
        var json_url = 'example.json';

        //Build the XMLHttpRequest (aka AJAX Request)
        xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() { 
            if (this.readyState == 4 && this.status == 200) {//when a good response is given do this

                var data = JSON.parse(this.responseText); // convert the response to a json object
                append_json(data);// pass the json object to the append_json function
            }
        }
        //set the request destination and type
        xmlhttp.open("POST", json_url, true);
        //set required headers for the request
        xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        // send the request
        xmlhttp.send(); // when the request completes it will execute the code in onreadystatechange section
    }

    // FUNCTION TO ADD OR CREATE "member" DIVS NEEDS TO HERE 
    //need function to add json data to the div 'newmembers' and make new div? 
    // No idea 

    function append_json(data){
        var member = document.getElementById('newmembers');
        data.forEach(function(object) {

NOT SURE WHAT TO PUT HERE 

        });
    }
</script>

Assistance would be awesome, let me know if additional information or clarification is required.

1

1 Answers

3
votes

You're close, you can use what you've got as your hard coded as a template.

We'll keep the template as HTML, do you really want to go change javascript for a layout change?

I've removed the ajax logic as what you have should be fine.

I've also left some work for you to do with the alt and title attributes, but you should have enough to work with.

var postData = [{
    "type": "* RENEWING *",
    "year": "THREE",
    "memurl": "https://example.com/smithville.html#5a2f81",
    "memimgsrc": "https://example.com/smithville.html/u/#59e5c8.jpg",
    "membername": "Andy Smith",
    "group": "Smithville",
    "company": "Andys Lawn",
    "classification": "Gardening"
  },
  {
    "type": "* RENEWING *",
    "year": "FOUR",
    "memurl": "https://example.com/brownsville.html#5a2f86",
    "memimgsrc": "https://example.com/brownsville.html/u/#5a2f86.jpg",
    "membername": "Dave Brown",
    "group": "Brownsville",
    "company": "Daves Paint",
    "classification": "Paint"
  },
  {
    "type": "* NEW *",
    "year": "ONE",
    "memurl": "https://example.com/applegate.html#5b3a51",
    "memimgsrc": "https://example.com/applegate.html/u/#5b3a51.jpg",
    "membername": "May Apple",
    "group": "Applegate",
    "company": "Marys Conserves",
    "classification": "Canning"
  }
];

function append_json(data) {
  //Set Up the template
  var s = $("#postTemplate")[0].innerHTML.trim();
  var holder = document.createElement('div');
  holder.innerHTML = s;
  var template = holder.childNodes;

  var member = document.getElementById('newmembers');
  data.forEach(function(object) {

    //Clone Template
    var newItem = $(template).clone();

    //Populate it
    $(newItem).find(".type").html(object.type);
    $(newItem).find(".year").html($(newItem).find(".year").html() + " " + object.year);
    $(newItem).find(".memurl").attr("href", object.memurl);
    var img = $(newItem).find(".thumb")
    $(img).attr("src", object.memimgsrc).attr("alt", $(img).attr("alt") + object.membername + " " + "etc")
      .attr("title", $(img).attr("title") + object.membername + " finish this off");
    $(newItem).find(".membername").html(object.membername);
    $(newItem).find(".group").html(object.group);
    $(newItem).find(".company").html(object.company);
    $(newItem).find(".classification").html(object.classification);
    //Append it

    $(".newmembers").append(newItem);

  });
}

$("document").ready(function() {
  append_json(postData);
});
.newmembers {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(155px, 175px));
  grid-auto-rows: 370px;
  grid-auto-flow: dense;
  justify-content: center;
  padding: 10px 10px 10px;
  background-color: #c7c7c7;
}

.member {
  background: rgba(255, 213, 70, 0.3);
  border: 1px solid grey;
  text-align: center;
  border-radius: 4px;
  box-shadow: 3px 3px 3px grey;
}

.type {
  color: #1f7665;
  font-weight: 900;
  text-transform: uppercase;
  margin: 5px 5px 0px;
  text-align: center;
}

.year {
  color: #1f7665;
  font-weight: bold;
  font-size: x-small;
  margin: 0px 0px 0px;
  text-align: center;
}

.thumb {
  width: 85%;
  min-height: 160px;
  max-height: 160px;
  min-width: 160x;
  max-width: 160px;
  object-position: center top;
  -o-object-fit: cover;
  object-fit: cover;
  overflow: hidden;
  border: 5px solid #fff;
  border-radius: 4px;
  box-shadow: 5px 5px 5px grey;
  -webkit-filter: grayscale(100%);
  filter: grayscale(100%);
}

.thumb:hover {
  position: relative;
  top: 5px;
  left: 5px;
  background: #00CCCC;
  -webkit-filter: grayscale(10%);
  filter: grayscale(10%);
}

.membername {
  color: #1f7665;
  font-weight: 900;
  text-transform: uppercase;
  margin: 10px 0px 0px;
}

.group {
  color: #333333;
  font-weight: bold;
  margin: 0px 0px 5px;
}

.company {
  color: #333333;
  font-weight: normal;
  margin: 0px 0px 5px;
}

.classification {
  color: #333333;
  font-weight: bold;
  margin: 0px 0px 10px;
  font-size: x-small;
}

.info {
  margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>


<div class="newmembers">

  <!-- Template for our posts -->
  <script type="text/template" id="postTemplate">
    <div class="member">
      <p class="type"></p>
      <p class="year">Year:</p>
      <a class="memurl" href="">
        <img class="thumb" alt="MEMBER PROFILE: " title="MEMBER PROFILE: " src="">
      </a>
      <!-- Replaced p  with div, can't nest p tags -->
      <div class="info">
        <p class="membername"></p>
        <p class="group"></p>
        <p class="company"></p>
        <p class="classification"></p>
      </div>

    </div>
  </script>




</div>