Using ng-hide based on previous element in Angular - javascript

How do I use ng-hide based on the previous select dropdown? I would like to show #additional-option if option C is selected in the dropdown.
<div class="form-group">
<label class="control-label col-md-3">Option:
<span class="required">
*
</span>
</label>
<div class="col-md-4">
<select class="form-control">
<option selected>A</option>
<option>B</option>
<option>C</option>
<option>D</option>
</select>
</div>
</div>
<!-- Show the below only if C is selected -->
<div class="form-group" id="additional-option">
<label class="control-label col-md-3"></label>
<div class="col-md-4">
<label>
<div class="checker">
<span>
<input type="checkbox">
</span>
</div>
Additional option
</label>
</div>
</div>

You bind the view controls to scope items and check the values in other bindings. So in your case you can bind your first select to scope as below.
ng-model="formData.selectedLetter"
Then you can use ng-show in the next control to check the value for the previous select control.
ng-show="formData.selectedLetter === 'C'"
You could also use ng-hide if you must, by reversing the condition expression.
This will ensure that the second control is only visible if the formData.selectedLetter is 'C'.

You simply need to setup a two-way binding on your element like so
<select class="form-control" ng-model="selectedOption">
and use that value in the ng-show directive for the div that needs to be hidden, like so
<div ng-show="selectedOption === 'C'" class="form-group" id="additional-option">
here's the plunker - http://plnkr.co/edit/XsXs4uhNTB6cKAL4IM5f?p=preview

Related

Multiple Select dropdown with dynamic data in Angular

currently i'm working on a angular project and i'm facing some issue in creating multiple select dropdown with dynamic data.
I want the to acheive something like this. There will be one button which when clicked will add multiple select dropdown in the form and that select dropdown will have dynamic data fetched from api.
The above thing is already acheived but the problem that i'm facing is that all the dynamic select dropdown had same ng-model and same name, so when i'm selecting value for one select dropdown, the same value is getting selected for all the dynamic select dropdown.
Attaching the screenshot for referrence
Now when i select any single dropdown, all the value for other dropdown are getting selected as well.
I hope i'm able to explain as much as possbile.
The code i used to add multiple dropdown
<div class="pull-right"><button (click)="addNewRow()" class='btn btn-success'>Add New Subjects</button></div>
This html is added dynamically in the form
<div class="row" *ngFor="let ts of total_subjects; let i=index">
<div class="col-4">
<div class="mb-3">
<label class="form-label" for="Status">Select Subject</label>
<select class="form-select digits" id="subject_id" name="subject_id" [(ngModel)]="form.subject_id"
required
#subject_id="ngModel" (change)="getChapter(subject_id.value)">
<option value="">Select Subject</option>
<option *ngFor="let sub of subjectList" value="{{sub.subject_id}}">{{sub.name}}</option>
</select>
</div>
</div>
<div class="col-4">
<div class="mb-3">
<label class="form-label" for="Status">Select Chapters</label>
<select class="form-select digits" id="chapter_id" name="chapter_id" [(ngModel)]="form.chapter_id"
required
#chapter_id="ngModel" >
<option value="">Select Chapter</option>
<option *ngFor="let chap of chapterList" value="{{chap.subject_id}}">{{chap.name}}</option>
</select>
</div>
</div>
<div class="col-3">
<div class="mb-3">
<label class="form-label" for="questions">No of Questions</label>
<input class="form-control" id="questions" type="number" name="questions" [(ngModel)]="form.questions"
required
#questions="ngModel" />
</div>
</div>
<div class="col-1"><button (click)="removeRow(i)" class='btn btn-danger'>Remove</button></div>
</div>
Here is the component code i used
total_subjects:any = [{
subject:'',
chapter:'',
questions:''
}];
addNewRow(): void{
this.total_subjects.push({
subject:'',
chapter:'',
questions:''
});
}
I don't really like to work with ngmodel when it is something complex, but in any case, I would try to give them in runtime a different name to each row, based on the index.
If you had left a StackBlitz with your current code worling, I would have tried to change it in your code to prove that it works, but more or less it consists of something like this:
<div class="row" *ngFor="let ts of total_subjects; let i=index">
<div class="col-4 mb-3">
<label class="form-label" for="Status">Select Subject</label>
<select
class="form-select digits"
id="subject_id_{{i}}"
name="subject_id_{{i}}"
[(ngModel)]=`form.subject_id_${i}`
required
#subject_id_{{i}}="ngModel"
(change)=`getChapter(subject_id_${i}.value)`>
<option value="">Select Subject</option>
<option *ngFor="let sub of subjectList,let i2 as index" value="{{`sub.subject_id_${i2}}">{{sub.name}}</option>
</select>
</div>
Note that you will have to play with the sintaxis {{ index}} and ${index} (backtips), depending on the case...
I hope this idea helps you.

