"select form" does not sync with model - angularjs

This is my template:
<div class="form-group"
ng-repeat="recipeIngredient in recipes.currentRecipe._ingredients">
<label class="col-sm-2 control-label">Ingredient {{ $index + 1 }}</label>
<div class="col-sm-10 form-inline" role="form">
<input
type="text"
class="form-control"
placeholder="quantity"
ng-model="recipeIngredient.quantity"
>
<input
type="text"
class="form-control"
ng-model="recipeIngredient._unit"
>
<select
class="form-control"
ng-model="recipeIngredient._unit"
ng-options="unit._id for unit in units"
/>
<select
ng-model="recipeIngredient._ingredient"
class="form-control"
ng-model="recipeIngredient._ingredient"
ng-options="ingredient._id for ingredient in ingredients"
/>
<button
type="button"
class="btn btn-default btn-xs glyphicon glyphicon-remove"
ng-click="recipes.currentRecipe.removeRecipeIngredient($index)">
</button>
</div>
</div>
I want to display the ingredients listed in the currentRecipe
If I use:
<input type="text" class="form-control" ng-model="recipeIngredient._unit">
I can see the value of _unit showed
But why the select form does not show at all the current value of recipeIngredient._unit?
<select
class="form-control"
ng-model="recipeIngredient._unit"
ng-options="unit._id for unit in units"
/>
I've verified the the _unit is part of the list of units
If I change the value of the select box to some value, the input text show "Object", which means the real value of the model is the unit object and not the unit._id text
ng-options="unit._id for unit in units"`
Please tell me if you want additional code

I've found out that when I use:
ng-options="unit._id for unit in units"
The text showed in the drop box is unit._id, but the ng-model will be the object in unit and not the text showed!
To correct my problem I've written like this:
<select ng-model="recipeIngredient._unit" class="form-control">
<option ng-repeat="unit in getId(units, '_id')">{{unit}}</option>
</select>
the getId is the function that return a list of _id from units

Related

Dynamically add reqired attribute to input fields in angularjs

I am not able to dynamically set required attribute to input fields
My form's required attribute has to change dynamically based on a radio button field.
This is how the form looks when the radio button is set as wants to join screenshot. and when radio button is set as member/alumnus the form looks like this screenshot
I am not able to dynamically switch the required attribute for input fields in respective forms.
This is the code for contact and DOB field if new Member is checked
<label class="control-label is-imp"></label>
<div class="input-group">
<input type="radio" ng-model="joinFormData.joinType" value="wantsToJoin">I Want to join as member
<input type="radio" ng-model="joinFormData.joinType" value="alreadyMember">I am a member/alumnus
</div>
</div>
<div class="form-group no-pad-left" ng-if="joinFormData.joinType == 'wantsToJoin'">
<div class="nss-only" ng-if="clubType == 'NSS'">
<div class="form-group col-md-12 no-pad-left no-pad-right">
<div class="col-md-6 no-pad-left">
<label class="control-label is-imp">Contact:</label>
<input
type="text" class="form-control" id="body_contact"
name="body_contact" ng-model="joinFormData.contact" placeholder="1234567890" ng-pattern="/^[0-9]{10}$/" ng-minlength="10" ng-maxlength="10" integer [ng-required]="joinFormData.joinType == 'wantsToJoin'">
<span ng-show="joinForm.body_contact.$error.$invalid || joinForm.body_contact.$error.pattern"><span class = "red-color">Enter a valid number!</span></span>
</div>
<div class="col-md-6 no-pad-right">
<label class="control-label is-imp">DOB:</label>
<input
type="date" class="form-control" id="body_dob"
name="body_dob" ng-model="joinFormData.dob"
required ng-maxlength="100" required>
<span ng-show="joinForm.body_dob.$error.required && joinForm.body_dob.$touched"><span class="red-color">Required!</span></span>
</div>
</div> </div> </div>
This is the code for select type field if Member/ Alumnus is checked
<div class="form-group col-md-12 no-pad-left no-pad-right">
<div class="col-md-6 no-pad-left" ng-if="joinFormData.joinType == 'alreadyMember'">
<label class="control-label is-imp">I am already a member/alumnus:</label>
<div class="input-group">
<select ng-model="joinFormData.memberType"
class="form-control selectpicker" [required]="joinFormData.joinType == 'alreadyMember'" name="body_type">
<option value="" selected disabled>Select Type</option>
<option value="member">Member</option>
<option value="alumni">Alumni</option>
</select>
<!-- <span ng-if="!joinForm.body_type.$valid && joinForm.body_type.$touched"><span class="red-color">Required!</span></span> -->
</div>
</div></div>
I tried using [required]="joinFormData.joinType == 'alreadyMember'" conditions but that didn't work.
Kindly help me out. I am not able to figure out the mistake as i am new to angular

Ensure at least one checkbox is selected in angular

I need to validate that at least one checkbox, in 3, has been selected. I can't use radio buttons because two of the options are can be selected and exclude the third. I'm not really sure if it's best to put these checkboxes into a model array, rather than binding them to separate models and creating a longer ng-required expression. The docs aren't particularly helpful in describing what 'best practise' is for this sort of thing...
Code:
<div class="form-inline form-group">
<div class="row">
<div class="col-xs-12">
<h4 class="card-title left test-list-header">Balcony</h4>
</div>
</div>
<fieldset class="form-group">
<input type="checkbox" id="balconyBalcony" ng-model="balcony">
<label for="balconyBalcony">Balcony</label>
</fieldset>
<fieldset class="form-group">
<input type="checkbox" id="patioBalcony" ng-model="patio">
<label for="patioBalcony">Patio</label>
</fieldset>
<fieldset class="form-group">
<input type="checkbox" id="noBalcony" ng-model="noBalcony" ng-disabled="balcony || patio">
<label for="noBalcony">No</label>
</fieldset>
<fieldset class="form-group" ng-show="noBalcony && !patio && !balcony">
<div class="md-form">
<input
type="text"
id="{{ Plot::FIELD_BALCONY_NOTES }}"
class="form-control"
name="{{ Plot::FIELD_BALCONY_NOTES }}"
inline-edit
inline-edit-callback="UpdateHandler()"
ng-model="Model.BalconyNotes.Value"
ng-class="{ invalid: createPlot.balconyNotes.$invalid && submitted, valid: createPlot.floor.$valid }"
ng-init="Model.BalconyNotes.Value = '{{ old(Plot::FIELD_BALCONY_NOTES) or $Model->BalconyNotes }}'" ng-required="noBalcony">
<label for="{{ Plot::FIELD_BALCONY_NOTES }}" data-error="#{{ Model.BalconyNotes.ValidationMessage }}" class="w-100">Comments</label>
<span class="help-block" ng-show="createPlot.balconyNotes.$invalid && submitted">As there is no balcony or patio, you must enter a comment</span>
</div>
</fieldset>
You could use ng-required built in directive to validate your form.
Like this:
<form novalidate name="myForm" ng-submit="mySubmitFunc()">
<label>Checkbox 1
<input ng-required="!(cb2 || cb3)" ng-model="cb1" type="checkbox">
</label>
<label>Checkbox 2
<input ng-required="!(cb1 || cb3)" ng-model="cb2" type="checkbox">
</label>
<label>Checkbox 3
<input ng-required="!(cb1 || cb2)" ng-model="cb3" type="checkbox">
</label>
<input type="submit" ng-disabled="myForm.$invalid" value="submit">
</form>
Here is a fiddle demonstrating how to handle such logic.
You could add a validation line:
<div ng-show="myForm.$submitted">
<p style="color: red" ng-show="!myForm.balcony && !myForm.patio && !myForm.noBalcony">You must select at least one of the options above.</p>
</div>
That div shows when the user tries to submit and the p shows when none are selected.
Your button will also need an ng-disabled directive with the same condition.

get value of dynamic ng-model value

I want to get ng-model's value in scope varialbe
<div class="form-group" data-ng-repeat="wing in getNumber(app.wingnum) track by $index">
<label for="InputMessage">Enter name of Wing </label>
<div class="input-group" >
<input type="text" class="form-control" name="" placeholder="Enter Name of wings"
ng-model="control[$index]"
ng-keyup="addNewWing()"required/>
</div>
</div>
Since it's your ngModel - you should have access to it via $scope.control[indexValue]

how can I apply has-error to a single input inside form-group, where multiple inputs exist

Im using angularjs and $invalid to add .has-error to my form group.. problem is one of my form groups has multiple inputs in it, side by side..
<div class="form-group">
<div class="col-sm-6">
<label for="location">Location</label>
<select class="form-control input-lg" name="location" ng-model="newRack.location" ng-options="location as location.name for location in locations" placeholder="Locations" required></select>
</div>
<div class="col-sm-6">
<label for="name">Rack Size</label>
<input type="number" class="form-control input-lg" name="size" ng-model="newRack.size" min="1" max="48" required>
</div>
</div>
validation would look similar to this, but would include additional validations for the size element as well.
ng-class="{ 'has-error': rackForm.location.$invalid && rackForm.location.$dirty }"
if name=size becomes invalid, as it stands .has-error is applied to the entire form group, and that can be confusing to the end user. Is there a way to either
apply the .has-error to a specific input
rearrange my form
layout a bit so each input is in its own form group, yet still retain
the side by side look.
The way i do it is to create form-group for each input element. Also, I believe you don't need inner <div class="col-sm-6"> since you can join that class with form-group and get the same results.
<div class="form-group col-sm-6" ng-class="{ 'has-error': rackForm.location.$invalid && rackForm.location.$dirty }">
<label for="location">Location</label>
<select class="form-control input-lg" name="location" ng-model="newRack.location" ng-options="location as location.name for location in locations" placeholder="Locations" required></select>
</div>
<div class="form-group col-sm-6" ng-class="{ 'has-error': rackForm.size.$invalid && rackForm.size.$dirty }">
<label for="name">Rack Size</label>
<input type="number" class="form-control input-lg" name="size" ng-model="newRack.size" min="1" max="48" required>
</div>
Let me know if it helped
The simple answer is you are trying to put too much logic into your HTML. Look in to creating Angular directives that implement your logic behind the scenes or do it in your controller, and set the state you are trying to check on your scope.
One of the key precepts of Angular is to not put logic in the HTML.
To do this without changing your layout, just use ng-class sintax in each div with col class. Like that:
<div class="form-group">
<div class="col-sm-6" ng-class="{ 'has-error': rackForm.location.$invalid && rackForm.location.$dirty }">
<label for="location">Location</label>
<select class="form-control input-lg" name="location" ng-model="newRack.location" ng-options="location as location.name for location in locations" placeholder="Locations" required></select>
</div>
<div class="col-sm-6" ng-class="{ 'has-error': rackForm.size.$invalid && rackForm.size.$dirty }">
<label for="name">Rack Size</label>
<input type="number" class="form-control input-lg" name="size" ng-model="newRack.size" min="1" max="48" required>
</div>
</div>

How to pass ng-models to a form

i have a form with two differently named ng-models. I need to pass both of them with the form. How would this work? I need to pass currentItem + currentItem.Customer I am having trouble with a PdfSharp controller and I want to see if this is the reason why the Customer Values are being passed back as Null.
controller
$scope.EmailPdf = function () {
var id = $scope.currentItem.JobId
$http.get('/api/Pdf/' + id).success(function () {
$scope.PrintPreviewModal();
});
}
form
<form ng-submit="submitJob()" enctype="multipart/form-data" name="myForm">
<fieldset>
<div class="col-xs-12">
<label>Number:</label>
<input ng-model="currentItem.JobNumber" type="text" name="JobNumber">
<label>Customer:</label>
<input type="text" ng-model="currentItem.Customer.CustomerName"
typeahead="customer.CustomerName for customer in customerArray | filter:$viewValue"
typeahead-on-select="selectEditCustomer($item)">
</div>
<input ng-model="currentItem.CustomerId" type="text" ng-hide="true"/>
<div class="inline-fields">
<label >Status:</label>
<selectng-model="currentItem.JobStatus">
<option value="" selected="selected">Select</option>
<option value="Active">Active</option>
<option value="InActive">InActive</option>
<option value="Complete">Complete</option>
</select>
<label>Address:</label>
<input ng-model="currentItem.Customer.CustomerAddress" type="text">
</div>
<div class="inline-fields">
<label>Name:</label>
<input ng-model="currentItem.JobName" type="text">
<label>City:</label>
<input ng-model="currentItem.Customer.CustomerCity" type="text">
<label>St:</label>
<inputng-model="currentItem.Customer.CustomerState" type="text">
<label>Zip:</label>
<input ng-model="currentItem.Customer.CustomerZipcode" type="text">
</div>
<div class="inline-fields">
<label>Address:</label>
<input ng-model="currentItem.JobAddress" type="text">
<label>Ph:</label>
<input ng-model="currentItem.Customer.CustomerPhoneNumber" type="text">
<label>Fax:</label>
<input disabled style="width: 105px"ng-model="currentItem.Customer.CustomerFaxNumber" type="text">
</div>
<input ng-click="EmailPdf(currentItem)" type="button" value="Email" />
Well it's a bit difficult to tell exactly what you are asking here, but it sounds like you mean that you need to pass more information than the ID into your get. So you can pass the entire currentItem with all it's content like this
$http.get('/api/Pdf/' + id,angular.toJson($scope.currentItem)).....
Is that what you are trying to do?

Resources