I have a list but when I try to generate autodividers for that list I'm getting duplicate dividers. Here is the code for the ul and the relevant script:
<div data-role="content">
<ul data-role="listview" id="ScheduleList" data-autodividers="true">
<li time="3:30PM">Event 1</li>
<li time="3:30PM">Event 2</li>
<li time="4:30PM">Event 3</li>
<li time="3:30PM">Event 4</li>
<li time="3:30PM">Event 5</li>
<li time="4:30PM">Event 6</li>
</ul>
</div>
</div>
<script>
$(document).on("pageinit", "#ScheduleDay", function(){
$("#ScheduleList").listview({
autodividers: true,
autodividersSelector: function (li) {
var out = li.attr('time');
return out;
}
}).listview('refresh');
});
</script>
Here is the code in JSFiddle: http://jsfiddle.net/4fGT6/65/
I know that I could reorder the list items in the html and that would eliminate the duplicate autodividers, but if I made the list to be generated dynamically from user inputs then I couldn't manually reorder the html.
Is there a way to solve this if the list had been generated dynamically?
Thanks.
First step, sort list items based on data-time attribute (I added data to facilitate reading values - data attribute is ignored by user agent, thus it won't mess up your code).
I used the below simple code, yet genius, made by #undefined.
Update:
Thanks to #Keir Lavelle for reviewing the code of sorting li elements.
var listview = $('#ScheduleList'),
listitems = listview.children('li');
listitems.detach().sort(function (a, b) {
var adata = $(a).data('time');
var bdata = $(b).data('time');
/* return (adata > bdata) ? (adata > bdata) ? 1 : 0 : -1; */
return (adata > bdata) ? 1 : -1;
});
listview.append(listitems);
Second step, apply autodividers dynamically.
$("#ScheduleList").listview({
autodividers: true,
autodividersSelector: function (li) {
var out = li.jqmData('time');
return out;
}
}).listview('refresh');
Demo
Credits to #undefined and #Keir Lavelle
Related
I have ol li structure as html and I want to create JSON from that but my code doesn't create that JSON I need. Can any one please help me to solve it?
I need to create JSON like that
[
{"en":"Menu1","enlink":"#enlink1","tr":"Menü 1","trlink":"#trlink1","data":[
{"en":"Menu1-1","enlink":"#enlink1-1","tr":"Menü 1-1","trlink":"#trlink1-1","data":[
{"en":"Menu1-1-1","enlink":"#enlink1-1-1","tr":"Menü 1-1-1","trlink":"#trlink1-1-1"},
{"en":"Menu1-1-2","enlink":"#enlink1-1-2","tr":"Menü 1-1-2","trlink":"#trlink1-1-2"}
]},
]},
{"en":"Menu2","enlink":"#enlink2","tr":"Menü 2","trlink":"#trlink2","data":[
{"en":"Menu2-1","enlink":"#enlink2-1","tr":"Menü 2-1","trlink":"#trlink2-1"},
{"en":"Menu2-1","enlink":"#enlink2-1","tr":"Menü 2-1","trlink":"#trlink2-1"}
]},
{"en":"Menu3","enlink":"#enlink3","tr":"Menü 3","trlink":"#trlink3"}
]
And my sample codes are..
var buildJson = function (root){
if(!root){
root='#domenu-en';
}
var result = [];
$(' ol > li ',root).each(function() {
if($(this).children("ol").length){
result.push({"en":$(this).attr("data-en"),"data":buildJson($(this))});
//return false;
} else{
result.push({"en":$(this).attr("data-en")});
}
});
return result;
}
$('#results').val(JSON.stringify(buildJson()))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="domenu-en">
<ol>
<li data-enlink="#enlink1" data-en="Menu1" data-trlink="#trlink1" data-tr="Menü 1">
<ol>
<li data-enlink="#enlink1-1" data-en="Menu1-1" data-trlink="#trlink1-1" data-tr="Menü 1-1">
<ol>
<li data-enlink="#enlink1-1-1" data-en="Menu1-1-1" data-trlink="#trlink1-1-1" data-tr="Menü 1-1-1">
</li>
<li data-enlink="#enlink1-1-2" data-en="Menu1-1-2" data-trlink="#trlink1-1-2" data-tr="Menü 1-1-2">
</li>
</ol>
</li>
</ol>
</li>
<li data-enlink="#enlink2" data-en="Menu2" data-trlink="#trlink2" data-tr="Menü 2">
<ol>
<li data-enlink="#enlink2-1" data-en="Menu2-1" data-trlink="#trlink2-1" data-tr="Menü 2-1">
</li>
<li data-enlink="#enlink2-1" data-en="Menu2-1" data-trlink="#trlink2-1" data-tr="Menü 2-1">
</li>
</ol>
</li>
<li data-enlink="#enlink3" data-en="Menu3" data-trlink="#trlink3" data-tr="Menü 3">
</li>
</ol>
</div>
<textarea id="results" style=" height: 279px;"></textarea>
I found the solution its very simple, in case any one needed I like to share it. If we tell the jQuery select first li as ol:first >li then its generate same hierarchy as li structure.
var buildJson = function (root){
if(!root){
root='#domenu-en';
}
var result = [];
$('ol:first > li ',root).each(function() {
var itemdata = {};
$.each($(this).data(), function(key, value) {
itemdata[key] = value;
});
if($(this).children("ol").length){
itemdata["data"] = buildJson($(this));
}
result.push(itemdata);
});
return result;
}
The main difference seem to be that you don't include the other data- attributes other than the data-en. You can iterate all of the data- attributes on an element with $.each($(this).data(), function(key, value) {}).
In your case that would be something like:
$(' ol > li ',root).each(function() {
var itemdata = {};
$.each($(this).data(), function(key, value) {
itemdata[key] = value;
});
if($(this).children("ol").length){
itemdata["data"] = buildJson($(this));
}
result.push(itemdata);
});
That should give you an equal JSON result. The properties may be in a different order, but that shouldn't matter for JSON (for example: your JSON example had the order en, enlink, tr and trlink, while I got tr, trlink, en and enlink in my example. The order of the menu items in the list is still the same (1, 1-1, 1-2, etc.).
A working example at https://jsfiddle.net/gpctm9d1/
Friends have a problem.
When clicking a link from a menu, I need to generate below the selected sub-menu item.
So far I can send the request via ajax, and generate a sub-menu, but this sub-menu always appears in the first position:
HTML CODE (simple menu)
<ul>
<li>Item 1
<ul id="city"></ul>
</li>
<li>Item 2
<ul id="city"></ul>
</li>
<li>Item 3
<ul id="city"></ul>
</li>
<li>Item 4
<ul id="city"></ul>
</li>
<li>Item 5
<ul id="city"></ul>
</li>
</ul>
JS CODE:
$('.region_id').on('click', function(event) {
event.preventDefault();
$.get('{!! url("filter_city") !!}', {id : $(this).attr('data-id'), token: $('input[name="_token"]').val() }, function(data) {
var cities = $('#city');
cities.empty();
$.each(data, function(key, value) {
cities.append($("<li></li>").text(value));
});
});
});
Result I get when clicking any option
As I can achieve what I want? Greetings from Chile
Identifier in HTML must be unique. You can use a common class and then traverse DOM using various methods.
Here's an example, I have used city as CSS class instead of ID. then the relevant element can be identified using any of these methods.
var cities = $(this).next('.city');
//var cities = $(this).siblings('.city');
//var cities = $(this).closest('li').find('.city');
HTML
<ul>
<li>
Item 1
<ul class="city"></ul>
</li>
</ul>
Script
$('.region_id').on('click', function(event) {
event.preventDefault();
var cities = $(this).next('.city');
$.get('{!! url("filter_city") !!}',
{
id : $(this).data('id'),
token: $('input[name="_token"]').val()
},
function(data) {
cities.empty();
$.each(data, function(key, value) {
cities.append($("<li></li>").text(value));
});
}
);
});
I would recommend you to use .data() instead of attr() to fetch data-* custom attribute value.
var id = $(this).data('id');
I have an array, it contains values [1,2].
I also have an html list
<ul>
<li id="1">List Item 1</li>
<li id="2">List Item 2</li>
<li id="3">List Item 3</li>
</ul>
I need to iterate through the array, and if a value in the array matches an ID in my list, add a class to the list item.
The output example would be
<ul>
<li id="1" class="active">List Item 1</li>
<li id="2" class="active">List Item 2</li>
<li id="3">List Item 3</li>
</ul>
I'm a bit lost on this one, thanks in advance!
Try to use $.map() to translate the array into "#1,#2" and pass it as a selector then add class to it,
var arr = [1,2]; // var arr = Express.completedSteps;
$($.map(arr,function(val,_){
return "#" + val;
}).join()).addClass('active');
DEMO
try
var arr=[1,2];
for(var i in arr){
$("#"+arr[i]).addClass("active");
}
DEMO
Try out following.
$(document).ready(function(){
var obj = [1,2,5,7];
$.each( obj, function( key, value )
{
$('li').each(function(){
if($(this).attr('id')==value)
{
$('#'+value).addClass( "active" );
}
});
});
})
try out the demo here.
demo
I am creating a jquery plugin that will sort a list based on data attributes:
<ul class="reorder">
<li data-rating="1" data-category="3">Rating 1 - Category 3</li>
<li data-rating="5" data-category="1">Rating 5 - Category 1</li>
<li data-rating="2" data-category="2">Rating 2 - Category 2</li>
<li data-rating="7" data-category="1">Rating 7 - Category 1</li>
<li data-rating="21" data-category="3">Rating 21 - Category 3</li>
<li data-rating="19" data-category="2">Rating 19 - Category 2</li>
</ul>
As I don't know how many data attributes will be added, I want to be able to loop through the list and identify unique data attributes (NOT the value of those attributes) to create a set of links:
<ul class="reorder-nav">
<li>Sort by rating</li>
<li>Sort by category</li>
</ul>
My basic idea is to loop through each list item and create an array of data attributes, then filter that array for unique attributes.
I can create an array of all data attributes with .data() but other than that I'm a bit stuck so would appreciate any suggestions.
You can do something like this to extract the data-x attribute names :
var uniqueAttrs = {};
$('.reorder li').each(function(){
$.each(this.attributes, function(_,a){
if (a.name.indexOf('data-')===0) {
uniqueAttrs[a.name.slice(5)] = 1;
}
});
});
Then you can iterate over the keys of uniqueAttrs :
for (var attr in uniqueAttrs) {
console.log(attr); // for example "sort" or "ranking"
}
If you can afford to support a limited set of browsers, you can simplify the loop by using dataset instead of attributes.
I have used Lists within a list and I intend to send the id's using jquery to another php file(updateDB.php).
I tried serializing the list but couldn't get the data. I'm not sure if i've got it right, tried looking around every place but couldn't figure out what's wrong with the code.
<ul>
<li id="recordsArray_<?some number?>"><?php echo content?>`
<ul>
<?php
while (some condition) {
?>
<div>
<li id="subArray_<another number?>"><?php echo content?></li>
</div>
<?php
//conditions - increment within the loop
}
?>
</ul>
</li></ul>
the jquery code is something like this,
$(document).ready(function() {
$(function() {
$("#contentLeft ul").sortable({opacity: 0.6, cursor: 'move', update: function() {
var order = $(this).sortable('serialize') + '&action=updateMenuListings';
$.post("updateDB.php", order, function(theResponse) {
$("#contentRight").html(theResponse);
});
}});
});
$(function() {
$("#contentLeft ul li ul").sortable({opacity: 0.6, cursor: 'move', update: function() {
var order = $(this).sortable('serialize') + '&action=updateSubListings';
$.post("updateDB.php", order, function(theResponse) {
$("#contentRight").html(theResponse);
});
}});
});
});
the id's contentLeft are just the id's for before the lists.
I intend to make it draggable hence used sortable.
On debugging, i'm unable to get any id's of the lists in the variable 'order'.
Please do check out the code and help out.
Thanks
Below you'll find some HTML that is structure like yours along with the JavaScript and jQuery to do what you want. This allows you to move the top level items, with all their respective subitems or just rearrange the subitems. Both options generate a body that you can use in the commented out post line.
You can see it in action here: http://jsfiddle.net/WTjsG/
HTML:
<div id="ContentLeft">Sortable With Update
<ul id="Nav" class="sortable navLevel1">
<li id="Nav_1">Nav1
<!-- NOTE: format id's for UL and LI items as <name>_<int> for serialize to work properly -->
<ul id="NavRecords_1" class="sortable navLevel2">
<li id="Nav1_1">Nav1 Item1</li>
<li id="Nav1_2">Nav1 Item2</li>
<li id="Nav1_3">Nav1 Item3</li>
<li id="Nav1_4">Nav1 Item4</li>
</ul>
</li>
<li id="Nav_2">Nav2
<ul id="NavRecords_2" class="sortable navLevel2">
<li id="Nav2_1">Nav2 Item1</li>
<li id="Nav2_2">Nav2 Item2</li>
<li id="Nav2_3">Nav2 Item3</li>
<li id="Nav2_4">Nav2 Item4</li>
</ul>
</li>
</ul>
</div>
JavaScript w/ jQuery:
$(document).ready(function () {
var isDebugMode = true;
//Set common sort settings for all lists
$(".sortable").sortable({
opacity: 0.6,
cursor: 'move'
});
//Function used to configure update calls for each sort
function setSortAction(selector, updatePage, updateAction, itemLabel) {
$(selector).sortable({
update: function () {
var itemList = $(this).sortable(
"serialize", {
attribute: "id",
key: itemLabel
});
//Create POST request to persist the update
var bodyContent = "action=" + updateAction + "&" + itemList;
if (isDebugMode) { alert("DEBUG: bodyContent = \n" + bodyContent); }
//$.post(updatePage, bodyContent, function (postResult) { alert(postResult); });
}
});
}
//Set sort update action for top level and second level
setSortAction(".navLevel1", "updateDB.php", "updateMenuListings", "record");
setSortAction(".navLevel2", "updateDB.php", "updateMenuItemListings", "record");
});