First dropdown selection is not filtering second dropdown

I'm trying to filter dropdown based on selection of first dropdown, in my console log, everything is fine, but second dropdown allways showing all results, not filtered one, here is how I did it:
<!--Group-->
<div class="form-group">
<label class="control-label dash-control-label col-xs-3">GROUP:</label>
<div class="col-xs-9">
<select class="form-control" style="width: 100%;"
data-minimum-results-for-search="Infinity" name="articleGroups" required (change)="filterSubById(article.mainGroup.id)" [(ngModel)]="article.mainGroup">
<option disabled [ngValue]="null">-/-</option>
<option [ngValue]="group" *ngFor="let group of mainGroups">{{group.title}}</option>
</select>
</div>
</div>
<!--Subgroup-->
<div class="form-group">
<label class="control-label dash-control-label col-xs-3">SUBGROUP:</label>
<div class="col-xs-9">
<select class="form-control" style="width: 100%;" name="subGroup" required [(ngModel)]="article.subGroup">
<option disabled [ngValue]="null">-/-</option>
<option [ngValue]="subgroup" *ngFor="let subgroup of subGroups">{{subgroup.title}}</option>
</select>
</div>
</div>
You need to pass the outcome of the filterBySubId method back to the view. You're not doing anything with the returned value.
I'd do something like this:
filterSubById(Id) {
this.filteredSubGroups = this.subGroups.filter(item => item.parentId == Id);
}
and in view
<option [ngValue]="subgroup"
*ngFor="let subgroup of filteredSubGroups">{{subgroup.title}}</option>

Make drop down required only if it has values in AngularJs

I have two drop downs in form. First drop down has 4 values, but second drop down has value only if value with index 3 is selected in first drop down, otherwise is empty.
Code I have always preform validation and checks if both drop downs has values.
Is there an easy way in angular to preform validation for second drop down only if it has values inside of it?
In other words, if drop down is not empty that user has to select value.
This is my code for drop downs:
<form name="addNewTestSession" class="form-horizontal" novalidate>
<div class="row">
<div class="col-md-2" ng-class="{ 'has-error has-feedback': addNewTestSession.event.$touched && addNewTestSession.event.$invalid }">
<label for="event">Event<span class="mandatory">*</span></label>
<select id="event" name="event" class="form-control" ng-model="newTestSessionCtrl.formData.event"
ng-options="event.name for event in newTestSessionCtrl.viewData.events"
ng-required="true">
<option value="" disabled selected>Select</option>
</select>
<span ng-show="addNewTestSession.event.$touched && addNewTestSession.event.$invalid"
class="form-control-feedback fa fa-warning"
uib-popover="This field is required."
popover-trigger="'mouseenter'"
popover-placement="auto right"
popover-class="additional-info"></span>
</div>
<div class="col-md-2" ng-class="{ 'has-error has-feedback': addNewTestSession.subevent.$touched && addNewTestSession.subevent.$invalid }">
<label for="subevent">Sub-Event<span class="mandatory">*</span></label>
<select id="subevent" name="subevent" class="form-control" ng-model="newTestSessionCtrl.formData.subevent"
ng-options="subevent.name for subevent in newTestSessionCtrl.formData.event.subevents"
ng-required="true">
<option value="" disabled selected>Select</option>
</select>
<span ng-show="addNewTestSession.subevent.$touched && addNewTestSession.subevent.$invalid"
class="fa fa-warning form-control-feedback"
uib-popover="This field is required."
popover-trigger="'mouseenter'"
popover-placement="auto right"
popover-class="additional-info"></span>
</div>
</div>
</form>
As you can see 'subevent' drop down is always required. How can I change it to be required only if it has values inside?
You can give a condition to ng-required.
You didn't give your controller code, but I will assume that newTestSessionCtrl.formData.event.subevents is equal to [] when empty.
Your condition is then
<select id="subevent" name="subevent" class="form-control"
ng-model="newTestSessionCtrl.formData.subevent"
ng-options="subevent.name for subevent in newTestSessionCtrl.formData.event.subevents"
ng-required="newTestSessionCtrl.formData.event.subevents.length > 0"
>
Try something like:
ng-required="newTestSessionCtrl.formData.event.subevents.length > 0"

