Skip to content

Commit

Permalink
Update to closure actions only
Browse files Browse the repository at this point in the history
  • Loading branch information
Robdel12 committed Oct 8, 2016
1 parent 99b3100 commit 8d4a05a
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 37 deletions.
48 changes: 25 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,6 @@ through data rather than through the DOM.
{{/x-select}}
```

If you're using a lower version of Ember, `emberx-select` will continue
to work without block params for the forseeable future.

### Multiselect

As of version 1.1.0, `emberx-select` supports the `multiple`
Expand All @@ -80,28 +77,32 @@ its selections directly on that array.

The selections array will be initialized to an empty array if not present.

## Action and Action Arguments
## Actions and Action Arguments

The action that is dispatched by x-select whenever the selected value or values
change (change event) has a function signature of:
All of x-selects actions are closure actions. This means you must use
the `action` helper (i.e. `on-click=(action "onClick")`). The function
that is dispatched by x-select whenever the event fires has a function
signature of:

```js
/**
* @param value {Object} the value selected by the user.
* @param component {Ember.Component} the x-select component itself
* @param {Object} value - the value selected by the user.
* @param {Object} event - the jQuery event of the action
* @param {Object} componentState - object that contains `isDisabled`,
`isMultiple`, & `tabindex`
*/
function (value, component) {
function (value, event, componentState) {
// action body...
}
```

Most of the time all you need is the value that has been selected, but
sometimes your action requires more context than just that. In those
cases, you can associate arbitrary attributes with the component
itself and use them later inside your action handler. For example:
cases, you can use the `componentState` argument. It contains a couple
more things that relate to the components current state. For example:

```handlebars
{{#x-select action="didMakeSelection" default=anything as |xs|}}
{{#x-select action="didMakeSelection" required=true as |xs|}}
<option>Nothing</option>
{{#xs.option value=something}}Something{{/xs.option}}
{{/x-select}}
Expand All @@ -111,38 +112,39 @@ then, inside your action handler:
```js
export default Ember.Route.extend({
actions: {
didMakeSelection: function(selection, component) {
if (selection) {
this.set('selection', selection)
didMakeSelection(value, event, componentState) {
if (!value & componentState.isRequired) {
this.set('error', 'You must fill out this field');
} else {
this.set('selection', component.get('default'))
this.set('selection', value);
}
}
}
});
```

#### Other Actions

x-select also provides other actions that fire on different event
types. These actions follow the HTML input event naming convention.

**on-blur**

`on-blur` fires anytime the `blur` event is triggered on the x-select
component. When the action fires it sends two arguments: the value,
and the jQuery event.
component. When the action fires it sends three arguments: the value,
the jQuery event, and the components state (`isDisabled`,`isMultiple`,
`tabindex`).

**on-focus-out**

`on-focus-out` fires anytime the `focusOut` event is triggered on the x-select
component. When the action fires it sends two arguments: the value,
and the jQuery event.
component. When the action fires it sends three arguments: the value,
the jQuery event, and the components state (`isDisabled`,`isMultiple`,
`tabindex`).

**on-click**

`on-click` fires when x-select is clicked. When the action fires it
sends two arguments: the value, and the jQuery event.
sends three arguments: the value, the jQuery event, and the components
state (`isDisabled`,`isMultiple`, `tabindex`).

**on-disable** (x-option)

Expand Down
79 changes: 70 additions & 9 deletions addon/components/x-select.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,18 @@ export default Ember.Component.extend({
*
* @property disabled
* @type Boolean
* @default null
* @default false
*/
disabled: null,
disabled: false,

/**
* Bound to the `multiple` attribute on the native <select> tag.
*
* @property multiple
* @type Boolean
* @default null
* @default false
*/
multiple: null,
multiple: false,

/**
* The collection of options for this select box. When options are
Expand All @@ -71,39 +71,100 @@ export default Ember.Component.extend({
*/
tabindex: 0,

/**
* Function for the `on-blur` action
*
* @property on-blur
* @type Function
*/
"on-blur": Ember.K,

/**
* Function for the `on-click` action
*
* @property on-click
* @type Function
*/
"on-click": Ember.K,

/**
* Function for the `on-change` action
*
* @property on-change
* @type Function
*/
"on-change": Ember.K,

/**
* Function for the `on-focus-out` action
*
* @property on-focus-out
* @type Function
*/
"on-focus-out": Ember.K,

/**
* Object that holds the current state of the component
*
* @property componentState
* @type Object
* @return {Object} current state
*/
componentState: Ember.computed('disabled', 'multiple', 'required', 'autofocus', function() {
return {
isDisabled: this.get('disabled'),
isMultiple: this.get('multiple'),
isAutoFocus: this.get('autofocus'),
isRequired: this.get('required')
};
}),

/**
* Function that calls an action and sends the proper arguments.
*
* @method _handleAction
* @type Function
* @param {String} action - string name of the action to invoke
* @param {String|Object} value - current value of the component
* @param {Object} event - jQuery event from the current action
*/
_handleAction(action, value, event) {
this.get(action)(value, event, this.get('componentState'));
},

/**
* When the select DOM event fires on the element, trigger the
* component's action with the current value.
*/
change(event) {
let nextValue = this._getValue();

this.sendAction('action', nextValue, event);
this.sendAction('on-change', nextValue, event);
this.sendAction('action', nextValue, event, this.get('componentState'));
this._handleAction('on-change', nextValue, event);
},

/**
* When the click DOM event fires on the element, trigger the
* component's action with the component, x-select value, and the jQuery event.
*/
click(event) {
this.sendAction('on-click', this._getValue(), event);
this._handleAction('on-click', this._getValue(), event);
},

/**
* When the blur DOM event fires on the element, trigger the
* component's action with the component, x-select value, and the jQuery event.
*/
blur(event) {
this.sendAction('on-blur', this._getValue(), event);
this._handleAction('on-blur', this._getValue(), event);
},

/**
* When the focusOut DOM event fires on the element, trigger the
* component's action with the component, x-select value, and the jQuery event.
*/
focusOut(event) {
this.sendAction('on-focus-out', this._getValue(), event);
this._handleAction('on-focus-out', this._getValue(), event);
},

/**
Expand Down
4 changes: 2 additions & 2 deletions tests/dummy/app/controllers/single.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export default Ember.Controller.extend(Folks, {
attrSize: null,

actions: {
tagYouAreIt: function(object) {
this.set('it', object);
tagYouAreIt: function(value) {
this.set('it', value);
}
}
});
2 changes: 1 addition & 1 deletion tests/dummy/app/templates/events/blur.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<h2>Blur</h2>

{{#x-select value=it on-blur="onBlur" as |xs|}}
{{#x-select value=it on-blur=(action "onBlur") as |xs|}}
{{#xs.option value=charles}}Charles{{/xs.option}}
{{#xs.option value=bastion}}Bastion{{/xs.option}}
{{#xs.option value=stanley}}Stanley{{/xs.option}}
Expand Down
2 changes: 1 addition & 1 deletion tests/dummy/app/templates/events/click.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<h2>Click</h2>

{{#x-select value=it on-click="onClick" as |xs|}}
{{#x-select value=it on-click=(action "onClick") as |xs|}}
{{#xs.option value=charles}}Charles{{/xs.option}}
{{#xs.option value=bastion}}Bastion{{/xs.option}}
{{#xs.option value=stanley}}Stanley{{/xs.option}}
Expand Down
2 changes: 1 addition & 1 deletion tests/dummy/app/templates/events/focus-out.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<h2>Focus Out</h2>

{{#x-select value=it on-focus-out="focusOut" as |xs|}}
{{#x-select value=it on-focus-out=(action "focusOut") as |xs|}}
{{#xs.option value=charles}}Charles{{/xs.option}}
{{#xs.option value=bastion}}Bastion{{/xs.option}}
{{#xs.option value=stanley}}Stanley{{/xs.option}}
Expand Down

0 comments on commit 8d4a05a

Please sign in to comment.