Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit 6411bb5

Browse files
committed
docs(cookbook - jquery plugins)
tweak ignore fix array core shim e2e
1 parent b669e30 commit 6411bb5

File tree

15 files changed

+319
-0
lines changed

15 files changed

+319
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/// <reference path='../_protractor/e2e.d.ts' />
2+
'use strict';
3+
/* tslint:disable:quotemark */
4+
describe('Drag and Drop', function () {
5+
6+
beforeAll(function () {
7+
browser.get('');
8+
});
9+
10+
it('should drag hero to assignment', function () {
11+
12+
let assignment1 = element.all(by.css('.assignment')).get(0);
13+
14+
let hero1 = element.all(by.css('.hero')).get(0);
15+
16+
browser.actions()
17+
.dragAndDrop(hero1 as any as webdriver.WebElement,
18+
assignment1 as any as webdriver.WebElement)
19+
.perform();
20+
21+
let heroAssignment = element.all(by.xpath('//div[text()="Help Granny cross the street"]/following-sibling::ul/li[text()="Mr. Nice"]'));
22+
expect(heroAssignment.count()).toBe(1);
23+
24+
let doneButton = element(by.xpath('//div[@data-hero="Mr. Nice"]/div/button'));
25+
26+
// Remove Mr. Nice
27+
doneButton.click().then(function(){
28+
let remainingHeroes = element.all(by.css('.hero'));
29+
expect(remainingHeroes.count()).toBe(3);
30+
});
31+
});
32+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
**/*.js
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// #docregion
2+
import { Component } from '@angular/core';
3+
import { HeroAssignmentComponent } from './hero-assignment.component';
4+
import { HeroComponent } from './hero.component';
5+
6+
@Component({
7+
selector: 'my-app',
8+
template: `
9+
<div id="hero-wrapper">
10+
<h2>Hero Assignments</h2>
11+
<div *ngFor="let assignment of assignments">
12+
<cb-assignment [title]="assignment"></cb-assignment>
13+
</div>
14+
<div class="heroList">
15+
<div *ngFor="let hero of heroes">
16+
<cb-hero (remove)="removeHero($event)" [name]="hero"></cb-hero>
17+
</div>
18+
</div>
19+
</div>
20+
`,
21+
directives: [HeroAssignmentComponent, HeroComponent]
22+
})
23+
export class AppComponent {
24+
heroes = ['Mr. Nice',
25+
'Bombasto',
26+
'Celeritas',
27+
'Tornado'];
28+
29+
assignments = ['Help Granny cross the street',
30+
'Rescue village from dragon(s)',
31+
'Rescue princess from tower'];
32+
33+
removeHero(heroToRemove: string) {
34+
this.heroes = this.heroes.filter(hero => hero !== heroToRemove);
35+
}
36+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<!-- #docregion -->
2+
<div #assignment class="assignment" [ngClass]="{selected: heroDropped}">
3+
<div>{{title}}</div>
4+
<ul>
5+
<li *ngFor="let hero of assignedHeroes">{{hero}}</li>
6+
</ul>
7+
</div>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// #docregion
2+
import { Component, Input, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
3+
4+
declare var jQuery: any;
5+
6+
@Component({
7+
selector: 'cb-assignment',
8+
templateUrl: 'app/hero-assignment.component.html'
9+
})
10+
export class HeroAssignmentComponent implements AfterViewInit {
11+
@Input() title: string;
12+
@ViewChild('assignment') assignment: ElementRef;
13+
14+
assignedHeroes: string[] = [];
15+
16+
// #docregion add-plugin
17+
ngAfterViewInit() {
18+
jQuery(this.assignment.nativeElement).droppable({drop : (event: any, ui: any) => {
19+
let heroName = ui.draggable.data('hero');
20+
if (this.assignedHeroes.indexOf(heroName) === -1) {
21+
this.assignedHeroes = [...this.assignedHeroes, heroName];
22+
}
23+
}});
24+
}
25+
// #enddocregion add-plugin
26+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!-- #docregion -->
2+
<div #hero class="hero" [attr.data-hero]="name">
3+
{{name}}
4+
<div><button (click)="done()">Done</button></div>
5+
</div>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// #docregion
2+
import { Component, Input, Output, AfterViewInit, ViewChild, ElementRef, EventEmitter } from '@angular/core';
3+
4+
// #docregion declare-jquery
5+
declare var jQuery: any;
6+
// #enddocregion declare-jquery
7+
@Component({
8+
selector: 'cb-hero',
9+
templateUrl: 'app/hero.component.html'
10+
})
11+
export class HeroComponent implements AfterViewInit {
12+
@Input() name: string;
13+
@Output() remove: EventEmitter<string> = new EventEmitter<string>();
14+
@ViewChild('hero') hero: ElementRef;
15+
16+
// #docregion add-plugin
17+
ngAfterViewInit() {
18+
jQuery(this.hero.nativeElement).draggable({revert: 'invalid'});
19+
}
20+
// #enddocregion add-plugin
21+
22+
done() {
23+
this.remove.emit(this.name);
24+
}
25+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { bootstrap } from '@angular/platform-browser-dynamic';
2+
3+
import { AppComponent } from './app.component';
4+
5+
bootstrap(AppComponent, [])
6+
.catch((err: any) => console.error(err));

public/docs/_examples/cb-jquery-plugin/ts/example-config.json

Whitespace-only changes.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>JQuery Plugin</title>
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<!-- #docregion style -->
7+
<link rel="stylesheet" href="styles.css">
8+
<link rel="stylesheet" href="sample.css">
9+
<!-- #enddocregion style -->
10+
11+
<!-- Polyfill(s) for older browsers -->
12+
<script src="node_modules/core-js/client/shim.min.js"></script>
13+
14+
<script src="node_modules/zone.js/dist/zone.js"></script>
15+
<script src="node_modules/reflect-metadata/Reflect.js"></script>
16+
<script src="node_modules/systemjs/dist/system.src.js"></script>
17+
18+
<!-- #docregion jquery -->
19+
<script src="https://npmcdn.com/jquery@2.2.3"></script>
20+
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
21+
<!-- #enddocregion jquery -->
22+
23+
<script src="systemjs.config.js"></script>
24+
<script>
25+
System.import('app').catch(function(err){ console.error(err); });
26+
</script>
27+
28+
</head>
29+
30+
<body>
31+
<my-app>Loading app...</my-app>
32+
</body>
33+
34+
</html>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"description": "jQuery Plugin",
3+
"files":[
4+
"!**/*.d.ts",
5+
"!**/*.js",
6+
"!**/*.[1].*"
7+
],
8+
"tags":["cookbook"]
9+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
.hero{
2+
background: lightblue;
3+
border: 1px solid black;
4+
width: 100px;
5+
color:black;
6+
height: 50px;
7+
margin-bottom: 20px;
8+
text-align: center;
9+
padding-top: 30px;
10+
}
11+
12+
.assignment{
13+
background: darkblue;
14+
width: 250px;
15+
height: 150px;
16+
color:white;
17+
margin-right: 20px;
18+
text-align: center;
19+
padding-top: 10px;
20+
float: left;
21+
margin-bottom: 30px;
22+
}
23+
24+
.assignment li{
25+
text-align: left;
26+
}
27+
28+
.heroList{
29+
clear:both;
30+
}

public/docs/ts/latest/cookbook/_data.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
"hide": true
3939
},
4040

