Last active
December 17, 2015 20:39
-
-
Save cburgdorf/5668949 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| angular.module('sdk.directives.ccVariantSelector', []); | |
| angular.module('sdk.directives.ccVariantSelector') | |
| .filter('ccVariantFilter', ['$filter', function($filter) { | |
| 'use strict'; | |
| return function(values, selectedValues, key) { | |
| var selected = {}, | |
| applyFilters = false; | |
| // reformat for built in filter and exclude current property | |
| for (var property in selectedValues){ | |
| if (key!==property && selectedValues[property]!==null && selectedValues[property]!==undefined) { | |
| selected['properties.' + property] = selectedValues[property]; | |
| applyFilters = true; | |
| } | |
| }; | |
| // extract available variants | |
| var variants = applyFilters ? $filter('filter')(values, selected, true) : values; | |
| // extract flat values for the curent property | |
| var result = []; | |
| variants.forEach(function(variant){ | |
| if (result.indexOf(variant.properties[key]) === -1 && variant.stock > 0){ | |
| result.push(variant.properties[key]); | |
| }; | |
| }); | |
| return result; | |
| }; | |
| }]) | |
| .directive('ccVariantSelector', function() { | |
| 'use strict'; | |
| return { | |
| restrict: 'E', | |
| replace: true, | |
| scope: { | |
| variants: '=' | |
| }, | |
| templateUrl: '../sdk/src/directives/ccVariantSelector/ccvariantselector.tpl.html', | |
| link: function(scope, element, attrs){ | |
| // extract flat list of available properties | |
| // maybe iterating on the first variant is enough ? | |
| scope.properties = []; | |
| scope.variants.forEach(function(variant){ | |
| for (var property in variant.properties){ | |
| if (scope.properties.indexOf(property) === -1){ | |
| scope.properties.push(property); | |
| }; | |
| }; | |
| }); | |
| scope.selectedValues = {}; | |
| } | |
| }; | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="cc-variant-selector"> | |
| <select ng-repeat="property in properties" | |
| class="cc-variant-selector-select" | |
| name="{{property}}" | |
| ng-model="selectedValues[property]" | |
| ng-options="val for val in variants|ccVariantFilter:selectedValues:property"> | |
| <option value="">-- chose {{property}} --</option> | |
| </select> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Ext.define('CouchCommerce.view.CustomAttributesPane', { | |
| extend: 'Ext.form.FieldSet', | |
| xtype: 'customattributespane', | |
| requires: [ | |
| 'Ext.form.FieldSet' | |
| ], | |
| config: { | |
| layout: 'vbox', | |
| cls: 'cc-custom-attributes-pane', | |
| //Don't make that 'null' Sencha has a bug that will prevent | |
| // the picker from working | |
| selectboxNullValue: CouchCommerce.Lang.getNoSelection(), | |
| selectboxNullValueText: CouchCommerce.Lang.getNoSelection(), | |
| variants: [ | |
| // { | |
| // variantID: 1, | |
| // stock: 1, | |
| // properties: { | |
| // color: 'red', | |
| // size: 'XL', | |
| // zipside: 'left' | |
| // } | |
| // }, | |
| // { | |
| // variantID: 2, | |
| // stock: 1, | |
| // properties: { | |
| // color: 'green', | |
| // size: 'XL', | |
| // zipside: 'right' | |
| // } | |
| // }, | |
| // { | |
| // variantID: 3, | |
| // stock: 1, | |
| // properties: { | |
| // color: 'green', | |
| // size: 'L', | |
| // zipside: 'left' | |
| // } | |
| // } | |
| ] | |
| }, | |
| /** | |
| * @public | |
| * get a validation object with an boolean success property and an | |
| * invalidKeys property holding all invalid keys | |
| */ | |
| getValidations: function(){ | |
| var invalidInputs = []; | |
| for (var key in this._variantsHashSet){ | |
| if (this[key].getValue() === this.getSelectboxNullValue()){ | |
| invalidInputs.push(key); | |
| } | |
| } | |
| return { | |
| success: invalidInputs.length === 0, | |
| invalidKeys: invalidInputs | |
| }; | |
| }, | |
| /** | |
| * @public | |
| * get the choosen variant | |
| */ | |
| getValue: function(){ | |
| var me = this; | |
| var hashSet = me._variantsHashSet; | |
| var filteredVariants = me | |
| .getVariants() | |
| .filter(function(item){ | |
| for (var key in hashSet){ | |
| if (item.properties[key] !== me[key].getValue()){ | |
| return false; | |
| } | |
| } | |
| return true; | |
| }); | |
| return filteredVariants.length > 0 ? filteredVariants[0] : null; | |
| }, | |
| /** | |
| * @private | |
| * Renders all needed selectboxes every time the variants change | |
| */ | |
| updateVariants: function(oldValue, newValue){ | |
| var me = this; | |
| me.removeAll(true); | |
| var variants = me.getVariants(); | |
| var hashSet = me._variantsHashSet = this._variantsToHashset(variants); | |
| var hashSetItemCount = 0; | |
| for (var key in hashSet){ | |
| hashSetItemCount++; | |
| var selectItems = me._hashSetItemToSelectEntries(hashSet[key]); | |
| me[key] = me.add({ | |
| xtype: 'selectfield', | |
| ui: 'couch-default', | |
| label: key, | |
| labelWidth: 120, | |
| height: 40, | |
| //usePicker:true, | |
| options: selectItems, | |
| placeHolder: key, | |
| name: key, | |
| defaultPhonePickerConfig: { | |
| cancelButton: CouchCommerce.Lang.getBtnCancel(), | |
| doneButton: CouchCommerce.Lang.getBtnDone() | |
| } | |
| }); | |
| me[key].on('change', me._onValueSelected, me); | |
| } | |
| me._filterBoxes(); | |
| //Todo: Figure out what's best to calculate the size for now | |
| //let's just assume X times the size of what | |
| //Sencha uses as default for select boxes | |
| me.setHeight(hashSetItemCount * 2.5 + 'em'); | |
| }, | |
| _onValueSelected: function(origin, newValue, oldValue, eOpts){ | |
| this._filterBoxes(); | |
| //based on the current filter, get all matching variants | |
| var variants = this._getFilteredVariantsWithoutFilterFor(''); | |
| //And pick the first match or raise with null | |
| var matchingVariant = variants.length > 0 ? variants[0] : null; | |
| this.fireEvent('variantchanged', this, matchingVariant); | |
| }, | |
| /** | |
| * @private | |
| * Filters the data of each select box according | |
| // to what should be currently valid | |
| */ | |
| _filterBoxes: function(){ | |
| var me = this; | |
| //This method triggers change events itself so we need to asure | |
| // we don't get into an invinite loop | |
| if (me._updatingEntries){ | |
| return; | |
| } | |
| me._updatingEntries = true; | |
| var hashSet = me._variantsHashSet; | |
| //loop through each variant | |
| for (var key in hashSet){ | |
| //get all variant items that are valid. Filter only by all | |
| // other variant keys (NOT by the current key) | |
| var filteredItems = me._getFilteredVariantsWithoutFilterFor(key); | |
| if (filteredItems.length === 0){ | |
| me[key].setOptions({ | |
| text: this.getSelectboxNullValueText(), | |
| value: this.getSelectboxNullValue() | |
| }); | |
| continue; | |
| } | |
| //transform the filtered variant items into a hashset | |
| var tempHashset = me._variantsToHashset(filteredItems); | |
| //create selectbox entries for this variant property | |
| var selectItems = me._hashSetItemToSelectEntries(tempHashset[key]); | |
| //set the options for the current variant property | |
| me[key].setOptions(selectItems); | |
| } | |
| me._updatingEntries = false; | |
| }, | |
| /** | |
| * @private | |
| * Filters the variants by all the values that are | |
| * chosen in the selectboxes *except one* which is specified by the | |
| * excludeFilter parameter | |
| */ | |
| _getFilteredVariantsWithoutFilterFor: function(excludedFilter){ | |
| var me = this; | |
| var hashSet = me._variantsHashSet; | |
| var selectBoxNullValue = me.getSelectboxNullValue(); | |
| var filteredVariants = me.getVariants() | |
| .filter(function(item){ | |
| if (item.stock <= 0){ | |
| return false; | |
| } | |
| for (var key in hashSet) { | |
| if (key === excludedFilter){ | |
| continue; | |
| } | |
| var selectBoxValue = me[key].getValue(); | |
| if (selectBoxValue !== selectBoxNullValue){ | |
| if (item.properties[key] !== selectBoxValue){ | |
| return false; | |
| } | |
| } | |
| } | |
| return true; | |
| }); | |
| return filteredVariants; | |
| }, | |
| /** | |
| * @private | |
| * Takes an array of variants and returns a hashset where each key | |
| * is a variant and the value | |
| * is an array of the items that are legal for the variant | |
| */ | |
| _variantsToHashset: function(attributes){ | |
| //generate a hashset for all custom attributes | |
| var hashSet = {}; | |
| attributes.forEach(function(value){ | |
| for (var property in value.properties){ | |
| var entry = value.properties[property]; | |
| if (!hashSet[property]){ | |
| hashSet[property] = [entry]; | |
| } | |
| else if (!Ext.Array.contains(hashSet[property], entry)){ | |
| hashSet[property].push(entry); | |
| } | |
| } | |
| }); | |
| return hashSet; | |
| }, | |
| /** | |
| * @private | |
| * Takes an array of strings and returns an array of objects with a key | |
| * and a value. Those can be used as entries | |
| * for the selectfield | |
| */ | |
| _hashSetItemToSelectEntries: function(hashSetItem){ | |
| var items = Ext.Array.map(hashSetItem, function(item){ | |
| return { | |
| text: item, | |
| value: item | |
| }; | |
| }); | |
| return [{ | |
| text: this.getSelectboxNullValueText(), | |
| value: this.getSelectboxNullValue() | |
| }].concat(items); | |
| } | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment