I have some 1000 of records which I want to display in divs. I'm displaying them in bundles of 20, and when you scroll to bottom loads next 20 records. I'm sorting the records on a range attribute, but when I scroll and load new 20 records in success function of my ajax call, that sorting condition of div is not working for those divs.
Those new Records are displayed in serial order without getting sorted. I'm able to sort the records in present page but if u sort and then scroll to bottom and load new records - those records are not getting sorted on scrolling.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js">
</script>
</head>
<body>
<div id="container">
<div class="content" data-name="Peter" data-price="1000" data-location="US"><span class="productPriceForSorting">1000</span</div><br />
<div class="content" data-name="Willy" data-price="1200" data-location="Mexico"><span class="productPriceForSorting">1200</span</div><br />
<div class="content" data-name="Peter" data-price="2000" data-location="US"><span class="productPriceForSorting">2000</span</div><br />
<div class="content" data-name="Willy" data-price="800" data-location="Mexico"><span class="productPriceForSorting">800</span</div><br />
<div class="content" data-name="Willy" data-price="1300" data-location="Mexico"><span class="productPriceForSorting">1300</span</div><br />
<div class="content" data-name="Peter" data-price="800" data-location="US"><span class="productPriceForSorting">800</span</div><br />
</div>
</div>
<div id="prod"></div>
<button id="asc">sort by price asd</button>
below is my ajax scrolled records
<script type="text/javascript">
$(document).ready(function() {
var page=1;
<%String name1=(String)session.getAttribute("name");%>
var name2="<%=name1%>";
$(window).scroll(function(e)
{if ($(window).scrollTop()+ $(window).height() == $(document).height())
{page++;
$.ajax({ type : "Get",
url : "Someservlet",
datatype : "JSON",
contentType : 'application/json',
data : {pagenumber : page,
Pname : name2},
success : function(data) {
var data1 = data[0],
var len = data1.length;
for (var i = 0; i < len; i++) {
var name = "<div class=content data-name=" + data1[i].name + '' + " data-location=" + data1[i].location + ">"
+ "Peter" +"</div>"+"<div class=content data-name=" + data1[i].name + '' + " data-location=" + data1[i].location + ">"
+ "Willy" +"</div>";
$(name).appendTo("#prod");
}
}
});
}
});
});
</script>
Following is code for sorting
<script type="text/javascript">
function sortByPrice(a, b) {
return $(a).find('.productPriceForSorting').text() > $(b).find(
'.productPriceForSorting').text();
}
function reorderEl1(el) {
var container = $('#container');
container.html('');
el.each(function() {
$(this).appendTo(container);
});
}
$(document).ready('#asc').click(function() {
reorderEl1($('.content').sort(sortByPrice));
});
</script>
Please help me guys, how to sort the scrolling elements once sorting is clicked?
Your AJAX call generates records as following:
var name = "<div class=content data-name=" + data1[i].name + '' + " data-location=" + data1[i].location + ">"
+ "Peter" +"</div>"+"<div class=content data-name=" + data1[i].name + '' + " data-location=" + data1[i].location + ">"
+ "Willy" +"</div>";
Burt your sorting function is looking for .productPriceForSorting element which is not added by AJAX. That's what you need to change. Sorting function is not detecting .productPriceForSorting so it's not comparing.
Also your sort function is not comparing properly, it should be:
function sortByPrice(a, b) {
return parseInt($(a).find('.productPriceForSorting').text()) > parseInt($(b).find('.productPriceForSorting').text());
}
Here's the working demo of fixed sorting. Ajax is for you to be fixed. It must contain <span class=\"productPriceForSorting\">"+data1[i].price+"</span> or something like that.
Related
I have created a simple one page APP using Flickr API to display 25 images based on the keywords typed in the search box. Each new search should replace the previous search results within the div. It works, however, I am only getting one image to post instead of the 25 I have requested "per_page".
I originally tried to use the append method which got me my 25 images, however as expected, instead of refreshing with each new search, it just added the new results to the bottom of the previous results. I also tried the empty() method to clear the results but I was still only getting one image to post. I then tried .replaceWith() and got no results at all. I'm beginning to ask myself if perhaps the order of my code is causing the problem.
EDIT: This works if I use ".append" instead of ".html" however it does not clear the #images div and replace the old data.
<body>
<div class="navbar">
<input type="text" id="content">
<button id="submit", type="submit" class="button">GO!</button>
</div>
<div class="container">
<div id="images"></div>
</div>
<!--script-->
<script>
$(document).ready(function () {
$("#submit").click(function (event) {
var searchVal = $("#content").val();
var flickrAPI = "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=//KEY_GOES_HERE//c&nojsoncallback=1";
$.getJSON( flickrAPI, {
tags: searchVal,
per_page: 25,
//safeSearch
safe_search: 1,
format: "json"
},
function( data ) {
$.each( data.photos.photo, function( i, item ) {
var url = 'https://farm' + item.farm + '.staticflickr.com/' + item.server + '/' + item.id + '_' + item.secret + '.jpg';
$('#images').html('<img src="' + url + '"/>');
});
});
});
});
</script>
My expected outcome was to have the Flickr API post 25 pictures based on what is typed into the search box. If the user performs a new search, 25 new results should replace the previous results.
emptying the #images element before looping over the return data.
then append each element inside the loop to the #images div
<body>
<div class="navbar">
<input type="text" id="content">
<button id="submit", type="submit" class="button">GO!</button>
</div>
<div class="container">
<div id="images"></div>
</div>
<!--script-->
<script>
$(document).ready(function () {
$("#submit").click(function (event) {
var searchVal = $("#content").val();
var flickrAPI = "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=//KEY_GOES_HERE//c&nojsoncallback=1";
$.getJSON( flickrAPI, {
tags: searchVal,
per_page: 25,
//safeSearch
safe_search: 1,
format: "json"
},
function( data ) {
$('#images').empty(); //clear div here
$.each( data.photos.photo, function( i, item ) {
var url = 'https://farm' + item.farm + '.staticflickr.com/' + item.server + '/' + item.id + '_' + item.secret + '.jpg';
$('#images').append('<img src="' + url + '"/>'); //append data here
});
});
});
});
</script>
I have a textarea that will contains a code entered by user and I want to get that code and scan it with jQuery to get the value inside a custom tag called setting then add this value to an input so the user will be able to change the value inside setting tag without touching the code. I was able to get the values and add them inside the inputs but I couldn't update the code with the new values.
HTML CODE :
<div id='tab-1'>
<textarea id='template-code' cols='67' rows='27'></textarea>
<button id='submit-code'>Submit Code</button>
</div>
<div id='tab-2' class='unactive'>
<form id='settings-form' method='POST'>
<div id='result'></div>
<button id='update-code'>Update Code</button>
</form>
</div>
CSS CODE :
.unactive {
display: none
}
jQuery CODE :
$('#template-code').change(function (){
var $that = $(this),
template_code = $that.val(),
code = '',
new_data = '',
text = '',
newCode = '';
// Extract settings from the theme and add them to #result
$(document).on('click', '#submit-code', function (){
$('#tab-1').addClass('unactive');
$('#tab-2').removeClass('unactive');
$(template_code).find('setting').each(function (i){
var $this = $(this),
setting_std = $this.text(),
setting_id = $this.attr('id');
code += '<input id="'+setting_id+'" name="'+setting_id+'" type="text" value="'+setting_std+'"><br>';
});
if(code !== ''){
$('#result').html(code);
}
});
// Update old data with the new one
$(document).on('click', '#update-code', function (){
new_data = $( "#settings-form" ).serializeArray();
$.each( new_data, function( i, new_field ) {
var start_key = "id='"+new_field.name+"'>",
end_key = '</setting>',
start = template_code.indexOf(start_key),
end = template_code.indexOf(end_key);
text = template_code.substring(start + start_key.length, end);
// THE PROBLEM IS HERE
// I want the variable template_code to contains the new value not the old one so I used replace but it seems that it doesn't work
template_code.replace(text, new_field.value);
});
$('#template-code').val(template_code);
$('#tab-1').removeClass('unactive');
return false;
});
});
This is an example of the theme code that will be added inside the textarea :
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html b:version='2' class='v2' expr:dir='data:blog.languageDirection' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'>
<head>
<b:include data='blog' name='all-head-content'/>
<link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300,300italic,700' rel='stylesheet' type='text/css'/>
<link href='http://fonts.googleapis.com/css?family=Lora:400,400italic,700,700italic' rel='stylesheet' type='text/css'/>
<link href='https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css' rel='stylesheet'/>
<title><data:blog.pageTitle/></title>
<div id='option-panel' style='display:none!important'>
<setting id='post_thumbnail'>http://lorempixel.com/640/300/</setting>
<setting id='search_icon'>on</setting>
</div>
</head>
<body>
</body>
</html>
To understand my issue please enter to this JsFiddle and copy the code above then put it inside the textarea and click submit code, you will get two inputs the content of those inputs come from these two tags :
<setting id='post_thumbnail'>http://lorempixel.com/640/300/</setting>
<setting id='search_icon'>on</setting>
I want when the user change the value of inputs and click "update code" to change the value of setting tag inside the entire code.
Try this and see if it's what you're looking for:
HTML
<div id='tab-1'>
<textarea id='template' cols='67' rows='27'></textarea>
<button id='submit'>Submit Code</button>
</div>
<div id='tab-2'>
<form id='settings-form' method='POST'>
<div id='result'></div>
<button id='update'>Update Code</button>
</form>
</div>
JavaScript:
function wrap(data) {
var string = '';
var i, l;
string += "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n";
string += "<!DOCTYPE html>\r\n";
string += "<html b:version='2' class='v2' expr:dir='data:blog.languageDirection' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'>\r\n";
string += " <head>\r\n";
string += " <b:include data='blog' name='all-head-content'/>\r\n";
string += " <link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300,300italic,700' rel='stylesheet' type='text/css'/>\r\n";
string += " <link href='http://fonts.googleapis.com/css?family=Lora:400,400italic,700,700italic' rel='stylesheet' type='text/css'/>\r\n";
string += " <link href='https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css' rel='stylesheet'/>\r\n";
string += " <title><data:blog.pageTitle/></title>\r\n";
string += " </head>\r\n";
string += " <body>\r\n";
string += " <div id='option-panel' style='display:none!important'>\r\n";
for (i = 0, l = data.length; i < l; i++)
string += " " + data[i].toString() + "\r\n";
string += " </div>\r\n";
string += " </body>\r\n";
string += "</html>\r\n";
return string;
}
$("#submit").on('click', function() {
var virtual = document.createElement("div");
var temp = '';
virtual.innerHTML = $("#template").val();
$(virtual).find('setting').each(function(i) {
var $this = $(this),
setting_std = $this.text(),
setting_id = $this.attr('id');
temp += '<input id="' + setting_id + '" name="' + setting_id + '" type="text" value="' + setting_std + '"><br>';
});
if (temp !== '')
$('#result').html(temp);
});
$("#update").on('click', function(event) {
var temp = [];
event.preventDefault();
$("#result").find("input").each(function() {
temp.push("<setting id=\"" + this.id.toString() + "\">" + this.value.toString() + "</setting>");
});
$("#template").val(wrap(temp));
});
I believe that does what you're looking for? Even though you're using jQuery, I think you ended up making it a lot harder than it had to be. I used a virtual node to quickly/easily find and pull ONLY the setting tag from the textarea on submit (down and dirty, I suppose?).
I removed the styles and whatnot since it was interfering with rapid testing, and you'll need to apply proper sanity checking/validation against user input.
Edit: Updated answer to include a ghetto wrapping function to elucidate the concept. I would not recommend using it as is, but instead utilizing a real template, which would require work outside the scope of this question.
Most recent JSFiddle after editing: http://jsfiddle.net/zo3hh2ye/6/
Here's another version of the code. I saved the new values in an array and then replaced them with the existing values in the textarea text. Give a try and see if that solves your problem.
Script :
<script type="text/javascript">
$('#template-code').change(function () {
var $that = $(this),
template_code = $that.val(),
code = '',
new_data = '',
text = '',
newCode = '';
// Extract settings from the theme and add them to #result
$('#submit-code').click(function () {
$('#tab-1').addClass('unactive');
$('#tab-2').removeClass('unactive');
$(template_code).find('setting').each(function (i) {
var $this = $(this),
setting_std = $this.text(),
setting_id = $this.attr('id');
code += '<input id="' + setting_id + '" name="' + setting_id + '" type="text" value="' + setting_std + '"><br>';
});
if (code !== '') {
$('#result').html(code);
}
});
// Update old data with the new one
$('#update-code').click(function () {
new_data = $("#settings-form").serializeArray();
$(template_code).find('setting').each(function (i) {
template_code = template_code.replace("<setting", "").replace("id='" + $(this).attr("id") + "'>", "").replace($(this).html(), "{" + i + "}").replace("</setting>", "");
});
$.each(new_data, function (i, new_field) {
template_code = template_code.replace("{" + i + "}", "<setting id='" + new_field.name + "'>" + new_field.value + "</setting>");
});
$('#template-code').val(template_code);
$('#tab-1').removeClass('unactive');
return false;
});
});
</script>
HTML Template :
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html b:version='2' class='v2' expr:dir='data:blog.languageDirection' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'>
<head>
<b:include data='blog' name='all-head-content'/>
<link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300,300italic,700' rel='stylesheet' type='text/css'/>
<link href='http://fonts.googleapis.com/css?family=Lora:400,400italic,700,700italic' rel='stylesheet' type='text/css'/>
<link href='https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css' rel='stylesheet'/>
<title><data:blog.pageTitle/></title>
<div id='option-panel' style='display:none!important'>
<setting id='post_thumbnail'>text1</setting>
<setting id='search_icon'>text2</setting>
</div>
</head>
<body>
</body>
</html>
I couldn't replace the text 'on' in the template you provided, not sure if it has something to do with some reserved key word but everything else works fine.
I wrote the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>JSON On-change Sample</title>
</head>
<body>
<style>
span {
font-weight: bold;
}
</style>
<div id="placeholder"></div>
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script>
$(document).ready(function(){
//DOCUMENT READY FUNCTION
loadData();
});
function loadData() {
$.getJSON('data.json', function(data) {
var output="<span>";
output+= data.response.items[0].state;
output+= data.response.items[1].state;
output+="</span>";
document.getElementById("placeholder").innerHTML=output;
var initial = (data.response.items[0].state);
var initialSecond = (data.response.items[1].state);
if (initial>0 || initialSecond>0) {
document.title= 'State 1:' + " " + initial + " " + "and" + " " + "State 2:" + " " + initialSecond;
}
$('#placeholder').change(function() {
alert("Changed!");
});
});
setTimeout("loadData()",800);
}
</script>
</body>
</html>
It's purpose is to simply update every 800 milliseconds and update the results on the page. It works.
The problem is that I want a simple alert whenever either of the state of the two items changes, saying which product ID change from which state to which state.
I can't even seem to be able to get the alert first, not even mentioning telling it which product changed and from what state to what state.
Why isn't my alert working? The jQuery documentation state that this... this should be functional.
EDIT:
Solved with the help of blunderboy's solution below.
Here's how it ended-up looking:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>JSON On-change Sample</title>
</head>
<body>
<style>
span {
font-weight: bold;
}
#placeholderOne, #placeholderTwo {
font-weight: bold;
margin-bottom: 15px;
text-align: center;
color: #b20000;
}
h3, h4 {
margin-bottom: 15px;
text-align: center;
}
</style>
<h3>The numbers represent the state of the two products. Get the alert and the update via AJAX by changing the state data in the data.json file and saving it.</h3>
<h4> Product 1: </h4>
<div id="placeholderOne"></div>
<h4> Product 2: </h4>
<div id="placeholderTwo"></div>
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script>
$(document).ready(function(){
//DOCUMENT READY FUNCTION
loadData();
});
function loadData() {
$.getJSON('data.json', function(data) {
var output = data.response.items[0].state;
var outputTwo = data.response.items[1].state;
// Cache the initialState before putting updated value in it
var initialStateOne = document.getElementById("placeholderOne").innerHTML;
var initialStateTwo = document.getElementById("placeholderTwo").innerHTML;
document.getElementById("placeholderOne").innerHTML=output;
document.getElementById("placeholderTwo").innerHTML=outputTwo;
var initial = (data.response.items[0].state);
var initialSecond = (data.response.items[1].state);
if (initial > 0 || initialSecond > 0) {
document.title= 'State 1:' + " " + initial + " " + "and" + " " + "State 2:" + " " + initialSecond;
}
if (initialStateOne != output && initialStateOne > 0) {
alert("Product ID " + data.response.items[0].product_id + " state changed from " + initialStateOne + " to " + data.response.items[0].state);
if (initialStateTwo != outputTwo && initialStateTwo > 0) {
alert("Product ID " + data.response.items[1].product_id + " state changed from " + initialStateTwo + " to " + data.response.items[1].state);
}
};
});
setTimeout("loadData()",800);
}
</script>
</body>
</html>
Check out jQuery Change Event API. It clearly says change event is limited to textarea, select and input. That's why you can not get this working.
Instead you could compare previous and the latest values manually and alert your change event.
Your code will look like this:
function loadData() {
$.getJSON('data.json', function(data) {
var output="<span>";
output+= data.response.items[0].state;
output+= data.response.items[1].state;
output+="</span>";
// Cache the initialState before putting updated value in it
var initialState = document.getElementById("placeholder").innerHTML;
document.getElementById("placeholder").innerHTML=output;
var initial = (data.response.items[0].state);
var initialSecond = (data.response.items[1].state);
if (initial > 0 || initialSecond > 0) {
document.title= 'State 1:' + " " + initial + " " + "and" + " " + "State 2:" + " " + initialSecond;
}
if (initialState != output) { //See this is the only change
alert("Changed!");
};
});
setTimeout("loadData()",800);
Here is another answer to your problem. You can use DOM Mutation Event: DOMSubtreeModified to figure out the changes in the subtree of an element. Here is JSbin Demo
HTML
<div id='a'></div>
JS
var $a = $('#a');
$a.on('DOMSubtreeModified', function() {
alert('Changed');
});
$a.html('This is test1');
$a.html('This is test2');
PS: Please note that this method will also call the event handler when you change any element inside this div. So you better remove this event handler when no longer required or handle such cases gracefully.
I've put together a little app using Kendo UI that stores user inputs in a Javascript array, and then prints these items out by adding text to a div. Along with the text, I need to have a delete button to remove these items from the array.
Since I'm adding the delete buttons to the DOM after I initialize Kendo UI, I assume I need to use the .kendoMobileButton() method on each button I add. If I don't do this, my buttons aren't styled correctly, despite being given the attribute data-role="button".
Still, when I try to use these buttons, I can't get them to call a function with data-click="deleteNumber". The function simply doesn't seem to fire. Any hints?
Here is a quick example I threw together that illustrates my problem: http://crocdoc.ifas.ufl.edu/files/kendo_example/
It is pasted here for easy reference:
<!DOCTYPE HTML>
<html>
<head>
<title>Example code</title>
<meta charset="utf-8">
<link rel="stylesheet" href="styles/kendo.mobile.all.min.css" type="text/css">
<script src="js/jquery.min.js"></script>
<script src="js/kendo.mobile.min.js"></script>
</head>
<body>
<div data-role="view" id="main">
<div data-role="header">
<div data-role="navbar">Generate numbers</div>
</div>
<a data-role="button" data-click="addNumber" style="display: block; margin: 10px; text-align: center;">Add number</a>
<div id="number_list" style="padding: 0 20px 0 20px;"></div>
</div>
<script>
var app = new kendo.mobile.Application();
var number_container = [];
var addNumber = function () {
var current_number = Math.floor(Math.random() * 1000 + 1);
number_container.push(current_number);
console.log(number_container);
var current_index = number_container.length - 1;
$('#number_list').append('Number ' + current_index + ': ' + current_number + ' <a id="delete_' + current_index + '" data-role="button" data-click="deleteNumber">Delete</a><br >');
$('#delete_'+current_index).kendoMobileButton();
};
var deleteNumber = function (e) {
console.log('Delete button hit');
var button_id = e.button.context.id;
button_id = button_id.replace('delete_', '');
button_id = parseFloat(button_id);
number_container.splice(button_id, 1);
$('#number_list').empty();
for (var i = 0; i < number_container.length; i++) {
$('#number_list').append('Number '+i+': '+number_container[i]+' <a id="delete_' + i + '" data-role="button" data-click="deleteNumber">Delete</a><br >');
}
};
</script>
</body>
</html>
You need to modify your code as following ,
$('#number_list').append('Number ' + current_index + ': ' + current_number + ' <a id="delete_' + current_index + '">Delete</a><br/>');
$('#delete_'+current_index).kendoMobileButton({click: deleteNumber});
Thanks
DJ
#debug_mode
This is driving me freaking BATTY as hell.
This is essentially what I am trying to accomplish.
You'll see the Json there are a 2 different departments "Office" and "Stockroom"
What I am trying to accomplish is to arrange everyone by the department they are in. The problem with this is that the HTML needs to look something like this
<h3>Section 1</h3>
<div>
<p>
First Paragraph
</p>
<p>
Second Paragraph
</p>
<p>
Third Paragraph
</p>
</div>
But unfortunately I cannot seem to get the </div> tag in the right spot at the end of the last paragraph of each section
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="http://jqueryui.com/themes/base/jquery.ui.all.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="http://jqueryui.com/ui/jquery.ui.core.js"></script>
<script type="text/javascript" src="http://jqueryui.com/ui/jquery.ui.widget.js"></script>
<script type="text/javascript" src="http://jqueryui.com/ui/jquery.ui.accordion.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var contacts = [{"displayname":"Bruce Lee","email":"Bruce.lee#karate.com","department":"stockroom"},
{"displayname":"Your Momma","email":"Your.Momma#Yourmom.com ","department":"stockroom"},
{"displayname":"Bob","email":"Bob#bob.com ","department":"Office"},
{"displayname":"Cathy","email":"Cathy#Cathy.com ","department":"Office"},
{"displayname":"mike","email":"mike#Cathy.com ","department":"Office"},
{"displayname":"scott","email":"scott#Cathy.com ","department":"Office"}
];
var contacts2 = contacts;
var r = 1;
var lastvalue = 'blah';
for(var i=0; i <=contacts.length; i++)
{
if(contacts[i].department != null)
{
if(lastvalue != contacts[i].department)
{
if(i<1)
{
$('#accordion').append('</div><h3>' + contacts[i].department + '</h3>');
$('#accordion').append('<div><p>' + contacts[i].displayname + '</p>');
}else{
$('#accordion').append('<h3>' + contacts[i].department + '</h3>');
$('#accordion').append('<div><p>' + contacts[i].displayname + '</p>');
}
}else{
$('#accordion').append('<p>' + contacts[i].displayname + '</p>');
}
lastvalue = contacts[i].department;
r++;
}
}
});
$(function() {
$( "#accordion" ).accordion();
});
</script>
</head>
<body>
<div id="contactlist">
<div id="accordion">
</div>
</div>
</body>
</html>
You might want to change this to a jquery each loop and work with json objects directly inside it. The reason you were getting an accordion level each time was due to your loop inserting a h3 every time. I've supplied code to get you pretty much what you need.
edit:
Here is a link to my forked jsfiddle => http://jsfiddle.net/TTV6d/12/
Hope this helps
var departmentlist=new Array();
$.each(contacts, function(i,contact) {
//insert the departments
if (contact.department != null && $('#' + contact.department).length == 0) {
$('#accordion').append('<h3 id='+ contact.department +'>' + contact.department + '</h3>');
departmentlist.push(contact.department);
}
//insert contacts in the accordion
$('#' + contact.department).after('<p>' + contact.displayname + '</p>');
});
$.each(departmentlist, function(i,list) {
$("#" + list).nextUntil("h3").wrapAll("<div></div>");
});
First, be aware that browsers will generally attempt to normalize markup appended to the document: (http://jsfiddle.net/EVjaq/)
$('#container').append('<div><p>Testing</p>'); // no `</div>`
console.log($('#container').html()); // `<div><p>Testing</p></div>`
So, the open <div> in this line will be closed at the end for you, before the next <p> is appended:
$('#accordion').append('<div><p>' + contacts[i].displayname + '</p>');
To avoid this, you can store all of the HTML in a variable, concatenating segments together, and append it to the DOM only once it's done. Or, you can store the <div> and append to that, which can make the conditionals a bit simpler:
var lastvalue = null,
lastdiv = null;
for (var i = 0; i <= contacts.length - 1; i++) {
if (contacts[i].department != null) {
if (lastvalue != contacts[i].department) {
$('#accordion').append('<h3>' + contacts[i].department + '</h3>');
// remember `<div>`
lastdiv = $('<div>').appendTo('#accordion');
}
// append to the `<div>` directly rather than `#accordion`
// also, skip the `else` so you don't have to type this twice
lastdiv.append('<p>' + contacts[i].displayname + '</p>');
lastvalue = contacts[i].department;
r++;
}
}