Angular - unable to get selected ng-repeated radio button using ng-submit - javascript

I might be missing something really simple here - but if I use ng-repeat to create a bunch of radio buttons - I cannot get the selected one using ng-submit.
The controller simply attaches an array of options to the scope.
The markup simply creates a bunch of radio buttons with ng-repeat within a form. It uses ng-submit to capture the submit event. Click 'Run code snippet' below to see the issue.
angular.module('myApp', [])
.controller('myController', ['$scope', function($scope) {
$scope.selectedoption = "";
$scope.submitCalled = "";
$scope.options=[];
$scope.options[0]={id: "option1", name: "option 1"}
$scope.options[1]={id: "option2", name: "option 2"}
$scope.options[2]={id: "option3", name: "option 3"}
$scope.options[3]={id: "option4", name: "option 4"}
$scope.submitForm = function() {
console.log($scope.selectedoption);
$scope.submitCalled = "submit called " + $scope.selectedoption;
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<form ng-submit="submitForm()" ng-controller="myController">
<div ng-repeat="option in options">
<input type="radio" name="option" ng-value="option.id" ng-model="selectedoption">
<label for="radio">{{option.name}}</label>
</div>
<h2>{{selectedoption}}</h2>
<h2>{{submitCalled}}</h2>
<input type="submit" id="submit" value="Submit" />
</form>
</div>

You ng-repeat div should be using ng-model="$parent.selectedoption"
Reason
ng-repeat creates a new child scope every time, as you are declaring new ng-model inside ng-repeat will be added into the ng-repeat scope(child), this child scope has been created on each iteration by ng-repeat. As you want to create a scope variable to the parent scope, so you need to use $parent variable that will point the parent scope.
<div ng-repeat="option in options">
<input type="radio" name="option" ng-value="option.id" ng-model="$parent.selectedoption">
<label for="radio">{{option.name}}</label>
</div>
Demo Fiddle
Update
Other good way to avoid this sort of $parent annotation is by using object annotation, that will do follow the scope prototypal inheritance. Only thing you need to do is define one scope variable in your controller like $scope.selected = { option: '' } then while using it on html you could refer it as selected.option directly no need to use $parent for parent scope reference.
Demo Fiddle

Related

Resolving ng-model outside the form

I have an html file with 2 form elements with input elements inside both. I would be using the ng-if to select which form element I need. The input elements are bound to the same model. But I am unable to resolve it outside the form scope.
<form ng-if="some_name == '1'">
<input ng-model="model_name">
</form>
<form ng-if="some_name == '2'">
<input ng-model="model_name">
</form>
{{model_name}} //This is different from the value of either of the input elements
//it has the initial value which i would assign : $model_name = "xyz"; in my associated js file
The reason you are not able to see those changes outside your form is because you are using 'ngIf' directive to add/remove the DOM and also the 'ngIf' directive creates a new scope.
There are two quick ways to solve this:
1) Make use of 'ngShow'. Look at the below example:
angular.module('app', [])
.controller('HomeController', function($scope) {
$scope.model_name = 'Hi';
$scope.some_name = '1';
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-app="app" data-ng-controller="HomeController">
<form ng-show="some_name == '1'">
<input ng-model="model_name">
</form>
<form ng-show="some_name == '2'">
<input ng-model="model_name">
</form>
{{model_name}}
</div>
2) Make the input model an object, instead of a primitive.
angular.module('app', [])
.controller('HomeController', function($scope) {
$scope.model_name = {
value: 'Hi'
};
$scope.some_name = '1';
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-app="app" data-ng-controller="HomeController">
<form ng-if="some_name == '1'">
<input ng-model="model_name.value">
</form>
<form ng-if="some_name == '2'">
<input ng-model="model_name.value">
</form>
{{model_name.value}}
</div>

$event not defined in ng-change on text input

I hope my issue is simple to solve, I can't access the value by ng-model because i have multiple of these boxes as they are rendered as part of a list of inputs in a form. I am trying to get the ID and text value of a text box with ng-change. heres my html:
<input type="text" class="other-box" ng-model="test" id="4" ng-change="otherBoxUpdate(this)"/>
(ng-model is required, which is why it's in there). Hers is my controller snippet:
$scope.otherBoxUpdate = function (obj, $event) {
console.log(obj)
console.log($event)
console.log($event.target)
}
obj seems to return a scope value, however from what i've read I need to access $event.target, however $event is not defined. What am i doing wrong?
ng-change not allow to pass $event as parameter.
ng-change="otherBoxUpdate(test)"
var myapp = angular.module('app', []);
myapp.controller('Ctrl', function ($scope) {
$scope.otherBoxUpdate = function (obj) {
console.log(obj);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="Ctrl as vm">
<input type="text" class="other-box" ng-model="test" id="4" ng-change="otherBoxUpdate(4)"/>
</div>
If you only need to identify the input that was clicked, you can pass some other piece of identifying information to your handler. For example, we can pass the id:
<input type="text" class="other-box" ng-model="test" id="4" ng-change="otherBoxUpdate(4)"/>

Angular js get div element issue

I am trying to get a div element value by ng-click but it comes an alert undefined.
my html is
<div ng-model='myName'>this is my name</div>
<br/>
<input type="button" value="Show Name" ng-click="showName()"/>
script is
$scope.showName = function(){
var nameOne = $scope.myName;
alert(nameOne);
}
How to solve this issue. Thank you.
ngModel directive can't be used with plain div (unless the element is a custom form control), see https://docs.angularjs.org/api/ng/directive/ngModel
<div ng-init="myName = 'this is my name'">{{ myName }}</div>
<br/>
<input type="button" value="Show Name" ng-click="showName()"/>
Plunker here
Edit: using ngInit outside of ngRepeat is considered a bad practice, initialize scope vars in the controller
$scope.myName = 'this is my name';
$scope.showName = function() {
alert($scope.myName);
}
<div>{{myName}}</div>
<br/>
<input type="button" value="Show Name" ng-click="showName()"/>
script is
$scope.showName = function(){
var nameOne = $scope.myName;
alert(nameOne);
}
Actually ng-model should be use on inputs.
<input type="text" ng-model="myName">
This Will create a $scope.myName var and bind it to the input content.
If you intitialize the myName in your javascript and want it to be displayed in this div you should use this syntax :
JS
$scope.myName = "Ben";
HTML
<div>This is my name : {{myName}}</div>
In both case your button click will not show undefined unless you didn't initialize it before the click (on the 2nd exemple).
Hope it helped.

How to check a radio button with angularJS?

I am creating a html / angularjs form. In the form i have a radio button with yes or no. So i want to check by default the button No.
This is the code i use :
My controller :
angular.module('radioExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.myvariable = 'false';
}]);
My html code snippet:
<div class="col-lg-10">
<input type="radio" id="variable" name="variable" ng-model="myvariable" value="true">Yes</input>
<input type="radio" id="variable" name="variable" ng-model="myvariable" value="false">No</input>
</div>
But nothing is selected(checked) when i load the form the first time. I have to click to one value to have one selected (checked)
What's wrong with my code ? Here the plunker link
Thanks
I've made a fiddle for you. Check HERE
You should also set ng-value which should be true or false
<div ng-controller="MyCtrl">
<div ng-repeat="o in options">
<input type="radio" name="group1" ng-model="o.checked" ng-value="o.checked"></input>
<label>{{o.name}}</label>
</div>
</div>
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.options = [
{ name: 'OPT1', id: 1, checked: false },
{ name: 'OPT2',id: 2, checked: false },
{ name: 'OPT3',id: 3, checked: true }
];
}
The reason why it does not work in your plunkr is because you create a module named "radioExample" but you don't use it when you write the HTML code.
Basically, replace this -
<html ng-app>
at the beginning of the code with this
<html ng-app="radioExample">
This way, when you declare the controller, AngularJS knows which module it needs to look into to get the controller.
Note - if you had not associated your controller with a module, then your code would work.
Check out ng-checked. What you have to do is to add ng-app="radioExample" to the html-Tag of your Application.
Then add ng-checked="myvariable == 'false'" and ng-value="'value'" like in the following plunker example:
Plunker
<div class="col-lg-10">
<input ng-checked="myvariable == 'true'" type="radio" id="variable" name="variable" ng-model="myvariable" value="true">Yes
<input ng-checked="myvariable == 'false'" type="radio" id="variable" name="variable" ng-model="myvariable" value="false">No
</div>
Error in data binding. Define myvariable in controller override value in radiobutton. You must use ng-repeat like
<div ng-repeat="o in options">
<input type="radio" name="name" ng-model="o.checked" ng-value="o.checked"></input>
<label>{{o.name}}</label>
</div>
(I use code from previous answer)

ng-repeat scope issue: two level inheritance?

I got an array of objects, these objects having properties.
I want to be able modify the properties of one of these objects thanks to a ng-repeat -> and that the changes I make are also done in the original array
I've tried to properly do format my array so that the inheritance is ok: when I change in the ng-repeat it changes in the $scope. But it doesn't go to the original array.
I don't know how I could change my data/arrays in order to make it work.
What should I do ? How can I transform my data ?
here is a fiddle that shows all this
ps: I've tried using the parent scope but as you can see in my example I don't even success in that :( anyway it's advised to avoid it if possible
and here's the JS code:
var myApp = angular.module('myApp',[]);
myApp.controller('myController', function ($scope) {
//source array
var origine = [
{id:"1",name:"elem1"},
{id:"2",name:"elem2"},
{id:"3",name:"elem3"} ];
//what I am doing now
$scope.element = origine[1];
//i'd like to transform the array so that I have inheritance and I can avoid using parent scope
var reference = [];
var i =0;
for (var key in origine[2]) {
if (origine[1].hasOwnProperty(key)) {
reference[i] = {prop:origine[2][key]};
i++;
}
}
$scope.element2 = reference;
$scope.element3 = origine[0];
$scope.check = function()
{
//to check if the source array is modified
console.log(origine);
}
});
and here HTML:
<div ng-app="myApp">
<div ng-controller="myController">
--------------- BASIC example -----------------
<br/> Repeat scope
<div ng-repeat="property in element">
<input ng-model="property"/>
</div>
<br/>"Parent"
<input ng-model="element.name"/>
<br/><input type="button" ng-click="check()" value="check origine"/>
<br/><br/>--------------- Trying inheritance -----------------
<br/> Repeat scope
<div ng-repeat="property in element2">
<input ng-model="property.prop"/>
</div>
<br/> "Parent"
<input ng-model="element2[1].prop"/>
<br/><input type="button" ng-click="check()" value="check origine"/>
<br/><br/>--------------- Trying parent scope -----------------
<br/> Repeat scope
<div ng-repeat="property in element3">
<input ng-model="$parent.property"/>
</div>
<br/> "Parent"
<input ng-model="element3.name"/>
<br/><input type="button" ng-click="check()" value="check origine"/>
</div>
</div>
Thats because the variable is being assigned by reference.
Try assigning the array directly to the scope and manipulate that array, or create a scope method to push, splice, update that private array
If I understand you question correctly you can refer to property by key to get it updated:
<div ng-repeat="(key, property) in element">
<input ng-model="element[key]"/>
</div>
Fiddle: http://jsfiddle.net/xezbs8gn/7/

Categories

Resources