how to get a dom element from a template not html - javascript

here's the jsfiddle
at first try the script as is and then comment the last line and uncomment the one before it that will give me the functionality i want but with the wrong data, basically i want to grub a template and insert data into it and the insert it before another element in the page.
the problem is that the method that i'm using requires me to use an object or elementNode to insert it but after fetching the template i'm left with html wich result in an error :
Error: NOT_FOUND_ERR: DOM Exception 8
the html:
<section class="container well">
<header></header>
<section id="section">
<h4 id="heading">heading 4</h4>
<div id="div_1" class="divs">
file_1.jpg
<button class="btn btn-mini btn-danger pull-right">✖</button>
</div>
<div id="div_2" class="divs">
file_2.jpg
<button class="btn btn-mini btn-danger pull-right">✖</button>
</div>
<div id="div_3" class="divs">
file_3.jpg
<button class="btn btn-mini btn-danger pull-right">✖</button>
</div>
<div id="div_4" class="divs">
file_4.jpg
<button class="btn btn-mini btn-danger pull-right">✖</button>
</div>
<div class="clearfix">
<button class="btn btn-primary pull-right add">
Add items
</button>
</div>
</section>
<footer></footer>
</section>
<script type="template" id="template">
<div id="{{id}}">
{{fileName}}
</div>
</script>​
my javascript code:
$(document).on('click', '.add', function(e){
e.preventDefault();
e.stopPropagation();
target = document.getElementById($('.divs')[0].id);
template = document.querySelector('#template').innerHTML;
div = template
.replace(/{{id}}/g, '0')
.replace(/{{fileName}}/g, 'file_0');
//target.parentNode.insertBefore(document.createTextNode('AZERTY'), target);
target.parentNode.insertBefore(div, target);
});
the jsfiddle again and thanks in advance.

You cannot insert div, which is a string containing HTML code, into the DOM as if it were an element. Instead, you could create another div and set its innerHTML.
$(document).on('click', '.add', function(e){
e.preventDefault();
e.stopPropagation();
target = document.getElementById($('.divs')[0].id);
template = document.querySelector('#template').innerHTML;
div = template
.replace(/{{id}}/g, '0')
.replace(/{{fileName}}/g, 'file_0');
outerDiv = document.createElement('div');
outerDiv.innerHTML = div;
target.parentNode.insertBefore(outerDiv, target);
});
As noted by a comment on another answer, you may want to skip having a containing div within the template, as you will end up with two divs unnecessarily. Instead you could have simply
{{fileName}}
as the template and then
div = document.createElement('div');
div.id = '0';
div.innerHTML = template.replace(/{{fileName}}/g, 'file_0');
target.parentNode.insertBefore(div, target);
in the script. Another alternative is simply to insert the HTML string directly into the target:
target.innerHTML = div + target.innerHTML;

Here is an article - with several links and lots of good advice - about manipulating templates with jQuery:
How can I create an embeded HTML template using <script type="text/template"> using jquery

