1

I am using JavaScript to display a list of data arrays on my website from Google sheets. At the moment the data is just printed as a long list so I would like to style it, starting by having each array in its own div. At the moment all the data is appended into the same div and is only separated by <p> tags.

In my code below you can see I have tried to create the individual divs with class 'group' but this just repeatedly prints all the data into <div class="group">, instead of each array being in a <div class="group">.

// ID of the Google Spreadsheet
var spreadsheetID = "1pruXYXrbITR7CoQXZG1I1kyS4DahYBXmGMDEK2T6MpY";

// Make sure it is public or set to Anyone with link can view
var url = "https://spreadsheets.google.com/feeds/list/1pruXYXrbITR7CoQXZG1I1kyS4DahYBXmGMDEK2T6MpY/od6/public/values?alt=json";

$(document).ready(function() {
  //Get JSON data
  $.getJSON(url, function(data) {
    var entry = data.feed.entry;

    // the master obj
    var grouped = {};
    // socs obj
    var socs = {};

    var i = 0;
    entry.forEach(function(a) {
      grouped[a.gsx$name.$t] = grouped[a.gsx$name.$t] || [];
      socs[i] = a.gsx$name.$t;
      grouped[a.gsx$name.$t].push({
        position: a.gsx$position.$t,
        member: a.gsx$member.$t
      });
      i++;
    });

    // remove the duplicates from socs array
    var uniqueSocs = [];
    $.each(socs, function(i, el) {
      if ($.inArray(el, uniqueSocs) === -1) uniqueSocs.push(el);
    });



    $(uniqueSocs).each(function(key, content) {
      //debug
      //console.log(grouped[content]);

      //the socs and positions
      socPos = grouped[content]

      var $newDiv = $("<div/>").addClass("group");

      //print the soc
      $('.test').append($newDiv);
      $('.group').append("<h4>" + content + "</h4>");

      $(socPos).each(function(key, param) {
        //print the positions

        $('.group').append(param.position + " - " + param.member + "<br />")

      });
    });

  });

});

1 Answer 1

2

After toy-ing with your dataset a bit more, I think I understood what you want. Here's an example of grouping your items by object properties. I used lodash's groupBy(), as I'm used to it, but there are other helper libraries having similar functions (although, personally, I don't think one ever needs more than lodash, no matter how complex their... thing is):

let spreadsheetID = "1pruXYXrbITR7CoQXZG1I1kyS4DahYBXmGMDEK2T6MpY",
  url = "https://spreadsheets.google.com/feeds/list/1pruXYXrbITR7CoQXZG1I1kyS4DahYBXmGMDEK2T6MpY/od6/public/values?alt=json";

$(document)
  .ready(function () {
    $.getJSON(url, function (data) {
      let grouped = _.groupBy(data.feed.entry, function (o) {
        return o['gsx$name']['$t'];
      });
      $.each(grouped, function (index, item) {
        $('#example')
          .append($('<fieldset />', {
            html: '<legend>' + index + '</legend>' +
              '<ul><li>' +
              Object.keys(_.groupBy(item, function (o) {
                return o['content']['$t']
              }))
              .map(function (o) {
                return o
                  .replace('position:', '')
                  .replace(', member:', ' &mdash; ')
              })
              .join('</li><li>') +
              '</li></ul>'
          }))
      })
    })
  })
body {
  margin: 0;
  background-color: #f5f5f5;
  font-family: sans-serif;
}
#example {
  display: flex;
  flex-wrap: wrap;
}
fieldset {
  border-radius: 4px;
  border: none;
  margin: .5rem .5rem 0;
  display: block;
  flex-grow: 1;
  background-color: #fff;
  box-shadow: 0 1px 3px 0 rgba(0,0,0,.2), 0 1px 1px 0 rgba(0,0,0,.14), 0 2px 1px -1px rgba(0,0,0,.12);
}
legend {
  background-color: white;
  padding: .2rem .7rem;
  border-radius: 3px;
  font-size: 13px;
  font-weight: bold;
  box-shadow: 0 1px 5px 0 rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.12)
}
ul {
  padding: 0 1rem;
  margin-bottom: .4rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="example"></div>

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

9 Comments

Using the <code> element for something that is not code is invalid semantically. As far as me being the first to correct you, other editors might have been intimidated by your higher rep. I am not. When I see a problem in text on the site, I edit it. So, just as I edited the question to allow the HTML to be viewable, I edited the answer to remove code formatting where it is invalid. Certainly, by now, you understand that others are allowed to edit "your" post? You are of course free to rollback my edit.
@MikeMcCaughan, as stated in my previous comment, I agree with you in principle. But, on the other hand, you missed lodash. ¯\_(ツ)_/¯ On a different note, I tend to disagree with your edit on the question. getJSON() has to do with JSON. But that's not to say I don't welcome your intentions and efforts. Have fun!
The question is not about JSON (or even about getJSON). It's about grouping data which happens to have been in the JSON format at some point. Keeping the json tag around, and leaving the misnomer 'JSON arrays' around only further muddies the already murky waters of JavaScript nomenclature in beginners' minds.
@MikeMcCaughan From my POV, it's less about being correct and more about being useful and helpful. A beginner is a lot more likely to use json in their search as opposed to data-objects, which would probably be a more correct tag (but nobody uses). You just denied the json indexing. It's about enabling people to get to knowledge fast, even if their query is not 100% correct. Following your logic, I don't quite understand why you left the html tag in. At its core, this question is about data-objects and grouping. Not about rendering those groups using html. But I might be wrong...
Thank you for your answer, this is exactly what I wanted! Your answer was very comprehensive and useful. I would like to add the third column in the data set 'member' next to each 'position'. I have tried this: '<ul><li>' + Object.keys(.groupBy(item, function(o){ return o['gsx$position']['$t']; })).join('</li><li>') + Object.keys(.groupBy(item, function(o){ return o['gsx$member']['$t']; })).join('</li><li>') + '</li></ul>' but it only prints next to the last position
|

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.