0

I'm a complete newby to html, javascript and to d3, so I apologize if my question is completely obvious.

I have a html list

 <div id="simpleList" class="list-group">
    <div class="list-group-item">item 1</div>
    <div class="list-group-item">item 2</div>
    <div class="list-group-item">item 3</div>
    <div class="list-group-item">item 4</div>
  </div>

and what I want is to be able to sort the list (by dragging the items for example) and then print the list current order in an html span field, for example

["item 3","item 4","item 2","item 1"]

This information will drive my datasource sort in a D3 graph after. I know that it should be really simple but ...

What I was trying was to use the js "Sortable" script of rubaxa found here . With this script I was able to drag and "sort" the list, but I just don't know how to retrieve the list order.

Any other suggestion about how to do the drag and sort list and how to retrieve the order are welcome. Please have in mind that I'm a total newby. Thanks

nanicpc
  • 27
  • 4

1 Answers1

1

You probably want to do some housekeeping using for example data-attributes to store ids.

  <div id="simpleList" class="list-group">
    <div class="list-group-item" data-myId="item1">actual content</div>
    <div class="list-group-item" data-myId="item2">actual content</div>
    <div class="list-group-item" data-myId="item3">actual content</div>
    <div class="list-group-item" data-myId="item4">actual content</div>
  </div>

Let's now define a function to calc the order:

function getOrderOfData(listId){

    //get the list
    var list = document.getElementById(listId);

    //and iterate the children in order. Get the myId property and add (in order)
    //to array.
    var orderArray = [];
    var childs = list.children;
    for(var i=0; i< childs.length; i++){
      var child = childs[i];
      orderArray.push(child.dataset.myId);
    }

    return orderArray;

    //NOTE: the native map probably doesn't work on list.children
    //since children is not a proper array. 
    // Instead using lodash as suggested, e.g. _.map(list.children, ...) 
    //will do things without having to worry about it. 
    //
    //OLD CODE
    //alternative which is nicer / more terse: 
    // return list.children.map(function(child){
    //  return child.dataset.myId;
    // });

    // //and using ES6
    // return list.children.map((child) => child.dataset.myId);
}

Now whenever you need it call getOrderOfData("simpleList") and use the result. (untested)

Geert-Jan
  • 18,623
  • 16
  • 75
  • 137
  • it seems soo simple that I love it but, I'm getting a `list.children is not a function` – nanicpc Feb 16 '17 at 17:45
  • arghh, children is not a function but a property. My bad. Updated. – Geert-Jan Feb 16 '17 at 18:07
  • you'll not believe me but now I'm getting a `list.children.forEach is not a function` :/ – nanicpc Feb 16 '17 at 18:24
  • oh I do believe you :).. Always forget `children` is a strange beast. i.e.: not a proper array. See here: http://stackoverflow.com/questions/15094886/why-is-foreach-not-working-for-children. I'll update the code with a simple for loop, which is probably simpler to digest than the other slightly advanced solution. BTW: a third option (besides the 2 listed in the link) is using a library like lodash which allows you to do `_.each(children, fn)` and get rid of all this 'children is not an array' issue automatically. Hth – Geert-Jan Feb 16 '17 at 18:39
  • It works perfectly, thanks for the explanation – nanicpc Feb 17 '17 at 08:21