Angular5 with HTML5 Drag and Drop - javascript

I try to use HTML5 Drag and Drop inside an Angular5 Component.
Where do I have to place my function in order to get it to work?
HTML example:
<div class="itemBox">
<div *ngFor="let count of this.modul.getSemesterCollums(input.maxKlausur)" id="{{ count }}" class="semesterBox" ondrop="drop(event)" ondragover="allowDrop(event)">
<a *ngFor="let item of this.modul.getArray(); let i = index">
<div *ngIf="item.getIDSemesterInt(input.maxKlausur, this.i) == (count + 1)" id="{{ item.getName() }}" class="item" draggable="true" ondragstart="drag(event)">
<p>{{item.getName()}}</p>
<hr/>
<ul>
<li>Übung: {{item.getUebungen()}}</li>
<li>Klausur: {{item.getKlausur()}}</li>
<li>Semester: {{item.getSemester()}}</li>
<li>Bestanden: <i class="fa fa-times"></i></li>
</ul>
</div>
</a>
</div>
</div>
Javascript Example:
function allowDrop(ev) {
ev.preventDefault();
if (ev.target.getAttribute("draggable") == "true")
ev.dataTransfer.dropEffect = "none"; // dropping is not allowed
else
ev.dataTransfer.dropEffect = "all"; // drop it like it's hot
}
it won't find it inside the component.ts and it won't find it inside "" Tags in the component.html.
Thanks for your time :)

fixed it.
Inserted the function in the export class:
export class DropComponent {
allowDrop(ev) {
ev.preventDefault();
if (ev.target.getAttribute("draggable") == "true")
ev.dataTransfer.dropEffect = "none"; // dropping is not allowed
else
ev.dataTransfer.dropEffect = "all"; // drop it like it's hot
}
[.....]
}
And I edit the HTML as following:
<div class="itemBox">
<div *ngFor="let count of this.modul.getSemesterCollums(input.maxKlausur)" id="{{ count }}" class="semesterBox" (drop)="drop($event)" (dragover)="allowDrop($event)">
<a *ngFor="let item of this.modul.getArray(); let i = index">
<div *ngIf="item.getIDSemesterInt(input.maxKlausur, this.i) == (count + 1)" id="{{ item.getName() }}" class="item" draggable="true" (dragstart)="drag($event)">
<p>{{item.getName()}}</p>
<hr/>
<ul>
<li>Übung: {{item.getUebungen()}}</li>
<li>Klausur: {{item.getKlausur()}}</li>
<li>Semester: {{item.getSemester()}}</li>
<li>Bestanden: <i class="fa fa-times"></i></li>
</ul>
</div>
</a>
</div>
</div>
And it works like a charm :)

Related

filtering category with detach()

Help me with detach () function.
I figured out how it works, but I need help in applying it, in my case now it deletes all the selected categories, but you need to do the opposite so that all categories except the selected one are deleted. Is it necessary to somehow put everything except the selected one into a class and use detach () or what is better?
html
<div class="blog-filter">
<div class="blog-filter_item active js-filter-blog-list" data-filter="all">All</div>
</div>
<div class="blog-filter-container">
<div class="container">
<h1 class="blog-filter-title">Choose Category</h1>
<div class="item-wrapper">
<div class="blog-filter_item active" data-filter="all">All</div>
#foreach($categories as $category)
<div class="blog-filter_item" data-filter=".category_{{$category->id}}">{{ $category->title }} ({{ $category->articles_count }})</div>
#endforeach
</div>
</div>
</div>
<div class="blog-list">
#foreach($articles as $article)
<div class="blog-article category_{{ $article->blog_category_id }}">
<h2 class="blog-article__title">{{ $article->title }}</h2>
</div>
#endforeach
</div>
js
var divs;
$('.blog-article').each(function(i){
$(this).data('initial-index', i);
});
document.querySelectorAll('.blog-filter_item').forEach(el => {
el.addEventListener('click', () => {
document
.querySelector('.blog-filter_item.active')
.classList.remove('active');
el.classList.add('active');
var dataFilter = $(el).attr('data-filter');
$(divs).appendTo('.blog-list').each(function(){
var oldIndex = $(this).data('initial-index');
$('.blog-article').eq(oldIndex).before(this);
});
divs = null;
if (dataFilter == 'all') {
$('.blog-article').show();
}
else {
divs = $(dataFilter).detach();
$('.blog-article').show();
}
});
});
Solution:
divs = $('.blog-article').not(dataFilter).detach();

selecting elements javascript

