Make drop down required only if it has values in AngularJs - javascript

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"

Related

Data not showing in select dropdown after value is set

the foundation of my code is that I am taking data from ag-grid and showing that data into select drop-down (inside a popup) when "Edit" button is clicked.
But the data is not showing in the select drop-down.
When I click Edit, "YES" or "NO" should show as already selected in the drop-down based on the data I get from the grid. The code I used is mentioned below:-
<!-- Alter Part -->
<div class="form-group row">
<label for="alter_part" class="col-sm-3 col-form-label">Alter Part</label>
<div class="col-sm-9">
<select id="alter_part" class="form-control" onchange="alternatefunc();" required>
<option value="1">YES</option>
<option value="0">NO</option>
</select>
</div>
</div>
<!-- Test Type -->
<div class="form-group row">
<label for="test_type" class="col-sm-3 col-form-label">Select Test Type</label>
<div class="col-sm-9">
<select id="test_type" class="form-control" required>
<option value="1">YES</option>
<option value="0">NO</option>
</select>
</div>
</div>
function getInitialData(params)
{
//Setting value using grid data
document.getElementById('alter_part').value = params.node.data[params.columnApi.getAllGridColumns()[3].colId];
document.getElementById('test_type').value = params.node.data[params.columnApi.getAllGridColumns()[7].colId];
}
I have verified that the select drop-down stores the value from grid,
var a = document.getElementById('test_type').value;
variable "a" here returns the correct value of the grid row.

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.

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

Form input length and selected items from dropdown validation

I have following form and I'm trying to validate following form states:
themeName must is required and should have min. 4 chars.
themeLangFrom selected value cannot be same as themeLangTo (and vice versa).
I would like to display span error message under each invalidated field.
I tried to do by this way but I cannot resolve it with select inputs.
Could somebody tell to me how to do it in the right way please?
Form code:
<ul class="nav nav-pills pull-right">
<li>Close form</li>
</ul>
<h3 class="text-muted">Add New Theme</h3>
<form role="form" name="addThemeForm" id="addThemeForm" >
<div class="form-group">
<label for="themeName">Theme name:</label>
<input id="themeName" type="name" required class="form-control" ng-minlength="4" ng-model="newtheme.name" placeholder="Enter Theme Name">
<span class="formValidationError" ng-show="addThemeForm.themeName.$error">Enter valid e-mail</span>
</div>
<div class="form-group">
<label for="themeLangFrom">Language from:</label>
<select id="themeLangFrom" required class="form-control" ng-options="language as language.name for language in languages" ng-model="newtheme.langFrom" >
<option value="">{{language.name}}</option>
</select>
</div>
<div class="form-group">
<label for="themeLangTo">Language to:</label>
<select id="themeLangTo" required class="form-control" ng-options="language as language.name for language in languages" ng-model="newtheme.langTo" >
<option value="">{{language.name}}</option>
</select>
</div>
<input ng-click="addTheme(newtheme)" ng-disabled="!addThemeForm.$valid" type="submit" value="Add New Theme" class="btn btn-success btn-block btn-lg">
</form>
In order to validate that themeLangFrom is diferent from themeLangTo you will need to implement a custom directive.
You can use angular-ui's ui-validate directive (http://angular-ui.github.io/ui-utils/) for that or proabbly better:
Roll your own... You can take example from the many implementations for password validation directives out there just notice that unlike password validation you need the fields to not be equal.
You can see some examples here: password-check directive in angularjs

Using ng-hide based on previous element in Angular

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

Categories