Remove all previous content from a DOM element - javascript

Let's say we have this HTML. The task is to make a function that should remove all previous content from the DOM element with id="removeAbove"
<nav class="navbar>
<div class="container">
<div class="navbar-header">
<button type="button">
<span class="sr-only">Toggle navigation</span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div id="navbar" class="navbar-collapse">
<form class="navbar-form">
<div class="form-group">
<input type="text">
</div>
<div class="form-group">
<input type="password">
</div>
<button type="submit" class="btn">Sign in</button>
</form>
</div>
</div>
</nav>
<div class="jumbotron">
<div class="container">
<h1>Hello, world!</h1>
<p>This is a template</p>
<p id="removeAbove"><a class="btn" href="#">Learn more</a></p>
</div>
</div>
Tried el.previousElementSibling.innerHTML = "" but didn't solve the problem. Also tried using the parents. I am thinking about traversing the DOM tree and when the function finds the element with this ID, the previous items start deleting. But...no idea how this could be achieved with pure JS.

If you want to remove everything in the body except the element with the id="removeAbove" please try this:
var el = document.getElementById("removeAbove");
(function removeAllChilds(el, protected) {
//Make the protected elemnt the last in the list !
el.appendChild(protected);
//Remove all child but the protected
while (el.firstChild && el.firstChild !== protected) el.removeChild(el.firstChild);
//If we reachthe body we stop
if (el.tagName.toLowerCase() === 'body') return;
//Call the function with the parent element
removeAllChilds(el.parentElement, el);
})(el.parentElement, el);
Demo:
var el = document.getElementById("removeAbove");
(function removeAllChilds(el, protected) {
//Make the protected elemnt the last in the list !
el.appendChild(protected);
//Remove all child but the protected
while (el.firstChild && el.firstChild !== protected) el.removeChild(el.firstChild);
//If we reachthe body we stop
if (el.tagName.toLowerCase() === 'body') return;
//Call the function with the parent element
removeAllChilds(el.parentElement, el);
})(el.parentElement, el);
<div class="wrapper">
<div>Some div</div>
<nav class="navbar">
<div class="container">
<div class="navbar-header">
<button type="button">
<span class="sr-only">Toggle navigation</span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div id="navbar" class="navbar-collapse">
<form class="navbar-form">
<div class="form-group">
<input type="text">
</div>
<div class="form-group">
<input type="password">
</div>
<button type="submit" class="btn">Sign in</button>
</form>
</div>
</div>
</nav>
<div class="jumbotron">
<div class="container">
<h1>Hello, world!</h1>
<p>This is a template</p>
<p id="removeAbove"><a class="btn" href="#">Learn more</a></p>
</div>
</div>
</div>

If you want to remove all the elements before removeAbove, you'll need a loop:
removeAllBefore(document.getElementById('removeAbove'));
function removeAllBefore(el)
{
var prevEl;
while (prevEl = el.previousElementSibling)
prevEl.parentNode.removeChild(prevEl);
if (el.parentNode.tagName.toUpperCase() != 'BODY')
removeAllBefore(el.parentNode);
}
This solution removes everything before the element, recursively, and stops at the body element.
See it in action at plnkr

Related

JavaScript How to Print A Label in a DIV?

