diff --git a/components/selectbutton/selectbutton.ts b/components/selectbutton/selectbutton.ts new file mode 100644 index 00000000000..559ac86be12 --- /dev/null +++ b/components/selectbutton/selectbutton.ts @@ -0,0 +1,85 @@ +/// + +import {Component, ElementRef, AfterViewInit, OnDestroy, OnChanges, Input, Output, SimpleChange, EventEmitter} from 'angular2/core'; +import {SelectItem} from '../api/selectitem'; + +@Component({ + selector: 'p-selectbutton', + template: ` +
+
+ {{choice.label}} +
+
+ ` +}) +export class Selectbutton { + + initialized: boolean; + + @Input() choices: SelectItem[]; + + @Input() formfield: string; + + @Input() unselectable: boolean; + + @Input() tabindex: number; + + @Input() multiple: boolean; + + @Input() style: string; + + @Input() styleClass: string; + + @Input() value: any; + + @Output() valueChange: EventEmitter = new EventEmitter(); + + @Output() onChange: EventEmitter = new EventEmitter(); + + constructor(private el: ElementRef) { + this.initialized = false; + } + + ngAfterViewInit() { + jQuery(this.el.nativeElement.children[0]).puiselectbutton({ + value: this.value, + unselectable: this.unselectable, + tabindex : this.tabindex, + formfield: this.formfield, + multiple: this.multiple, + enhanced: true, + style: this.style, + styleClass: this.styleClass, + change: (event: Event, ui: PrimeUI.SelectbuttonEventParams) => { + this.onChange.next({ originalEvent: event, value: ui.value }); + if (this.multiple) { + var values: any = []; + for (var i = 0; i < ui.index.length; i++) { + values.push(this.choices[ui.index[i]].value); + this.valueChange.next(values); + } + + } + else { + this.valueChange.next(this.choices[ui.index].value); + } + } + }); + this.initialized = true; + } + + ngOnChanges(changes: { [key: string]: SimpleChange }) { + if (this.initialized) { + for (var key in changes) { + jQuery(this.el.nativeElement.children[0]).puiselectbutton('option', key, changes[key].currentValue); + } + } + } + + ngOnDestroy() { + jQuery(this.el.nativeElement.children[0]).puiselectbutton('destroy'); + this.initialized = false; + } + +} \ No newline at end of file diff --git a/showcase/app.component.html b/showcase/app.component.html index fedd5faa16e..684014a5637 100644 --- a/showcase/app.component.html +++ b/showcase/app.component.html @@ -19,6 +19,7 @@ ● RadioButton ● Rating ● Spinner + ● SelectButton ● ToggleButton diff --git a/showcase/app.component.ts b/showcase/app.component.ts index e32acaebbe9..6d5e58b6e8c 100644 --- a/showcase/app.component.ts +++ b/showcase/app.component.ts @@ -24,6 +24,7 @@ import {MessagesDemoComponent} from './demo/messages/messagesdemo.component'; import {GrowlDemoComponent} from './demo/growl/growldemo.component'; import {CarouselDemoComponent} from './demo/carousel/carouseldemo.component'; import {InputSwitchDemoComponent} from './demo/inputswitch/inputswitchdemo.component'; +import {SelectbuttonDemoComponent} from './demo/selectbutton/selectbuttondemo.component'; @Component({ selector: 'primeng-showcase', @@ -54,7 +55,8 @@ import {InputSwitchDemoComponent} from './demo/inputswitch/inputswitchdemo.compo {path: '/messages', name: 'MessagesDemo', component: MessagesDemoComponent}, {path: '/growl', name: 'GrowlDemo', component: GrowlDemoComponent}, {path: '/carousel', name: 'CarouselDemo', component: CarouselDemoComponent}, - {path: '/inputswitch', name: 'InputSwitchDemo', component: InputSwitchDemoComponent} + {path: '/inputswitch', name: 'InputSwitchDemo', component: InputSwitchDemoComponent}, + {path: '/selectbutton', name: 'SelectbuttonDemo', component: SelectbuttonDemoComponent} ]) export class AppComponent { diff --git a/showcase/demo/selectbutton/selectbuttondemo.component.html b/showcase/demo/selectbutton/selectbuttondemo.component.html new file mode 100644 index 00000000000..f07ff692c60 --- /dev/null +++ b/showcase/demo/selectbutton/selectbuttondemo.component.html @@ -0,0 +1,169 @@ +
+
+ SelectButton + SelectButton is used to choose single or multiple items from a list using buttons. +
+
+ +
+

Single

+ + +

Selected Team: {{selectedTeam}}

+ +

Multiple

+ + +

Selected Teams: {{selectedTeams}}

+ +

Preselect

+ +

Select Car: {{selectedCar}}

+ + +
+ +
+ + +

Import

+
+import {Panel} from 'primeng/primeng';
+
+ +

Getting Started

+

Panel is defined with p-panel element.

+
+<p-panel header="Title">
+    Content
+</p-panel>
+
+

Toggleable

+

Content of the panel can be expanded and collapsed using toggleable option. Duration of the toggle effect + is customized with toggleDuration and default state is defined with collapsed option. Orientation is "vertical" by default + and other possible value is "horizontal".

+
+<p-panel header="Title" toggleable="true">
+    Content
+</p-panel>
+
+ +

Attributes

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefaultDescription
headerstringnullHeader text of the panel.
toggleablebooleanfalseDefines if content of panel can be expanded and collapsed.
toggleDurationanynormalDuration of the effect in milliseconds or pre-defined values like "slow","normal" and "fast".
toggleOrientationstringverticalDefines orientation of toggle direction, valid values are "vertical" and "horizontal".
collapsedbooleanfalseWhen specified, displays the panel as collapsed initially.
closablebooleanfalseDefines if panel can be hidden using close option.
closeDurationanynormalDuration of the effect in milliseconds or pre-defined values like "slow","normal" and "fast".
+
+ +

Events

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameParametersDescription
onBeforeCollapseevent: Toggle eventCallback to invoke before content is collapsed.
onAfterCollapseevent: Toggle eventCallback to invoke after content is collapsed.
onBeforeExpandevent: Toggle eventCallback to invoke before content is expanded.
onAfterExpandevent: Toggle eventCallback to invoke after content is expanded.
onBeforeCloseevent: Toggle eventCallback to invoke before panel is closed.
onAfterCloseevent: Toggle eventCallback to invoke after panel is closed.
+
+ +

Dependencies

+

jQuery, jQuery UI WidgetFactory API, PrimeUI Panel.

+
+ + +
+<p-panel header="Godfather I" toggleable="true">
+    The story begins as Don Vito Corleone, the head of a New York Mafia family, oversees his daughter's wedding.
+    His beloved son Michael has just come home from the war, but does not intend to become part of his father's business.
+    Through Michael's life the nature of the family business becomes clear. The business of the family is just like the head of the family,
+    kind and benevolent to those who give respect, but given to ruthless violence whenever anything stands against the good of the family.
+</p-panel>
+
+
+
+
\ No newline at end of file diff --git a/showcase/demo/selectbutton/selectbuttondemo.component.ts b/showcase/demo/selectbutton/selectbuttondemo.component.ts new file mode 100644 index 00000000000..a4365e2f0a0 --- /dev/null +++ b/showcase/demo/selectbutton/selectbuttondemo.component.ts @@ -0,0 +1,43 @@ +import {Component} from 'angular2/core'; +import {Selectbutton} from '../../../components/selectbutton/selectbutton'; +import {TabView} from '../../../components/tabview/tabview'; +import {TabPanel} from '../../../components/tabview/tabpanel'; +import {Button} from '../../../components/button/button'; +import {SelectItem} from '../../../components/api/selectitem'; +import {ROUTER_DIRECTIVES} from 'angular2/router'; + +@Component({ + templateUrl: 'showcase/demo/selectbutton/selectbuttondemo.component.html', + directives: [Selectbutton, TabPanel, TabView, Button, ROUTER_DIRECTIVES] +}) +export class SelectbuttonDemoComponent { + + teams: SelectItem[]; + + selectedTeam: string; + + selectedTeams: string[]; + + cars: SelectItem[]; + + selectedCar: string = 'BMW'; + + constructor() { + this.teams = []; + this.teams.push({label: 'Barcelona', value: 'Barcelona'}); + this.teams.push({label: 'Real Madrid', value: 'Real Madrid'}); + this.teams.push({label: 'Bayern Munich', value: 'Bayern Munich'}); + + this.cars = []; + this.cars.push({ label: 'Audi', value: 'Audi' }); + this.cars.push({ label: 'BMW', value: 'BMW' }); + this.cars.push({ label: 'Fiat', value: 'Fiat' }); + this.cars.push({ label: 'Ford', value: 'Ford' }); + this.cars.push({ label: 'Honda', value: 'Honda' }); + this.cars.push({ label: 'Jaguar', value: 'Jaguar' }); + this.cars.push({ label: 'Mercedes', value: 'Mercedes' }); + this.cars.push({ label: 'Renault', value: 'Renault' }); + this.cars.push({ label: 'Volkswagen', value: 'Volkswagen' }); + this.cars.push({ label: 'Volvo', value: 'Volvo' }); + } +} \ No newline at end of file diff --git a/showcase/resources/primeui/primeui.js b/showcase/resources/primeui/primeui.js index 7ab9b347b7e..c0474b40d78 100644 --- a/showcase/resources/primeui/primeui.js +++ b/showcase/resources/primeui/primeui.js @@ -9505,27 +9505,41 @@ PUI.resolveUserAgent();/** $.widget("primeui.puiselectbutton", { options: { + value: null, choices: null, formfield: null, unselectable: false, tabindex: '0', - multiple: false + multiple: false, + enhanced: false }, _create: function() { this.element.addClass('pui-selectbutton pui-buttonset ui-widget ui-corner-all').attr('tabindex'); //create buttons - if(this.options.choices) { - this.element.addClass('pui-buttonset-' + this.options.choices.length); - for(var i = 0; i < this.options.choices.length; i++) { - this.element.append('
' + - '' + - this.options.choices[i].label + - '
'); + if(!this.options.enhanced) { + if(this.options.choices) { + this.element.addClass('pui-buttonset-' + this.options.choices.length); + for(var i = 0; i < this.options.choices.length; i++) { + this.element.append('
' + + '' + + this.options.choices[i].label + + '
'); + } } } + else { + var $this = this, + buttons = this.element.children('div.pui-button'); + this.options.choices = []; + $('div.pui-button').each(function(buttons) { + var value = $(this).attr('data-value'), + label = $(this).children('span').html(); + $this.options.choices.push({value,label}); + }); + } //cornering this.buttons = this.element.children('div.pui-button'); @@ -9549,8 +9563,29 @@ PUI.resolveUserAgent();/** this.input.attr('name', this.options.formfield); } + //preselection + if(this.options.value) { + this._updateSelection(this.options.value); + } + this._bindEvents(); }, + fireEvent : function() { + var $this = this, + values = [], + indexes = []; + for(var i = 0; i < $this.buttons.length; i++) { + if($this.selectOptions.eq(i).prop('selected')) { + values.push($this.buttons.eq(i).attr('data-value')); + indexes.push(i); + } + } + + $this._trigger('change', event, { + value: values, + index: indexes + }) + }, _bindEvents: function() { var $this = this; @@ -9569,19 +9604,23 @@ PUI.resolveUserAgent();/** if($(this).hasClass("ui-state-active")) { if($this.options.unselectable) { $this.unselectOption(btn); - $this._trigger('change', e); + $this.fireEvent(); } } else { if($this.options.multiple) { $this.selectOption(btn); + $this.fireEvent(); } else { $this.unselectOption(btn.siblings('.ui-state-active')); $this.selectOption(btn); } - $this._trigger('change', e); + $this._trigger('change', e, { + value: $this.buttons.eq(btn.index()).attr('data-value'), + index: btn.index() + }); } }) .on('focus', function() { @@ -9609,8 +9648,9 @@ PUI.resolveUserAgent();/** selectOption: function(value) { var btn = $.isNumeric(value) ? this.element.children('.pui-button').eq(value) : value; - if(this.options.multiple) + if(this.options.multiple) { this.selectOptions.eq(btn.index()).prop('selected',true); + } else this.input.val(btn.data('value')); @@ -9627,8 +9667,32 @@ PUI.resolveUserAgent();/** btn.removeClass('ui-state-active'); btn.removeClass('ui-state-focus'); - } + }, + _setOption: function (key, value) { + if (key === 'data') { + this.element.empty(); + this._bindEvents(); + } + else if (key === 'value') { + this._updateSelection(value); + } + else { + $.Widget.prototype._setOption.apply(this, arguments); + } + }, + _updateSelection: function(value) { + this.buttons.prop('selected', false); + this.buttons.removeClass('ui-state-highlight') + for(var i = 0; i < this.buttons.length; i++) { + var button = this.buttons.eq(i); + if(button.attr('data-value') == value) { + button.prop('selected', true); + this.buttons.eq(i).addClass('ui-state-highlight'); + } + } + } + }); })(); diff --git a/typedefinition/primeui.d.ts b/typedefinition/primeui.d.ts index 630f9f5954e..aae86acad16 100644 --- a/typedefinition/primeui.d.ts +++ b/typedefinition/primeui.d.ts @@ -233,6 +233,24 @@ declare module PrimeUI { offLabel?: string; change?: (event?: Event, ui?: InputSwitchEventParams) => void; } + + //SelectButton + interface SelectbuttonEventParams { + value?: any; + index?: any; + } + + interface SelectbuttonOptions { + value?: any; + formfield?: string; + unselectable?: boolean; + tabindex?: number; + style?: string; + styleClass?: string; + multiple?: boolean; + enhanced?: boolean; + change?: (event?: Event, ui?: ListboxEventParams) => void; + } } interface JQuery { @@ -452,4 +470,16 @@ interface JQuery { puiswitch(optionLiteral: string, optionName: string): any; puiswitch(optionLiteral: string, options: PrimeUI.InputSwichOptions): any; puiswitch(optionLiteral: string, optionName: string, optionValue: any): JQuery; + + puiselectbutton(): JQuery; + puiselectbutton(methodName: 'destroy'): void; + puiselectbutton(methodName: 'disable'): void; + puiselectbutton(methodName: 'enable'): void; + puiselectbutton(methodName: 'refresh'): void; + puiselectbutton(methodName: 'widget'): JQuery; + puiselectbutton(methodName: string): JQuery; + puiselectbutton(options: PrimeUI.CarouselOptions): JQuery; + puiselectbutton(optionLiteral: string, optionName: string): any; + puiselectbutton(optionLiteral: string, options: PrimeUI.SelectbuttonOptions): any; + puiselectbutton(optionLiteral: string, optionName: string, optionValue: any): JQuery; } \ No newline at end of file