41+
"jquery-plugin": {
42+
"title": "jQuery Plugin Integration",
43+
"intro": "Integrate with jQuery plugins"
44+
},
4145
"set-document-title": {
4246
"title": "Set the Document Title",
4347
"intro": "Setting the document or window title using the Title service."
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
include ../_util-fns
2+
3+
:marked
4+
Using jQuery for direct DOM access is not recommended in Angular projects, but we do see value in supporting integration with third party jQuery plugins.
5+
6+
In this cookbook we show how to integrate `draggable` and `droppable` from jQuery UI to make it easier for our admins to assign new adventures to our brave heroes.
7+
8+
Before a hero can set out on a new quest, one of our admins will give the hero a new assignment by dragging and dropping the hero's name on top of the assignment.
9+
:marked
10+
**See the [live example](/resources/live-examples/cb-jquery-plugin/ts/plnkr.html)**.
11+
12+
<a id="toc"></a>
13+
:marked
14+
## Table of contents
15+
16+
[Add jQuery](#jquery-add)
17+
18+
[Drag](#drag)
19+
20+
[Drop](#drop)
21+
22+
.l-main-section
23+
<a id="jquery-add"></a>
24+
:marked
25+
## Add jQuery
26+
27+
Before we can start we have to add the necessary script references to load the jQuery library and the two plugins, `draggable` and `droppable`, from jQuery UI.
28+
29+
+makeExample('cb-jquery-plugin/ts/index.html', 'jquery', 'index.html (add jquery scripts)')(format=".")
30+
31+
:marked
32+
jQuery declares a global variable called`jQuery`, but this variable is not know to TypeScript. In order to reference `jQuery` in our TypeScript code we have to declare it as a TypeScript variable as well.
33+
34+
In our case we don't need to access the jQuery api, so it's unnecessary to add ambient typings for jQuery. Instead we will just declare `jQuery` as an `any` variable.
35+
36+
If we don't declare the `jQuery` variable, the TypeScript compiler will give us an error when we try to reference `jQuery` from our code.
37+
38+
+makeExample('cb-jquery-plugin/ts/app/hero.component.ts', 'declare-jquery', 'app/hero.component.ts (declare jquery)')(format=".")
39+
40+
.l-main-section
41+
<a id="drag"></a>
42+
:marked
43+
## Drag
44+
45+
`draggable` is a jQuery plugin that allows us to move an element on the screen. In the UI our admins will "drag" heroes and drop them on assignments.
46+
47+
`HeroComponent` is created to represent "draggable" hero elements.
48+
49+
+makeTabs(
50+
`cb-jquery-plugin/ts/app/hero.component.ts,
51+
cb-jquery-plugin/ts/app/hero.component.html`,
52+
null,
53+
`hero.component.ts,
54+
hero.component.html`
55+
)
56+
57+
:marked
58+
We want to be careful not to access the DOM directly, so we are using `@ViewChild` to access the target element for the `draggable` plugin.
59+
60+
`@ViewChild('hero')` declares a reference to an element in the template with a matching `#hero` variable reference.
61+
62+
:marked
63+
Now, we can go ahead and apply the draggable plugin to `this.hero.nativeElement` using familiar jquery syntax.
64+
+makeExample('cb-jquery-plugin/ts/app/hero.component.ts', 'add-plugin', 'app/hero.component.ts (add plugin)')(format=".")
65+
66+
:marked
67+
We apply the plugin in the `AfterViewInit` lifecycle hook since we know the component view has been fully initialized at this point.
68+
69+
.l-main-section
70+
<a id="drop"></a>
71+
:marked
72+
## Drop
73+
74+
`droppable` is used in tandem with draggable to create a drop-zone for dragged elements.
75+
76+
`HeroAssignmentComponent` represents an assignment that we can assign one or more heroes to using drag and drop.
77+
78+
+makeTabs(
79+
`cb-jquery-plugin/ts/app/hero-assignment.component.ts,
80+
cb-jquery-plugin/ts/app/hero-assignment.component.html`,
81+
null,
82+
`hero-assignment.component.ts,
83+
hero-assignment.component.html`
84+
)
85+
86+
:marked
87+
Same as with draggable, we are applying the droppable plugin in `AfterViewInit`.
88+
89+
`droppable` lets us specify a callback that executes when a hero is dropped on the assignment. We use this callback to manage an array of assigned heroes whenever a new hero is assigned.
90+
91+
+makeExample('cb-jquery-plugin/ts/app/hero-assignment.component.ts', 'add-plugin', 'app/hero-assignment.component.ts (add plugin)')(format=".")
92+
93+
:marked
94+
The final UI looks like this.
95+
96+
Our admin users can assign any given hero to multiple assignments by dragging and dropping.
97+
figure.image-display
98+
img(src="/resources/images/cookbooks/jquery-plugin/hero-assignments.png" alt="Hero Assignments")
99+
100+
:marked
101+
[Back to top](#top)
102+
103+
104+
Loading

0 commit comments

Comments
 (0)