I have 4 boxes labeled a1, a2, a3, a4 as an example. And when someone clicks on 2 boxes, I want the label (a1, a2 as an example) to print on html output. I just spent over an hour and the best I can come up was printing undefined and null.
Sorry, here is my code
HTML
<div class="container">
<div class="row">
<div class="col-md-3" label="a1">
<a class="btn btn-primary" href="#" role="button">Button 01</a>
<div class="output"></div>
</div>
<div class="col-md-3" label="a2">
<a class="btn btn-primary" href="#" role="button">Button 02</a>
<div class="output"></div>
</div>
<div class="col-md-3" label="a3">
<a class="btn btn-primary" href="#" role="button">Button 03</a>
<div class="output"></div>
</div>
<div class="col-md-3" label="a4">
<a class="btn btn-primary" href="#" role="button">Button 04</a>
<div class="output"></div>
</div>
</div>
</div>
const button = document.querySelector('.btn');
button.addEventListener('click', printLabel);
function printLabel(){
const name = document.querySelector('label');
const print = document.querySelector('.output');
print.innerText = name;
}
label isn't really a standard attribute of the <div> tag. You could try id if you're just looking for a quick solution. Also, you're accessing everything in a pretty strange way.
You should change label to id. The id attribute is pretty much universal to all HTML elements (that I know of) and will allow you to uniquely identify that element.
<div class="container">
<div class="row">
<div class="col-md-3" id="a1">
<a class="btn btn-primary" href="#" role="button">Button 01</a>
<div class="output"></div>
</div>
<div class="col-md-3" id="a2">
<a class="btn btn-primary" href="#" role="button">Button 02</a>
<div class="output"></div>
</div>
<div class="col-md-3" id="a3">
<a class="btn btn-primary" href="#" role="button">Button 03</a>
<div class="output"></div>
</div>
<div class="col-md-3" id="a4">
<a class="btn btn-primary" href="#" role="button">Button 04</a>
<div class="output"></div>
</div>
</div>
</div>
Add a unique id to all of the div elements that are meant to be your "output". This will allow your code to direct the "output" to the right element.
<div class="container">
<div class="row">
<div class="col-md-3" id="a1">
<a class="btn btn-primary" href="#" role="button">Button 01</a>
<div class="output" id="a1-output"></div>
</div>
<div class="col-md-3" id="a2">
<a class="btn btn-primary" href="#" role="button">Button 02</a>
<div class="output" id="a2-output"></div>
</div>
<div class="col-md-3" id="a3">
<a class="btn btn-primary" href="#" role="button">Button 03</a>
<div class="output" id="a3-output"></div>
</div>
<div class="col-md-3" id="a4">
<a class="btn btn-primary" href="#" role="button">Button 04</a>
<div class="output" id="a4-output"></div>
</div>
</div>
</div>
Finally, a couple of changes to your JavaScript. The first change you'll see is that I changed document.querySelector('.btn') to document.querySelectorAll('.btn'). The difference between these methods is that the first one selects ONLY the first element it finds that matches the selector, but the second one selects all elements that match the selector and creates an array.
Next, we loop through that array to add an event listener for each element.
After that, we add a parameter e (for event) to the printLabel() function because addEventListener() passes an event object in the callback function (printLabel). This object gives information about the target element related to the event.
Next, we get the target element of the event and that's your button. Then we get the parentElement of your button because your id or "label" is on the parent element. Then, you can get the name from the id of the parent element.
As a note, remember that id attributes CANNOT have spaces or . or # or really most special characters besides _.
Finally, we need to select your "output" element, and we'll use the id to do that.
document.querySelector('#' + name + '-output'); will get the element that has an id with the given name + -output. For example, if you click button a1 this will get the element with the id of a1-output. The # signifies that you're searching for an id.
Now that we stored this element in a variable print, we can place the text in it using the innerHTML property.
const button = document.querySelectorAll('.btn');
for(var i=0; i < button.length; i++) {
button[i].addEventListener('click', printLabel);
}
function printLabel(e) {
var target = e.target;
var parent = target.parentElement;
const name = parent.id;
const print = document.querySelector('#' + name + '-output');
print.innerHTML = name;
}
I created a JSFiddle to help you.
If you have any questions, please let me know.
<script>
function printDiv(divName){
var printContents = document.getElementById(divName).innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContents;
window.print();
document.body.innerHTML = originalContents;
}
</script>
<h1> do not print this </h1>
<div id='printMe'>
Print this only
</div>
<button onclick="printDiv('printMe')">Print only the above div</button>
We can use event bubbling and data attributes to our advantage here. Replace your label attribute which is non-standard with a data attribute. Also, don't use a if it is not a navigation element, use button instead.
//Get the divs
let divs = document.querySelectorAll("[data-label]")
for(var i = 0; i < divs.length; i++){
//Add the event listener to the DIVs, yes the divs
divs[i].addEventListener("click", function(event){
//Did a button fire the event?
if(event.target.tagName === "BUTTON"){
//update the output div in the clicked div
this.querySelector(".output").innerText = this.dataset.label;
}
});
}
<div class="container">
<div class="row">
<div class="col-md-3" data-label="a1">
<button class="btn btn-primary" role="button">Button 01</button>
<div class="output"></div>
</div>
<div class="col-md-3" data-label="a2">
<button class="btn btn-primary"role="button">Button 02</button>
<div class="output"></div>
</div>
<div class="col-md-3" data-label="a3">
<button class="btn btn-primary" role="button">Button 03</button>
<div class="output"></div>
</div>
<div class="col-md-3" data-label="a4">
<button class="btn btn-primary" role="button">Button 04</button>
<div class="output"></div>
</div>
</div>
</div>
just change your script part to the following to make it work without changing HTML
<script>
//getting all buttons
var buttons = document.getElementsByClassName("btn");
//adding event listner to all buttons
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", printLabel, false);
}
function printLabel() {
const outputDiv = this.parentElement.querySelector(".output"); // this will select only closet div with given class
outputDiv.innerText = this.parentElement.getAttribute("label");
}
</script>

