Reputation:
Currently I am using this for loop for getting parent
angular.forEach(queryTicketCategories, function(category) {
if(category.id === $scope.ticketCategory.parentId) {
$scope.parent = category;
}
});
Please suggest common directive that will return category
. Here queryTicketCategories
is an object of arrays. And I wanna assign a array to $scope.parent
that equals $scope.ticketCategory.parentId
Html code is
<input type="text" ng-model="parent"
placeholder="{{'PARENT_CATEGORY' | translate}}"
typeahead="category as category.name for category in getTicketCategories($viewValue)"
typeahead-loading="loading" class="form-control">
Upvotes: 7
Views: 513
Reputation: 6035
I am not sure what you want, you have to update your answer and provide an example with what you want: i have A, i pass B, i expect C.
In any case here is a simple directive that implements the logic in the code in your question. And here is the jsfiddle.
var app = angular.module('HelloApp', [])
app.controller('MyController',
function MyController($scope) {
$scope.myCategoryId = 11;
$scope.myParentCategory;
$scope.myCategories = [{
"id": 1,
"name": "Tara"
}, {
"id": 11,
"name": "Opal"
}, {
"id": 21,
"name": "Whitfield"
}, {
"id": 31,
"name": "Alta"
}, {
"id": 41,
"name": "Tucker"
}, {
"id": 51,
"name": "Sims"
}, {
"id": 61,
"name": "Bradshaw"
}];
});
app.directive('parentCategory', function() {
return {
restrict: "AE",
scope: {
categories: "=",
categoryId: "=",
parent: "="
},
link: function(scope, iElement, iAttrs, controller, transcludeFn) {
scope.$watch('categoryId', findParent);
function findParent() {
var parent;
angular.forEach(scope.categories, function(category) {
if (category.id === scope.categoryId) parent = category;
});
scope.parent = parent;
}
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="HelloApp">
<div ng-controller="MyController">
<label for="">CategoryId:</label>
<input type="number" ng-model="myCategoryId">
<h3>Parent</h3>
<pre>{{myParentCategory|json}}</pre>
<parent-category categories="myCategories" category-id="myCategoryId" parent="myParentCategory"></parent-category>
</div>
</div>
<!-- or you can use it like this, as an attribute
<input type="number" ng-model="myCategoryId" parent-category categories="myCategories" category-id="myCategoryId" parent="myParentCategory">
-->
Upvotes: 3
Reputation: 306
angular.forEach(queryTicketCategories, function(category) {
if(category.id === $scope.ticketCategory.parentId) {
$scope.parent = category;
}
});
From your code, queryTicketCategories must be an array of objects. Since you can not loop an object. So try using,
angular.forEach(queryTicketCategories, function(category) {
if(angular.equals(parseInt(category.id), parseInt($scope.ticketCategory.parentId)) {
$scope.parent = category;
return;
}
});
Here make sure that queryTicketCategories is in the format,
[ { ... }
, { ... }
, { ... }
]
in order to category.id to work, and we are using parseInt since there might be a chance that category.id or $scope.ticketCategory.parentId might be in String.
Note that, '===' and angular.equals() has the same implementation.
Upvotes: 5
Reputation: 27738
For your case, it's better to look into typeahead directive and make max use of it.
http://angular-ui.github.io/bootstrap/#/typeahead
Instead of creating your own directive or service, you can use the existing directive with callback, typeahead-on-select
typeahead-on-select($item, $model, $label) (Defaults: null) :
A callback executed when a match is selected
This is the example that I created without using callback. It enables you to select a google address from what you type.
Without typeahead-on-select
:
http://plnkr.co/edit/GMnzod9MQZWxsKSuJUJu?p=preview
The following is going step further by changing the selected address to uppercase. You can do whatever you want in this callback.
http://plnkr.co/edit/jaeSZdSKucMQgIF05KwD?p=preview
I used this function to change the selected address to uppercase.
$scope.myFunc = function($item, $model, $label) {
$scope.asyncSelected = $item.toUpperCase();
}
For your case you can make like the following
$scope.myFunc = function(category) {
if(category.id === $scope.ticketCategory.parentId) {
$scope.parent = category;
}
}
HTML
typeahead-on-select="myFunc($item)"
In summary, your use case and data might be different from the example that I used above, but the main approach is the same. There is a callback after you select an item, and you can manipulate your data control more with the callback typeahead-on-select
.
Upvotes: 7
Reputation: 12739
If I understand correctly, you want to set the $scope.parent
object that appears in the text box based on $scope.ticketCategory.parentId
If so, then a directive is not the best way to do this. Directive are meant for DOM manipulation or logic that affects your view. But this functionality has nothing to do with updating view. It just happens that the view binds to $scope.parent
, but if you just set this object in code the view will update automatically (or maybe with an $apply()
call)
In that case, you should create a service or filter to make this operation reusable (also make sure to return once a match is found as there is no need to continue the loop after that, right?)
However, if you insist on using a directive. You can make a directive that depends on ng-model, and set the value of the model based on other attributes (the category list, the selected id). So the usage will be like this maybe
<input type="text" ng-model="parent" set-model="ticketCategory.parentId" set-model-list="queryTicketCategories" >
and the directive code will basically find the object from queryTicketCategories
that has the same id as ticketCategory.parentId
and set the model with this object.
You should probably set a flag or so in the directive to run this code only once and not every $apply()
loop. But with the service/filter approach you get to set the parent
value whenever you want (maybe after a server request or in a callback) so I recommend you use that instead of a directive.
Upvotes: 6
Reputation: 528
You can have watch expression on $scope.ticketCategory.parentId. Once the value for $scope.ticketCategory.parentId is changed then update $scope.parent to the category having the same id.for searching you can create filter.
Example -
app.filter('getById', function() {
return function(queryTicketCategories, id) {
var i=0, len=queryTicketCategories.length;
for (; i<len; i++) {
if (queryTicketCategories[i].id == +id) {
return queryTicketCategories[i];
}
}
return null;
}
});
$scope.$watch('ticketCategory.parentId', function() {
// do something here
var found = $filter('getById')(queryTicketCategories, ticketCategory.parentId);
console.log(found);
$scope.parent = found;
}, true);
Upvotes: 4