slideToggle() doesn't push elements created with jquery append() down - javascript

I do have a problem using slideToggle(). The following DOM elements won't be pushed down, they just overlap. I tried a lot of versions. I do create the tags with jquery getting a JSON from which I fill in the tag content, so I iterate over the JSON to create the HTML tags for each element :
var project_infos = '';
jQuery(document).ready(function(){
$.getJSON('project.json', function(data){
project_infos += '<div class=\"row\">'
+ '<div class=\"span3\">'
+ '<div class=\"well\">'
+ '<div>'
+'<ul class=\"nav nav-list sidebar-list\">';
for( var i = 0; i < data.length; i ++ ) {
var project_name = data[i]["item"];
project_infos += '<li>'
+'<label class=\"tree-toggler nav-header\">'
+'<i class=\"fa fa-arrow-right\"></i>' + project_name + '</label>'
+'<ul class=\"nav nav-list tree\">'
+'<li><label class=\"tree-toggler nav-header\">Katalogue</label></li>'
+'<li>'
+'<ul class=\"nav nav-list tree\">'
+'<li>Link</li>'
+'<li>Link</li>'
+'<li>Link</li>'
+'</ul>'
+'</li>'
+'<li><label class=\"tree-toggler nav-header\">History</label></li>'
+'<li><label class=\"tree-toggler nav-header\">Whole project</label></li>'
+'</ul>'
+'</li>';
}
project_infos += '</ul></div></div></div></div>';
$('#tree').append(project_infos);
$('.tree-toggler').click(function () {
$(this).parent().children('ul.tree').slideToggle('slow');
});
});
});
EDIT : screenshot of html output.
screenshot html output
Thanks in advance!

Use
find() instead of children()
$(this).parent().find('ul.tree').slideToggle('slow');
children() will only search for first level child elements.

I just reset all css styles for my div and finally it worked. I already defined styles for the sidebar and for the ul and li tags. One of the styles was the problem. It kept the elements from toggle down in the sidebar.
Thanks for your time!

Related

JQuery AJAX is not inserting HTML?

ajax working with the simple javascript but not with the jquery
Here is the code
$(document).ready(function (){
var url = 'data.json';
$.getJSON(url, function(response){
var htm = '<ul class="bulleted">';
$.each(response, function(index, value){
htm += '<li>';
htm += value.name;
htm += value.inoffice;
htm += '</li>';
});
htm += '</ul>';
$("container").html(htm);
});
});
The problem is nothing is added in the container div.
Without being able to see your HTML, my guess would be that you've done your jQuery selector wrong when fetching your container.
$("container") will select all <container></container> elements.
$("#containter") will select <div id="container"></div> element.
$(".container") will select all <div class="container"></div> elements.
Currently, you're using the first selector but that will only work if the element in your HTML is a <container>. If it's just a typo and you have an ID or a class, use one of the other selectors instead.

JQuery - Selecting nested elements by class

I want to select li elements by class names but it's not working as I want. See the following code:
var HTML = '<div class="product">' +
'<ul class="listing">' +
'<li class="item">1</li>' +
'<li class="item">2</li>' +
'<li class="item">3</li>' +
'<li class="item">4</li>' +
'<li class="item">5</li>' +
'</ul>' +
'</div>';
alert($(HTML).find('.product .listing .item').html()); //does not work
alert($(HTML).find('.listing .item').html()); //WORKS!
Why I am not able to select items product class?
Because .product is one of the selected elements, it's a top level element. .find would try to find the elements with class product inside the .product element.
Maybe you are looking for .filter:
Reduce the set of matched elements to those that match the selector or pass the function's test.
alert($(HTML).filter('.product').find('.listing .item').html());
jQuery find looks for descendents of the current jQuery selection. In this case, $(HTML) is already the div with the product class, so .find('.product .listing .item') would look for descendents of the top div with the class of product. In this case, using .find('.listing .item') is correct.
i am not sure if this is something you're looking for?
var HTML = '<div class="product">' +
'<ul class="listing">' +
'<li class="item">1</li>' +
'<li class="item">2</li>' +
'<li class="item">3</li>' +
'<li class="item">4</li>' +
'<li class="item">5</li>' +
'</ul>' +
'</div>';
alert($('.item', HTML));
please see the fiddle http://jsfiddle.net/s1s3zjdL/

Wrap each list array in a Tag

