ActionON
ActionON

Reputation: 106

How do I sort a whole element based off of one piece of it?

I have a table with the general structure

<tr>
  <td>1</td>
  <td>
  <a href="http://www.anime-planet.com/anime/accel-world">Accel World</a>
  </td>
</tr

but with many more table rows, each having a td with an index and another td with an 'a element' with the title of a show and a place to find said show.

I end up sorting it, alphabetically based off the text content of the a element, the stuff inside the tag. I then sort all of those outside as an array and plug them back into the element. The problem is the href didn't move. I sorted the text Content but not the hyper reference link the text corresponds to.

How can I sort it to where the hyper reference corresponds to the text within-the title? Keep in mind, I can't sort it based off the href and plug it in because there are too many special cases which make it not work.

Here is my code so far, you can ignore the parseText as it is what generates the table.

function parseText(file, tableNumb, link) {
var xhr = new XMLHttpRequest();
xhr.open('GET', file, true);
xhr.send(null);
xhr.onload = function () {
    if(xhr.status === 200) {
        var response = xhr.responseText;
        var reg = /[^|(\r\n|\n|\r)]+/g;
        var regResponse = response.match(reg);
        var table = document.getElementById(tableNumb);
        var length = 0;
        var tIndex = 1; //get the length of the table to match number count
        var count = 0;
        var links = [];
        for(i = length; i < regResponse.length/2;i++){ 
            var row = table.insertRow(-1);
            var cell = row.insertCell(-1);
            var cell1 = row.insertCell(-1);
            cell.innerHTML = tIndex;
            cell1.innerHTML = '<a href=\'' + regResponse[count+1] + '\'>' + regResponse[count] + '</a>';
            link[i] = regResponse[count];
            count++;
            count++;
            tIndex++;
          }
        sorted(link); //keep
    }
}



    }
    var sortList = document.getElementById("one");
    var link = sortList.getElementsByTagName("a");


    var sortList2 = document.getElementById("two");
    var link1 = sortList2.getElementsByTagName('a');
    var sortList3 = document.getElementById("three");
    var link2 = sortList3.getElementsByTagName('a');


parseText('Watched.txt', 'one', link);
parseText('Watching.txt', 'two', link1);
parseText('Dropped.txt', 'three', link2);

function sorted(sortList) {
    var sibling = [];


    for(i = 0; i < sortList.length; i++){
        sibling[i]=sortList[i].textContent;

    }

    function insensitive(s1, s2) {
      var s1lower = s1.toLowerCase();
      var s2lower = s2.toLowerCase();
      return s1lower > s2lower ? 1 : (s1lower < s2lower? -1 : 0);
    }
    sibling.sort(insensitive);

    for(var i = 0; i < sortList.length; i++){
        sortList[i].childNodes[0].nodeValue=sibling[i];


    }

    }

Here is some data from a table:

Attack on Titan|http://www.anime-planet.com/anime/attack-on-titan
Durarara!!|http://www.anime-planet.com/anime/durarara
Kyoukai no Kanata|http://www.anime-planet.com/anime/beyond-the-boundary
Log Horizon|http://www.anime-planet.com/anime/log-horizon
Mahou Shoujo Madoka Magica|http://www.anime-planet.com/anime/mahou-shoujo-madoka-magica
Mushishi|http://www.anime-planet.com/anime/mushishi
Naruto|http://www.anime-planet.com/anime/naruto
Neon Genesis Evangelion|http://www.anime-planet.com/anime/neon-genesis-evangelion
Space Dandy|http://www.anime-planet.com/anime/space-dandy
Tengen Toppa Gurren Lagann|http://www.anime-planet.com/anime/tengen-toppa-gurren-lagann
Ore Monogatari|http://www.anime-planet.com/anime/my-love-story
Yahari Ore no Seishun Love Come wa Machigatteiru|http://www.anime-planet.com/anime/yahari-ore-no-seishun-love-come-wa-machigatteiru
Diebuster|http://www.anime-planet.com/anime/gunbuster-2

Upvotes: 0

Views: 94

Answers (1)

Matt Way
Matt Way

Reputation: 33189

Firstly, this is a prime example of when you should be using a framework. To do something like you want using say angular can be done with much less code and be more easily maintainable. With that being said, I quickly put together a fiddle using pure js to solve what I think you are looking for:

https://jsfiddle.net/7sd6nwxq/2/

// given a url, return the responseText in a callback
function ajaxText(url, cb) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.send(null);
    xhr.onload = function(){
        if(xhr.status === 200) {
            var response = xhr.responseText;
            cb(null, response);
        }
    }
    xhr.onerror = function(err){
        cb(err);
    }
}

// convert text string into a list of items
function listFromText(text){
    var list = [];

    var reg = /[^|(\r\n|\n|\r)]+/g;
    var regResponse = text.match(reg);

    for(var i=0; i<regResponse.length; i+=2){
        list.push({
            title: regResponse[i],
            href: regResponse[i+1]
        });
    }

    return list;
}

// function for performing lower case sorting on items
function sorter(a, b){
    var s1lower = a.title.toLowerCase();
    var s2lower = b.title.toLowerCase();
    return s1lower > s2lower ? 1 : (s1lower < s2lower? -1 : 0);
}

// function for building the table html from a list
function buildTable(id, list){
    var table = document.getElementById(id);
    for(var i=0; i<list.length; i++){
        var row = table.insertRow(-1);
        var cell = row.insertCell(-1);
        var cell1 = row.insertCell(-1);

        cell.innerHTML = i;
        cell1.innerHTML = '<a href=\'' + list[i].href + '\'>' + list[i].title + '</a>';
    }
}

// get the text via ajax from a gist i created
ajaxText('https://gist.githubusercontent.com/matt-way/90eb514ed8d897649be9/raw/538a7bbfd0f7406634190c3dac0984e6c2dcc532/ajaxtest.txt', function(err, resultText){
    // get the unsorted list
    var tableList = listFromText(resultText);
    // sort the list
    tableList.sort(sorter);
    // build the html from the sorted list
    buildTable('1', tableList);
});

Upvotes: 1

Related Questions