Skip to content
This repository was archived by the owner on Oct 2, 2019. It is now read-only.

fix(multiple): formatter binding #748

Merged
merged 1 commit into from
Mar 17, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 58 additions & 50 deletions src/uiSelectMultipleDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,28 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec

controller: ['$scope','$timeout', function($scope, $timeout){

var ctrl = this;
var $select = $scope.$select;
var ctrl = this,
$select = $scope.$select,
ngModel;

//Wait for link fn to inject it
$scope.$evalAsync(function(){ ngModel = $scope.ngModel; });

ctrl.activeMatchIndex = -1;

ctrl.updateModel = function(){
ngModel.$setViewValue(Date.now()); //Set timestamp as a unique string to force changes
ctrl.refreshComponent();
};

ctrl.refreshComponent = function(){
//Remove already selected items
//e.g. When user clicks on a selection, the selected array changes and
//the dropdown should remove that item
$select.refreshItems();
$select.sizeSearchInput();
};

// Remove item from multiple select
ctrl.removeChoice = function(index){

Expand All @@ -33,6 +50,8 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
});
});

ctrl.updateModel();

};

ctrl.getPlaceholder = function(){
Expand All @@ -48,9 +67,11 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
link: function(scope, element, attrs, ctrls) {

var $select = ctrls[0];
var ngModel = ctrls[1];
var ngModel = scope.ngModel = ctrls[1];
var $selectMultiple = scope.$selectMultiple;

//$select.selected = raw selected objects (ignoring any property binding)

$select.multiple = true;
$select.removeSelected = true;

Expand All @@ -76,63 +97,49 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
var data = $select.parserResult.source (scope, { $select : {search:''}}), //Overwrite $search
locals = {},
result;
if (data){
var resultMultiple = [];
var checkFnMultiple = function(list, value){
//if the list is empty add the value to the list
if (!list || !list.length){
resultMultiple.unshift(value);
return true;
if (!data) return inputValue;
var resultMultiple = [];
var checkFnMultiple = function(list, value){
if (!list || !list.length) return;
for (var p = list.length - 1; p >= 0; p--) {
locals[$select.parserResult.itemName] = list[p];
result = $select.parserResult.modelMapper(scope, locals);
if($select.parserResult.trackByExp){
var matches = /\.(.+)/.exec($select.parserResult.trackByExp);
if(matches.length>0 && result[matches[1]] == value[matches[1]]){
resultMultiple.unshift(list[p]);
return true;
}
}
for (var p = list.length - 1; p >= 0; p--) {
locals[$select.parserResult.itemName] = list[p];
result = $select.parserResult.modelMapper(scope, locals);
if($select.parserResult.trackByExp){
var matches = /\.(.+)/.exec($select.parserResult.trackByExp);
if(matches.length>0 && result[matches[1]] == value[matches[1]]){
resultMultiple.unshift(list[p]);
return true;
}
}
if (result == value){
resultMultiple.unshift(list[p]);
return true;
}
if (angular.equals(result,value)){
resultMultiple.unshift(list[p]);
return true;
}
return false;
};
if (!inputValue) return resultMultiple; //If ngModel was undefined
for (var k = inputValue.length - 1; k >= 0; k--) {
if (!checkFnMultiple($select.selected, inputValue[k])){
checkFnMultiple(data, inputValue[k]);
}
return false;
};
if (!inputValue) return resultMultiple; //If ngModel was undefined
for (var k = inputValue.length - 1; k >= 0; k--) {
//Check model array of currently selected items
if (!checkFnMultiple($select.selected, inputValue[k])){
//Check model array of all items available
if (!checkFnMultiple(data, inputValue[k])){
//If not found on previous lists, just add it directly to resultMultiple
resultMultiple.unshift(inputValue[k]);
}
}
return resultMultiple;
}
return inputValue;
return resultMultiple;
});

//Watch selection
//Watch for external model changes
scope.$watchCollection(function(){ return ngModel.$modelValue; }, function(newValue, oldValue) {
if (oldValue != newValue)
if (oldValue != newValue){
ngModel.$modelValue = null; //Force scope model value and ngModel value to be out of sync to re-run formatters
});
//TODO Should be a better way to detect first pass
$select.firstPass = true; // so the form doesn't get dirty as soon as it loads
scope.$watchCollection('$select.selected', function() {
if (!$select.firstPass) {
ngModel.$setViewValue(Date.now()); //Set timestamp as a unique string to force changes
} else {
$select.firstPass = false;
$selectMultiple.refreshComponent();
}
//Remove already selected items
//e.g. When user clicks on a selection, the selected array changes and
//the dropdown should remove that item
$select.refreshItems();
//TODO Should add a test
$select.sizeSearchInput();
});

ngModel.$render = function() {
// Make sure that model value is array
if(!angular.isArray(ngModel.$viewValue)){
Expand All @@ -144,11 +151,12 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
}
}
$select.selected = ngModel.$viewValue;
scope.$evalAsync(); //To force $digest
};

scope.$on('uis:select', function (event, item) {
$select.selected.push(item);
$select.sizeSearchInput();
$selectMultiple.updateModel();
});

scope.$on('uis:activate', function () {
Expand Down