I have the following HTML code:
<div ng-controller="DemoController">
<label class="list-group-item" ng-repeat="option in DesignOptions">
<input type="radio" name="optionsRadios" value="{{option[0]}}" />
{{option[1]}}</label>
<label class="list-group-item" ng-repeat="option in StyleOptions">
<input type="checkbox" value="{{option[1]}}">
{{option[2]}}
</label>
</div
And I have the following AngularJS code:
<script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('DemoController', function ($scope) {
var json = '{"Table":[[4,"Full"],[5,"Half"]],"Table1":[[4,1,"Elbow Patch"],[5,2,"Roll Up"]]}';
var obj = $.parseJSON(json);
$scope.DesignOptions = obj.Table;
$scope.StyleOptions = obj.Table1;
});
</script>
This gives me the following result:
Now, I need to display Elbow Patch checkbox only when Full radio button is selected. And Roll Up when Half radio button is selected. This is because, if you see obj.Table array, it has id of '4' for Full and obj.Table1 has id of '4' for Elbow Patch and so on.
I tried Angularjs - showing element based on a presence of id in array but could not modify it to work in my case as my array is very different.
Add a new property to your controller which will store the selected design option:
$scope.designOption = 4; // default to Full
Add the binding to this property in the view:
<input ng-model="$parent.designOption" type="radio" value="{{option[0]}}" />
Add an ng-show directive to the checkbox label:
<label ng-repeat="option in StyleOptions" ng-show='option[0] == designOption'>
I've removed the class and name attributes from the element just to make the code clearer.
NB Need to reference the $parent scope on the radio input as the ng-repeat directive will create a scope for each repeated element and javascript prototypical inheritance rules means that using just 'designOption' will create a designOption property on the child scope and not use the one in your controller.
Related
I'm making a basic todo app in angularjs.
Here's the code that's used to create a new todo with a checkbox
<div class="container" ng-controller = 'controller' >
<h3>Enter Todo </h3> <input type="text" ng-model = 'new'>
<button ng-click = 'add();' ng-disabled="status();">Add</button>
<div ng-repeat = "i in todo" >
<input type="checkbox" ng-model = "todo.done" /> <label>{{i.name}}</label>
</div>
</div>
The problem is that all the checkboxes get checked even when I check just one
Here's my controller module
todoApp.controller('controller',['$scope',function($scope){
$scope.new = '';
$scope.todo = [];
$scope.add = function(){
$scope.todo.push({name : $scope.new, done: false});
console.log($scope.todo);
$scope.new = '';
};
$scope.status = function(){
return !(/\S+/.test($scope.new));
};
ng-model = "i.done"
should solve the problem. In your version ng-model = "todo.done" todo is an array and angular just creates a property on the fly, when it's used for the first time. This way all of your checkboxes are connected to this property, that's why checking one checkbox affects all of them.
Because the list of the checkbox are sharing the same model. You can create a custom directive or you can use checklist-model directive.
Demo URL:
https://vitalets.github.io/checklist-model/
Angular 1.*
I have:
<div class="filter-column">
<div class="filter-title">Market</div>
<div class="bottom-line"></div>
<div class="overflow-container">
<input type="radio" value="all" name="marketRadio"
ng-checked="true" class="resetAll" ng-model="filter.markets"
ng-change="radioMap('market')" checked>All
<div ng-repeat="choice in markets| orderBy: 'name'">
<input type="radio" value="{{choice.name}}" name="marketRadio"
ng-change="radioMap('market')" ng-model="filter.markets" >
{{choice.description}}
</div>
</div>
In the controller I have:
var ppvFilter = {
regions: [],
markets: [],
dealers: []
};
$scope.$watchCollection(function() {
return ppvFilter;
},
function(newValue) {
$scope.regions = newValue.regions;
$scope.markets = newValue.markets;
$scope.dealers = newValue.dealers;
});
When I refresh the radio button list programaticly(not page refresh) with ppvFilter.markets.length = 0; ppvFilter.markets = ppvFilter.markets.concat(['a', 'b', 'c']), the list of radio button choices updates as it should in the gui. However, ng-checked="true" no longer works for all and it is unchecked after the list updates.
I suspect it is because the angular form is referencing old memory even though it is showing the new list of radio buttons.
From the angular documentation on ngChecked: Note that this directive should not be used together with ngModel, as this can lead to unexpected behavior.
I figured it out.... the default item HAS to be in the ng-repeat. ng-check is not much use in real life.
Reference:
Radio button checked by default when using ng-repeat
The issue I'm having is that I'd like to have a text input be blank while it has a defined ng-model that has a default value, then, when the input becomes dirty, I'd like that specific ng-model to be redefined. Example:
<span ng-init="level='Base'">{{level}}</span>
<input ng-model="level" placeholder="Specify Level">
Optimally, the example above would say "Base" as a default value in the span, but not in the input (so the placeholder is visible) until the input becomes dirty with the redefined 'level' value. I've tried something along these lines, but was unable to achieve what I was looking for:
<span ng-init="level='Base'">{{level}}</span>
<input ng-model="noop" ng-change="checkDirty()" name="lvl" id="lvl" placeholder="Specify Level">
// Controller code
$scope.checkDirty = function(){
if ($scope.myform.lvl.$dirty) {
angular.element("#lvl").attr("ng-model", "level")
}
}
Thanks for your time!
You don't need to have a change event to check if the form is dirty. You can directly have a condition inside the span element.
{{level ? level : 'Base'}}
Demo
var app = angular.module('app', []);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app">
<span>{{level ? level : 'Base'}}</span>
<input ng-model="level" name="lvl" id="lvl" placeholder="Enter level">
</body>
I want to loop through an array of objects that I receive from a REST service and create a dynamic form using the ng-repeat directive.
This is my form with a rating directive (taken for the UI Bootstrap library)
<form name="categoryRatingFrom" data-ng-submit="updateCategories(catRatings) >
<div data-ng-repeat="cats in categories" class="form-group clearfix">
<label class="control-label">{{ cats.name }}</label>
<div class="no-outline"
data-rating
data-ng-model=" // Here I want to concatenate {{ cats.id }} with the ng-model name catRatings // "
data-max="6"
data-rating-states="ratingOptions.ratingStates"
data-on-hover="atmosphereRating.onHover(value)"
data-on-leave="atmosphereRating.onLeave()"></div>
</div>
<form>
I want to set the data-ng-model value using the object name that I pass when submitting and the ID of the current object tin my loop/array, however I don't seem to be able to do this. Should I do the concatenation in the controller on receiving the object array using a loop and then set the data-ng-model using a value from the ng-repeat nothing is passed to the controller when submitting the form (see my code below):
// loop through the object adding a ng-model name that we match in our form...
for (var i = 0, l = $scope.categories.length; i < l; i++) {
$scope.categories[i]['modelId'] = 'catRatings.' + $scope.categories[i].id;
}
I add the following to my HTML data-ng-model="cats.modelId" but nothing is passed to the controller when submitting - can any one help me with a solution or give me an answer to what I am doing wrong?
ng-model takes a variable, not a string value. I'm not sure what exactly you're trying to do but I would think it would be something like:
ng-model="catRatings[cats.id]"
However, I am not familiar with that directive so I'm not sure if it accepts a ng-model attribute.
I have created an example that will be referenced throughout the post. The following variables are declared within the scope as follows.
$scope.data = [
{
'id' : 0,
'name' : 'Tim'
},
{
'id' : 1,
'name' : 'John'
}
];
$scope.ratings = [ '5 stars', '2 stars' ];
When you are setting your model to 'catRatings' + {{ cats.id }} that means somewhere you are declaring a $scope.catRatings1, $scope.catRatings2, etc. Instead you should bind directly the the category object as follows.
<label ng-repeat="person in data">
<input type="text" ng-model="person.name">
...
</label>
or bind to an array with a corresponding index
<label ng-repeat="person in data">
...
<input type="text" ng-model="ratings[$index]">
</label>
or bind to an array using the id...
<label ng-repeat="person in data">
...
<input type="text" ng-model="ratings[person.id]">
</label>
I am new to AngularJS. In my scenario, the user has to create a mcq question. The question has 4 default option and one of the options is correct. Now the user who is teacher can give greater or less then 4 options for the question. So its a variable number of options. If hard code the input as follow
<input name = "input0" type = "text", class = "form-control" ng-model = "input_0" required>
<input name = "input1" type = "text", class = "form-control" ng-model = "input_1" required>
and so on it works good. I want to use dynamic solution here, so it does not matter how many options the teacher provide.
What I was trying to do is
$scope.mcq_options = [$scope.input_0,$scope.input_1 ...]
use ng-repeat in html template and do something like
<div ng-repeat = "input in mcq_options">
<input name = "input1" type = "text", class = "form-control" ng-model = "input" required>
For removing splice entry from array
For adding more push entry in array
The solution is quite straightforward (Associated PLUNKER):
1 Create an empty array that you may store all your options, in your controller.
var inputArray = $scope.inputArray = [];
[2] Create a function to add new options.
$scope.addNewOption = function() {
inputArray.push('');
};
[3] Create another function to splice an option entry that accepts the index of an option to remove.
$scope.removeOption = function(index) {
inputArray.splice(index, 1);
};
[4] Your view can be something like this:
<form name="form" novalidate>
<div ng-repeat="input in inputArray track by $index" ng-form="subform">
<input name="input" type="text" ng-model="inputArray[$index]" required> <button ng-click="removeOption($index)">Remove</button>
<br>
<span ng-show="subform.input.$error.required">This field is rqeuired</span>
</div>
<button ng-click="addNewOption()">Add New Option</button>
</form>
Note:
The track by $index in the ng-repeat directive helps in avoiding duplicate values error.
The ng-form directive helps you in validating each models that is created in every ng-repeat iteration.
Instead of using the input value in the ng-repeat directive, use its direct reference by using the ng-repeat's $index property. If you dont't do this, changes in the inputArray may affect the current ngModel reference of your inputs. e.g. adding or removing options will give you weird behaviours.