var htmlComponent = [
{
element : 'button',
text : "Addition"
},
{
element : 'h1',
text : "This is the heading"
},
{
element : 'p',
text : "This is the paragraph."
}
];
htmlComponent.forEach(function(item) {
// Problem here
document.body.appendChild(document.createElement(item.element).appendChild(document.createTextNode(item.text)));
}
Actually I wanted to create an html element using DOM Object but this is not working. I mean my code is not working properly..
but when I changed something Like that:
htmlComponent.forEach(function(item) {
var _element = document.createElement(item.element);
var text = document.createTextNode(item.text);
_element.appendChild(text);
document.body.appendChild(_element);
}
Then the code is working.
Here the main question is why 2nd code is working and the 1st one is not working...... what is the problem in my code.
please Explain me........
You are chaining the calls together like body.createElement().appendChild() where you shouldn't.
This works with createElement() because it returns the element you want to append to, but it doesn't work with appendChild() because that returns the child you just appended, which you are then appending again to the body.
This programming style is known as a "fluent" interface. It is supported by some libraries e.g. jQuery, but not by native Javascript DOM functions.
See https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild
Try as follows
appendChild does not return parent
var htmlComponent = [{
element: 'button',
text: "Addition"
},
{
element: 'h1',
text: "This is the heading"
},
{
element: 'p',
text: "This is the paragraph."
}
];
htmlComponent.forEach(function(element) {
var btn = document.createElement(element.element);
var t = document.createTextNode(element.text);
btn.appendChild(t);
document.body.appendChild(btn);
});
According to the documentation for appendChild:
The returned value is the appended child except when the given child
is a DocumentFragment, in which case the empty DocumentFragment is
returned.
You are appending a text node to the button, then trying to append the returned result to the body. This is the reason why you are not seeing the button being appended to the body.
If you break it down like this, it's easier to see what's going on:
document.body.appendChild(
// createElement returns button
document.createElement("button")
// button.appendChild then returns the appended child (a text node)
.appendChild(document.createTextNode("text"))
)
Related
Since I want to use classes instead of id's in these functions(I have three of the same function with different things I want to .append) I am sure I need to put $(this) in those functions somewhere to only trigger only ONE function on button click and not all three of them. but I am not sure because I am a total beginner in jquery/js, so I would appreciate some help.
$(document).ready(function () {
$(".onclick").click(function () {
$('#favorites').append('<div data-role="main"class="ui-content"><div class="ui-grid-b"><div class="ui-block-a">Arrow</div><div class="ui-block-b">More Info</div><div class="ui-block-c">Unfavorite</div></div></div>');
});
});
http://codepen.io/anon/pen/JYxqEw - HTML And the Jquery Code
$('.onclick') selects all the elements with a class of onclick. That means that, whenever something with class="onclick" is clicked, that function will fire.
If you want all of those elements to append that exact HTML to the #favorites element, then you can leave your code as-is.
However, if what you're trying to do is append that html to the clicked element, that is when you'd use $(this) -- that selects the element you clicked with jQuery, then you can append directly to that element ie:
$(document).ready(function () {
$(".onclick").click(function () {
// this will append the HTML to the element that triggered the click event.
$(this).append('<div data-role="main"class="ui-content"><div class="ui-grid-b"><div class="ui-block-a">Arrow</div><div class="ui-block-b">More Info</div><div class="ui-block-c">Unfavorite</div></div></div>');
});
});
EDIT
so to insert the contents of each .onclick into #favorites, you'll need to use the innerHTML value of the DOM node. example fiddle:
http://jsbin.com/qazepubuzu/edit?html,js,output
When you select something with jQuery, you're actually getting back not just the DOM node, but a jQuery object -- this object contains both a reference to the actual DOM node ([0]), as well as a jquery object ([1]).
So to select the DOM node with $(this), you target the node: $(this)[0]. Then you can use .innerHTML() to grab the HTML contents of the node and do as you like.
Final result:
$(function () {
$('.onclick').click(function () {
$('#favorites').append( $(this)[0].innerHTML );
});
});
So the building blocks are not that complex, but I think you're a novice jQuery developer and so you may not be clear on the difference between jQuery and JS yet.
$(selector, context) allows us to create a jQuery collection for a CSS selector which is the child of a current context DOM node, though if you do not specify one there is an automatic one (which is document.body, I think). Various functions iterating over jQuery collections make the particular element available as this within the JavaScript. To get to the strong element from the .onclick element in the HTML fragment you need to travel up in the hierarchy, then to the appropriate element. Then, we can collect the text from the element. We can do this in either JS or jQuery.
To do this with simply jQuery:
// AP style title case, because Chicago is too crazy.
var to_title_case = (function () { // variable scope bracket
var lower_case = /\b(?:a|an|the|and|for|in|so|nor|to|at|of|up|but|on|yet|by|or)\b/i,
first_word = /^(\W*)(\w*)/,
last_word = /(\w*)(\W*)$/;
function capitalize(word) {
return word.slice(0, 1).toUpperCase() + word.slice(1).toLowerCase();
}
function capitalize_mid(word) {
return lower_case.exec(word) ? word.toLowerCase() : capitalize(word);
}
return function to_title_case(str) {
var prefix = first_word.exec(str),
str_minus_prefix = str.slice(prefix[0].length),
suffix = last_word.exec(str_minus_prefix),
center = str_minus_prefix.slice(0, -suffix[0].length);
return prefix[1] + capitalize(prefix[2]) + center.replace(/\w+/g, capitalize_mid)
+ capitalize(suffix[1]) + suffix[2];
};
})();
$(document).ready(function() {
$(".onclick").click(function () {
var text = $(this).parents('.ui-grid-a').find('.ui-block-a').text();
var html = '<div data-role="main"class="ui-content">'
+ '<div class="ui-grid-b"><div class="ui-block-a">'
+ to_title_case(text) + '</div><div class="ui-block-b">More Info</div>'
+ '<div class="ui-block-c">Unfavorite</div></div></div>';
$("#favorites").append(html);
});
});
I created a tinymce menu item and what I want it to do is add a class to the selected text element. I cannot seem to figure out how to do this. Any suggestions?
Adding my menu item looks like this:
tinymce.PluginManager.add('button', function(editor, url) {
editor.addMenuItem('button', {
icon: '',
text: 'Button',
onclick: function() {
tinyMCE.activeEditor.dom.addClass(tinyMCE.activeEditor.selection, 'test'); //not working
},
context: 'insert',
prependToContext: true
});
});
I'd be very thankful for any helpful hint.
I found a solution that may not be perfect (for example, if you select part of a text then this doesn't work as I hoped), but for now it does what I want:
tinyMCE.activeEditor.dom.addClass(tinyMCE.activeEditor.selection.getNode(), 'test');
if I do this on a link, for example, the scripts add the classname "test" to my tag.
In order to be able to add a class to the editor you need a dom element in the editor to add the class to. Textnodes may not hold a class.
So i propose you insert a span element with the class you want to add wrapped around the actual selection. Be aware that this won't work if the selection leaps over paragraph boundaries (in this case you will need a bit more complicated code). Try this:
onclick: function() {
var ed = tinyMCE.activeEditor;
var content = ed.selection.getContent({'format':'html'});
var new_selection_content = '<span class="test">' + content + '</span>';
ed.execCommand('insertHTML', false, new_selection_content);
},
this works for me:
setup: function(editor) {
editor.ui.registry.addButton("addClassBtn", {
icon: "insertdatetime",
text: "Highlight ",
onAction: function (_) {
var newContent = "<span class='test'>" + editor.selection.getContent() + "</span>";
editor.selection.setContent(newContent);
}
}
}
I use the following code to get a sap.ui.commons.TreeNode and to select it.
var newNode = this.tree.getNodes()[typeIdx].getNodes()[typeArray.length - 1];
newNode.select();
Unfortunately though, nothing happens. While newNode.getIsSelected() returns true, no handlers are executed (neither select on the tree nor selected on the node).
P.S. I made sure newNode.getSelectable() is true.
Did anyone use TreeNode's select() method sucessfully?
Code example
Here is an example
Adding an element does highlight the element but the alert is only shown when clicking with the mouse.
Here's an example of how this works.
Here's the function that we want to call on the node selection:
var sel = function(oEvent) {
console.log(oEvent.getSource().getText() + " selected");
};
And here's the tree with some nodes, nodes 1.1 and 1.2 have the handler:
new sap.ui.commons.Tree("tree", {
nodes: [
new sap.ui.commons.TreeNode({
text: "1",
nodes: [
new sap.ui.commons.TreeNode({
text: "1.1",
selected: sel
}),
new sap.ui.commons.TreeNode({
text: "1.2",
selected: sel
})
]
}),
new sap.ui.commons.TreeNode({
text: "2"
})
]
}).placeAt("content");
And when we do this (based on your example):
newNode = sap.ui.getCore().byId("tree").getNodes()[0].getNodes()[0]
newNode.select()
we get
1.1 selected
in the console, and the the node is highlighted.
Can you try using newNode.setIsSelected(true); That works for me
Best,
Robin
Having read the exact requirement (the event onSelect not being fired), I think there were two things missing:
the fireSelected event was not explicitly fired
the select event was set on the Tree element rather than the TreeNode template
I have updated your example to a new version: http://jsbin.com/hososexu/7/edit
I create a textarea and a button on a loop based on a certain condition:
while($row_c= mysqli_fetch_array($result_comments))
{
//some code goes here
<textarea type="text" id="pm_text" name="text"></textarea><br>
<button name="send_comment" id="post_comment" class="button" onClick="post_pm_comment()">Post</button>
}
Now in my function "post_pm_comment" I would like to access the text written in the textarea when the post button is clicked.
I tried this, but it only gives me the text of the first textarea and button created:
function post_pm_comment(thidid, pm_id, path, pm,getter)
{
var pm_text = document.getElementById("pm_text").value;
}
What should I do?
Thank you
Your code is outputting an invalid DOM structure, because id values must be unique on the page. You cannot have the same id on more than one element. Remove the id values entirely, you don't need them.
Having done that, the minimal-changes answer is to pass this into your handler:
onClick="post_pm_comment(this)"
...and then in your handler, do the navigation:
function post_pm_comment(postButton)
{
var pm_text;
var textarea = postButton.previousSibling;
while (textarea && textarea.nodeName.toUpperCase() !== "TEXTAREA") {
textarea = textarea.previousSibling;
}
if (textarea) {
pm_text = textarea.value; // Or you may want .innerHTML instead
// Do something with it
}
}
Live Example | Source
I created a custom jquery event called 'loading' in my application. I want to append a masking element with a spinner, when this event is triggered. I can figure out that part without problems. However, some elements (images, form inputs, etc..) cannot append child elements. I need to be able to detect if the target of this event can receive child elements. If it cannot, then I will add the spinner & mask to it's parent element.
You have to check the name:
/*global $, jQuery */
function isVoid(el) {
var tags = ['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input',
'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'],
i = 0,
l,
name;
if (el instanceof jQuery) {
el = el[0];
}
name = el.nodeName.toLowerCase();
for (i = 0, l = tags.length; i < l; i += 1) {
if (tags[i] === name) {
return true;
}
}
return false;
}
And use it like this:
var el = document.getElementById('el'),
elj = $('#el');
if (!isVoid(el)) {
// append
}
You can add child elements, they just won't render. This may sound like a semantic distinction, but it's critical to your problem: the DOM doesn't know whether a particular tag is rendered or not.
Your best bet is just to check manual:
var allowChildren = function(elem) {
return ! (elem.nodeName in { INPUT : true, IMG : true }) ;
};
http://jsfiddle.net/mblase75/eGyRH/3/ -- Chrome lets me add a child element to an <input> tag, even though it's not displayed at all. It's visible in the DOM debugger, just not in the browser window.
However, I can test it's .width() and see that's equal to zero or not: http://jsfiddle.net/mblase75/eGyRH/4/
alert($('.element').append('<span>asdf</span>').children().width());
However, this will also be zero width if, for instance, I'm adding the span to a hidden div: http://jsfiddle.net/mblase75/eGyRH/5/ -- so it's not totally reliable either.
The accepted answer has a very nice fuction based on which types of nodes can be void. It can be replaced by a jQuery one-liner:
node.is("area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr")