AngularJS - checkboxes and dropdownlist - javascript

As I mentioned in topic i try do depends checkboxes from dropdownlist. I fill data to my dropdownlist from controller:
#RequestMapping(value = "/all", method = GET)
public List<Warehouse> findAll(){
return warehouseService.findAll();
}
$http
.get('/api/warehouses/all')
.then(function (response) {
$scope.warehouses = response.data;
});
Every Warehouse object have a List with package:
#OneToMany
private List<Package> packages = new ArrayList<>();
Now when i am creating Route and when i select one Warehouse from dropdownlist i wanna fill checkboxes from List from currently selected Warehouse.
Select Warehouse:
<select ng-model="credentials.warehouseStart">
<option ng-selected="credentials.warehouseStart == x" id="startId" ng-value="x" ng-repeat="x in warehouse" >{{x.name}}</option>
</select>
And checkboxes:
<div flex-xs flex="50">
<md-checkbox aria-label="Select All"
ng-checked="isChecked()"
md-indeterminate="isIndeterminate()"
ng-click="toggleAll()">
<span ng-if="isChecked()">Un-</span>Select All
</md-checkbox>
</div>
<div class="demo-select-all-checkboxes" ng-model="credentials.packages" flex="100" ng-repeat="item in packages">
<md-checkbox ng-checked="exists(item, selected)" ng-click="toggle(item, selected)">
{{ item.name }} <p> </p>
{{ item.user.firstName }} {{ item.user.lastName }}
</md-checkbox>
</div>
Checkbox fill:
$http
.get('/api/package/all')
.then(function (response) {
$scope.packages = response.data;
});
It is possible if i select one object in Dropdowlist(Warehouse) can i get a object id? Then i think i can get a correct chebkoxes by directive /package/all/{id} ?

I am basing my answer of your comment that every warehouse has a list of packages. That said, I am expecting packages to be a part of your GET call to /api/warehouses/all.
First, I would change your warehouse selection to use ngOptions:
<select ng-model="selected.warehouse"
ng-options="x.name for x in warehouses"></select>
Then, to list the packages:
<div ng-model="selected.packages"
ng-repeat="item in selected.warehouse.packages">
<input type="checkbox"
ng-checked="exists(item, selected)"
ng-click="toggle(item, selected)"> {{ item.name }}
<p> </p>
{{ item.firstName }} {{ item.user.lastName }}
</div>
I have created a sample here. Within, I have added a couple of wrappers around the package list in your ui using ngIf, but that's not necessary, but figured you'd probably have a view area to show based on whether or not a selection was made.

Related

Vue: Rendered list show selected checkboxes

I try to display my selected checkboxes, which I render like this:
<pre>{{ JSON.stringify(selectedAttributes, null, 2) }}</pre>
<ul
class="list-unstyled"
v-for="category in categories"
:key="category.name"
>
<strong>{{ category.category_name }} </strong>
<li
v-for="attributes in category.attributes"
:key="attributes.attribute_id"
>
<Field
as="input"
name="attribute"
type="checkbox"
class="form-check-input"
v-model="selectedAttributes"
:id="attributes.attribute_id"
:value="attributes.attribute_id"
/>
<label class="form-check-label" for="attributes.attribute_id">
{{ attributes.attribute_name }}
</label>
</li>
</ul>
...
data() {
return {
selectedAttributes: [],
};
},
Unfortunately, the attribute_id of my selected checkboxes is not showing. Where is my mistake?
Update: The data from my api looks like this:
What I need here is, I want the user to check his preferred options and display the selected options in the JSON.stringify. The selectedAttributes should display the attribute_id of the chosen option.
Your data does not have attribute_id id property at all. Only attribute_name you can see at the image you provided

$watch changes ui-select in individual object iterated via ng-repeat

I am working with <ui-select> and came across a problem I apparently do not understand how to tackle. There is a bunch of related topics on it here on SO, however, none of them covered my specific problem, which is I think quite simple for people who have worked with this directive before.
I have a big object with item objects inside, like this one:
let items = [{id: 1, name: 'name'}, {id: 2, name: 'name2'}];
I am iterating over object to make it visible in front. The option will be displayed in
<ui-select-match allow-clear="true">
<span>{{ $select.selected.label }}</span>
</ui-select-match>
The label will be selected in controller based on the "watched" value. My question here is what should I set in ng-model to watch the changes on the level of individual items and update it?
I tried to use track by index, ng-change instead of watch and a bunch of other approaches which brought no results.
Template:
<div ng-repeat="item in vm.items">
<div class="form-group field">
<label>Items:</label>
<ui-select ng-model="item.id"
ng-keyup="vm.newItems({ keyword: $select.search })"
search-enabled="false">
<ui-select-match allow-clear="true">
<span>{{ $select.selected.label }}</span>
</ui-select-match>
<ui-select-choices repeat="item.id as item in vm.shortlistsList">
<pre>Name: {{ item.label }}</pre><pre>Id: {{ item.id }} </pre>
</ui-select-choices>
</ui-select>
</div>
In controller:
function $onChanges() {
$scope.$watch('item.id', function (newValue, oldValue) {
console.log(item.id);
});
}
QUESTION: How can I watch each individual item, what/how should I pass to ng-model? At the moment I see no way of doing it as my half day of attempts is gone in vain.
Following a long and painful day of experiments, I found a workable solution:
Template:
<div ng-repeat="item in vm.items track by $index">
<div class="form-group field">
<label>Items:</label>
<ui-select ng-model="item[$index]"
ng-keyup="vm.newItems({ keyword: $select.search })"
search-enabled="false">
<ui-select-match allow-clear="true">
<span>{{ $select.selected.label }}</span>
</ui-select-match>
<ui-select-choices repeat="item.id as item in vm.shortlistsList">
<pre>Name: {{ item.label }}</pre><pre>Id: {{ item.id }} </pre>
</ui-select-choices>
</ui-select>
</div>
Controller:
for (let i = 0; i < vm.items.length; i++) {
$scope.$watch('vm.items[' + i + ']', function (newValue, oldValue) {
if (newValue && oldValue !== null) {
return newValue.label = newValue.name;
}
}, true);
}

nested ng-repeat on two separate arrays

More than finding a way to resolve this, I am now interested in understanding why this is not working.
Let's say I have this array in angular:
$scope.movieThemes = [ 'Fiction', 'Drama'];
And another array with with movies like:
$scope.movies=[{theme:'Drama', movie:'One million dollar baby'}, {theme:'Drama', movie:'Green mille'},{theme:'Fiction', movie:'Avatar'}, {theme:'Fiction', movie:'The Hobbit'}]
I have an ngRepeat with my themes
<div ng-repeat= "t in movieThemes">
And a nested datalist filtering the themes:
ng-repeat="m in movies|filter:{theme:t}
Where t is from the parent repeater like:
<datalist id="movieList">
<option ng-repeat="m in movies|filter:{theme:t}" value="{{m.movie}} - {{t}}"></option>
</datalist>
OK as you can confirm on my fiddle this is not working:
Online Demo
But the question is why not?
Worth to mentioned without a data list it works fine:
Without Data List Demo
Try like this. i change your filter function syntax and also add select tag to dataList.
Edit:
Your problem cuase for datalist id. i.e your datalist ids in ne-repeat are same. i change datalist ids by adding $index to it. now it work correctly.
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', ["$scope",function MyCtrl($scope) {
$scope.movieThemes = [ 'Fiction', 'Drama'];
$scope.movies=[
{theme:'Drama', movie:'One million dollar baby'},
{theme:'Drama', movie:'Green mille'},
{theme:'Fiction', movie:'Avatar'},
{theme:'Fiction', movie:'The Hobbit'}
];
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<div ng-repeat= "t in movieThemes">
<input type="text" ng-model="t" />
{{t}} - {{$index}} <input type="text" placeholder="Users" list="movieList{{$index}}">
<datalist id="movieList{{$index}}">
<select>
<option ng-repeat="m in movies|filter:{theme:t}" value="{{m.movie}} - {{t}}"></option>
</select>
</datalist>
</div>
</div>
You can use groupBy filter. This way you don't need wot worry about themes array. You can write your own/use angular filters module.(https://github.com/a8m/angular-filter)
<ul>
<li ng-repeat="(key, value) in movies| groupBy: 'theme'">
Group name: {{ key }}
<ul>
<li ng-repeat="m in value">
player: {{ m.movie}}
</li>
</ul>
</li>
</ul>
BTW I like angular filters modules

How to distinct HTML select options with angularjs?

I have an HTML for select tag, with this code :
<div ng-controller="Models">
<select ng-model="myModel" ng-options="Model.name for Model in Models" class="form-control"></select>
{{ {selected_Model:myModel.name} }} {{ {selected_Model:myModel.id} }}
</div>
and I want it to show only myModel.id==1.
how can I do it ?
I think this question needs a bit more of an explanation.
Do you mean you want to display a select for each model in models however only if the model.id ==1?
You can do this with a filter, while the models are being written to the page in your select box this filter checks if they have an .id == 1 and if TRUE then allows it to be written into the select.
I would imagine however that this means you'll only have 1 item in your select box as duplicate id's in objects are bad news bears.
angular.module('YOURAPPNAME', [])
.filter('myModelFilter', function() {
return function(myModel) {
if (myModel.id == 1) {
return myModel;
}
};
})
<div ng-controller="Models">
<select ng-model="myModel" ng-options="Model.name for Model in Models | myModelFilter" class="form-control"></select>
{{ {selected_Model:myModel.name} }} {{ {selected_Model:myModel.id} }}
</div>
EDIT: P.s.
Calling a controller and objects in your controllers "Model" and "Models" is confusing, I'd recommend choosing a different naming convention as AngularJS is an MVWhatever framework the term "Model" has a very different meaning to what you're using it for.
You could this on HTML side itself by using filter with strict checking true like ng-options="Model.name for Model in Models | filter: {id: 1}: true"
Markup
<div ng-controller="Models">
<select ng-model="myModel" class="form-control"
ng-options="Model.name for Model in Models | filter: {id: 1}: true" >
</select>
{{ {selected_Model:myModel.name} }} {{ {selected_Model:myModel.id} }}
</div>

AngularJS add CSS class on new item in ng-repeat

Here is my view for a list.
back...
<ul>
<input type="text" ng-model="search">
<li ng-repeat="item in items | filter:search | orderBy:'date'">
{{ item.ID }} - {{ item.heading }} - {{ item.date | date:"dd.MM.yy" }}
<button ng-click="deleteItem(item.ID)">del</button>
</li>
<form>
<input type="text" ng-model="itemName">
<input type="date" min="{{ date }}" max="{{ maxDate }}" value="{{ date }}" ng-model="itemDate">
<button ng-click="addItem()">add</button>
</form>
</ul>
On click my contoller adds a new item to the view, which works fine. Now i want to animate only the new item with css3. Therefore the new item needs a class. How can i achieve this with angular?
This should assign class the-class to the last element of the list dynamically:
<li ng-class="{'the-class': $last}" ng-repeat="item in items | filter:search | orderBy:'date'">
{{ item.ID }} - {{ item.heading }} - {{ item.date | date:"dd.MM.yy" }}
<button ng-click="deleteItem(item.ID)">del</button>
</li>
If you're using Angular 1.1.5, you can use ngAnimate enter event instead which is precisely designed for this kind of situation.
Have a look at http://www.nganimate.org/ and http://code.angularjs.org/1.1.5/docs/api/ng.directive:ngAnimate
If you use a function to add an Item, you could also set a variable to know which Id is the last inserted while adding the item to the list
First, you can see what I did here http://jsfiddle.net/DotDotDot/Eb2kR/
I just created a lastInsertedId variable, which I use to add a class in the ng-repeat :
<span ng-class='{lastinserted: item.ID==lastInsertedId}'>{{ item.ID }} - {{ item.heading }} - {{ item.date | date:"dd.MM.yy" }}</span>
I had no idea how you implemented you addItem method and what are your IDs, so I created my own method and I assumed your IDs are unique numbers, but it could work with anything (hoping you can find a unique set of data)
$scope.addItem=function(){
var dd=new Date($scope.itemDate);
$scope.items.push( {"ID":$scope.items.length+1, "heading":$scope.itemName, "date":dd.getTime()});
$scope.lastInsertedId=$scope.items.length;
}
I change the last inserted id, which will apply the selected class to the item
You could also unset the lastInsertedId value in the delItem() method
If you have a more difficult logic (here I assumed you had unique IDs) you can also use a function in the ng-class. Here, on my example it wouldn't be hard to code :
$scope.amITheOne=function(item){
return item.ID==$scope.lastInsertedId;
}
then
<span ng-class='{lastinserted: amITheOne(item)}'>
It doesn't change much with a simple logic, but you could totally have a logic based on the ID, the name and the date for example
Have fun

Categories