so basically I'm trying to reproduce some kind of Trello, and what I'm trying to do, is to create (or clone) an existing div, and insert it before the button. Yes I know, there's a method called ".insertBefore()" but I actually tried, it works... But halfway.
This is how the div should look like
Blocks are disposed in this way, and as I said, what I am trying to do is when I click on the "Add Category button" It clones the div and inserts it before the button.
Nothing difficult I know I know. I actually managed to achieve this, but halfway : It works. But only once.
I looked what's happening in the inspector and I noticed, that everytime I click on "Add Category", the div I just cloned, is actually replaced by the div itself. So I can only add it once, not more.
There is my code :
window.onload = function() {
var board = document.querySelector('#board');
var model = document.querySelectorAll('#model');
//creating the block, didn't use .cloneNode()
var newTask = document.createElement('div');
newTask.className='newTask';
newTask.appendChild(document.createElement('p'));
newTask.querySelector('p').innerHTML = 'New Task';
newTask.appendChild(document.createElement('i'));
newTask.querySelector('i').className = 'fa fa-plus';
var newCategory = document.createElement('div');
newCategory.className = 'category';
newCategory.appendChild(newTask);
/* Look like this :
* <div class="category">
* <div class="newTask">
* <p>New Task</p>
* <i class="fa fa-plus">
* </div>
* </div>
*/
var addCategory = document.querySelector('#addCategory');
addCategory.onclick = function() {
board.insertBefore(newCategory, addCategory);
};
};
<div id="board">
<div class="category hidden" id="model">
<div class="newTask">
<p>New task</p>
<i class="fa fa-plus" aria-hidden="true"></i>
</div>
</div>
<div class="category">
<div class="newTask">
<p>New task</p>
<i class="fa fa-plus" aria-hidden="true"></i>
</div>
<div class="task">
<h3>Task title</h3>
<p>This is the description of what we have to do</p>
</div>
</div>
<div class="category" id="addCategory">
<h3>Add a category</h3>
<i class="fa fa-plus-circle" aria-hidden="true"></i>
</div>
</div>
So this is what's happening : https://i.neilrichter.com/c7kd3.gif (File too large sorry)
How would you solve this ? I forgot to mention it, but I'm not allowed to use jQuery...
You are only creating the div once (when the window loads) and then inserting that same div every time the onclick handler runs.
You need to create a new div each time the onclick handler runs:
window.onload = function() {
var board = document.querySelector('#board');
var model = document.querySelectorAll('#model');
var addCategory = document.querySelector('#addCategory');
addCategory.onclick = function() {
var newTask = document.createElement('div');
newTask.className='newTask';
newTask.appendChild(document.createElement('p'));
newTask.querySelector('p').innerHTML = 'New Task';
newTask.appendChild(document.createElement('i'));
newTask.querySelector('i').className = 'fa fa-plus';
var newCategory = document.createElement('div');
newCategory.className = 'category';
newCategory.appendChild(newTask);
board.insertBefore(newCategory, addCategory);
};
};
<div id="board">
<div class="category hidden" id="model">
<div class="newTask">
<p>New task</p>
<i class="fa fa-plus" aria-hidden="true"></i>
</div>
</div>
<div class="category">
<div class="newTask">
<p>New task</p>
<i class="fa fa-plus" aria-hidden="true"></i>
</div>
<div class="task">
<h3>Task title</h3>
<p>This is the description of what we have to do</p>
</div>
</div>
<div class="category" id="addCategory">
<h3>Add a category</h3>
<i class="fa fa-plus-circle" aria-hidden="true"></i>
</div>
</div>
Related
HTML Code indicating the classes and id of the respective elements.
<div class="input-group mb-3" >
<input type="text" class="form-control" id="input-item" value="">
<div class="input-group-preppend">
<button type="button" class="btn btn-success" id="add-item" >Add</button>
<button type="button" class="btn btn-info" id="delete">Delete</button>
</div>
</div>
<div id="display-item">
<div class="item">
<!--<p>New list items appear here!</p>
<div class="item-btn">
<i class="fa-regular fa-pen-to-square"></i>
<i class="fa-solid fa-square-xmark"></i>
</div>-->
</div>
</div>
JS Code showing what should be happen when i key in a word inside the input section and click on add, it shows ${input.value} instead
let input = document.querySelector('#input-item');
let add = document.querySelector('#add-item');
let display = document.querySelector('#display-item');
add.addEventListener('click', () => {
if (input.value.trim() !=0) {
let newItem= document.createElement('div');
newItem.classList.add('item')
newItem.innerHTML = '<p> ${input.value} </p> <div class="item-btn"> <i class="fa-
regular fa-pen-to-square"></i> <i class="fa-solid fa-square-xmark"></i> </div>'
display.appendChild(newItem);
input.value= '';
} else {
alert('please add an item!')
}
});
this is the js code
Use
`
instead of
'
newItem.innerHTML = `<p> ${input.value} </p> <div class="item-btn"> <i class="fa-
regular fa-pen-to-square"></i> <i class="fa-solid fa-square-xmark"></i> </div>`
I was making my first pure Js project of todolist. I want when user adds an item in the list it gets it placed at the list. I was using this code I saw in a tutorial but it gives an error.
It gives an error: jeep.insertAdjacentHTML is not a function
Here is the markup:
<section class="listContent">
<div class="container">
<ul class="list" id="deep">
<li style="text-align: center" id="itemList">
<!-- < i class="fa fa-circle-o pull-left" id = "circle" aria - hidden="true" > </i>
<p class="text" > DRINK COFFEE < /p>
<i class="fa fa-trash pull-right" id = "delete" aria - hidden="true" > </i> -->
</li>
</ul>
</div>
</section>
Here is the JS
const date = document.getElementById("date");
const jeep = document.getElementById("deep");
const items = document.getElementById("itemList");
function addToDo(todo) {
const item =
`<i class="fa fa-circle-o pull-left" job="complete" id="circle" aria-hidden="true"></i>
<p class="text"> ${todo}</p>
<i class="fa fa-trash pull-right" id="delete" job="delete" aria-hidden="true"></i>
` ;
const position = "beforeend";
console.log(item);
console.log(position);
jeep.insertAdjacentHTMl(position, item);
}
addToDo("drink coffe");
first try .insertAdjacentHTML - the L should be capitalized. Also it looks like in the HTML markup that element lives inside of the <li> no adjacent to it. It looks like you might want to use .appendChild() on the <ul id="deep"></ul>
I would like to animate the clicked accordion item to the top of the page. The first click works, but everything after seems to accumulate and makes the accordion slide up and out of view. The correct functionality would be each item scrolling to the exact spot as the previous, in a fixed position from the top of the window. Part of the issue is that I am using a prototype and not sure how to stop the accumulation of clicks each time an instance is created.
var media = window.matchMedia("(max-width: 767px")
var Accordion = function(el, multiple) {
this.el = el || {}
this.multiple = multiple || false
var links = this.el.find('.link')
links.on('click', {el: this.el, multiple: this.multiple}, this.dropdown)
}
Accordion.prototype.dropdown = function(e) {
var $el = e.data.el
$this = $(this)
$next = $this.next()
$next.slideToggle()
$this.parent().toggleClass('open')
if(!e.data.multiple) {
$el.find('.content').not($next).slideUp().parent().removeClass('open')
}
if(media.matches) {
$("html, body").animate({
scrollTop: $this.offset().top - 85
}, 900)
}
}
var accordion = new Accordion($('.hollow-accordion-03 #accordion'), false)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="hollow-accordion-03">
<div class="flex-container">
<ul id="accordion">
<li>
<div class="link">
<i class="fa fa-database"></i>
<h3>First List Item</h3>
<div class="state-wrap">
<i class="fa fa-plus"></i>
<i class="fa fa-minus"></i>
</div>
</div>
<div class="content">
<p>This is filler content for the list item. Content in this section will be replaced by copy for your site. This is filler text. Content in this section will be replaced by copy for your site. This is filler text.</p>
</div>
</li>
<li>
<div class="link">
<i class="fa fa-database"></i>
<h3>Second List Item</h3>
<div class="state-wrap">
<i class="fa fa-plus"></i>
<i class="fa fa-minus"></i>
</div>
</div>
<div class="content">
<p>This is filler content for the list item. Content in this section will be replaced by copy for your site. This is filler text. Content in this section will be replaced by copy for your site. This is filler text.</p>
</div>
</li>
<li>
<div class="link">
<i class="fa fa-database"></i>
<h3>Third List Item</h3>
<div class="state-wrap">
<i class="fa fa-plus"></i>
<i class="fa fa-minus"></i>
</div>
</div>
<div class="content">
<p>This is filler content for the list item. Content in this section will be replaced by copy for your site. This is filler text. Content in this section will be replaced by copy for your site. This is filler text.</p>
</div>
</li>
<li>
<div class="link">
<i class="fa fa-database"></i>
<h3>Fourth List Item</h3>
<div class="state-wrap">
<i class="fa fa-plus"></i>
<i class="fa fa-minus"></i>
</div>
</div>
<div class="content">
<p>This is filler content for the list item. Content in this section will be replaced by copy for your site. This is filler text. Content in this section will be replaced by copy for your site. This is filler text.</p>
</div>
</li>
</ul>
</div>
</section>
I have a <div> containing a <a> tags and further divs:
<div>
<div class="icons">
<div class="group popOutDisplay">
<i class="fa fa-home"></i>
<i class="fa fa-search"></i>
<i class="fas fa-bicycle"></i>
</div>
<div class="group">
<i class="fa fa-globe"></i>
</div>
<div class="group bottom">
<i class="fa fa-trash"></i>
</div>
</div>
<div class="content">
<div id="128910";>
<p>some content</p>
</div>
<div id="239019";>
</div>
<div id="346653";>
</div>
</div>
</div>
Im trying to select the data attribute on the anchor tag with jquery so that i can display the the <div> tags in <div class="content"> which have the same ID (if that makes sense?).
So far i've been able to identify the data id with
$(".group.popOutDisplay a")[0].attributes[1].value;
but this only gives the ID of the first element, due to the [0] index.
tldr:
How can I get the data-ID of the <a> tag that has just been clicked?
Here we go:
$('.popOutDisplay a').click(function(e) {
e.preventDefault();
console.log($(this).data('id'));
});
Here the documentation of .data() attribute.
Demo: https://jsfiddle.net/ru4pjz3c/2/
You can use ".click()" for this. check snippet below..
$('.popOutDisplay a').click(function(e){
e.preventDefault();
var elID = $(this).data('id');
console.log(elID);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<div>
<div class="icons">
<div class="group popOutDisplay">
<i class="fa fa-home"></i>
<i class="fa fa-search"></i>
<i class="fas fa-bicycle"></i>
</div>
<div class="group">
<i class="fa fa-globe"></i>
</div>
<div class="group bottom">
<i class="fa fa-trash"></i>
</div>
</div>
<div class="content">
<div id="128910";>
<p>some content</p>
</div>
<div id="239019";>
</div>
<div id="346653";>
</div>
</div>
</div>
$(".group a").click(function(){
var data=$(this).attr("data-id");
alert(data)
});
To retrieve the value's attribute as a string without any attempt to convert it, use the attr() method.
$(document).on("click", "[data-id]", function (event){
event.preventDefault();
var id = $(this).attr("data-id");
// Apply your logic here
// $("#" + id)
});
bind click event listener on the a element container div <div class="group popOutDisplay". the reason is because click events on the a elements will bubble up to div container.
something like
$('.group.popOutDisplay').bind('click', function(e) {
var target = e.target;
if (target.tagName.toLowerCase() === 'a') {
e.preventDefault(); //prevent the default action of navigating to the url
var id = target.dataset.id;
//you now have the id;
$('#' + id).css('display', 'block'); //display the div
}
});
Hello I want to toggle one specific panel but if I click on the button the panels of other objects will be opened. How can I just open the clicked panel?
toggle.component.ts
opened:Boolean=false;
toggle () {
this.opened = !this.opened;
}
HTML
<div class="main" *ngFor="let x of data; let i=index;">
<footer>
<div class="icons">
<span id="{{item.id}}" (click)="toggle()">6<i class="fa fa-users {{i}}" ></i></span>
<span >6<i class="glyphicon glyphicon-picture"></i></span>
<span >6<i class="glyphicon glyphicon-tag"></i></span>
<div class="iconsRight pull-right">
<span >EXIF<i class="glyphicon glyphicon-info-sign"></i></span>
<span ><i class="fa fa-map-marker"></i></span>
<span ><i class="fa fa-share-alt-square"></i></span>
</div>
</div>
</footer>
<div class="togglePanel{{item.id}}" *ngIf="opened" >
<hr/>
<ul class="toggleWrapper">
<li>YES</li>
<hr/>
<li>YES</li>
<hr/>
<li>YES</li>
<hr/>
<li>YES</li>
</ul>
</div>
</div>
You need to save state of individual panel. Currently you just set one variable which toggles all the panels.
In your toggle.component.ts, add a variable to store every item's state:
togglePanel: any = {};
Then, change your html to following:
<div class="main" *ngFor="let x of data; let i=index;">
<footer>
<div class="commentAgent">Text des Bewerters, der die Bearbeitung dieses Bildes vorgenommen hat</div>
<div class="icons">
<span id="{{item.id}}" (click)="togglePanel[i] = !togglePanel[i]">6<i class="fa fa-users {{i}}" ></i></span>
<span>6<i class="glyphicon glyphicon-picture"></i></span>
<span>6<i class="glyphicon glyphicon-tag"></i></span>
<div class="iconsRight pull-right">
<span>EXIF<i class="glyphicon glyphicon-info-sign"></i>/span>
<span><i class="fa fa-map-marker"></i></span>
<span><i class="fa fa-share-alt-square"></i></span>
</div>
</div>
</footer>
<div class="togglePanel{{item.id}}" *ngIf="togglePanel[i]">
<hr/>
<ul class="toggleWrapper">
<li>YES</li>
<hr/>
<li>YES</li>
<hr/>
<li>YES</li>
<hr/>
<li>YES</li>
</ul>
</div>
</div>
Also, you don't need the toggle() method and the variable opened in this approach.
If you need only one panel opened, then this method will work. Instead on setting your 'flag' property boolean, use number. It will keep the panel id. Set it to the panel id and you don't need an additional property on your data:
Typescript:
opened = -1;
toggle (index) {
this.opened = index;
}
HTML:
....
<span id="{{item.id}}" (click)="toggle(item.id)">6<i class="fa fa-users {{i}}" ></i>
...
<div class="togglePanel{{item.id}}" *ngIf="opened===item.id" >