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>
Related
I Know I can do this with static HTML, but I want to create dynamically, and I am struggling a lot.
Here is what I want to do:
I have 2 divs.
<div class="TxtTile">
</div>
<div class="pInfo">
</div>
Inside each div I want to have several paragraphs. Let's say 10, in each div.
The first div with class "TxtTile" i want to have the title of something, let's say titles like, age,country,experience,street etc.In the other div with class 'pInfo' I want to contain the information that corresponds with TxTtitle.
Like, age 25, experience 10 years etc, that will be taken from local Storage, where I already have it set up. This two divs will be next to each other, which I have already done with css.
For example.
Left side
<div class="TxtTile"> `<div class="pInfo">
<p class="styleforP"> <p class="styleforP">
Age 25
</p>
</p>
</div> </div>`
I would be happy if I can make this with native js.
There are two ways you can do this:
1) you can create an element and keep appending to its place
First get div element inside which you want to create new element, Here rather than having a class i would prefer to have id based selection of the element
var element = document.querySelector('.TxtTile');
Create a p element and add class to it, you can similarly add content inside it aswell
var pElem = document.createElement('p');
pElem.className = 'styleforP';
pElem.innerHTML = 'Age';
Append that created element inside your div
element.appendChild(pElem);
2) Create an HTML template pass your values to that template and create innerHTML and directly put that innerHTML into your parent element
var item = {
name: "My Name",
age: 30,
other: "Other Info"
}
var template = [];
template.push(
'<div class="row">',
'<span class="name-info">' + item.name + '</span>',
'<span class="age-info">' + item.age + '</span>',
'<span class="other-info">' + item.other + '</span>',
'</div>'
);
var htmlString = template.join('');
var element = document.querySelector('.TxtTile');
element.innerHTML = htmlString;
If you are going to add a lot of items then second approach is a lot better, as creating single element and appending them to DOM tree is quite slow, then passing whole HTML string.
var myData = {
title: "My title",
info: 25
};
// Store references to the wrapper elements
// The first element that has this class, or null if there aren't any
var titleWrapper = document.querySelector(".js-titleWrapper");
var infoWrapper = document.querySelector(".js-infoWrapper");
// Create the paragraph elements
var titleP = document.createElement("p");
var infoP = document.createElement("p");
// Add classes
titleP.classList.add("styleForP");
infoP.classList.add("styleForP");
// Add the text
titleP.innerText = myData.title;
infoP.innerText = myData.info;
// Add the paragraphs to their wrappers
titleWrapper.appendChild(titleP);
infoWrapper.appendChild(infoP);
<div class="TxtTile js-titleWrapper">
</div>
<div class="pInfo js-infoWrapper">
</div>
i think this is a bad idea for doing this if you have multiple records then you cant handle by querySlector.
good idea is create a parent element like this
<div id="parent"></div>
then get this element by javascript and then append this element with your dynamic records like this
var parentEle = document.getElementById("parent");
apply loop if records are multiple
var child = Document.createElement("div");
child.innerHTML = "<div class='TxtTile'>age</div><div class='pInfo'>25</div>";
parentEle.appendChild(child);
I have the following HTML code :
<div id="someId">
<div ng-transclude>
</div>
</div>
Really simple I am getting the div element which has ID attribute using the following function :
var getElementById = function (id) {
return angular.element("#" + id);
};
Where in this example case the ID is 'someId'. My goal is to get the div inside the one I just got. So I want to return the div with ng-transclude attribute. I believe that this will happen by getting an element by attribute name or something.
Thanks in advance.
PS: I can't put any other attributes in the div I wanted(like id) because in the real life it is far more complecated and the code is auto-generated.
I think this will help you
var getElementByAttribute = function (attribute) {
return angular.element(document).find('[' + attribute + ']');
};
var el = getElementByAttribute('ng-transclude')
I don't know if that will be the Angular way, but you can use native properties of the HTML element. Something like this:
var getElementById = function (id) {
return angular.element("#" + id);
};
var childDivWithTransclude = getElementById('someId').children[0];
I m new to jquey.I m facing a problem to attach data to particular inner div's. I am writing a demo code for the problem that i faced which did the same behaviour as original one. I have to small div inside a big div and i want to store (for some further processing) and show some data to small div's based on user input.
[html code]
<div id="ctrl-1001" class="big">
<div id="m1" class="small"></div>
<div id="m2" class="small"></div>
</div>
<div id="input" class="control-group module">
<label class="control-label">Module Name</label>
<div class="controls">
<select id="ModuleName" name="DSname" class="input-large">
<option>TitleImage</option>
<option>SearchBox</option>
<option>CategoryLinks</option>
<option selected>BannerSlides</option>
</select>
</div>
<button id="sa">save</button>
</div>
[jquery code]
$('.small').click(function(){
$('#input').show();
var myId = $(this).attr("id");
var myParentId = $(this).parents('.big').attr('id');
var uniqueId = '#'+myParentId+' #'+myId;
create(uniqueId);
});
function create(uniqueId){
$('#input').show();
$('#ModuleName').change(function(){
var name = this.value;
$('#sa').click(function(){
save_name(name,uniqueId);
});
});
}
function save_name(name,uniqueId){
var div = $(uniqueId)[0];
jQuery.data(div,'store',name);
//alert(uniqueId);
//var val = jQuery.data(div,'store');
$(uniqueId).text(name);
$('#input').hide();
}
But the problem is when I click on second div to store some data the first div also changes the value which second one contains. demo on Jsfiddle
It is because when you click the first time one change handler is added to the select with targeting #m1 element, then again when you click on #m2 a new change handler is added without removing the first one, so when you click the button both these code gets executed.
So try
$('.small').click(function () {
var uniqueId = '#' + this.id;
create(uniqueId);
});
function create(uniqueId) {
$('#input').show();
//remove previously added handlers
//take a look at namespaced event handlers
//also there is no need to have a change handler for the select element
$('#sa').off('click.create').on('click.create', function () {
var name = $('#ModuleName').val();
save_name(name, uniqueId);
});
}
function save_name(name, uniqueId) {
var div = $(uniqueId);
//you can use the .data() method instead of the static jQuery.data() method
div.data('store', name);
//alert(uniqueId);
var val = div.data('store');
$(uniqueId).text(name);
$('#input').hide();
}
Demo: Fiddle
But a more jQueryish solution might look like
var $smalls = $('.small').click(function () {
var uniqueId = '#' + this.id;
$smalls.filter('.active').removeClass('active');
$(this).addClass('active');
$('#input').show();
});
$('#sa').on('click', function () {
var name = $('#ModuleName').val();
save_name(name, '.small.active');
});
function save_name(name, target) {
var div = $(target);
//you can use the .data() method instead of the static jQuery.data() method
div.data('store', name);
//alert(uniqueId);
var val = div.data('store');
div.text(name);
$('#input').hide();
}
Demo: Fiddle
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'));
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>