Stumped on another one. I'm using boostrapJS to create a Nav-List. Ideally the headers will remain collapsed by default, but will expand when clicked. Right now I have some javascript that will go and dynamically populate the List, but the click event seems to be doing nothing. (sort of - I click on the header and it jitters a bit, but it does not collapse).
I've looked at the code examples, and I'm pretty sure I'm using the same classes and div structure, but It still seems to be not working, and it's not throwing any errors.
Here is my Code:
$('#header').append('<ul class="nav nav-list">');
for (i = 0; i < len; i++) {
k = keys[i];
$('#header').append('<label class="tree-toggle nav-header">' + keys[i] + '</label>');
for (var j in groupedtemplates[k]) {
$('#header').append('<li data-value=' + groupedtemplates[k][j].id + '>' + groupedtemplates[k][j].attributes.im_name.value + '</li>');
}
}
$('#header').append('</ul>');
$(document).ready(function () {
$('.tree-toggle').click(function () {
$(this).parent().children('ul.tree').toggle(200);
});
});
The HTML that it's being inserted into is just a simple container.
<div class="well" style="width:100%; padding: 8px 0;" id="header">
</div>
Figured it out.
When you append a tag without a closing tag, the browser inserts one for you. Because of this the objects were not appearing as children.
This is my revised solution that puts all the data to be appended in a variable, then appends it afterwards.
for (i = 0; i < len; i++) {
k = keys[i];
var toAppend = "";
toAppend = toAppend + '<ul class="nav nav-list">' + '<li><label class="tree-toggle nav-header">' + keys[i] + '</label</li>' + '<ul class="nav nav-list tree">'
for (var j in groupedtemplates[k]) {
toAppend = toAppend + '<li data-value=' + groupedtemplates[k][j].id + '>' + groupedtemplates[k][j].attributes.im_name.value + '</li>'
}
toAppend = toAppend + "</ul></ul>";
$('#header').append(toAppend);
}
Related
I keep getting the above error an uncaught type error saying something isn't a function when I think it is. I'll post the code and point out where I am referencing the elements. I'm making a Todo list which generates a todo item, a checkbox, and a remove icon. When users click the checkbox, I want it to apply the text-decoration: line-through to the Todo item. I added an onclick="boxChecked"() to the input with the checkbox and referenced right away in my function. It keeps saying in my HTML that it isn't defined. Is this because it is all JavaScript being referenced to the HTML doc externally? Maybe I have the function in the wrong spot?
Here is the Console Log
function show() {
var todos = get_todos();
var html = "<ul>";
for (var i = 0; i < todos.length; i++) {
html +=
'<li class="todo-item">' +
'<span class="todo-label">' +
todos[i] +
"</span>" +
/*Here is the onclick--->*/ '<input onclick="boxChecked()" class="checkBox" type="checkbox">' +
'<button class="remove" id="' +
i +
'">' +
'<i class="fa fa-trash" aria-hidden="true"></i>' +
"</button>" +
"</li>";
}
html += "</ul>";
document.getElementById("todos").innerHTML = html;
var buttons = document.getElementsByClassName("remove");
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", remove);
}
/*Here is the function for it---->*/ function boxChecked() {
var x = document.getElementByClassName("todo-item");
if (x.style.textDecoration === "none") {
x.style.textDecoration = "line-through";
} else {
x.style.textDecoration = "none";
}
}
}
document.getElementById("add").addEventListener("click", add);
show();
Below is an image from w3schools where I tried it all on one page (without referencing it through an external JavaScript file) and it works. I'm really not sure. Any help would be greatly appreciated!
Im using ajax to return some json. Here is what the json looks like.
[{"optionValue":"11","optionDisplay":"Canon","preitem":`[{"preitemId":"15","preitemLabel":"Canon EF 100mm f\/2.8L Macro IS USM "},{"preitemId":"18","preitemLabel":"12412"},{"preitemId":"21","preitemLabel":"Sonydas1df Test"}]},{"optionValue":"20","optionDisplay":"Nikon","preitem":""},{"optionValue":"21","optionDisplay":"Audio & Aerial","preitem":""},{"optionValue":"23","optionDisplay":"Sony","preitem":[{"preitemId":"19","preitemLabel":"Sony 1412Test"},{"preitemId":"20","preitemLabel":"Son124124y Test"}]}]`
From what you can see here each option has a few preitems.
For example Canon has the preitems Canon EF 100mm, 12412 and Sonydas1df Test.
The goal is to output everything onto a html page.
So canon will have its own heading with its pre items under it.
Here is my code.
for (var i = 0; i < j.length; i++) {
for (var u = 0; u < j[i].preitem.length; u++) {
preitems += j[i].preitem[u].preitemLabel+'<br>';
}
options += '<div class="itemBlock"><b>'+ j[i].optionDisplay +'</b><input class="subcheckboxes" type="checkbox" id="checkit" value="' + j[i].optionValue + '">' + j[i].optionDisplay + '</input><div class="" id="subcat' + j[i].optionValue + '">'+preitems+'</div></div>';
}
$("#subcat").html(options);
The main options (canon,etc) get displayed fine. However it does not output the only the pritems which are in the option. It outputs every single preitem in the whole json returned.
I want to only show the preitems which are in the option.
Thanks
You aren't resetting preitems
You probably want...
for (var i = 0; i < j.length; i++) {
preitems = '';
for (var u = 0; u < j[i].preitem.length; u++) {
...
When traversing multi-dimensional data objects, you need more specifically identify which actions happen how many times and where. Your plan of just scooping up all of the pre-items and dumping them for each item is fine if you reset the pre-items as rjdown suggests. I'd try something like this instead though:
for (var i = 0, lenj = j.length; i < lenj; i++) {
options += '<div class="itemBlock"><b>'+ j[i].optionDisplay +'</b><input class="subcheckboxes" type="checkbox" id="checkit" value="' + j[i].optionValue + '">' + j[i].optionDisplay + '</input><div class="" id="subcat' + j[i].optionValue + '">';
for (var u = 0, lenu = j[i].preitem.length; u < lenu; u++) {
options += j[i].preitem[u].preitemLabel+'<br>';
}
options += '</div></div>';
}
$("#subcat").html(options);
I feel like this is much more readable and fixes your problem.
Can you please tell me how to make list in jQuery mobile? I am trying to make this type list as given in fiddle on pop up screen dynamically .
Here is the fiddle
In this fiddle I make two rows.In first row there is only p tag. But in second row there is nested collapsible rows. I need to make same thing in pop up screen. I am able to make first row. But In my second row contend is null why? Can you suggest where I am wrong?
fiddle
$(function () {
$('#test').click(function(){
alert('d');
createCommandPopUpTabs();
$("#tabbedPopup").popup("open");
});
});
var tabsHeader = [ "InputParameter", "basic"];
var tabsHeader_basic = [ "XYZ", "Third Level",
];
function createCommandPopUpTabs(){
var header = "<h3 >dd</h3>";
var commmand = 'dd';
var button = '<button onclick="return submitCommand("'+
'")" style="" class="donebtn common-button1">Save</button>';
$("#commandInfo").append(button);
$("#commandInfoheader").html(header);
for ( var i = 0; i < tabsHeader.length; i++) {
var headerId = tabsHeader[i] + "_tab" + commmand;
var header = "<div data-role='collapsible' data-collapsed='false' id='"
+ headerId + "'><h3>InputParameter</h3></div>";
var content ;
if(tabsHeader[i]=="InputParameter"){
content = "<p>yes</p>";
}else if(tabsHeader[i]=="basic"){
for ( var i = 0; i < tabsHeader_basic.length; i++) {
headerId = tabsHeader_basic[i] + "_tab" + commmand;
header = "<div data-role='collapsible' data-collapsed='false' id='"
+ headerId + "'><h3>basic</h3></div>";
content += getcontend(tabsHeader_basic[i]);
}
}
$("#tabbedSet").append(header);
$("#tabbedSet").find("#" + headerId).append(content);
$("#tabbedSet").collapsibleset("refresh");
}
}
function getcontend(name){
if(name=="Third Level"){
return"<p>Third Level></p>";
} if(name=="XYZ"){
return"<p> second Level></p>";
}
}
There are errors in your code and logic. I will only go over a couple of them to hopefully get you on the right path:
In tabsHeader_basic array the Third Level has a space in it which you later use as an ID which makes it an invalid ID because you cannot have spaces in an ID.
From the HTML 5 Draft:
The value must not contain any space characters.
Also, the "basic" collapsible div needs to exist before you start adding the nested collapsible div.
So this line needs to come out of the for loop
header = "<div data-role='collapsible' data-collapsed='false' id='"+ headerId + "'><h3>basic</h3></div>";
Go through the JSFiddle and compare your code agaisnt my changes.
Hopefully that helps! Let me know if you have any other questions.
I have updated createCommandPopUpTabs() function.
Also removed space in Third Level on var tabsHeader_basic = ["XYZ", "ThirdLevel"];
Check the Updated Fiddle
function createCommandPopUpTabs() {
var header = "<h3 >dd</h3>";
var commmand = 'dd';
var button = '<button onclick="return submitCommand("' +
'")" style="" class="donebtn common-button1">Save</button>';
$("#commandInfo").html(button);
$("#commandInfoheader").html(header);
$("#tabbedSet").html('');
for (var i = 0; i < tabsHeader.length; i++) {
var headerId = tabsHeader[i] + "_tab" + commmand;
var header = "<div data-role='collapsible' data-collapsed='true' id='" + headerId + "'><h3>" + tabsHeader[i] + "</h3></div>";
$("#tabbedSet").append(header);
var content;
if (tabsHeader[i] == "InputParameter") {
content = "<p>yes</p>";
$("#tabbedSet").find("#" + headerId).append(content);
} else if (tabsHeader[i] == "basic") {
for (var j = 0; j < tabsHeader_basic.length; j++) {
var headerId1 = tabsHeader_basic[j] + "_tab" + commmand;
var header1 = "<div data-role='collapsible' data-collapsed='true' id='" + headerId1 + "'><h3>" + tabsHeader_basic[j] + "</h3></div>";
var content1 = getcontend(tabsHeader_basic[j]);
$("#tabbedSet").find("#" + headerId).append(header1);
$("#tabbedSet").find("#" + headerId1).append(content1);
}
}
$("#tabbedSet").collapsibleset("refresh");
}
}
I am trying to create drag and drop event in javascript. I get the data from the database by using a loop and create div according to that data. Then I try to catch drop() event when dropped an item. But its not working. But Its works on hard coded div.
for (i = 0; i < positions.length; i++) {
html += '<div class="column left first" ondrop="drop(event)" >';
html += '<ul class="sortable-list" id="pakageItemsUl_' + i + '">';
html += '</ul> ';
html += '</div>';
}
$('#PositonsDiv').html(html);
JavaScript events should be applied separately; you can't enable them inside document fragments:
for (i = 0; i < positions.length; i++) {
var $list = $('<ul class="sortable-list"></ul>')
.prop('id', 'packageItemsUl_' + i);
$('<div class="column left first"></div>')
.on('drop', drop)
.append($list)
.appendTo('#PositionsDiv');
}
I am appending html to a <ul> on an ajax success function.
HTML
<ul id="revisionList">
<!-- ajax.js will insert ordered list here based on number of revisions -->
</ul>
Ajax Success
success: function(json)
{
/*
If successful build the list of revision links
Links include link that will load images in next tab
*/
//loop through revisions and display
for(i = 0, j = json.revision_count.length; i < j; i++) {
//count for revision number
var k = i + 1;
//revision number, does not match k
var revisionID = json.revision_count[i].layout;
$('#revisionList').append(
"<li><a onclick=\"initEditRevision(" + galleryID + ',' + revisionID + ")\" href=\"#editRev\" data-toggle=\"tab\">Revision " + k + "</a></li>"
);
}
}
How do I go about fading in the whole <ul> after the list is built?
Try this
success: function(json) {
var $list = $('#revisionList');
$list.hide(); // Hide Here
for (i = 0, j = json.revision_count.length; i < j; i++) {
var k = i + 1;
var revisionID = json.revision_count[i].layout;
$list
.append("<li><a onclick=\"initEditRevision(" + galleryID + ',' +
revisionID + ")\" href=\"#editRev\"
data-toggle=\"tab\">Revision " + k + "</a></li>");
}
$list.fadeIn('slow'); // Fade In here
}
for (...
}
$("#revisionList").hide().fadeIn();
Or perhaps you can hide it before the for loop; whatever works best.
You have to hide it using CSS display property firstly or using style attribute if you don't want to use CSS.
#revisionList{display: none;}
OR
<ul id="revisionList" style="display: none;">
then fade in after that all lis appnded completely.
$("#revisionList").fadeIn(500);