JavaScript appendChild for element not working - javascript

I am attempting to use JavaScript to dynamically append child elements (li elements) into an existing list.
Target DOM:
<body>
<div class="dd" name="agenda-nestable" id="nestable">
<ol id="agenda-root" class="dd-list">
<li class="dd-item" id="2879">
<div class="dd-handle">Section123</div>
</li>
<li class="dd-item" id="2880">
<div class="dd-handle">Section 4</div>
</li>
<li class="dd-item" id="2881">
<div class="dd-handle">Section 5</div>
</li>
</ol>
</div>
<button value onclick='addSection()'>Add Section</button>
</body>
JavaScript:
function addSection() {
var data = { SectionId: 123, SectionText: 'Section Name'};
var agendaDiv = $("[name='agenda-nestable']");
var agendaSections = $(agendaDiv).find("ol#agenda-root");
agendaSections.appendChild('<li class="dd-item" data-id="' + data.SectionId + '" id="' + data.SectionId + '">' +
'<div class="dd-handle">' + data.SectionText + "</div></li>");
}
Plunk: https://plnkr.co/edit/jLi9epblNAtMbzezcRSY?p=preview
Could someone please take a look and let me know what I am doing wrong? It seems like it should be straightforward, and I believe I am traversing the DOM correctly. :-/
Thanks,
Philip

appendChild isn’t a jQuery function; it’s part of the DOM API, and you can only use it on DOM nodes. jQuery objects aren’t DOM nodes. There’s no reason to be manipulating HTML in the first place, though, when you can create an actual <li> element:
agendaSections.append(
$('<li>', {
class: "dd-item",
'data-id': data.SectionId,
id: data.SectionId,
}).append(
$('<div>', { class: 'dd-handle', text: data.SectionText })
)
);
This also prevents HTML injection if SectionText is user-provided data.

