Can any one tell me are there any good references for learning Angular2 drag and drop?
I don't know any references. But if your drag'n'drop solution is HTML5 based, maybe you can make use of HostListener decorator from '#angular/core' to hack your drag and drop exchange logic:
HostListeners provide you ways to implement conventional listeners for element events like onmousedown, onkeyup, ondrop, ondragstart.
You can add something like this on your drop area component:
#HostListener('drop', ['$event'])
onDrop(event: any) {
//do something
}
And you can add something like this on your draggable component:
#HostListener('dragstart', ['$event'])
onDrag(event: any) {
//do something
}
The rest is think of some logic to identifiy what's being dragged/dropped and change the drag area component model.
Here's some functional code I've made inspired by W3Schools topic on drag'n'drop (http://www.w3schools.com/html/html5_draganddrop.asp):
import { Component, HostListener, Input } from '#angular/core';
// The draggable component
#Component({
selector: 'dragme',
template: `
<div draggable="true">
Drag {{name}}!
</div>
`,
styles: [`
[draggable] {
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
user-select: none;
-khtml-user-drag: element;
-webkit-user-drag: element;
background-color: #AAA;
border: 1px solid black;
padding: 24px;
margin: 12px;
}
`]
})
export class DragMe {
#Input()
name:string = "";
#HostListener('dragstart', ['$event'])
onDrag(event:any){
event.dataTransfer.setData("name",this.name);
}
}
// The drop area component
#Component({
selector: 'drop',
template: `
<div class="drop">
Drop over me!
<ul>
<li *ngFor="let i of items">{{i}}</li>
</ul>
</div>
`,
styles: [`
.drop{
border: 1px solid black;
padding: 24px;
}
`]
})
export class DropOverMe {
items:string[] = [];
#HostListener('dragover', ['$event'])
onDragover(event:any){
event.preventDefault();
}
#HostListener('drop', ['$event'])
onDrop(event:any){
event.preventDefault();
var name = event.dataTransfer.getData("name");
this.items.push(name);
}
}
// The functional example
#Component({
selector: "drag-example",
template: `
<dragme name="Bob"></dragme>
<dragme name="Alice"></dragme>
<dragme name="Carl"></dragme>
<drop></drop>
`
})
export class DragExample{
}
Full code at: https://github.com/rafaelodon/angular2-html5-dragndrop-example
The angular2-grid plugin gives grid-based directives for angular2. Maybe it can help in your case!
This is the github repo and you can find a working example there
Related
i'm doing the Free Code Camp "Random Quote Machine" project in svelte
here :
https://learn.freecodecamp.org/front-end-libraries/front-end-libraries-projects/build-a-random-quote-machine
I try to do a "scale" transition to the quote component. the transition is working only on the first time. I understand that I need to create and destroy the DOM element every time , like it is in the documentation :
"A transition is triggered by an element entering or leaving the DOM as a result of a state change".
how to do it correct ?
my App component :
<script>
import {onMount} from 'svelte'
import Quote from './Quote.svelte'
import Button from './Button.svelte'
let quotes=""
let quote=""
onMount(async ()=> {
const res=await fetch('https://gist.githubusercontent.com/natebass/b0a548425a73bdf8ea5c618149fe1fce/raw/f4231cd5961f026264bb6bb3a6c41671b044f1f4/quotes.json')
quotes=await res.json()
let r=Math.ceil(Math.random()*quotes.length)
quote= quotes[r]
})
const handleClick=()=>{
quote=quotes[Math.ceil(Math.random()*quotes.length)]
}
</script>
<style>
#quote-box {
margin: 50px auto;
width: 50%;
border: 3px solid green;
padding: 10px;
text-align: center;
background: whitesmoke;
}
</style>
<div id="quote-box">
<Quote {quote} />
<Button on:newQ={handleClick}
id="new-quote">New Quote</Button>
<Button
href="{`https://twitter.com/intent/tweet?text="${quote.quote}"-${quote.author}`}"
{quote} id="tweet-quote">
Twit</Button>
</div>
my Button component (it's the same component to the "twit" button with "a" tag, and to the newQuote button):
<script>
import { createEventDispatcher } from 'svelte';
export let href
export let quote
export let id
export let color
const dispatch=createEventDispatcher()
function twit() {
dispatch('twit',"");
}
function newQuote() {
dispatch('newQ',"");
}
</script>
<style>
button, a {
/* background-color:#008CBA; */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 10px;
}
#tweet-quote{
background-color:#008CBA;
}
#new-quote {
background-color: #f44336;
}
</style>
{#if href}
<a {id} target="_blank" {href} ><slot/></a>
{:else }
<button {id} on:click={newQuote}><slot/></button>
{/if}
my Quote component :
<script>
import { scale } from 'svelte/transition';
export let quote
</script>
{#if quote}
<div class="container" transition:scale>
<p id="text">{quote.quote}</p>
<p id="author">{quote.author}</p>
</div >
{:else}
<p>loading</p>
{/if}
One quite simple way to do this is to set the quote to null, hiding the element, and then wait for a timeout before updating the quote, resulting in the div hiding and re-appearing REPL example
Been trying to change footer background but I cant get it right. I have a color for each tag but only the last tag is changed (blue - #0000ff) . How does one do styling in Ionic 4?
<template>
<ion-footer>
<ion-toolbar>
<ion-title v-if="loggedIn">
<a href="https://www.facebook.com/" target="_blank">
<ion-icon name="logo-facebook"></ion-icon>
</a>
<a href="https://www.instagram.com/" target="_blank">
<ion-icon name="logo-instagram"></ion-icon>
</a>
</ion-title>
</ion-toolbar>
</ion-footer>
</template>
<script>
export default {
name: "pageFooter",
computed: {
loggedIn() {
return this.$store.getters.loggedIn;
}
}
};
</script>
<style lang="scss">
ion-footer {
background-color: #ff0000;
ion-toolbar {
background-color: #00FF00;
ion-title {
background-color: #0000ff;
a {
font-size: 25px;
color: #000;
}
}
}
}
</style>
It has something to do with "shadow dom" concept which I dont fully undersrtand yet . This DOM structure for the footer.
Ionic 4 uses web components, so the way to style components in Ionic 4 is to use the CSS variables that Ionic provides.
In your case, set the --background property of the component:
ion-footer {
--background: #ff0000;
}
I have a background image that I want to have full screen with an input section at the bottom. When the input is focused, the keyboard appears and shrinks the image to fit the screen. What I want is for the image to push the full div up without re-sizing it.
I've tried numerous things, but my current attempt is as follows:
.background{
url('assets/background.png') center center fixed;
height: 100%;
width: 100%;
}
.input-area{
position: absolute;
left: 10px;
bottom: 10px;
right: 10px;
}
<div class="background">
<div class="input-area">
//textboxes
</div>
</div>
This seems like it should be easy to accomplish, but can't get the desired outcome. Any input would be appreciated, thanks.
ionic cli 4.12.0
#ionic/angular 4.4.0
#ionic-native 5.5.1
node v10.15.2
npm 6.4.1
cordova 8.1.2 (cordova-lib#8.1.1)
this is how I managed to do it:
I added an id to my ion-content and ion-toolbar in html file to reference them in my typescript file
...
<ion-content #content >
...
<ion-toolbar #toolbar color="light">
<ion-input #input >...
...
in my typescript I referenced them with ViewChild and added the functionality in the constructor like this
...
#ViewChild('content', {read: ElementRef}) contentRef: ElementRef;
#ViewChild('toolbar', {read: ElementRef}) toolbarRef: ElementRef;
...
private startkeyboardAnimationTimestamp = 0;
private endkeyboardAnimationTimestamp = 0.3;
private keyboardAnimationDuration = 0.3;
...
constructor(private renderer: Renderer2) {
if (this.platform.is('capacitor')) {
window.addEventListener('keyboardWillShow', (e) => {
this.startkeyboardAnimationTimestamp = Date.now();
this.keyboardHeight = (<any>e).keyboardHeight;
this.renderer.setStyle(this.contentRef.nativeElement, 'transform', `translate3d(0, ${-this.keyboardHeight}px, 0)`);
this.renderer.setStyle(this.contentRef.nativeElement, 'transition', `${this.keyboardAnimationDuration}s ease-in-out`);
this.renderer.setStyle(this.toolbarRef.nativeElement, 'transform', `translate3d(0, ${-this.keyboardHeight}px, 0)`);
this.renderer.setStyle(this.toolbarRef.nativeElement, 'transition', `${this.keyboardAnimationDuration}s ease-in-out`);
window.addEventListener('keyboardDidShow', (e) => {
this.endkeyboardAnimationTimestamp = Date.now();
});
window.addEventListener('keyboardWillHide', () => {
this.renderer.setStyle(this.contentRef.nativeElement, 'transform',
`translate3d(0, 0px, 0)`);
this.renderer.setStyle(this.toolbarRef.nativeElement, 'transform',
`translate3d(0, 0px, 0)`);
});
...
** as for the keyboardAnimationDuration I have it default to 0.3s and update it after the first show and hide.
This worked for me:
in the AndroidManifest.xml
android:windowSoftInputMode="adjustResize"
In the scss:
ion-content{
--background: url("./../../../assets/img/login-bg.jpg") no-repeat fixed center;
padding: 0;
}
I am trying to give a div with class "left2" a border-radius when class "left1_sub" is hovered.
I´ve searched a lot of solutions, but nothing seems to work for me.
The html to it: http://web318.login-11.hoststar.at/ben/kleinraum/wp/menuimg/index.html
and the full css: http://web318.login-11.hoststar.at/ben/kleinraum/wp/menuimg/style.css
.left1_sub{
padding-top:2%;
padding-bottom:2%;
width: 100%;
float: left;
background-color: #cccccc
}
.left1_sub:hover ~ .left2 {border-radius: 10px;}
.left2{
float: left;
margin-right: 20px;
margin-top: 20px;
width: 500px;
height:600px;
background-color: #ccccff
}
Just introducing myself to css3 so sorry if there are failures.
ben
This can be done very easily with jQuery or something similar.
If are comfortable using jQuery something like this would work.
First, create a class in CSS with a border radius:
.rounded { border-radius: 5px; /* (or whatever) */ }
Then, in <script> tags:
jQuery(document).ready(function($) {
var obj = $('.left1_sub'),
target = $('.left2');
obj.hover(
//mouse in
function(){
target.addClass('rounded');
//mouse out
},function(){
target.removeClass('rounded');
});
});
http://jsfiddle.net/wGzgB/11/
I'm just trying to print back to better understand how to move around the tree traversal using console.log.
When I click on a parent I'd like to print back it's children. I thought it would be easy as
console.log($(event.target).children());
I've tried to use
console.log($(event.target).children("ul li a"));
It gives me []. I'm looking to print out the child's ID.
HTM:
<body>
<div class = "testButton">
<ul>
<li>
Parent One
<ul>
<li> P1 child </li>
</ul>
Parent Two
<ul>
<li> P2 child </li>
</ul>
Parent Three
<ul>
<li> P3 child </li>
</ul>
Parent Four
<ul>
<li> P4 child </li>
</ul>
</li>
</ul>
</div>
</body>
</html>
CSS:
.testButton ul {
list-style-type: none;
padding-left: 0;
margin-left: 0;
}
.testButton li {
display: inline;
}
.testButton a {
display: block;
width: 6em;
text-align: center;
text-decoration: none;
margin: 0em auto .14em;
padding: .1em .5em .1em .5em;
font-size: 2.5em;
}
.upButton {
background-color: #ccc;
color: #000;
}
.overButton {
background-color: #222;
color: #fff;
}
.outButton {
background-color: #ccc;
color: #000;
}
.clickButton {
background-color: #F90;
color: #222;
}
JS:
google.load('jquery', '1.6.2');
google.setOnLoadCallback(function(){
$(".testButton a").addClass("upButton");
$(".testButton a").mouseover(function(event){
$(event.target).removeClass("outButton").addClass("overButton");
});
$(".testButton a").mouseout(function(event){
$(event.target).addClass("outButton");
});
$(".testButton a").click(function(event){
$(".testButton a").removeClass("clickButton");
$(event.target).addClass("clickButton");
$(this).blur();
console.log($(event.target));
console.log($(event.target).children());
console.log($(event.target).parent().children());
console.log($(event.target).siblings());
});
});
This should do the trick for the structure of your ul/li/a tags.
DEMO
For the demo I have just simply alerted the ids for you. You can change these to console.log if you like. So now what I did...
$('.button').click(function() {
$(this).next('ul').children().each(function() {
alert($(this).children('a').attr('id'));
});
});
I added a class 'button' to each of your parents just to make it clear. So now when any item with a class 'button' is clicked, we get the next 'ul' in your html structure - (next() gets the next element at the same hierachy level of your code). Then for each child within that 'ul' I have alerted the id of each anchor within each child (as your structure is <li><a id="..."></li>).