I'm making a script that will notify you when someone is online on whatsapp web and i have this:
var onlineCheck = window.setInterval(function() {
var y = document.getElementsByClassName("emojitext ellipsify")[19];
if (y == null) {
console.log("online notification failed");
} else {
if (y.innerText === 'online') {
new Notification("contact is online");
window.clearInterval(onlineCheck);
}
}
},1000);
now the problem is that i'm selecting an element by the class "emojitext ellipsify" th 19th and if someone texts me another element with the class "emojitext ellipsify" will be made and the 19th won't be the status anymore, so i want to know if i can select an element with the same method from css which is : element>element
like this (div#main>header.pane-header pane-chat-header>div.chat-body>div.chat-status ellipsify>span.emojitext ellipsify)
or any other possible way.
var onlineCheck = window.setInterval(function() {
var y = document.getElementsByClassName("emojitext ellipsify")[19];
if (y == null) {
console.log("online notification failed");
} else {
if (y.innerText === 'online') {
new Notification("contact is online");
window.clearInterval(onlineCheck);
}
}
}, 1000);
<header class="pane-header pane-chat-header">
<div class="chat-avatar">
<div class="avatar icon-user-default" style="*somestyle*">
<div class="avatar-body">
<img src="*srcpath*" class="avatar-image is-loaded">
</div>
</div>
</div>
<div class="chat-body">
<div class="chat-main">
<h2 class="chat-title" dir="auto">
<span class="emojitext ellipsify" title="*person'sname*"><!-- react-text: 3216 -->*person'sname*<!-- /react-text --></span>
</h2>
</div>
<div class="chat-status ellipsify">
<span class="emojitext ellipsify" title="typing…"><!-- react-text: 3219 -->*the info that i need to get(typing…)*<!-- /react-text --></span>
</div>
</div>
<div class="pane-chat-controls">
<div class="menu menu-horizontal">
<div class="menu-item">
<button class="icon icon-search-alt" title="Search…"></button>
<span></span>
</div>
<div class="menu-item">
<button class="icon icon-clip" title="Attach"></button>
<span></span>
</div>
<div class="menu-item">
<button class="icon icon-menu" title="Menu"></button>
<span></span>
</div>
</div>
</div>
</header>
What you are looking for is document.querySelectorAll
With that function, you can select elements with a selector, the same used with css. So, you could do this:
document.querySelectorAll(".emojitext.ellipsify")
Or put a better selector, in order to get the desired elements, and not others.
Your example would be:
document.querySelectorAll("div#main>header.pane-header pane-chat-header>div.chat-body>div.chat-status ellipsify>span.emojitext.ellipsify")
You could use JQuery, much simpler
$('parent > child')
https://api.jquery.com/child-selector/

how to dynamically set text to an element in jquery

i have an onclick function that that calls a changeName function anytime a click event on that element happens.
function changeName() {
var frag = $('<span class="Name">change me</span>');
$( ".list" ).prepend(frag);
var x =[];
$('.ch-gname').each(function(index, obj)
{
x.push($(this).text());
for(i=0; i<x.length; i++) {
$('.Name').text(x[i]);}}});
$('#action').on('click', changeName);
HTML
<div>
<a href="#0" class="cb-pgcar"</a>
<span class="ch-gname">Greenhouse</span>
</div>
<div>
<a href="#0" class="cb-pgcar"</a>
<span class="ch-gname">tree house</span>
</div>
<div>
<a href="#0" class="cb-pgcar"</a>
<span class="ch-gname">light house</span>
</div>
<div class="list">
</div>
<div class="list">
</div>
<div class="list">
</div>
i want to able to change the text of the class Name to the text of class ch-gname. My function gives me only the last text text(lighthouse) for the three links.Any help please
The function changeName() has $('#action').on('click', changeName); but i do not see any element with id 'action'. Anyhow i've made necessary changes in order to make it work.
Added Action id to the elements
Changed the $('.Name').text(x[i]); to $('.Name')[i].innerHTML = x[i];
Look at the below example
function changeName() {
var frag = $('<span class="Name">change me</span>');
$(".list").prepend(frag);
var x = [];
$('.ch-gname').each(function(index, obj) {
x.push($(this).text());
});
for (i = 0; i < x.length; i++) {
$('.Name')[i].innerHTML = x[i];
}
}
$('#action').on('click', changeName);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<a href="#0" class="cb-pgcar" </a>
<span id="action" class="ch-gname">Greenhouse</span>
</div>
<div>
<a href="#0" class="cb-pgcar" </a>
<span id="action" class="ch-gname">tree house</span>
</div>
<div>
<a href="#0" class="cb-pgcar" </a>
<span id="action" class="ch-gname">light house</span>
</div>
<div class="list">
</div>
<div class="list">
</div>
<div class="list">
</div>

angular2 bootstrap dynamic carousel

I have a dynamic images coming from a json and doing *ngFor to loop through the objs and putting it in a carousel using bootstrap carousel, but I want to put a readmore link within the *ngFor so each item will have a read more.
I can't figure out how to do when a user click "readmore" it will scroll to its relative item showing about the image if that makes sense.
<div class="col-sm-4" *ngFor="let journey of Journey">
<div class="journey_block">
<div class="icon-workflow">
<div class="view view-fourth">
<img src="{{ journey.imageName }}" alt="">
<div class="mask">
Read More
</div>
</div>
<h4 class="journey_title">
<a [href]="journey.journey_url" *ngIf="journey.journey_url != 'javascript:;' " class="float-shadow">
{{journey.title}}
</a>
</h4>
</div>
</div>
My attempt is I thought I would then need to do for loop, I have 5 items in total in the json data.
getImg() {
this.http.get('./journey.json')
.map((res:Response) => res.json())
.subscribe(data => {
if(data) {
var jsonObj = JSON.parse(JSON.stringify(data));
this.Journey = jsonObj.journey;
for (var i = 0; i < this.Journey.length; i++) {
var element = this.Journey[i];
this.objCount = element;
console.log(this.objCount);
}
}
});
};
View full html structure of the carousel
Carousel structure
You need to have the index inside of the loop for making the data-slide-to attribute unique. This could be done by the predefined Angular2 value index.
Example
<!-- Angular 2.0 -->
<ul>
<li *ngFor="let item of items; let i = index">
{{i}} {{item}}
</li>
</ul>
In your code:
<div class="col-sm-4" *ngFor="let journey of Journey; let i = index">
<div class="journey_block">
<div class="icon-workflow">
<div class="view view-fourth">
<img src="{{ journey.imageName }}" alt="">
<div class="mask">
Read More
</div>
</div>
<h4 class="journey_title">
<a [href]="journey.journey_url" *ngIf="journey.journey_url != 'javascript:;' " class="float-shadow">
{{journey.title}}
</a>
</h4>
</div>
</div>

how to create generic html with javascript

I have the following html:
<div id="prog" class="downloads clearfix">
<div class="item">
<div class="image_container">
<img src="/img/downloads/company.png" width="168" height="238" alt="">
</div>
<div class="title">
pricelist: <label id="pr1"></label>
</div>
<div class="type">
pdf document
</div>
<div class="link">
<a id="pdfdocument" class="button" target="_blank" href="#">start Download </a>
</div>
</div>
</div>
I want build HTML which is inside the <div id="prog"> with Javascript:
<div id="prog" class="downloads clearfix"></div>
I'm trying to use this Javascript, but without success:
var tmpDocument, tmpAnchorTagPdf, tmpAnchorTagXls, parentContainer, i;
parentContainer = document.getElementById('prog');
for (i = 0; i < documents.length; i++) {
tmpDocument = documents[i];
tmpAnchorTagPdf = document.createElement('a id="pdfdocument" ');
tmpAnchorTagPdf.href = '/role?element=' + contentElement.id + '&handle=' + ope.handle;
tmpAnchorTagPdf.innerHTML = 'start Download';
tmpAnchorTagXls = document.createElement('a');
tmpAnchorTagXls.href = '/role?element=' + contentElement.id + '&handle=' + ope.handle;
tmpAnchorTagXls.innerHTML = 'start Download';
parentContainer.appendChild(tmpAnchorTagPdf);
parentContainer.appendChild(tmpAnchorTagXls);
}
If this is a section of code that you will be using more than once, you could take the following approach.
Here is the original div without the code you want to create:
<div id="prog" class="downloads clearfix">
</div>
Create a template in a hidden div like:
<div id="itemtemplate" style="display: none;">
<div class="item">
<div class="image_container">
<img src="/img/downloads/company.png" width="168" height="238" alt="">
</div>
<div class="title">
pricelist: <label></label>
</div>
<div class="type">
pdf document
</div>
<div class="link">
<a class="button" target="_blank" href="#">start Download </a>
</div>
</div>
</div>
Then duplicate it with jquery (OP originally had a jquery tag; see below for JS), update some HTML in the duplicated div, then add it to the document
function addItem() {
var item = $("#itemtemplate div.item").clone();
//then you can search inside the item
//let's set the id of the "a" back to what it was in your example
item.find("div.link a").attr("id", "pdfdocument");
//...the id of the label
item.find("div.title label").attr("id", "pr1");
//then add the objects to the #prog div
$("#prog").append(item);
}
update
Here is the same addItem() function for this example using pure Javascript:
function JSaddItem() {
//get the template
var template = document.getElementById("itemtemplate");
//get the starting item
var tempitem = template.firstChild;
while(tempitem != null && tempitem.nodeName != "DIV") {
tempitem = tempitem.nextSibling;
}
if (tempitem == null) return;
//clone the item
var item = tempitem.cloneNode(true);
//update the id of the link
var a = item.querySelector(".link > a");
a.id = "pdfdocument";
//update the id of the label
var l = item.querySelector(".title > label");
l.id = "pr1";
//get the prog div
var prog = document.getElementById("prog");
//append the new div
prog.appendChild(item);
}
I put together a JSFiddle with both approaches here.

Categories