Try to replace appendChild() to append():
JSfiddle Demo
function addSection() {
var data = { SectionId: 123, SectionText: 'Section Name'};
var agendaDiv = $("[name='agenda-nestable']");
var agendaSections = $(agendaDiv).find("ol#agenda-root");
agendaSections.append('<li class="dd-item" data-id="' + data.SectionId + '" id="' + data.SectionId + '">' +
'<div class="dd-handle">' + data.SectionText + "</div></li>");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="dd" name="agenda-nestable" id="nestable">
<ol id="agenda-root" class="dd-list">
<li class="dd-item" id="2879">
<div class="dd-handle">Section123</div>
</li>
<li class="dd-item" id="2880">
<div class="dd-handle">Section 4</div>
</li>
<li class="dd-item" id="2881">
<div class="dd-handle">Section 5</div>
</li>
</ol>
</div>
<button value onclick='addSection()'>Add Section</button>
</body>

The method appendChild is from native js. agendaSections is a jQuery element, so you need to use append() method from jQuery.

Change your generateRemoveSectionDropDown method code to this:
function generateRemoveSectionDropDown() {
$("#nestable ol#agenda-root>li").each( function() {
$('#RemoveSectionId').append($('<option>', {text: $(this).text() }));
});
}
And add to your html this:
<select id="RemoveSectionId"></select>
It will work well.
See plunk.

Related

jquery - on hover li width id - show the matching id div

<ul class="level0">
<li class="level1" id="cat2441"></li>
<li class="level1" id="cat2450"></li>
<li class="level1" id="cat2455"></li>
</ul>
<div class="alles-zwei" id="new-cat2441"></div>
<div class="alles-zwei" id="new-cat2450"></div>
<div class="alles-zwei" id="new-cat2455"></div>
Hallo, on hover the li(id) element I would like to show the matching div(id) – and hover an another li (wrong id) or leaving the ul I would like to hide the div
my approach was
jQuery('.alles li').mouseover(function() {
var cat = '"#new-' + this.id + '"';
jQuery(cat).fadeIn();
});
You were using the wrong selectors. Also '"#new-' + this.id + '"' this syntax is wrong. There is no need to add those double quotes inside the string.
jQuery('.level0 li').hover(function() {
var cat = '#new-' + this.id;
jQuery(cat).show();
}, function() {
var cat = '#new-' + this.id;
jQuery(cat).hide();
});
.alles-zwei {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul class="level0">
<li class="level1" id="cat2441">cat2441</li>
<li class="level1" id="cat2450">cat2450</li>
<li class="level1" id="cat2455">cat2455</li>
</ul>
<div class="alles-zwei" id="new-cat2441">cat2441</div>
<div class="alles-zwei" id="new-cat2450">cat2450</div>
<div class="alles-zwei" id="new-cat2455">cat2455</div>
You could do this without having to rely on the id of the element just use the class of the two elements. When you select the class it gets returned as an array so you can match the level1 class array with the alles-zwei class array. It will also simplify your HTML code.
$('.level1').hover(function(){
// Gets the index of the current li emement.
var indx = $(this).index();
// Gets the div element based on the hovered li and hides its siblings.
$('.alles-zwei').eq(indx).show().siblings('div').hide();
});

showing a particular div dynamically on a html page

I want to show only a particular div by calling a function though onclick event .At a time I just want to show a single div and rest all divs should not show in my web page. I have tried this through using display css property.I just want a single function which can handle this .I can do this question by making more than one function.
<html>
<head>
</head>
<body>
<ul>
<li>1</li><!-- show div1-->
<li>2</li><!-- show div2-->
<li>3</li><!-- show div3-->
</ul>
<div id="first">content 1</div>
<div id="second">content2</div>
<div id="third">content3</div>
</body>
</html>
How about this:
Each div needs the same class so you can find and hide them all at once.
The function needs to know the id of the div to show, so pass in the id.
See changes below:
<html>
<head>
</head>
<body>
<ul id="controls">
<li>1</li><!-- show div1-->
<li>2</li><!-- show div2-->
<li>3</li><!-- show div3-->
</ul>
<div id="first" class="content">content 1</div>
<div id="second" class="content">content2</div>
<div id="third" class="content">content3</div>
<script>
$("#controls a").click(function() {
someFunction($(this).attr("data-target"));
});
function someFunction(divId) {
$(".content").hide();
$("#" + divId).show();
}
</script>
</body>
</html>
Note: You need a reference to jQuery for the $ syntax to work.
FYI, you could do this with just CSS:
.panel {display: none}
.panel:target {display: block}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<div class='panel' id="first">content 1</div>
<div class='panel' id="second">content2</div>
<div class='panel' id="third">content3</div>
I think this is what you want:
<ul>
<li id="li_1">1
</li>
<li id="li_2">2
</li>
<li id="li_3">3
</li>
</ul>
<div class='panel' id="li_1_panel">content 1</div>
<div class='panel' id="li_2_panel">content2</div>
<div class='panel' id="li_3_panel">content3</div>
.panel {
display: none;
}
var panelID = "";
for (i = 1; i <= 3; i++) {
alert('#li_' + i);
$('#li_' + i).on('click', function () {
panelID = "#" + $(this).attr("id") + "_panel";
alert(panelID);
$(panelID).toggle();
});
}
Edit
Also, if you did not want to rely on a rigid naming scheme, you could use a hash.
<ul>
<li id="zeus">1
</li>
<li id="athena">2
</li>
<li id="hades">3
</li>
</ul>
<div class='panel' id="isis">content 1</div>
<div class='panel' id="thor">content 2</div>
<div class='panel' id="aphrodite">content 3</div>
var panelID = "";
var li_to_panel = {
"zeus": "isis",
"athena": "thor",
"hades": "aphrodite"
};
$.each(li_to_panel, function(key, value){
alert(key);
liID = "#" + key;
$(liID).on('click', function () {
panelID = "#" + li_to_panel[$(this).attr('id')];
alert(panelID);
$(panelID).toggle();
});
});

Keep beautified indentation structure when putting html into a variable?

Beginning at coding, JS, today I inject an HTML template several times into the HTML thanks to JS. However, I'am confused by the systematic need to minify the html indentation and fold all the dozen(s) of lines --div, h1, span, table, tr, td, tt-- into a single var line. Minified html is both harder to ready and frequently need to be beautified back along the testing phase.
Also: is there a way to keep Beautified indented html in variable ?
Some syntaxe to have a valid version of:
var exampleTpl = "
<div data-demo-html="true">
<div data-role="collapsible-set" data-inset="true" data-theme="b" data-content-theme="d">
<div data-role="collapsible" data-collapsed="false">
<h4>Heading</h4>
<ul data-role="listview" data-filter="false" data-inset="true">
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
</div>
"
Best thanks in advance,
For templating purpose, you should have a look at the example on Handlebars.js homepage :
Declare your template
<script id="entry-template" type="text/x-handlebars-template">
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{body}}
</div>
</div>
</script>
Compile a template in JavaScript
var source = $("#entry-template").html();
var template = Handlebars.compile(source);
Inflate the HTML
var context = {title: "My New Post", body: "This is my first post!"}
var html = template(context);
This will result in an instance of your template (value injected into your template) :
<div class="entry">
<h1>My New Post</h1>
<div class="body">
This is my first post!
</div>
</div>
You COULD do it like this:
var exampleTpl =
'<div data-demo-html="true">' +
'<div data-role="collapsible-set" data-inset="true" data-theme="b" data-content-theme="d">' +
'<div data-role="collapsible" data-collapsed="false">' +
'<h4>Heading</h4>' +
'<ul data-role="listview" data-filter="false" data-inset="true">' +
'<li>List item 1</li>' +
'<li>List item 2</li>' +
'<li>List item 3</li>' +
'</ul>' +
'</div>' +
'</div>' +
'</div>';
If you really wanted...
However, if you're representing a template in mustache JS (just looking at your tags there), I personally add the templates into a script element, and then access them using innerHTML as is suggested by some templating libraries (such as handlebarsjs.com).
eg:
<script type="text/html" id="myTemplate">
<div data-demo-html="true">
<div data-role="collapsible-set" data-inset="true" data-theme="b" data-content-theme="d">
<div data-role="collapsible" data-collapsed="false">
<h4>Heading</h4>
<ul data-role="listview" data-filter="false" data-inset="true">
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
</div>
</div>
</div>
</script>

Appending wrapped elements doesn't include wrapper

I am trying understand why the .wrap() function in my basic table of contents function isn't working. The function filters headers from a textarea and places them in an iframe, and the basic part works. But whereas my desired output is this:
<ul>
<li class="toc_h2">This is an h2</li>
<li class="toc_h3">This is an h3</li>
<li class="toc_h1">This is an h1</li>
</ul>
What I am actually getting is this:
<ul>
<h2>This is an h2</h2>
<h3>This is an h3</h3>
<h1>This is an h1</h1>
</ul>
How can I fix this/what am I misunderstanding? The code is here and at http://jsfiddle.net/supertrue/JgWxJ/
headers.each(function(i) {
$(this).wrap('<li class="toc_' + this.nodeName.toLowerCase() + '"></li>').appendTo(toc);
});
You can change this:
$(this).wrap('<li class="toc_' + this.nodeName.toLowerCase() + '"></li>').appendTo(toc);
to this:
$('<li class="toc_' + this.nodeName.toLowerCase() + '"></li>').html(this).appendTo(toc);
Here's your fiddle: http://jsfiddle.net/JgWxJ/7/
Alternatively, you could just add .parent() before appending:
$(this).wrap('<li class="toc_' + this.nodeName.toLowerCase() + '"></li>').parent().appendTo(toc);
...and here's the fiddle: http://jsfiddle.net/JgWxJ/10/

jQuery append() and data()

I have unknown number of divs with increasing ID's:
<div id="source-1" data-grab="someURL"/>Content</div>
<div id="source-2" data-grab="anotherURL"/>Content</div>
<div id="source-3" data-grab="anddifferentURL"/>Content</div>
<div id="source-4" data-grab="andthelastoneURL"/>Content</div>
And I have another list:
<ul>
<li id="target-1" class="target"> </li>
<li id="target-2" class="target"> </li>
<li id="target-3" class="target"> </li>
<li id="target-4" class="target"> </li>
</ul>
Now, what I want to achive is grabbing data-grab URL from source-1 and append it to target-1 as a image and so forth. So finally the output list will look just like:
<ul>
<li id="target-1"><img src="someURL" /> </li>
<li id="target-2"><img src="anotherURL" /> </li>
<li id="target-3"><img src="anddifferentURL" /> </li>
<li id="target-4"><img src="andthelastoneURL" /> </li>
</ul>
I'm grabbing all the data from the first list, but I'm not sure how to append right source element to right target element?
$(document).ready(function(){
$('.target').each(function(){
var URL = jQuery(this).data('grab');
});
});
$(document).ready(function(){
$('.target').each(function(){
var $this = $(this);
var divID = "source-" + ($this.id()).split("-")[1];
$("a", $this).append('<img src="' + $(divID).data("grab") + '" />');
});
});
You can use indices to select the right elements, if you add a class to your source elements (like .source):
$(document).ready(function(){
var targets = $( '.target' );
$('.source').each(function(index, value){
$(target[index]).children("a").first().append($("<img src=" + value.data('grab') + " />"));
});
});

Categories