admin管理员组文章数量:1323169
I have a list as follows:
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
<li>Fourth</li>
<li>Fifth</li>
</ul>
What I want is to order the list based on different conditions. For example if the variable state == "foo"
, I want the Fourth
li
to appear first and the Second
li
to appear last like so:
<ul>
<li>Fourth</li>
<li>First</li>
<li>Third</li>
<li>Fifth</li>
<li>Second</li>
</ul>
And if the state == "bar"
I want the list to appear in some other way.
Also consider that there may be future conditions where state
may be equal to "baz"
or "foobar"
each having their own order. So writing custom conditionals for each state is not an option.
My idea was to maintain an ordered array for each state and then render the list according to the array using something like Mustache or Handlebars. Is there any better solution to this which is also future proof?
I have a list as follows:
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
<li>Fourth</li>
<li>Fifth</li>
</ul>
What I want is to order the list based on different conditions. For example if the variable state == "foo"
, I want the Fourth
li
to appear first and the Second
li
to appear last like so:
<ul>
<li>Fourth</li>
<li>First</li>
<li>Third</li>
<li>Fifth</li>
<li>Second</li>
</ul>
And if the state == "bar"
I want the list to appear in some other way.
Also consider that there may be future conditions where state
may be equal to "baz"
or "foobar"
each having their own order. So writing custom conditionals for each state is not an option.
My idea was to maintain an ordered array for each state and then render the list according to the array using something like Mustache or Handlebars. Is there any better solution to this which is also future proof?
Share Improve this question edited Aug 21, 2018 at 17:40 Takit Isy 10.1k3 gold badges28 silver badges48 bronze badges asked Aug 17, 2018 at 7:35 radiantshawradiantshaw 5451 gold badge5 silver badges19 bronze badges 3- please share the conditions – brk Commented Aug 17, 2018 at 7:44
-
@brk The
state
variable acts like the condition. – radiantshaw Commented Aug 17, 2018 at 7:49 - 1 Hey @radiantshaw, just to let you know I've added a snippet without jQuery! – Takit Isy Commented Aug 21, 2018 at 18:14
5 Answers
Reset to default 4Here is how I'll do it:
- Using an object to store the different orders,
- Using a
.forEach()
to follow the selected order to re-order theli
s.
New snippets
- Using
.map()
, the on'change'
function
can be reduced to a single line!
Without jQuery (lighter!)
var original_list = document.querySelectorAll('#listToOrder li');
const orders = {
def: [0, 1, 2, 3, 4],
foo: [3, 0, 2, 4, 1],
bar: [3, 2, 4, 1, 0],
baz: [2, 4, 0, 3, 1]
}
document.querySelector('#selector').addEventListener('change', function() {
document.querySelector('#listToOrder').innerHTML = orders[this.value].map(index => original_list[index].outerHTML).join('');
});
<ul id="listToOrder">
<li>First</li>
<li>Second</li>
<li>Third</li>
<li>Fourth</li>
<li>Fifth</li>
</ul>
<label>Select order: </label>
<select id="selector">
<option value="def">Default</option>
<option value="foo">Foo</option>
<option value="bar">Bar</option>
<option value="baz">Baz</option>
</select>
With jQuery
var original_list = $('#listToOrder li');
const orders = {
def: [0, 1, 2, 3, 4],
foo: [3, 0, 2, 4, 1],
bar: [3, 2, 4, 1, 0],
baz: [2, 4, 0, 3, 1]
}
$('#selector').on('change', function() {
$('#listToOrder').html(orders[this.value].map(index => original_list[index].outerHTML));
});
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="listToOrder">
<li>First</li>
<li>Second</li>
<li>Third</li>
<li>Fourth</li>
<li>Fifth</li>
</ul>
<label>Select order: </label>
<select id="selector">
<option value="def">Default</option>
<option value="foo">Foo</option>
<option value="bar">Bar</option>
<option value="baz">Baz</option>
</select>
Old snippet
I couldn't think about an easier way… but .map()
was a good point!
var original_list = $('#listToOrder li');
const orders = {
def: [0, 1, 2, 3, 4],
foo: [3, 0, 2, 4, 1],
bar: [3, 2, 4, 1, 0],
baz: [2, 4, 0, 3, 1]
}
$('#selector').on('change', function() {
var lis = '';
orders[this.value].forEach(function(i){
lis += original_list[i].outerHTML;
})
$('#listToOrder').html(lis);
});
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="listToOrder">
<li>First</li>
<li>Second</li>
<li>Third</li>
<li>Fourth</li>
<li>Fifth</li>
</ul>
<label>Select order: </label>
<select id="selector">
<option value="def">Default</option>
<option value="foo">Foo</option>
<option value="bar">Bar</option>
<option value="baz">Baz</option>
</select>
I suggest to work with a constant for data
and an array of states
objects to give the appropriate order.
dataOrder
key in the states
will hold the order for the indexed data
array:
const data = ['First', 'Second', 'Third', 'Fourth', 'Fifth'];
const states = [
{
state: 'foo',
dataOrder: [0, 1, 2, 3]
},
{
state: 'bar',
dataOrder: [3, 2, 1, 0]
}
];
Note: In the template view you can use Mustache or Handlebars as you wrote in the question
Probably the best option is to just maintain a map of the states which map to the order.
const statesOrder = {
'foo': [0, 1, 2, 3],
'baz': [2, 1, 3, 0],
...
}
And then access the order by passing in the state
.
const listOrder = statesOrder[state];
Also don't forget that if you only need to order the list in a visual way, CSS has an order
property you might be able to take advantage of.
You need to add a unique selector to the elements of the ul
's li
so you can select them, as for example, I am considering a select
will contain the condition selector and then on the onChange
of the select I am calling a function which inside is calling a function to change the order of the list.
Here is the snippet:
var list = $('#listToOrder');
var original_order = $('#listToOrder').html();
$('#ddlchangeOrder').on('change', function() {
var selected_value = this.value;
orderSwitcher(selected_value);
});
function orderSwitcher(order) {
switch (order) {
case "foo":
var elementToPush = list.find('li[data-select="4"]').clone(); //creating a clone of the element
list.find('li[data-select="4"]').remove(); //removing the existing element
list.prepend(elementToPush);
break;
case "bar":
var elementToPush = list.find('li[data-select="2"]').clone(); //creating a clone of the element
list.find('li[data-select="2"]').remove(); //removing the existing element
list.prepend(elementToPush);
break;
//add other cases as per your need.
default:
list.html(original_order);
break;
}
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="listToOrder">
<li data-select="1">First</li>
<li data-select="2">Second</li>
<li data-select="3">Third</li>
<li data-select="4">Fourth</li>
<li data-select="5">Fifth</li>
</ul>
<div>
<label for="ddlchangeOrder">Define Order</label>
<select name="" id="ddlchangeOrder">
<option value="0">Select Order</option>
<option value="foo">Foo</option>
<option value="bar">Bar</option>
<option value="no">no Case</option>
</select>
</div>
var values= ["First", "Second", "Third", "Fourth", "Fifth"];
//Re-arrange values on condition(state == "bar"/"foo" etc)
var element = '<ul>'
for(var i = 0; i < values.length; i++){
var value = values[i];
element += '<li>'+ value+ '</li>';
}
element += '</ul>';
document.getElementById("ulContainer").innerHTML = element;
<div id="ulContainer"></div>
本文标签: javascriptReorder li items according to a variableconditionStack Overflow
版权声明:本文标题:javascript - Reorder li items according to a variablecondition - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742135841a2422364.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论