Create element inside of parent element in Dojo - javascript

I can create a div inside the body like so:
var n = dojo.create("div", { innerHTML: "<p>helloWorld</p>" }, dojo.body());
I would like to create a div inside of my parent element such as this:
<div id="parent"></div>
I have tried this but it doesn't seem to work:
var n = dojo.create("div", { innerHTML: "<p>helloWorld</p>" }, dojo.query('#parent'));
How can I create my div inside of my parent div which already exists in the DOM?

The solution you posted is entirely valid. A couple of alternatives:
No need to look up the dom node, you can pass in a String (the id of the node)
require(["dojo/dom-construct"], function(domConstruct){
var n = domConstruct.create("div", { innerHTML: "<p>helloWorld</p>" }, 'parent');
});
Or you could construct the node and place it later using domConstruct#place:
require(["dojo/dom-construct"], function(domConstruct){
var n = domConstruct.create("div", { innerHTML: "<p>helloWorld</p>" });
domConstruct.place(n, 'parent');
});
domConstruct#place can also take an optional position parameter. The API Docs have more information on it

Should you need to target a class instead of a element id, I found the following to be and effective and easy to maintain method:
require([
'dojo/query',
'dojo/dom-construct'
], function(
query,
domConstruct,
){
var parent = query('.someClass')[0];
var child = domConstruct.create('div', { innerHTML: '<p>helloWorld</p>'});
domConstruct.place(child, parent, 'position');
});
Given it is always better to target an id instead of a class, but in cases when you are relying on outside libraries that isn't always viable.

The way I did it was this (I am open to any other solutions):
// dojo 1.7+ (AMD)
require(["dojo/dom-construct"], function(domConstruct){
var n = domConstruct.create("div", { innerHTML: "<p>helloWorld</p>" }, dojo.byId('parent'));
});
// dojo < 1.7
var n = dojo.create("div", { innerHTML: "<p>helloWorld</p>" }, dojo.byId('parent'));

Related

Creating the multiple div dynamically using Javascript

I have div element and have a class for it. I want to create multiple div using that class, but I don't want to create nested div, I want to create div outside using Javascript. I used append property, but its create nested div below is html as I required. I need help.
//have this div
<div data-bind="dynamicDiv" class="one"></div>
//need to create multiple div
//Knockoutjs && javascript//
ko.bindingHandlers.dynamicDiv = {
init: function (element, valueAccessor) {
var parentclassName = element.className;
lastId += 1;
///it is creating nested div, want to create outside of parentclass not inside the parent class
$element.append(DivHtml(lastId,parentclassName));
},
};
function DivHtml(lastId,parentclassName) {
Newdiv = document.createElement('div');
Newdiv.id = "divId_"+lastId
document.querySelector("." + parentclassName).appendChild(Newdiv)
}
Fixes for your current code:
In DivHtml, the third line should be return NewDiv
init should append to element.parentElement using appendChild
You never define $element, it should be just element or $(element)
But even if you fix this, I don't understand what you're trying to achieve.
Your example doesn't really show why you'd need a custom binding handler for this. Seems to me that knockout's default bindings should suffice:
<div data-bind="attr: { id: 'divId_' + ++lastId }" class="one"></div>
If you need to copy the class name dynamically, I'd take care of that in a view model if I were you. Look in to the template and foreach bindings as well.
var className = "one";
var idPrefix = "divId_";
var nrOfElements = 5;
var elements = [];
for (var i = 0; i < nrOfElements; i += 1) {
elements.push({
className: className,
id: idPrefix + i
});
};
ko.applyBindings({items: elements });
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="foreach: elements">
<div data-bind="attr: { id: id, 'class': className }, text: id"></div>
</div>

How to get jQuery elements after declairation

I have created Tr with jQuery as below
var elemTr = $("<tr>", {
});
var elemEmpName = $("<div>", { }).data('otherDtls', {
recordId: 10
});;
Then in elemTr appended elemEmpName
elemTr.append(jQuery("<td>", {}).append(elemEmpName));
There are n no of elemTr which will be displayed inside Table
Now if I have "elemTr" -- How should I get "elemEmpName" which is present inside it, So I can get 'otherDtls' associated with it.
elemTr.find('td div').data('otherDtls')
You can use initial reference to do that.
// wrap it in jQuery so it becomes a collection
var elemEmpName = $("<div>", { }).data('otherDtls', {
recordId: 10
});;
// append to the DOM
elemTr.append(jQuery("<td>", {}).append(elemEmpName));
// do stuff, using the initial reference
$(elemEmpName).find('otherDtls');//do something

