diff --git a/demos/item-reorder/avatar-cher.png b/demos/item-reorder/avatar-cher.png new file mode 100644 index 0000000000..a06fff3590 Binary files /dev/null and b/demos/item-reorder/avatar-cher.png differ diff --git a/demos/item-reorder/avatar-dionne.png b/demos/item-reorder/avatar-dionne.png new file mode 100644 index 0000000000..521e0657b8 Binary files /dev/null and b/demos/item-reorder/avatar-dionne.png differ diff --git a/demos/item-reorder/avatar-murray.png b/demos/item-reorder/avatar-murray.png new file mode 100644 index 0000000000..a2f2df468a Binary files /dev/null and b/demos/item-reorder/avatar-murray.png differ diff --git a/demos/item-reorder/index.ts b/demos/item-reorder/index.ts new file mode 100644 index 0000000000..940b1e9ff1 --- /dev/null +++ b/demos/item-reorder/index.ts @@ -0,0 +1,88 @@ +import { Component, ViewEncapsulation } from '@angular/core'; + +import { ionicBootstrap, ItemSliding, NavController, Toast, reorderArray } from 'ionic-angular'; + +@Component({ + templateUrl: 'main.html', + encapsulation: ViewEncapsulation.None +}) +class ApiDemoPage { + chats: any[]; + editButton: string = 'Reorder'; + editing: boolean = false; + + constructor(private nav: NavController) { + this.chats = [ + { + img: './avatar-cher.png', + name: 'Cher', + message: 'Ugh. As if.', + time: '9:38 pm' + }, { + img: './avatar-dionne.png', + name: 'Dionne', + message: 'Mr. Hall was way harsh.', + time: '8:59 pm' + }, { + img: './avatar-murray.png', + name: 'Murray', + message: 'Excuse me, "Ms. Dione."', + time: 'Wed' + }, + { + img: './avatar-cher.png', + name: 'Cher', + message: 'Ugh. As if.', + time: '9:38 pm' + }, { + img: './avatar-dionne.png', + name: 'Dionne', + message: 'Mr. Hall was way harsh.', + time: '8:59 pm' + }, { + img: './avatar-murray.png', + name: 'Murray', + message: 'Excuse me, "Ms. Dione."', + time: 'Wed' + }, + { + img: './avatar-cher.png', + name: 'Cher', + message: 'Ugh. As if.', + time: '9:38 pm' + }, { + img: './avatar-dionne.png', + name: 'Dionne', + message: 'Mr. Hall was way harsh.', + time: '8:59 pm' + }, { + img: './avatar-murray.png', + name: 'Murray', + message: 'Excuse me, "Ms. Dione."', + time: 'Wed' + }]; + } + + toggleEdit() { + this.editing = !this.editing; + if (this.editing) { + this.editButton = 'Done'; + } else { + this.editButton = 'Reorder'; + } + } + + reorderData(indices: any) { + this.chats = reorderArray(this.chats, indices); + } +} + + +@Component({ + template: '' +}) +class ApiDemoApp { + root = ApiDemoPage; +} + +ionicBootstrap(ApiDemoApp); diff --git a/demos/item-reorder/main.html b/demos/item-reorder/main.html new file mode 100644 index 0000000000..5f71730195 --- /dev/null +++ b/demos/item-reorder/main.html @@ -0,0 +1,50 @@ + + + + Item Reorder + + + + + + + + + + + + + Chats + + + + + + + + +

{{chat.name}}

+

{{chat.message}}

