mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-21 04:53:58 +08:00
docs(reorder): adds docs and demo for reorder directive
This commit is contained in:
BIN
demos/item-reorder/avatar-cher.png
Normal file
BIN
demos/item-reorder/avatar-cher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
demos/item-reorder/avatar-dionne.png
Normal file
BIN
demos/item-reorder/avatar-dionne.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
demos/item-reorder/avatar-murray.png
Normal file
BIN
demos/item-reorder/avatar-murray.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
88
demos/item-reorder/index.ts
Normal file
88
demos/item-reorder/index.ts
Normal file
@ -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: '<ion-nav [root]="root"></ion-nav>'
|
||||||
|
})
|
||||||
|
class ApiDemoApp {
|
||||||
|
root = ApiDemoPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
ionicBootstrap(ApiDemoApp);
|
50
demos/item-reorder/main.html
Normal file
50
demos/item-reorder/main.html
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<ion-header>
|
||||||
|
|
||||||
|
<ion-navbar>
|
||||||
|
<ion-title>Item Reorder</ion-title>
|
||||||
|
<ion-buttons end>
|
||||||
|
<button (click)="toggleEdit()">{{editButton}}</button>
|
||||||
|
</ion-buttons>
|
||||||
|
</ion-navbar>
|
||||||
|
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
|
||||||
|
<ion-content class="outer-content" fullscreen>
|
||||||
|
|
||||||
|
<ion-list class="chat-sliding-demo">
|
||||||
|
<ion-list-header>
|
||||||
|
Chats
|
||||||
|
</ion-list-header>
|
||||||
|
|
||||||
|
<ion-item-group [reorder]="editing" (ionItemReorder)="reorderData($event)">
|
||||||
|
|
||||||
|
<ion-item *ngFor="let chat of chats">
|
||||||
|
<ion-avatar item-left>
|
||||||
|
<img [src]="chat.img">
|
||||||
|
</ion-avatar>
|
||||||
|
<h2>{{chat.name}}</h2>
|
||||||
|
<p>{{chat.message}}</p>
|
||||||
|
<ion-note item-right>
|
||||||
|
{{chat.time}}
|
||||||
|
</ion-note>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
</ion-item-group>
|
||||||
|
</ion-list>
|
||||||
|
|
||||||
|
</ion-content>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.chat-sliding-demo ion-item-options .button-inner {
|
||||||
|
font-size: 14px;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-sliding-demo ion-item-options ion-icon {
|
||||||
|
padding-right: 0;
|
||||||
|
padding-bottom: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
@ -1,5 +1,5 @@
|
|||||||
import {Item} from './item';
|
import {Item} from './item';
|
||||||
import {Reorder} from '../item/item-reorder';
|
import {ItemReorder} from '../item/item-reorder';
|
||||||
import {UIEventManager} from '../../util/ui-event-manager';
|
import {UIEventManager} from '../../util/ui-event-manager';
|
||||||
import {closest, Coordinates, pointerCoord, CSS, nativeRaf} from '../../util/dom';
|
import {closest, Coordinates, pointerCoord, CSS, nativeRaf} from '../../util/dom';
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ export class ItemReorderGesture {
|
|||||||
|
|
||||||
private events: UIEventManager = new UIEventManager(false);
|
private events: UIEventManager = new UIEventManager(false);
|
||||||
|
|
||||||
constructor(public list: Reorder) {
|
constructor(public list: ItemReorder) {
|
||||||
let element = this.list.getNativeElement();
|
let element = this.list.getNativeElement();
|
||||||
this.events.pointerEvents(element,
|
this.events.pointerEvents(element,
|
||||||
this.onDragStart.bind(this),
|
this.onDragStart.bind(this),
|
||||||
|
@ -6,13 +6,104 @@ import { Item } from './item';
|
|||||||
import { ItemReorderGesture } from '../item/item-reorder-gesture';
|
import { ItemReorderGesture } from '../item/item-reorder-gesture';
|
||||||
import { isTrueProperty } from '../../util/util';
|
import { isTrueProperty } from '../../util/util';
|
||||||
|
|
||||||
export interface ReorderIndexes {
|
|
||||||
|
export interface ReorderIndices {
|
||||||
from: number;
|
from: number;
|
||||||
to: 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
|
||||||
|
* <ion-list reorder="true">
|
||||||
|
* <ion-item *ngFor="let item of items">{{item.name}}</ion-item
|
||||||
|
* </ion-list>
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* **GOOD!**
|
||||||
|
*
|
||||||
|
* ```html
|
||||||
|
* <ion-list reorder="true">
|
||||||
|
* <ion-list-header>HEADER</ion-list-header>
|
||||||
|
* <ion-item *ngFor="let item of items">{{item.name}}</ion-item>
|
||||||
|
* </ion-list>
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* **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
|
||||||
|
* <ion-list>
|
||||||
|
* <ion-list-header>HEADER</ion-list-header>
|
||||||
|
* <ion-item-group reorder="true">
|
||||||
|
* <ion-item *ngFor="let item of items">{{item.name}}</ion-item>
|
||||||
|
* </ion-item-group>
|
||||||
|
* </ion-list>
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* **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
|
||||||
|
* <ion-list>
|
||||||
|
* <ion-list-header>HEADER</ion-list-header>
|
||||||
|
* <ion-item-group reorder="true" (ionItemReorder)="reorderItem($event)">
|
||||||
|
* <ion-item *ngFor="let item of items">Number: {{item}}</ion-item>
|
||||||
|
* </ion-item-group>
|
||||||
|
* </ion-list>
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @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({
|
@Directive({
|
||||||
selector: '[reorder]',
|
selector: '[reorder]',
|
||||||
@ -20,13 +111,13 @@ export interface ReorderIndexes {
|
|||||||
'[class.reorder-enabled]': '_enableReorder',
|
'[class.reorder-enabled]': '_enableReorder',
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class Reorder {
|
export class ItemReorder {
|
||||||
private _enableReorder: boolean = false;
|
private _enableReorder: boolean = false;
|
||||||
private _reorderGesture: ItemReorderGesture;
|
private _reorderGesture: ItemReorderGesture;
|
||||||
private _lastToIndex: number = -1;
|
private _lastToIndex: number = -1;
|
||||||
private _element: HTMLElement;
|
private _element: HTMLElement;
|
||||||
|
|
||||||
@Output() ionItemReorder: EventEmitter<ReorderIndexes> = new EventEmitter<ReorderIndexes>();
|
@Output() ionItemReorder: EventEmitter<ReorderIndices> = new EventEmitter<ReorderIndices>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
elementRef: ElementRef,
|
elementRef: ElementRef,
|
||||||
@ -174,7 +265,7 @@ export class Reorder {
|
|||||||
selector: 'ion-reorder',
|
selector: 'ion-reorder',
|
||||||
template: `<ion-icon name="menu"></ion-icon>`
|
template: `<ion-icon name="menu"></ion-icon>`
|
||||||
})
|
})
|
||||||
export class ItemReorder {
|
export class Reorder {
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(forwardRef(() => Item)) private item: Item,
|
@Inject(forwardRef(() => Item)) private item: Item,
|
||||||
private elementRef: ElementRef) {
|
private elementRef: ElementRef) {
|
||||||
|
@ -3,7 +3,7 @@ import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, Dire
|
|||||||
import { Button } from '../button/button';
|
import { Button } from '../button/button';
|
||||||
import { Form } from '../../util/form';
|
import { Form } from '../../util/form';
|
||||||
import { Icon } from '../icon/icon';
|
import { Icon } from '../icon/icon';
|
||||||
import { ItemReorder } from '../item/item-reorder';
|
import { Reorder } from '../item/item-reorder';
|
||||||
import { Label } from '../label/label';
|
import { Label } from '../label/label';
|
||||||
|
|
||||||
|
|
||||||
@ -281,7 +281,7 @@ import { Label } from '../label/label';
|
|||||||
'<ion-reorder></ion-reorder>' +
|
'<ion-reorder></ion-reorder>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<ion-button-effect></ion-button-effect>',
|
'<ion-button-effect></ion-button-effect>',
|
||||||
directives: [forwardRef(() => ItemReorder)],
|
directives: [forwardRef(() => Reorder)],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
encapsulation: ViewEncapsulation.None,
|
encapsulation: ViewEncapsulation.None,
|
||||||
})
|
})
|
||||||
|
@ -248,11 +248,11 @@ export class TabsPage {
|
|||||||
root3 = Tab3;
|
root3 = Tab3;
|
||||||
|
|
||||||
onChange(ev: Tab) {
|
onChange(ev: Tab) {
|
||||||
console.log("Changed tab", ev);
|
console.log('Changed tab', ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelect(ev: Tab) {
|
onSelect(ev: Tab) {
|
||||||
console.log("Selected tab", ev);
|
console.log('Selected tab', ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ import { Tabs } from '../components/tabs/tabs';
|
|||||||
import { Tab } from '../components/tabs/tab';
|
import { Tab } from '../components/tabs/tab';
|
||||||
import { List, ListHeader } from '../components/list/list';
|
import { List, ListHeader } from '../components/list/list';
|
||||||
import { Item, ItemContent } from '../components/item/item';
|
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 { ItemSliding, ItemOptions } from '../components/item/item-sliding';
|
||||||
import { VirtualScroll } from '../components/virtual-scroll/virtual-scroll';
|
import { VirtualScroll } from '../components/virtual-scroll/virtual-scroll';
|
||||||
import { VirtualItem, VirtualHeader, VirtualFooter } from '../components/virtual-scroll/virtual-item';
|
import { VirtualItem, VirtualHeader, VirtualFooter } from '../components/virtual-scroll/virtual-item';
|
||||||
@ -145,7 +145,7 @@ export const IONIC_DIRECTIVES: any[] = [
|
|||||||
ItemContent,
|
ItemContent,
|
||||||
ItemSliding,
|
ItemSliding,
|
||||||
ItemOptions,
|
ItemOptions,
|
||||||
Reorder,
|
ItemReorder,
|
||||||
VirtualScroll,
|
VirtualScroll,
|
||||||
VirtualItem,
|
VirtualItem,
|
||||||
VirtualHeader,
|
VirtualHeader,
|
||||||
|
Reference in New Issue
Block a user