I am trying to get each Post lists wrapped in the href so it can be clicked on. Basically when I try to click on each Posts, it does not work until I hover my mouse close to the top of each posts before it works.
Below is my code and also an image of what I mean:
JS:
function getPosts(data) {
var $output = $('<ul class="posts" data-role="listview" data-filter="true">')
$.each(data.posts,function(i, val) {
$('<li><a href="#devotionpost" onclick="showPost(' + val.id + ')"</a>').append([$("<h3>", {html: val.title}),$("<p>", {html: val.excerpt})]).appendTo($output);
if ( i == 3 ) return false;
// return (postlimit-- > 1);
});
$('#postlist').empty().append($output);
}
function showPost(id) {
$('#mypost').html('<span class="img_spin">Loading post...</span>');
$.getJSON('http://howtodeployit.com/category/daily-devotion/?json=get_post&post_id=' + id + '&callback=?', function(data) {
var posts='';
posts += '<h3>' + data.post.title + '</h3>';
posts += data.post.content;
$('#mypost').html(posts);
});
}
Image:
If you look at the image, when i hover my mouse close to the top edge of the Post, then the URL at the bottom shows and that works but any where else does not work.
From looking at the Chrome Elements tab in this demo the JavaScript is generating invalid HTML because of mismatched closing elements.
Using an example posts of var posts = { "posts" : [ {"id":"1", "title":"lorem", "excerpt":"foo"}, {"id":"2", "title":"ipsum", "excerpt":"bar"} ] }
This '<li><a href="#devotionpost" onclick="showPost(' + val.id + ')"</a>' is resulting in the broken first child of the following <li>:
<li>
<a href="#devotionpost" onclick="showPost(1)" < a></a>
<h3>lorem</h3>
<p>foo</p>
</li>
Depending on exactly what you want to wrap in the anchor element, you could just build the post <li> like in this updated demo or see code below:
$.each(data.posts,function(i, val) {
$output.append('<li><h3>' + val.title + '</h3><p>' + val.excerpt + '</p></li>');
});
Or if you want to have a little less string concatenation, you could use .wrapInner()
$.each(data.posts,function(i, val) {
var $post = $('<li><h3>' + val.title + '</h3><p>' + val.excerpt + '</p></li>');
$post.wrapInner('');
$output.append($post);
});
Or keeping your .append() approach:
$.each(data.posts,function(i, val) {
var $post = $('<li/>').append([$("<h3>", {html: val.title}),$("<p>", {html: val.excerpt})]).wrapInner('');
$output.append($post);
});
Note: The string concatenation approach, combined with a single .append() is the best performing code.
By the looks of it, your lists are floating. You should use a clearfix technique to make "A" element box include the list. You also should know that by standard "A" elements are not allowed to contain block elements and as far as internet explorer 9 (didn't check in 10 or 11) "A" will not work the way you intended.
Possible workaround:
<div style="position:relative">
<ul>
<li></li>
<ul>
<a style="position:absolute;display:block;top:0;bottom:0;left:0:right:0;" href="#"></a>
<div>

Divs with same id error

<div id="tagTree1" class="span-6 border" style='width:280px;height:400px;overflow:auto;float:left;margin:10px; '>
<a class="tabheader" style="font-size:large">Data Type</a><br />
<div class="pane">Refine search by Data Type</div>
</div>
Above div(tagTree1) is present in a division ad.
<div id="newtagTree1" class="span-6 border" style='width:200px;height:400px;overflow:auto;float:left'>
<a class="tabheader"><strong>Geographic Location</strong></a><br />
<div class="pane"><strong>Refine search by geographic location</strong></div>
</div>
newTagTree1 division is present in another division search. But both have the same functionality to generate children divisions within them, which is written in a js file. All the children division generated dynamically in js file. Both of them uses same function to generate children divs. I am facing problem when i am using them in same page. If one works fine then the other doesn't. Can any one say me about the mistake i am doing in this?
Thanks in advance.
$.getJSON('/api/TagsApi/Children?id=800002', function (data) {
//$(tagDiv).empty();
$.each(data, function (i, item) {
$("#tagTree1").append(tagTabBuilder(item));
});
$("#tagTree1").tabs("#tagTree1 div.pane", { api: true, tabs: 'a', effect: 'slide', onClick: buildChildren, initialIndex: 0 });
});
function tagTabBuilder(tagData) {
var str = "<input type='checkbox' name='tagchkbox[]' value='" + tagData.ID + "' onClick='startQuery()' /><a class='tabheader '>" + tagData.NAME;
if (tagData.count == 0) {
str += " (<span class='el_count' id='t" + tagData.ID + "'>" + tagData.count + "</span>)" + "</a><br/>";
} else {
str += " (<span class='el_count' id='t" + tagData.ID + "'><strong>" + tagData.count + "</strong></span>)" + "</a><br/>";
}
str += "<div id='tid-" + tagData.ID + "' class='pane tag'><!--Loading subtags. . .<img src='/assets/modules/gaiaModule/shared/images/load-small.gif' />--></div>";
return str;
}
My guess would be that when they generate child divs, they're generating them with the same ID scheme. Thus, either of them can generate child divs just fine by itself, but when both of them are included, there is ID collision. The answer is to modify the child generation code to, for example, include the id of the parent div as the first portion of the id of the child div.
Alternately, if you dont' need them for other portions of the javascript, leave the child div ids out entirely. In general, I find that it's better to avoid the id attribute in generated nodes, and instead use classes or the like.

making a list in jquery mobile using innerhtml

I am trying to create a list using the styles provided by jquery mobile. When I make the list in the html file, the list incorporates the styles that jquery mobile provide: http://jquerymobile.com/demos/1.0/docs/lists/lists-search.html
However in my website, i need to generate the list based on the number of objects in my array so I want to do this by making the html script using javascript and changing the innerHTML of a div. When I do this, a normal list appears without the stylings of jquery mobile.
Does anyone have a solution to my problem?
Here's my markup code:
function GenerateList(appArray) {
var searchList = document.getElementById('searchList');
var app;
var htmlString = "<ul data-role='listview' data-filter='true' data-filter- placeholder='Search...' data-filter-theme='a' data-theme='a'>";
for(i=0; i<appArray.length;i++) {
app = appArray[i];
htmlString = htmlString + "<li><a id=App" + (i+1).toString() + " onclick='AppSelected(id);'>";
htmlString = htmlString + "<img src='DummyImages/" + app[1] + "' alt='Logo' class='ListAppLogo'>";
htmlString = htmlString + "<h3>"+ app[2] + "</h3>";
htmlString = htmlString + "<p>" + app[4] + ".0/5.0</p>";
htmlString = htmlString + "<input type='hidden'>" + app[0] + "</a></li>";
}
htmlString = htmlString + "</ul>";
searchList.innerHTML = htmlString;
}
You'll want to make sure JQuery Mobile initializes the list after you've created it with javascript. Use the following snippet where thislist is the id of the unordered list element.
$('#thislist').listview()
Also, if the unordered list with data-role='listview' already exists, then you'll want to use the same initializer with a parameter, 'refresh'. Here is another snippet where thislist is the id of the unordered list. You'll want to use the refresh if you've added/removed items from it dynamically.
$('#thislist').listview('refresh');
I'm not taking credit for the solution instead trying to explain it in detail since it took me some time to figure it out but the changes should be something like this.
Original code:
function GenerateList(appArray) {
var searchList = document.getElementById('searchList');
var app;
var htmlString = "<ul data-role='listview' data-filter='true' data-filter- placeholder='Search...' data-filter-theme='a' data-theme='a'>";
...
searchList.innerHTML = htmlString;
}
Fixed code:
function GenerateList(appArray) {
var searchList = document.getElementById('searchList');
var app;
var htmlString = "<ul id='thislist' data-role='listview' data-filter='true' data-filter- placeholder='Search...' data-filter-theme='a' data-theme='a'>";
...
searchList.innerHTML = htmlString;
$('#thislist').listview();
}
This way it shows your list using the listview from jquery mobile.
You're not using the same CSS as jQuery Mobile. If you look at the HTML on the link you provided, you'll see that they have additional classes on their list items:
<ul data-role="listview" data-filter="true" class="ui-listview">
<li data-theme="c" class="ui-btn ui-btn-icon-right ui-li-has-arrow ui-li ui-btn-up-c">
<div class="ui-btn-inner ui-li" aria-hidden="true">
<div class="ui-btn-text">Acura</div>
<span class="ui-icon ui-icon-arrow-r ui-icon-shadow"></span>
</div>
</li>
</ul>

Categories