Scoping issue when adding multiple instances of views using ng-repeat

I'm hitting a scoping issue when using the ng-repeat functionality of AngularJS.
please see the plnkr
I have an array of objects 'boxCollection' and a list of items 'itemCollection' which I display in a drop down.
$scope.boxCollection = [];
$scope.itemCollection =
[
{name: 'item1'},
{name: 'item2'},
{name: 'item3'}
];
Now I have my view as
<script type="text/ng-template" id="addBox.html">
<div class="box-controls">
<span class="glyphicon glyphicon-plus pull-left" ng-click="addBox()"></span>
<span class="glyphicon glyphicon-minus pull-left" ng-class="{disable_div:boxCollection.length < 2} " ng-click="removeBox($index)"></span>
</div>
<div class="box-container">
<div class="box-details">
<div class="boxItem">
<form class="form-horizontal">
<div class="form-group">
<label class="control-label col-md-3">Item</label>
<div class="col-md-8">
<select class="form-control" ng-options="item.name for item in itemCollection" ng-model="boxCollection[$index].item" ng-disabled="false">
<option value=""> None </option>
</select>
</div>
</div>
<div class=" form-group ">
<label class="control-label col-md-3">Item Desc</label>
<div class="col-md-8">
<input type="text " class="form-control " ng-model="boxCollection[$index].item.desc ">
</div>
</div>
</form>
</div>
</div>
<div class="clearfix "></div>
</div>
</script>
The view is wrapped in a script tag with an id and is called with an ng-repeat.
I have one function to add a box element into my view 'addBox()'. It generates one entry in 'boxCollection' array and another entry in 'boxTmplList' array. 'boxTmplList' is responsible for showing the views.
Now if you select let's say 'item1' from the drop down in box1 and add a value in the input field, add another box in the view using the '+' button and select 'item1' again in the another instance. It displays the value of input field 1 in the input field 2.
enter image description here
On further analysis I found that Angular tracks the objects with similar 'item' name using the same $hashkey.
I'm using a workaround by adding another property to the object 'boxCollection[$index].itemDesc' instead of 'boxCollection[$index].item.desc' and then later on modify the object using another function, but I feel that's not the most efficient way.
Any insight on this would be greatly appreciated.
You need to change ng-model="boxCollection[$index].item" to ng-model="boxCollection[$index].item.name" , like as-
<select class="form-control" ng-options="item.name for item in itemCollection" ng-model="boxCollection[$index].item.name" ng-disabled="false">
Working Plnkr
Change ng-model="boxCollection[$index].item.desc" to ng-model="itemCollection[$index].name".
<div class=" form-group ">
<label class="control-label col-md-3">Item Desc</label>
<div class="col-md-8">
<input type="text " class="form-control " ng-model="itemCollection[$index].name">
</div>
</div>

Hide elements with ng-change Angular

I want to show/hide element in form with ng-change or whatever you suggest . here is my html:
<div ng-app ng-controller="Controller">
<select ng-model="myDropDown" ng-change="changeState(0)">
<option value="one">One</option>
<option value="two">Two</option>
</select>
<div class="row-container">
first One
<span class="sp-right">
<label>
1
</label>
</span>
<span class="sp-left">
<input type="text">
</span>
<div class="row-container">
second One
<span class="sp-right">
<label>
2
</label>
</span>
<span class="sp-left">
<input type="text">
</span>
for example i want to show first one when user click on option 1 .
Fiddle
No need for ng-change, just use ng-if (or ng-show) to inspect the model's state:
<div class="row-container" ng-if="myDropDown == 'one'">
<div class="row-container" ng-if="myDropDown == 'two'">
Fiddle (with correct closing tags so that it actually works).
I would use ng-switch. If you want to show a div if none is selected then you can use ng-switch-default. If you want to default one of the div's below, then remove ng-switch-when= and replace it ng-switch-default
<div ng-app ng-controller="Controller" ng-switch on="myDropDown">
<select ng-model="myDropDown">
<option value="one">One</option>
<option value="two">Two</option>
</select>
<div class="row-container" ng-switch-when="one">
first One
<span class="sp-right">
<label>
1
</label>
</span>
<span class="sp-left">
<input type="text">
</span>
</div>
<div class="row-container" ng-switch-when="two">
second One
<span class="sp-right">
<label>
2
</label>
</span>
<span class="sp-left">
<input type="text">
</span>
</div>
</div>
http://plnkr.co/edit/QNdMxmYjR5LhsNvsHPpJ?p=preview

Categories