UNPKG

knockout-switch-case

Version:

Powerful control flow bindings for Knockout

120 lines (96 loc) 5.49 kB
### **SWITCH/CASE** bindings for [Knockout](http://knockoutjs.com/) *Knockout* includes only the `if` and `ifnot` bindings for control flow. The `switch` and `case` bindings provide a flexible and powerful control flow mechanism that can simplify your code. Let's start with some examples. Here we want to display a different message based on a status value: ```html <div data-bind="switch: orderStatus"> <div data-bind="case: 'shipped'"> Your order has been shipped. Your tracking number is <span data-bind="text: trackingNumber"></span>. </div> <div data-bind="case: 'pending'"> Your order is being processed. Please be patient. </div> <div data-bind="case: 'incomplete'"> Your order could not be processed. Please go back and complete the missing data. </div> <div data-bind="case: $default"> Please call customer service to determine the status of your order. </div> </div> ``` Here's an equivalent example using source data values: ```html <div data-bind="switch: true"> <div data-bind="case: trackingNumber"> Your order has been shipped. Your tracking number is <span data-bind="text: trackingNumber"></span>. </div> <div data-bind="case: isReady"> Your order is being processed. Please be patient. </div> <div data-bind="casenot: isComplete"> Your order could not be processed. Please go back and complete the missing data. </div> <div data-bind="case: $else"> Your order could not be processed. Please go back and complete the missing data. </div> </div> ``` A *switch* block can contain any number of *case* blocks. No more than one *case* block will be used. The contents of the remaining blocks will be cleared. Both `switch` and `case` take a single parameter. In most cases the values of the two parameters are matched against each other to determine which case block to use. The first block (top-down) to match is used; subsequent blocks are cleared. Here, in detail, is how the values are matched: 1. If the *case* value is the special value `$else` or `$default`, the block is used if no non-default blocks were used. There can be multiple blocks with `$else` or `$default` and they can be in any order. 1. If the *switch* value is boolean (`true` or `false`), each *case* value's "truthiness" is matched against the *switch* value. 1. If the *case* value is boolean (and the *switch* value is not boolean), the *case* value is used as is. The special variable `$value` can be used in a *case* expression to refer to the *switch* value. The block will be used if the expression is true. 1. If the *case* value is an array, the block will be used if the *switch* value matches (strict) an item in the array. 1. Otherwise, the block will be used if the *case* value matches the *switch* value (loose comparison). If you want a block to be used based on the parameter not matching, you can use the `casenot` binding. This works similarly to `case`, except that the result of the value matching is reversed. Here are some more examples. This example demonstrates items 1, 3, 4, and 5 above and uses container-less bindings: ```html <!-- ko switch: somevalue --> <!-- ko case: $default --> Value doesn't match <!-- /ko --> <!-- ko case: 'foo' --> Value is foo <!-- /ko --> <!-- ko case: 'bar' --> Value is bar <!-- /ko --> <!-- ko case: ['baz', 'qux'] --> Value is either baz or qux <!-- /ko --> <!-- ko case: $value.length == 3 --> Value is a three-letter word <!-- /ko --> <!-- /ko --> ``` This example demonstrates item 2 (also see the second example above): ```html <!-- ko switch: isReady --> <div data-bind="case: true">You are ready!</div> <div data-bind="case: false">You are not ready!</div> <!-- /ko --> ``` ### Controlling visibility instead of inclusion You can use the `case.visible` and `casenot.visible` bindings to conditionally show an element. For example: ```html <!-- ko switch: true --> <p data-bind="case.visible: isReady">You are ready!</p> <p data-bind="case.visible: $else">You are not ready!</p> <!-- /ko --> ``` ### Switch shortcut when using Knockout 3.x When using Knockout 3.0+, you do not need to include the `true` value for the `switch` binding. For example: ```html <!-- ko switch --> <!-- ko case: 'abc' -->Value matched<!-- /ko --> <!-- ko case: $else -->Value didn't match<!-- /ko --> <!-- /ko --> ``` ### Extending `switch/case` to control other UI aspects `ko.bindingHandlers.switch.makeCaseHandler` can be used to create new bindings that control any UI aspect. It returns a new binding handler object that you should assign to a `ko.bindingHandlers` property. It takes three parameters: * `binding` This is the name of the binding to wrap (`case` wraps the `if` binding, for example). * `isNot` (optional) If set to *true*, the new binding will reverse the result of the value matching (like `casenot`). * `makeValueAccessor` (optional) If the wrapped binding needs the value specified in a certain format, you can provide a function that accepts a `value` parameter and returns a `valueAccessor` function. The default looks like this: `function (value) { return function() { return value } }` License: MIT (http://www.opensource.org/licenses/mit-license.php) Michael Best<br> https://github.com/mbest<br> mbest@dasya.com