Javascript animate content In and hide

I want to animate whole bunch of cards in with javascript and hide them when they press a button a data filter. what would be the best way in doing this?
I was thinking of using hide() and show() but zooms the content out and looks bad, I would like to do more of a sorting fade in and out but want to clear the grid and fade items in nicely.
<script src="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/js/foundation.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/css/foundation.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button-group">
<button class="button category-button" data-filter="all" type="button">
All
</button>
<button class="button category-button" data-filter="attraction" type="button">
attraction
</button>
<button class="button category-button" data-filter="bar-pub" type="button">
bar-pub
</button>
<button class="button category-button" data-filter="theater" type="button">
theater
</button>
</div>
<div class="grid-container">
<div class="grid-x grid-padding-x small-up-2 medium-up-3">
<div class="cell">
<div class="card">
<img src="assets/img/generic/rectangle-1.jpg">
<div class="card-section">
<h4>This is a row of cards.</h4>
<p>This row of cards is embedded in an X-Y Block Grid.</p>
</div>
</div>
</div>
<div class="cell">
<div class="card">
<img src="assets/img/generic/rectangle-1.jpg">
<div class="card-section">
<h4>This is a card.</h4>
<p>It has an easy to override visual style, and is appropriately subdued.</p>
</div>
</div>
</div>
<div class="cell">
<div class="card">
<img src="assets/img/generic/rectangle-1.jpg">
<div class="card-section">
<h4>This is a card.</h4>
<p>It has an easy to override visual style, and is appropriately subdued.</p>
</div>
</div>
</div>
</div>
</div>
I think this is what you're after?
This assumes each card is a type of category like your filter buttons.
Notice the new data-type added to the cards and the typo on theatre.
To achieve the fade effect, we use jQuery's fadeOut() and fadeIn() methods. You can view more information about jQuery effects here.
//when a button is clicked
$('.button-group button').on('click', function(){
//store the category of the clicked button
var category = $(this).attr('data-filter');
//Loop through all `.card` elements
$('.card').each(function(){
//If the current card in this loop has the same category as the button and it's not the 'all' button then hide it, otherwise fade all cards back in.
if($(this).attr('data-type') != category && category != 'all') {
$(this).fadeOut();
} else {
$(this).fadeIn()
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/js/foundation.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/css/foundation.css" rel="stylesheet"/>
<div class="button-group">
<button class="button category-button" data-filter="all" type="button">
All
</button>
<button class="button category-button" data-filter="attraction" type="button">
attraction
</button>
<button class="button category-button" data-filter="bar-pub" type="button">
bar-pub
</button>
<button class="button category-button" data-filter="theatre" type="button">
theater
</button>
</div>
<div class="grid-container">
<div class="grid-x grid-padding-x small-up-2 medium-up-3">
<div class="cell">
<div data-type="bar-pub" class="card">
<img src="https://placehold.it/100x100">
<div class="card-section">
<h4>I'm the bar/pub type</h4>
<p>This row of cards is embedded in an X-Y Block Grid.</p>
</div>
</div>
</div>
<div class="cell">
<div data-type="attraction" class="card">
<img src="https://placehold.it/100x100">
<div class="card-section">
<h4>I'm the attraction type</h4>
<p>It has an easy to override visual style, and is appropriately subdued.</p>
</div>
</div>
</div>
<div class="cell">
<div data-type="theatre" class="card">
<img src="https://placehold.it/100x100">
<div class="card-section">
<h4>I'm the theatre type</h4>
<p>It has an easy to override visual style, and is appropriately subdued.</p>
</div>
</div>
</div>
</div>
</div>
You'll wanna apply the data attributes set on your buttons to the corresponding card and from there just query the card based on its' value:
$(function() {
$('.category-button').on('click', function() {
const filter = this.dataset.filter;
const $filteredCard = $(`.card[data-filter="${filter}"]`);
if (filter === 'all') {
$('.card').stop().fadeIn();
} else {
$filteredCard.stop().fadeIn();
$('.card').not($filteredCard).stop().fadeOut();
}
});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/css/foundation.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button-group">
<button class="button category-button" data-filter="all" type="button">
All
</button>
<button class="button category-button" data-filter="attraction" type="button">
attraction
</button>
<button class="button category-button" data-filter="bar-pub" type="button">
bar-pub
</button>
<button class="button category-button" data-filter="theater" type="button">
theater
</button>
</div>
<div class="grid-container">
<div class="grid-x grid-padding-x small-up-2 medium-up-3">
<div class="cell">
<div class="card" data-filter="attraction">
<img src="assets/img/generic/rectangle-1.jpg">
<div class="card-section">
<h4>This is a row of cards.</h4>
<p>This row of cards is embedded in an X-Y Block Grid.</p>
</div>
</div>
</div>
<div class="cell">
<div class="card" data-filter="bar-pub">
<img src="assets/img/generic/rectangle-1.jpg">
<div class="card-section">
<h4>This is a card.</h4>
<p>It has an easy to override visual style, and is appropriately subdued.</p>
</div>
</div>
</div>
<div class="cell">
<div class="card" data-filter="theater">
<img src="assets/img/generic/rectangle-1.jpg">
<div class="card-section">
<h4>This is a card.</h4>
<p>It has an easy to override visual style, and is appropriately subdued.</p>
</div>
</div>
</div>
</div>
</div>

Open only one accordian collapse, bootstrap

Using Bootstrap...
How to make this so that only one accordion collapsable DIV is open at a time. When one is clicked open, the other should close (if it is open?)
Looking for the most simple and streamlined solution...
<div class="row" id="nav-top">
<div class="col-md-6">
<div>
<a href="#" data-toggle="collapse" data-target="#signin" >SIGN-IN</a>
</div>
<div id="signin" class="collapse">
FORM HERE
</div>
</div>
<div class="col-md-6">
<div>
REGISTER
</div>
<div id="register" class="collapse">
FORM HERE
</div>
</div>
</div>
You have to use show.bs.collapse event which is fired immediately when the collapse element starts showing. Then you can hide other collapsible menus, Like this:
// when showing signin accordion
$('#signin').on('show.bs.collapse', function () {
// hide register accordion
$('#register').collapse('hide');
});
$('#register').on('show.bs.collapse', function () {
$('#signin').collapse('hide');
});
But If you have multiple accordion you can't call this event in each one of them, You have to use a class to select them all and call show.bs.collapse only one time, Here is a working example:
$( document ).ready(function() {
$('.collapse').on('show.bs.collapse', function () {
// hide all accordion except the clicked one
$('.collapse').not(this).collapse('hide');
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
<div class="row" id="nav-top">
<div class="col-md-4">
<div>
<a href="#" data-toggle="collapse" data-target="#signin" >ABOUT</a>
</div>
<div id="signin" class="collapse">
FORM HERE
</div>
</div>
<div class="col-md-4">
<div>
<a href="#" data-toggle="collapse" data-target="#register" >REGISTER</a>
</div>
<div id="register" class="collapse">
FORM HERE
</div>
</div>
<div class="col-md-4">
<div>
<a href="#" data-toggle="collapse" data-target="#about" >SIGN-IN</a>
</div>
<div id="about" class="collapse">
FORM HERE
</div>
</div>
</div>
</div>

To access sibilings div in jquery

I want to alert panel-heading text when I click panel-footer
thanks in advance i tried .val() also but not working
$('.panel .panel-footer').on('click',function (e) {
alert($(this).parent('.panel').closest('.panel-heading .panel-title').text());
});
<div class="panel">
<div class="panel-heading">
<h3 class="panel-title">Super Admin</h3>
<div class="right">
on type="button" class="btn-toggle-collapse"><i class="lnr lnr-question-circle"></i></button>
</div>
</div>
<div class="panel-body">
<div>0 Members</div>
</div>
<div class="panel-footer">
<div>View All<i class="lnr lnr-arrow-right pull-right"></i></div>
</div>
</div>
Update closest to find, closest goes up and not down
$('.panel .panel-footer').on('click',function (e) {
alert( $(this).parent('.panel').find('.panel-title').text() );
});
https://api.jquery.com/closest/ it traverses up the DOM tree
Description: For each element in the set, get the first element that
matches the selector by testing the element itself and traversing up
through its ancestors in the DOM tree.
but you want to traverse down since you are already at the parent level($(this).parent('.panel')).
So we use find() https://api.jquery.com/find/ which traverses down
Description: Get the descendants of each element in the current set of
matched elements, filtered by a selector, jQuery object, or element.
If you prefer the 'siblings' approach, that will work, as you're triggering off the panel-footer el.
$('.panel .panel-footer').on('click',function (e) {
console.log($(this).siblings(".panel-heading").text() );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel">
<div class="panel-heading">
<h3 class="panel-title">Super Admin</h3>
<div class="right">
<button type="button" class="btn-toggle-collapse"><i class="lnr lnr-question-circle"></i></button>
</div>
</div>
<div class="panel-body">
<div>0 Members</div>
</div>
<div class="panel-footer">
<div>View All<i class="lnr lnr-arrow-right pull-right"></i></div>
</div>
</div>
Replace closest() by find():
$('.panel .panel-footer').on('click',function (e) {
alert($(this).parent('.panel').find('.panel-heading .panel-title').text());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel">
<div class="panel-heading">
<h3 class="panel-title">Super Admin</h3>
<div class="right">
<button type="button" class="btn-toggle-collapse"><i class="lnr lnr-question-circle"></i></button>
</div>
</div>
<div class="panel-body">
<div>0 Members</div>
</div>
<div class="panel-footer">
<div>View All<i class="lnr lnr-arrow-right pull-right"></i></div>
</div>
</div>

Getting clicked button values jquery

I am trying to find clicked button value.here is my htmlcode,I am not able to get but always getting first one.
<div id="addSentiment" class="dialogs">
<div id="1" class="dialogs">
<div class="itemdiv dialogdiv">
<div class="user">
<img src="assets/avatars/avatar1.png" alt="Alexas Avatar">
</div>
<div class="body">
<div class="time"> <i class="ace-icon fa fa-clock-o"></i>
<span class="green">Date : 10/01/2014</span>
</div>
<div class="name"> ki#n.com
</div>
<div id="cat_1" class="text">category : Scheduling
<br>
</div>
<div id="op_1" class="text">ddd word/phrase : providing solutions
<br>
</div>
<div id="feature_1" class="text">ddd word/phrase : listen to
<br>
</div>
<div class="text">
<input type="hidden" value="1" name="hd">
</div>
<div class="tools"> <a id="edit_1" class="btn acebtn btn-minier btn-info" href="#">
<i class="icon-only ace-icon fa fa-share"></i>
</a>
</div>
</div>
</div>
</div>
<div id="2" class="dialogs">
<div class="itemdiv dialogdiv">
<div class="user">
<img src="assets/avatars/avatar1.png" alt="Alexas Avatar">
</div>
<div class="body">
<div class="time"> <i class="ace-icon fa fa-clock-o"></i>
<span class="green">Date : 10/01/2014</span>
</div>
<div class="name"> tc#n.com
</div>
<div id="cat_2" class="text">category : Scheduling
<br>
</div>
<div id="op_2" class="text">dddd : providing solutions
<br>
</div>
<div id="feature_2" class="text">ddddddde : listen to
<br>
</div>
<div class="text">
<input type="hidden" value="2" name="hd">
</div>
<div class="tools"> <a id="edit_2" class="btn acebtn btn-minier btn-info" href="#">
<i class="icon-only ace-icon fa fa-share"></i>
</a>
</div>
</div>
</div>
</div>
<div id="3" class="dialogs">
<div class="itemdiv dialogdiv">
<div class="user">
<img src="assets/avatars/avatar1.png" alt="Alexas Avatar">
</div>
<div class="body">
<div class="time"> <i class="ace-icon fa fa-clock-o"></i>
<span class="green">Date : 10/01/2014</span>
</div>
<div class="name"> tn#nn.com
</div>
<div id="cat_3" class="text">category : Scheduling
<br>
</div>
<div id="op_3" class="text">Opinion word/phrase : providing solutions
<br>
</div>
<div id="feature_3" class="text">Feature word/phrase : listen to
<br>
</div>
<div class="text">
<input type="hidden" value="3" name="hd">
</div>
<div class="tools"> <a id="edit_3" class="btn acebtn btn-minier btn-info" href="#">
<i class="icon-only ace-icon fa fa-share"></i>
</a>
</div>
</div>
</div>
</div>
</div>
I tried following code in jquery
$(".dialogs .itemdiv .tools").live("click",function(e){
e.preventDefault();
alert('clicked on edit');
var n = $('.dialogs .itemdiv .tools a').attr('id');
alert(n);
});
I use live here because I am getting above html by using append method in jquery.
live is deprecated in later versions of jQuery - but to solve your issue you need to use an instance of this
$("#addSentiment").on("click", ".dialogs .itemdiv .tools", function(e){
e.preventDefault();
alert('clicked on edit');
var n = $("a", this).attr('id');
alert(n);
});
jQuery selectors catch the first match of their content.
To catch the n-th match, you need to use the n-th child selector, like this:
$(".dialogs .itemdiv .tools:nth-child(2)")
I am not familiar with the live method, but you should be able to do something like the following:
function addHandlers() {
$(".dialogs .itemdiv .tools a").each(function() {
$(this).click(function() {
alert('clicked on edit');
);
});
}
function yourAppendFunction() {
//your append code
//add call to a function that will create your event handlers
addHandlers();
}
The .each method runs through each and every item that fits the selection criteria, and then we use the this keyword within the function to reference what we are working on. Putting it in a function that we don't call until after you append the items ensures the html exists when you try to add the handlers you need.
API references:
each method: http://api.jquery.com/each/
click method: http://api.jquery.com/click/

Categories

Resources