2

I am trying to sort html elements with jQuery based off the order of items in a data attribute on an input. "data-order"

See the code setup here, but I am stuck.

http://jsbin.com/cixolonoqe/1/edit?html,js,output

HTML:

<div id="control">
   <input type="hidden" data-order="title,text,date">
  </div>
  <div id="parts">

    <p class="date part">20 January 2014</p>
    <h5 class="title part">Some Title</h5>
    <p class="text part">A line of Text</p>

  </div>

jQuery:

var input =  $('#control input');
var partsOrder = input.attr("data-order");

var parts = $('#parts');

parts.find('.part').each(function(i) {
      $(this).attr('data-index', 'index' + i);
});

//Make array from data-order attribute
var partsArray = partsOrder.split(',');

 $.partsArray(json, function(i, val) {


  //modify html order



 });

If data-order string changes, I want the html to re order accordingly.

title,text,date vs date,text,title

So far I have added a new data attribute with the original index onto the parts. And created an array from the data-order string so it can be looped through and modify the html.

But I am unable to get my head around it.

1
  • 1
    Could you click edit and post the code here, instead of the link. Questions ideally include it to survive link rot. Commented Nov 15, 2014 at 11:51

2 Answers 2

1

You can put the target index on the elements, get them in an array, sort the array on the index, and then rearrange the elements according to the array:

var partsOrder = $('#control input').attr("data-order").split(',');

var parts = $('#parts');

// set target index for elements
$.each(partsOrder, function(i, v){
  $('.' + v, parts).data('index', i);
});

// sort array on index
var items = parts.find('.part');
items.sort(function(a,b){ return $(a).data('index') - $(b).data('index'); });

// move elements into array order
parts.append(items);

Demo: http://jsbin.com/fejegeyoco/2/edit

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

2 Comments

How would I go about a hiding an html part if it is not listed in the data-order attr?
@Andy: You could hide them all, then in the loop where you set the target index add .show() to show the ones that are in the list.
0

This assumes that you are looping through and creating perhaps multiple sets of three within your div and does not require you to edit your HTML.

var input =  $('#control input');
var partsOrder = input.attr("data-order");
var parts = $('#parts');
var partsArray = partsOrder.split(',');

var $part = parts.find('.part');

var groupNum = 0;
$part.each(function(k,v) {
  if (k === 0 || k % 3 === 0) {
    var $div = $(v).wrap('<div class="group" data-group="' + groupNum + '"></div>');
    $(v).attr('data-group', groupNum);
    var $second = $($part.get(k+1)).attr('data-group', groupNum);
    var $third = $($part.get(k+2)).attr('data-group', groupNum);
    $second.remove();
    $third.remove();
    $div.append($second);
    $div.append($third);
    groupNum++;
  }  
});

for (var i = 0; i < groupNum; i++) {
  var $group = $('.group[data-group="' + i + '"]');
  for (var j = 0; j < partsArray.length; j++) {
    var $thePart = $group.find('.' + partsArray[j]);  
    $thePart.remove();
    $group.append($thePart);
  }
}

$('.group').unwrap();

JSBin

1 Comment

You can't wrap an element by using before and after to add starting and ending tags. The DOM consists of elements, not tags, so you can only add complete elements to it.

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.