jaminben
jaminben

Reputation: 149

Appending to a list

I'm trying to append data from a csv file to an unordered HTML list. My csv file contains two different types of data for the list.. single and grouped as show below:

Test Group Name A,Test Link Name 1,Test URL 1
Test Group Name A,Test Link Name 2,Test URL 2
Test Group Name B,Test Link Name 3,Test URL 3
Test Group Name B,Test Link Name 4,Test URL 4
Test Link Name 5,Test URL 5
Test Link Name 6,Test URL 6

The end result needs to look like the below:

Test Group Name A
        Test Link Name 1,Test URL 1
        Test Link Name 2,Test URL 2
Test Group Name B
        Test Link Name 3,Test URL 3
        Test Link Name 4,Test URL 4
Test Link Name 5,Test URL 5
Test Link Name 6,Test URL 6

I can append the single links fine but getting the grouped links out of the csv and into a separate <ul> with an id="" for each is proving rather tricky. I think I'd need to probably add each group item to its own array or object and then construct the html from those but I can't think how to do it. The code I've created so far looks like the below:

var htmlMenu = '';

$.get(csvFileFolder, function( csvFile ) {
    var data = $.csv.toArrays(csvFile);
        for(var row in data) {
            if (data[row].length > 2){
                htmlMenu += '<li><a href="#">'+data[row][0]+'</a><ul><li><a href="'+data[row][1]+'" target="_blank">'+data[row][2]+'</a></li></ul></li>' //I need to be able to add items to a <ul> by group names
               }else{
                htmlMenu += '<li><a href="'+data[row][1]+'" target="_blank">'+data[row][0]+'</a></li>'; //This works fine
               }
            }
    $('#usefulLinks').append(htmlMenu);
});

Anyone able to help?

Thanks

Ben

Upvotes: 1

Views: 278

Answers (2)

Gabriel Ratener
Gabriel Ratener

Reputation: 605

Below is a solution that clusters the data and orders the groups in the order in which they are encountered. To illustrate I swapped the group names of the 2nd and 3rd rows in the example you gave.

    // csv set as dummy string to illustrate (shuffled the list a bit,
            // order encountered is still the same)
    var csv = 'Test Group Name A,Test Link Name 1,Test URL 1\nTest Group Name B,Test Link Name 2,Test URL 2\nTest Group Name A,   Test Link Name 3,Test URL 3\nTest Group Name B,Test Link Name 4,Test URL 4\nTest Link Name 5,Test URL 5\nTest Link Name 6,Test URL 6';
    var lines = csv.split('\n');
    var id = 0;

    // table containing group names as key, member array as value
    var groups = {}; 

    // ungrouped entried go in here
    var ungrouped = [];

    // push new groups to list to keep original order
    var groupOrder = [];
    for (var i = 0; i < lines.length; i++) {
        // split lines by comma ommiting space
        row = lines[i].split(/\s*,\s*/g);
        if (row.length === 3) {
            // if group property does not exist in object
            // initialize emtpy list
            if (!(row[0] in groups)){
                groups[row[0]] = [];
                groupOrder.push(row[0]);
            }

            // group member text
            text = row[1] + ',' + row[2];

            // add to list groups[<groupname>]
            groups[row[0]].push(text);
        } else {
            // otherwise add to list of ungrouped elements
            ungrouped.push(row.join(','));
        }
    };

    // we have the data clustered, now we gennenrate the HTML
    var mainUl = $('<ul></ul>');
    for (var h = 0; h < groupOrder.length; h++){
        var group = groupOrder[h]; // get group names in order presented
        var mainLi = $('<li><h6>' + group + '</h6></li>');
        var subUl = $('<ul id="ul' + id + '"></ul>');
        for (var i = 0; i < groups[group].length; i++){
            var subLi = $('<li>' + groups[group][i] + '</li>');
            subUl.append(subLi);
        }

        mainLi.append(subUl);
        mainLi.appendTo(mainUl);
    }

    // append the ungrouped entries at the end
    for (var i = 0; i < ungrouped.length; i++) {
        var mainLi = $('<li>' + ungrouped[i] + '</li>');
        mainUl.append(mainLi);
    };

    // add main list to body for illustration or other element
    $('body').append(mainUl);

Upvotes: 1

Gabriel Ratener
Gabriel Ratener

Reputation: 605

It seems like you want to group (name, test) pairs in sublists when a group is specified, or add it to the main list if not specified. This should work:

// csv set as dummy string to illustrate
var csv = 'Test Group Name A,Test Link Name 1,Test URL 1\nTest Group Name A,Test Link Name 2,Test URL 2\nTest Group Name B,     Test Link Name 3,Test URL 3\nTest Group Name B,Test Link Name 4,Test URL 4\nTest Link Name 5,Test URL 5\nTest Link Name 6,Test URL 6';
var lines = csv.split('\n');
// initialize main list
var mainUl = $('<ul></ul>');
var group;
var id = 0;
for (var i = 0; i < lines.length; i++) {
    // split lines by comma ommiting space
    row = lines[i].split(/\s*,\s*/g);
    if (row.length === 3) {
        //if belonging to a group
        if (row[0] !== group) {
            group = row[0];

            // create new sub list with unique id
            var subUl = $('<ul id="ul' + id + '"></ul>');

            // add sublist to new list item on main list
            var li = $('<li><h6>' + row[0] + '</h6></li>');
            li.append(subUl);
            li.appendTo(mainUl);
            id += 1;
            // increment id after each subgroup to access each group's ul sequencially
            // as <ul id="ul0">, <ul id="ul1">... with ul preix so it works with
            // with older versions of HTML (where ids cannot start with number)
        }

        // add items to group
        $('<li>' + row[1] + ',' + row[2] + '</li>').appendTo(subUl);
    } else {
        // add li without sub list if 
        // not belonging to group
        var li = $('<li></li>');
        li.text(row[0] + ',' + row[1]);
        mainUl.append(li);
    }
};

// add main list to body
$('body').append(mainUl);

Upvotes: 1

Related Questions