+ + {{chat.time}} + +
+ +
+
+ +
+ + diff --git a/src/components/item/item-reorder-gesture.ts b/src/components/item/item-reorder-gesture.ts index 467d39723d..4962807cdb 100644 --- a/src/components/item/item-reorder-gesture.ts +++ b/src/components/item/item-reorder-gesture.ts @@ -1,5 +1,5 @@ import {Item} from './item'; -import {Reorder} from '../item/item-reorder'; +import {ItemReorder} from '../item/item-reorder'; import {UIEventManager} from '../../util/ui-event-manager'; import {closest, Coordinates, pointerCoord, CSS, nativeRaf} from '../../util/dom'; @@ -25,7 +25,7 @@ export class ItemReorderGesture { private events: UIEventManager = new UIEventManager(false); - constructor(public list: Reorder) { + constructor(public list: ItemReorder) { let element = this.list.getNativeElement(); this.events.pointerEvents(element, this.onDragStart.bind(this), diff --git a/src/components/item/item-reorder.ts b/src/components/item/item-reorder.ts index dcbbda9e45..03b2b4fd2a 100644 --- a/src/components/item/item-reorder.ts +++ b/src/components/item/item-reorder.ts @@ -6,13 +6,104 @@ import { Item } from './item'; import { ItemReorderGesture } from '../item/item-reorder-gesture'; import { isTrueProperty } from '../../util/util'; -export interface ReorderIndexes { + +export interface ReorderIndices { from: number; to: number; } /** - * @private + * @name ItemReorder + * @description + * ItemReorder can be used with `ion-list` or `ion-item-group` to provide a visual + * drap and drop interface for reordering of items in a list. + * + * ## Usage + * It is very important to follow the rules below in order to integrate reordering in your app. + * + * ### All items in a reorder list have to be part of the same set + * You can not have non-reorderable and reorderable items in the same list or item's group. + * + * ```html + * + * {{item.name}} + * ``` + * + * **GOOD!** + * + * ```html + * + * HEADER + * {{item.name}} + * + * ``` + * + * **BAD!** There is a `ion-list-header` that is not part of the same set. + * + * In order to mix different sets of items, `ion-item-group` has to be used: + * + * ```html + * + * HEADER + * + * {{item.name}} + * + * + * ``` + * + * **GOOD!** It's important to notice that in this case, the `[reorder]` directive it applied to `ion-item-group` instead of + * `ion-list`. This way we are able to have a list-header and satisfy the first gold rule at the same time. + * + * + * ### Implement a reorder function + * + * Once the user drags an item and drops it in the new position, this directive fires the `(ionItemReorder)` + * event providing the initial index (from) and the new index (to) of the reordered item. + * For example, if an user drags the first item to the 5th position, `(ionItemReorder)` would fire + * `{from:0, to: 4}` (note that the indices start at zero). + * + * In order to integrate reordering in your app, it's a MUST to implement your own function that takes this indices and perform + * the actual reordering of the data models. Here's is an example of how this can be done: + * + * @usage + * + * ```ts + * class E2EPage { + * items = []; + * + * constructor() { + * for (let x = 0; x < 5; x++) { + * this.items.push(x); + * } + * } + * + * reorderItem(indices) { + * let element = this.items[indices.from]; + * this.items.splice(indices.from, 1); + * this.items.splice(indices.to, 0, element); + * + * // For maximum convenience, ionic already provides an helper function: + * // import { reorderArray } from 'ionic-angular'; + * // this.item = reorderArray(this.item, indices); + * } + * } + * ``` + * + * ```html + * + * HEADER + * + * Number: {{item}} + * + * + * ``` + * + * + * @demo /docs/v2/demos/item-reorder/ + * @see {@link /docs/v2/components#lists List Component Docs} + * @see {@link ../../list/List List API Docs} + * @see {@link ../Item Item API Docs} */ @Directive({ selector: '[reorder]', @@ -20,13 +111,13 @@ export interface ReorderIndexes { '[class.reorder-enabled]': '_enableReorder', } }) -export class Reorder { +export class ItemReorder { private _enableReorder: boolean = false; private _reorderGesture: ItemReorderGesture; private _lastToIndex: number = -1; private _element: HTMLElement; - @Output() ionItemReorder: EventEmitter = new EventEmitter(); + @Output() ionItemReorder: EventEmitter = new EventEmitter(); constructor( elementRef: ElementRef, @@ -174,7 +265,7 @@ export class Reorder { selector: 'ion-reorder', template: `` }) -export class ItemReorder { +export class Reorder { constructor( @Inject(forwardRef(() => Item)) private item: Item, private elementRef: ElementRef) { diff --git a/src/components/item/item.ts b/src/components/item/item.ts index 5ff175b471..c98f66f248 100644 --- a/src/components/item/item.ts +++ b/src/components/item/item.ts @@ -3,7 +3,7 @@ import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, Dire import { Button } from '../button/button'; import { Form } from '../../util/form'; import { Icon } from '../icon/icon'; -import { ItemReorder } from '../item/item-reorder'; +import { Reorder } from '../item/item-reorder'; import { Label } from '../label/label'; @@ -281,7 +281,7 @@ import { Label } from '../label/label'; '' + '' + '', - directives: [forwardRef(() => ItemReorder)], + directives: [forwardRef(() => Reorder)], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, }) diff --git a/src/components/tabs/test/basic/index.ts b/src/components/tabs/test/basic/index.ts index a8dbfdeb75..03428939db 100644 --- a/src/components/tabs/test/basic/index.ts +++ b/src/components/tabs/test/basic/index.ts @@ -248,11 +248,11 @@ export class TabsPage { root3 = Tab3; onChange(ev: Tab) { - console.log("Changed tab", ev); + console.log('Changed tab', ev); } onSelect(ev: Tab) { - console.log("Selected tab", ev); + console.log('Selected tab', ev); } } diff --git a/src/config/directives.ts b/src/config/directives.ts index 573d656924..fc9e01b3c1 100644 --- a/src/config/directives.ts +++ b/src/config/directives.ts @@ -18,7 +18,7 @@ import { Tabs } from '../components/tabs/tabs'; import { Tab } from '../components/tabs/tab'; import { List, ListHeader } from '../components/list/list'; import { Item, ItemContent } from '../components/item/item'; -import { Reorder } from '../components/item/item-reorder'; +import { ItemReorder } from '../components/item/item-reorder'; import { ItemSliding, ItemOptions } from '../components/item/item-sliding'; import { VirtualScroll } from '../components/virtual-scroll/virtual-scroll'; import { VirtualItem, VirtualHeader, VirtualFooter } from '../components/virtual-scroll/virtual-item'; @@ -145,7 +145,7 @@ export const IONIC_DIRECTIVES: any[] = [ ItemContent, ItemSliding, ItemOptions, - Reorder, + ItemReorder, VirtualScroll, VirtualItem, VirtualHeader,