How to hide an element, based on its text, with JavaScript?

I'm a beginner developer. I'm trying to hide a div that is dynamically added to the page by a 3rd party JavaScript for aesthetic purposes.
The problem is that the div has no id attribute; is this even possible? Do divs have any inherent attributes based on the order in which they load? Or is there any way to search for a string of text and hide the element?
For example, removing <div>happy New year</div> based on its text happy New year.
You can select the relevant elements first and iterate through them until you find what you want.
In JQuery it can be done like this:
// select relevant elements
var elements = $('div');
// go through the elements and find the one with the value
elements.each(function(index, domElement) {
var $element = $(domElement);
// does the element have the text we're looking for?
if ($element.text() === "happy New year") {
$element.hide();
// hide the element with jQuery
return false;
// jump out of the each
}
});
Note that the code is a bit brittle and completely depends on the contents of the elements. Here are the relevant JQuery api docs:
Selectors in jQuery ($(...))
jQuery.each() - for going through the jquery objects array
jQuery.text() - for getting the value (there are small but noticable discrepancies between the browsers on how you do this in plain javascript)
jQuery.hide() - for hiding the element with CSS style display: none
Note that you can be more specific with your selection say you have the following code:
<div class="message">
<div>happy New year<div>
</div>
You can select the element with:
var domElement = $('.message div')[0]; // hopefully it only happens once
I thought I'd offer a plain-JavaScript alternative, which could be improved (quite a bit), particularly the passing of Booleans as strings (which feels hideous):
function hideByText(text, opts) {
if (!text) {
return false;
}
else {
var defaults = {
// the element we look within, expects:
// 1: node reference, eg the result of: document.getElementsByTagName('div')[0]
// 2: an element's id, as a string, eg: 'test'
'within': document.body,
// the element type, eg 'div', 'span', 'p', defaults to *everything*
'elemType': '*',
// case-sensitivity, as a string:
// 'true' : is case sensitive, 'Some' will not match 'some',
// 'false' : is case insensitive, 'Some' will match 'some'
'sensitive': 'true',
// 'absolute' : 'some text' will not match 'some text.'
// 'partial' : 'some text' will match 'some text.'
'match': 'absolute',
// 'true' : removes white-space from beginning, and end, of the text,
// 'false' : does not remove white-space
'trim': 'true',
// the class to add to elements if a match is made,
// use CSS to hide, or style, the matched elements
'matchedClass': 'hasText'
},
opts = opts || {};
for (var setting in defaults) {
if (defaults.hasOwnProperty(setting)) {
opts[setting] = opts[setting] || defaults[setting];
}
}
var within = opts.within.nodeType == 1 ? opts.within : document.getElementById(opts.within),
elems = within.getElementsByTagName(opts.elemType),
flags = opts.sensitive == 'true' ? 'i' : '',
needle = opts.trim == 'true' ? text.replace(/^(\s+) || (\s+)$/g, '') : text,
haystack,
reg = new RegExp(needle, flags);
if (opts.match == 'absolute') {
for (var i = 0, len = elems.length; i < len; i++) {
if ((elems[i].textContent || elems[i].innerText) == text) {
elems[i].className = opts.matchedClass;
}
}
}
else if (opts.match == 'partial') {
for (var i = 0, len = elems.length; i < len; i++) {
if ((elems[i].textContent || elems[i].innerText).match(reg)) {
elems[i].className = opts.matchedClass;
}
}
}
}
}
hideByText('some text', {
'match': 'partial',
'sensitive': 'true',
'elemType': 'p',
'matchedClass' : 'hasText'
});​
JS Fiddle demo.
A previous answer will hide a node based on the combined text content (see .text() behavior). The following test cases will illustrate this:
should stay: <div><em>happy New year</em></div><br>
should stay: <div>happy New years</div><br>
should stay: <div>happy New <em>year</em></div><br>
should stay: <div>Something else entirely</div><br>
should hide: <div>happy New year</div>
Shown here: jsFiddle
Depending on the details of your situation, this more general behavior may be what you want as it will ignore descendant structure and only match against the combined text. But, if you need to hide the <div> that specifically contains the text, something like the following will hide only the last <div> from the test cases:
var tx = 'happy New year';
$('div:contains(' + tx + ')').filter(function(){
var $content = $(this).contents();
return $content.length === 1 &&
$content[0].nodeType === 3 &&
$content.text() === tx;
}).hide();
Shown here: jsFiddle
The initial selector can be modified to hide anything that contains the specific text. This more general approach will hide the <em> element in the first case and the <div> element in the last case:
$(':contains(' + tx + ')').filter(// etc...
You might consider removing the element from the DOM instead of only hiding it.
:contains() jQuery selector
.filter() jQuery method
.contents() jQuery method
nodeType Node property
.remove() jQuery method
You can actually do it using one line
$("div").text("happy New year").hide();

How to change text inside span with jQuery, leaving other span contained nodes intact?

I have the following HTML snippet:
<span class="target">Change me <a class="changeme" href="#">now</a></span>
I'd like to change the text node (i.e. "Change me ") inside the span from jQuery, while leaving the nested <a> tag with all attributes etc. intact. My initial huch was to use .text(...) on the span node, but as it turns out this will replace the whole inner part with the passed textual content.
I solved this with first cloning the <a> tag, then setting the new text content of <span> (which will remove the original <a> tag), and finally appending the cloned <a> tag to my <span>. This works, but feels such an overkill for a simple task like this. Btw. I can't guarantee that there will be an initial text node inside the span - it might be empty, just like:
<span class="target"><a class="changeme" href="#">now</a></span>
I did a jsfiddle too. So, what would be the neat way to do this?
Try something like:
$('a.changeme').on('click', function() {
$(this).closest('.target').contents().not(this).eq(0).replaceWith('Do it again ');
});
demo: http://jsfiddle.net/eEMGz/
ref: http://api.jquery.com/contents/
Update:
I guess I read your question wrong, and you're trying to replace the text if it's already there and inject it otherwise. For this, try:
$('a.changeme').on('click', function() {
var
$tmp = $(this).closest('.target').contents().not(this).eq(0),
dia = document.createTextNode('Do it again ');
$tmp.length > 0 ? $tmp.replaceWith(dia) : $(dia).insertBefore(this);
});
​Demo: http://jsfiddle.net/eEMGz/3/
You can use .contents():
//set the new text to replace the old text
var newText = 'New Text';
//bind `click` event handler to the `.changeme` elements
$('.changeme').on('click', function () {
//iterate over the nodes in this `<span>` element
$.each($(this).parent().contents(), function () {
//if the type of this node is undefined then it's a text node and we want to replace it
if (typeof this.tagName == 'undefined') {
//to replace the node we can use `.replaceWith()`
$(this).replaceWith(newText);
}
});
});​
Here is a demo: http://jsfiddle.net/jasper/PURHA/1/
Some docs for ya:
.contents(): http://api.jquery.com/contents
.replaceWith(): http://api.jquery.com/replacewith
typeof: https://developer.mozilla.org/en/JavaScript/Reference/Operators/typeof
Update
var newText = 'New Text';
$('a').on('click', function () {
$.each($(this).parent().contents(), function () {
if (typeof this.tagName == 'undefined') {
//instead of replacing this node with the replacement string, just replace it with a blank string
$(this).replaceWith('');
}
});
//then add the replacement string to the `<span>` element regardless of it's initial state
$(this).parent().prepend(newText);
});​
Demo: http://jsfiddle.net/jasper/PURHA/2/
You can try this.
var $textNode, $parent;
$('.changeme').on('click', function(){
$parent = $(this).parent();
$textNode= $parent.contents().filter(function() {
return this.nodeType == 3;
});
if($textNode.length){
$textNode.replaceWith('Content changed')
}
else{
$parent.prepend('New content');
}
});
Working demo - http://jsfiddle.net/ShankarSangoli/yx5Ju/8/
You step out of jQuery because it doesn't help you to deal with text nodes. The following will remove the first child of every <span> element with class "target" if and only if it exists and is a text node.
Demo: http://jsfiddle.net/yx5Ju/11/
Code:
$('span.target').each(function() {
var firstChild = this.firstChild;
if (firstChild && firstChild.nodeType == 3) {
firstChild.data = "Do it again";
}
});
This is not a perfect example I guess, but you could use contents function.
console.log($("span.target").contents()[0].data);
You could wrap the text into a span ... but ...
try this.
http://jsfiddle.net/Y8tMk/
$(function(){
var txt = '';
$('.target').contents().each(function(){
if(this.nodeType==3){
this.textContent = 'done ';
}
});
});
You can change the native (non-jquery) data property of the object. Updated jsfiddle here: http://jsfiddle.net/elgreg/yx5Ju/2/
Something like:
$('a.changeme3').click(function(){
$('span.target3').contents().get(0).data = 'Do it again';
});
The contents() gets the innards and the get(0) gets us back to the original element and the .data is now a reference to the native js textnode. (I haven't tested this cross browser.)
This jsfiddle and answer are really just an expanded explanation of the answer to this question:
Change text-nodes text
$('a.changeme').click(function() {
var firstNode= $(this).parent().contents()[0];
if( firstNode.nodeType==3){
firstNode.nodeValue='New text';
}
})
EDIT: not sure what layout rules you need, update to test only first node, otherwise adapt as needed

How can I add a class to a DOM element in JavaScript?

How do I add a class for the div?
var new_row = document.createElement('div');
This answer was written/accepted a long time ago. Since then better, more comprehensive answers with examples have been submitted. You can find them by scrolling down. Below is the original accepted answer preserved for posterity.
new_row.className = "aClassName";
Here's more information on MDN: className
Use the .classList.add() method:
const element = document.querySelector('div.foo');
element.classList.add('bar');
console.log(element.className);
<div class="foo"></div>
This method is better than overwriting the className property, because it doesn't remove other classes and doesn't add the class if the element already has it.
You can also toggle or remove classes using element.classList (see the MDN documentation).
Here is working source code using a function approach.
<html>
<head>
<style>
.news{padding:10px; margin-top:2px;background-color:red;color:#fff;}
</style>
</head>
<body>
<div id="dd"></div>
<script>
(function(){
var countup = this;
var newNode = document.createElement('div');
newNode.className = 'textNode news content';
newNode.innerHTML = 'this created div contains a class while created!!!';
document.getElementById('dd').appendChild(newNode);
})();
</script>
</body>
</html>
3 ways to add a class to a DOM element in JavaScript
There are multiple ways of doing this. I will show you three ways to add classes and clarify some benefits of each way.
You can use any given method to add a class to your element, another way to check for, change or remove them.
The className way - Simple way to add a single or multiple classes and remove or change all classes.
The classList way - The way to manipulate classes; add, change or remove a single or multiple classes at the same time. They can easily be changed at any time in your code.
The DOM way - When writing code according to the DOM model, this gives a cleaner code and functions similar to the className way.
The className way
This is the simple way, storing all classes in a string. The string can easily be changed or appended.
// Create a div and add a class
var new_row = document.createElement("div");
new_row.className = "aClassName";
// Add another class. A space ' ' separates class names
new_row.className = "aClassName anotherClass";
// Another way of appending classes
new_row.className = new_row.className + " yetAClass";
If an element has a single class, checking for it is simple:
// Checking an element with a single class
new_row.className == "aClassName" ;
if ( new_row.className == "aClassName" )
// true
Removing all classes or changing them is very easy
// Changing all classes
new_row.className = "newClass";
// Removing all classes
new_row.className = "";
Searching for or removing a single class when multiple classes are used is difficult. You need to split the className string into an array, search them through one by one, remove the one you need and add all others back to your element. The classList way addresses this problem and can be used even if the class was set the className way.
The classList way
It is easy to manipulate classes when you need to. You can add, remove or check for them as you wish! It can be used with single or multiple classes.
// Create a div and add a class
var new_row = document.createElement("div");
new_row.classList.add( "aClassName" );
// Add another class
new_row.classList.add( "anotherClass" );
// Add multiple classes
new_row.classList.add( "yetAClass", "moreClasses", "anyClass" );
// Check for a class
if ( new_row.classList.contains( "anotherClass" ) )
// true
// Remove a class or multiple classes
new_row.classList.remove( "anyClass" );
new_row.classList.remove( "yetAClass", "moreClasses" );
// Replace a class
new_row.classList.replace( "anotherClass", "newClass" );
// Toggle a class - add it if it does not exist or remove it if it exists
new_row.classList.toggle( "visible" );
Removing all classes or changing to a single class is easier done the className way.
The DOM way
If you write code the DOM way, this looks cleaner and stores classes in a string by setting the class attribute.
// Create a div, add it to the documet and set class
var new_row = document.createElement( "div" );
document.body.appendChild( new_row );
new_row.setAttribute( "class", "aClassName anotherClass" );
// Add some text
new_row.appendChild( document.createTextNode( "Some text" ) );
// Remove all classes
new_row.removeAttribute( "class" );
Checking for a class is simple, when a single class is being used
// Checking when a single class is used
if ( new_row.hasAttribute( "class" )
&& new_row.getAttribute( "class" ) == "anotherClass" )
// true
Checking for or removing a single class when multiple classes are used uses the same approach as the className way. But the classList way is easier to accomplish this and can be used, even if you set it the DOM way.
If doing a lot of element creations, you can create your own basic createElementWithClass function.
function createElementWithClass(type, className) {
const element = document.createElement(type);
element.className = className
return element;
}
Very basic I know, but being able to call the following is less cluttering.
const myDiv = createElementWithClass('div', 'some-class')
as opposed to a lot of
const element1 = document.createElement('div');
element.className = 'a-class-name'
over and over.
If you want to create multiple elements all with in one method.
function createElement(el, options, listen = [], appendTo){
let element = document.createElement(el);
Object.keys(options).forEach(function (k){
element[k] = options[k];
});
if(listen.length > 0){
listen.forEach(function(l){
element.addEventListener(l.event, l.f);
});
}
appendTo.append(element);
}
let main = document.getElementById('addHere');
createElement('button', {id: 'myBtn', className: 'btn btn-primary', textContent: 'Add Alert'}, [{
event: 'click',
f: function(){
createElement('div', {className: 'alert alert-success mt-2', textContent: 'Working' }, [], main);
}
}], main);
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
<div id="addHere" class="text-center mt-2"></div>
var newItem = document.createElement('div');
newItem.style = ('background-color:red');
newItem.className = ('new_class');
newItem.innerHTML = ('<img src="./profitly_files/TimCover1_bigger.jpg" width=50 height=50> some long text with ticker $DDSSD');
var list = document.getElementById('x-auto-1');
list.insertBefore(newItem, list.childNodes[0]);
Cross-browser solution
Note: The classList property is not supported in Internet Explorer 9. The following code will work in all browsers:
function addClass(id,classname) {
var element, name, arr;
element = document.getElementById(id);
arr = element.className.split(" ");
if (arr.indexOf(classname) == -1) { // check if class is already added
element.className += " " + classname;
}
}
addClass('div1','show')
Source: how to js add class
var new_row = document.createElement('div');
new_row.setAttribute("class", "YOUR_CLASS");
This will work ;-)
source
It is also worth taking a look at:
var el = document.getElementById('hello');
if(el) {
el.className += el.className ? ' someClass' : 'someClass';
}
If you want to create a new input field with for example file type:
// Create a new Input with type file and id='file-input'
var newFileInput = document.createElement('input');
// The new input file will have type 'file'
newFileInput.type = "file";
// The new input file will have class="w-95 mb-1" (width - 95%, margin-bottom: .25rem)
newFileInput.className = "w-95 mb-1"
The output will be: <input type="file" class="w-95 mb-1">
If you want to create a nested tag using JavaScript, the simplest way is with innerHtml:
var tag = document.createElement("li");
tag.innerHTML = '<span class="toggle">Jan</span>';
The output will be:
<li>
<span class="toggle">Jan</span>
</li>
<script>
document.getElementById('add-Box').addEventListener('click', function (event) {
let itemParent = document.getElementById('box-Parent');
let newItem = document.createElement('li');
newItem.className = 'box';
itemParent.appendChild(newItem);
})
</script>

Categories