$('.add').on('click', function(e){
e.preventDefault();
e.stopPropagation();
target = document.getElementById($('.divs')[0].id);
template = document.querySelector('#template').html();
div = template.replace(/{{id}}/g, '0').replace(/{{fileName}}/g, 'file_0');
divtag = document.createElement('div');
divtag.innerHTML = div;
divtag.id = template.id;
target.parentNode.insertBefore(divtag, target);
}
This should work

here's the answer :
code:
$(document).on('click', '.add', function(e){
e.preventDefault();
e.stopPropagation();
target = document.getElementById($('.divs')[0].id);
template = document.querySelector('#template').innerHTML;
div = template
.replace(/{{id}}/g, '0')
.replace(/{{fileName}}/g, 'file_0.jpg');
new_div = document.createElement('div');
new_div.setAttribute('class', 'divs');
new_div.setAttribute('id', 'div_' + i);
new_div.innerHTML = div;
target.parentNode.insertBefore(new_div, target);
});
​
thanks to stuart.

Related

Why when I create several html tags with javascript then I can not delete it with the same javascript?

When I create a form with the write () command, then I want to delete it, but I can't. What is the cause of this problem?
In order to do this correctly, what command should I use or what should I change in my code?
var btn = document.querySelector('#btn');
var btn_alert = document.querySelector('#btn-alert');
var content = document.querySelector('.popup-container');
var div1 = document.getElementById('div1');
function message(message, btn) {
document.write('<div id="div1"><div id="content" class="popup-container"><div class="box-item"><div class="icon-success"><span class="span1"></span> <span class="span2"></span><div class="ring"></div></div><h2 class="alert-title">Good job!</h2><div class="alert-content">' + message + '</div><div class="actions-btn"><button onclick="ok()" class="btn-alert" id="btn-alert">' + btn + '</button></div></div></div></div>')
}
function ok() {
div1.removeChild(content);
}
<button class="btn-alert" id="btn">OK</button>
<!-- <div id="content" class="popup-container dis-active">
<div class="box-item">
<div class="icon-success">
<span class="span1"></span>
<span class="span2"></span>
<div class="ring"></div>
</div>
<h2 class="alert-title">Good job!</h2>
<div class="alert-content">is ok.</div>
<div class="actions-btn">
<button class="btn-alert" id="btn-alert">OK</button>
</div>
</div>
</div> -->
<script src="script.js"></script>
<script>
message("خوش اومدی!", "کلیک کن");
</script>
document.write is really outdated. In your script you write the elements to the document after you're trying to retrieve them. That won't work.
Here is an example snippet using insertAdjacentHTML to create a message element with a button to remove it.
It is generally not a good idea to use inline event handlers. The snippet uses event delegation to handle button clicks.
It may be wise to first learn more about html document manipulation or javascript.
document.addEventListener(`click`, handle);
const create = () => message(`خوش اومدی!`,`کلیک کن`);
create();
function handle(evt) {
if (evt.target.id === `btn-alert`) {
document.getElementById('div1').remove();
}
if (evt.target.id === `recreate`) {
create();
}
}
function message(message, btnTxt) {
document.body.insertAdjacentHTML(`beforeEnd`, `
<div id="div1">
<div id="content" class="popup-container">
<div class="box-item">
<div class="icon-success">
<span class="span1"></span>
<span class="span2"></span>
<div class="ring"></div>
</div>
<h2 class="alert-title">Good job!</h2>
<div class="alert-content">${message}</div>
<div class="actions-btn">
<button class="btn-alert" id="btn-alert">${btnTxt}</button>
</div>
</div>
</div>
</div>`);
}
<button id="recreate">(re)create message</button>

Unable to retrieve the class name of any parent element fails or returns undefined

Unable to retrieve the class name of any parent element fails or returns undefined:
$(function() {
$(document).on('click','.addfile', function() {
// need to be dinamicaly
var Target = $(this).parents('div').find('[class^="file-plugin-"]');
Target = Target.attr('class');
console.log(Target);
var Target = $(this).closest('div').find('[class^="file-plugin-"]');
Target = Target.attr('class');
console.log(Target);
var Target = $(this).parentsUntil('[class^="file-plugin-"]');
Target = Target.attr('class');
console.log(Target);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap1">
<div class="other class file-plugin-1">
<div class="wrap2">
<div class="input-group-append">
<button type="button" class="remfile">Remove</button>
<button type="button" class="addfile">Add</button>
</div>
</div>
</div>
</div>
i need get: "file-plugin-1" in a var.
You are using class^="
If you look at the documentation, you will see if it is Attribute Starts With Selector [name^=”value”]
That means the attribute needs to be
class="value-abc"
So it is not matching your case because the string is not at the very beginning. You would need to use Attribute Contains Selector [name*=”value”]
The other issue is closest will grab the wrapping div and the div you are looking for is still a grand parent of that div.
$(function() {
$(document).on('click','.addfile', function() {
var elm = $(this).closest('[class*="file-plugin-"]');
console.log(elm.attr("class"));
console.log(elm.attr("class").match(/file-plugin-\d+/)[0])
// how I would do it
var elem = $(this).closest('[data-index]');
console.log(elem.data("index"))
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap1">
<div class="other class file-plugin-1" data-index="1">
<div class="wrap2">
<div class="input-group-append">
<button type="button" class="remfile">Remove</button>
<button type="button" class="addfile">Add</button>
</div>
</div>
</div>
</div>
You can use regex to find elements class starting with certain text
$(document).on('click','.addfile', function() {
var Target = $(this).parents().filter((i, ele)=>ele.className.match(/\bfile-plugin-/)).attr('class')
console.log(Target);
});
The issue is that the class of the div you are after literally does not start with "file-plugin-", it just contains it. You need to examine the class attribute manually, JQuery does not help with this much (that I know of).
Something like this should work:
$(function() {
$(document).on('click','.addfile', function() {
// need to be dinamicaly
var target = $(this).parents("div").filter((_, div) => -1 != div.className.indexOf('file-plugin-'));
// console.log(target[0]);
// Or using the "contains" selector (credit to #epascarello)
target = $(this).parents("div[class*=file-plugin-]");
var string = target.attr("class").split(" ").filter( clazz => clazz.startsWith('file-plugin-'))[0];
console.log(string);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap1">
<div class="other class file-plugin-1">
<div class="wrap2">
<div class="input-group-append">
<button type="button" class="remfile">Remove</button>
<button type="button" class="addfile">Add</button>
</div>
</div>
</div>
</div>

Append Element Into Element

It might sound stupid , but i didn't find the correct way to achieve this . I want to create an element(in our example a div element) and add to it the textarea value . In my example it seems that the element is created but i cant embed it into the #notesPosition . I achieve this with JQuery but i`am not sure whats the best way to do it with pure Javascript.
var notesPositionToAdd = document.getElementById('notesPosition');
var notesTextareaBtn = document.getElementById('btnAddNotes');
notesTextareaBtn.addEventListener('click', function(e) {
e.preventDefault();
var notesTextarea = document.getElementById('addNotesTextarea').value;
console.log(notesTextarea);
var newEl = document.createElement('div');
newEl.append(notesTextarea);
newEl.className += " col-lg-2";
console.log(newEl);
});
<div class="row ">
<div class="col-lg-4 col-md-4 col-sm-4 col-12 offset-md-8 ">
<form id="newNoteForm">
<div class="form-group offset-lg-6">
<i class="fa fa-times text-md-right " aria-hidden="true"></i>
<label for="addNotesTextarea">Add notes !</label>
<textarea class="form-control" id="addNotesTextarea" rows="3"></textarea>
<input class="btn btn-danger btn-sm" type="submit" value="Add" id="btnAddNotes">
</div>
</form>
</div>
</div>
<div class="row" id="notesPosition">
</div>
Hello
Check if this helps:
newEl.append(notesTextarea);
newEl.className += " col-lg-2";
console.log(newEl);
to:
newEl.append(notesTextarea);
newEl.className += " col-lg-2";
notesPositionToAdd.append(newEl);
console.log(newEl);
I hope it helped you!
If you want to addTextNode() then you can...
var div = document.createElement('div');
var txt = document.createTextNode('Whatever Text');
div.appendChild(txt);
alternatively
var div = document.createElement('div')
div.innerHTML = 'Whatever Text' // Whatever text parsed, <p>Words</p> is OK
alternatively
var div - document.createElement('div')
div.textContent = 'Whatever' // Not parsed as HTML

Getting span content in another div

How can I get the html content of span with id of pageNum when I click on the button with id of id1 in Jquery?
In other words, is there any way to go to the closest "pagination" div and get "pageNum" from there?
<div class='pagination'>
<div class='pagination-tools'>
<span class='pageNum'>2</span>
</div>
</div>
</div>
<div>
<div>
<div>
<button id="id1"></button>
</div>
</div>
</div>
$('#2').on('click', function () {
var html = $('.pageNum').html();
});
Per my declarative suggestion comment:
$('#2').on('click', function () {
var html = $('[data-id="' + this.id + '"]').html();
});

How to select this element with jQuery?

I have this piece of HTML code.
<div class="row member-item">
<div class="col-md-3"><img src={{ i.mem_imgurl }}></div>
<div class="col-md-2">姓名<br><div class="mem_name">{{ i.mem_name }}</div></div>
<div class="col-md-2">组别<br><div class="mem_group">{{ i.mem_group }}</div></div>
<div class="col-md-2">年级<br><div class="mem_year">{{ i.mem_year }}</div></div>
<div class="col-md-1"><button class="btn btn-danger btn-sm deleteNode" onclick="delNode(this)">Delete</button></div>
</div>
And I write js as follows,
function delNode(btn) {
var mem_item = $(btn).parent().parent();
var mem_name = $(mem_item).children("div.mem_name").text();
alert(mem_name);
console.log(mem_name);
mem_item.hide()
}
I want to get the text value of div.mem_name, but somehow it just does not work:(
The children function only travels down the immediate children of the element. You can use find to search down the tree of children. This should work:
var mem_name = $(mem_item).find("div.mem_name").text();
This is from the jQuery children() documentation:
The .children() method differs from .find() in that .children() only travels a single level down the DOM tree while .find() can traverse down multiple levels to select descendant elements (grandchildren, etc.) as well.
Similarly, your parent().parent() call can be replaced with closest() or parents():
var mem_item = $(btn).parents(".member-item");
You can use .closest and .find together
Script :
$(document).ready(function(){
$(".deleteNode").click(function(){
var mem_name = $(this).closest('.row').find('.mem_name').text();
alert(mem_name);
console.log(mem_name);
});
});
HTML :
<div class="row member-item">
<div class="col-md-3"><img src=""></div>
<div class="col-md-2">姓名<br><div class="mem_name">name</div></div>
<div class="col-md-2">组别<br><div class="mem_group">mem_group</div></div>
<div class="col-md-2">年级<br><div class="mem_year">mem_year</div></div>
<div class="col-md-1"><button class="btn btn-danger btn-sm deleteNode" >Delete</button></div>
</div>
JSFIDDLE DEMO

Categories

Resources