Angular, ng-repeat and radio buttons - javascript

I am using radio buttons in a ng-repeat and it seems to have some problem. Basically, they work, however the user has to click on the radio button twice to uncheck itself and I can't seem to figure out why. Here's how I'm using it.
<div ng-repeat="parent in chains track by $index"><!-- Level 1 row -->
<input type="radio" name="levelCheckDat" ng-model="trackChain.value" ng-value="{{$index}}" ng-change="trackLevelIndex()">
<p style="font-weight:bold;">Chain {{$index+1}}</p>
</div>
It comes through the repeat, but it only will start working after you click on it twice. Any insight into this?
The ng- change just sets a boolean so I know something is select like so :
$scope.trackLevelIndex = function(){
//update index for tracking what level we have selected
$scope.levelChecked = true;
};
Then I use the trackChain.value to tell me what level is selected.

Related

angular material two check boxes, only one can be checked at a time

I am very new to Angular-material so this question might sound a bit silly, but please bear with me.
I have two checkboxes as following.
<mat-checkbox>Apply for Job</mat-checkbox>
<mat-checkbox>Modify a Job</mat-checkbox>
Let's say a user checked the first checkbox ("Apply for a Job") then later on clicks on "Modify Job" checkbox, I want the application to automatically uncheck the first one. How can I achieve this without using radio-buttons?
You can put a condition on checked attribute, as in this example:
Typescript:
selected=-1;
HTML
<div *ngFor="let item of [1,2,3]; let i = index">
<mat-checkbox [checked]="selected === i" (change)="selected = i">Check me!</mat-checkbox>
</div>
DEMO

Variable not changing value on checkbox condition

This section uses a checkbox to select your extras, once selected you move onto the next step and it will display your choice in a header called checkout[itemname]. When a check box is selected it changes a variable from false to true however my code doesn't seem to be doing that.
I will show an example section of the user selecting "Neck Tie" from the list of extras.
var hasNeckTie = false;
if (hasNeckTie = true) {
document.getElementById("checkoutnecktie").innerHTML = "Neck Tie";
}
<div class="three columns bear">
<h3>Matching Tartan Scarf (£2.50)</h3>
<label>
<input type="checkbox" autocomplete="off" name="scarf" id="scarf" value="2.5" />
<img src="Images/Scarft.png">
</label>
<p>Personalise your bear with a matching tartan scarf. It gets cold up here in Scotland, and this is the best way to keep your bear warm.</p>
</div>
<div id="checkoutnecktie"></div>
Any ideas why this code isn't running properly?
Your problem starts where you are using = instead of == in your if statement.
You are also trying to set the HTML value of an element which does not exist.
document.getElementById("checkoutnecktie").innerHTML = "Neck Tie";
You need to change "checkoutnecktie" to an element ID which exists.
You would need to hook an event to the checkbox.
You can do this with jQuery like so
$('#scarf').change(function(){
if($(this).is(":checked")) {
$('#checkoutnecktie').text('Neck tie');
}
}
Also like the other answer states, set the text to an element that exists.

get index of radio in ng-repeat outside of ng-repeat

I am trying to use the selected radio as a reference to it's index within its array so that I may add more children in it's sub array (using the selected radio).
So here's what I have:
<div class="fakeTableRow" ng-repeat="parent in listTable">
<div class="strcutionLeft"></div>
<!-- parent levels -->
<div class="strcutionCRight saInstrcutionTitle"><div class="parentSub1"> <input type="radio" name="levelCheckDat" ng-model="levelChecker" value="{{$index}}">{{parent.name}}</div></div>
</div>
And then outside of this (above) there is a button that when pushed calls a function, inside that function I would like a reference to the index the radio is in so I may then drop children inside. Here is my attempt at that:
$scope.submitNewSub = function(){
//get index of radio
console.log($scope.levelChecker.indexOf($scope.levelChecker));
// .....continue function with index stored
});
My assumption was that the radios are stored in their own scope, however if i simply log ($scope.levelChecker) it comes back undefined, so i believe I am thinking about this wrong, I just cannot seem to figure out how.
To be clear, I am just trying to figure out the index (in the ng-repeat) of the selected radio with the model of levelChecker. Thanks for reading!
Edit: i swapped the value of the button to the {{$index}} to see if i could pull a value off by just calling the scope

Angular - Toggling element class inside an ng-repeat based on radio input selection

I'm using Angular to write a questionnaire where the questions are retrieved from a resource. Based on the design, I have to toggle a custom icon instead of the standard radio button icon. The solution I've come up with is to hide the radio input (using opacity/filter) and absolutely position a div over the input with the same dimensions as the radio input. Clicking the radio input will toggle a background image which is the custom icon. Unfortunately, this has to work in IE8 so conventional CSS :checked tactics are out.
The question blocks will look something like this:
<h2>{{ quiz.questions[asked].questionText }}</h2>
<ul>
<li ng-repeat="answer in quiz.questions[asked].answers">
<label>
<input type="radio" ng-model="$parent.picked" name="answer" value="{{ answer.answerID }}"/>
<div class="radio-mimic {{ checked }}"></div>
{{ answer.answerText }}.
</label>
</li>
</ul>
<a class="btn" ng-click="submitAnswer()" ng-show="picked != null">
Submit
</a>
Here is a stripped down version of my controller for reference:
app.controller('QuizController', function($scope, Quiz) {
$scope.quiz = Quiz.get({quizID = X}); // Angular $resource
$scope.picked = null;
$scope.asked = 0;
$scope.answers = [];
$scope.submitAnswer = function() {
$scope.asked++;
$scope.picked = null;
// Push answer selected onto answers array
// Check if # asked == number of questions in quiz to determine flow
// If another question, $scope.quiz = Quiz.get({quizID = newQuizID});
// Else show results
};
});
For each answer I receive to a question, I'm outputting the radio input and the div icon wrapped in a label with the answer text. Clicking on an answer will change the value of 'picked' in the parent scope of the repeat, thus only displaying the submit button when a user has picked an answer.
The problem I'm having is how to handle the logic of {{ checked }} for the div class to show when an input is selected. When I click on an input, the div within its scope needs to get a class called 'checked'. Additionally, if I click on a different answer outside that scope, the other scopes in the ng-repeat need to know in order to reset their 'checked' values to null or ''. I know some value will have to go into the parent scope like 'picked' but the overlap of the parent and ng-repeat scopes is causing me some confusion. I can do this easily enough with jQuery but wanted to keep this purely Angular as part of my learning.
I found a solution to my issue by using ng-class and an expression to compare the parent scope's 'picked' with the answerID of the inner scope:
<div class="radio-mimic" ng-class="{checked: $parent.picked == answer.answerID}"></div>

Radio button on/off trigger works only one way

So this is the dumbest thing I've struggled with in awhile. I cannot get the state of a simple radio button set to toggle something on the page.
<label for="completeSw"><span>Completed?</span></label>
<input type="radio" id="completeSw" name="completeSw" value="1"/>Yes
<input type="radio" id="completeSw" name="completeSw" value="0" checked="checked"/>No<br/>
So you can see here an extremely simple yes/no radio button set to toggle an action. It needs to serve two purposes: to flag a yes/no value (1/0) in the POST data, and ideally trigger an action on the page using JS/jQuery. I'm having trouble with the latter.
The default state is "No"; if I click "Yes" I can retrieve an onchange or onclick event state and make something happen. However, this is a one-way switch; I cannot retrieve a state going back to the "No" selector once I've gone to "Yes". What I need to be able to do is show / hide an element on the page depending on what choice they've made in this radio set. If I click "Yes", I can trigger the action and see the page change. Once I click "No", however, it acts as if there was no state change and I cannot perform an action i.e. hide the element again.
I've tried variations on retrieving the "checked" state, the radio pair value, etc, e.g.
$("#completeSw").change(function(e){
alert( $(this).attr("checked") ); // only triggers when "Yes" is selected
});
Perhaps I should not be using a yes/no radio pair, but instead be using a single checkbox? Seems more user-friendly and elegant this way (radio buttons) to me.
IDs must be unique, so it will only ever find the first one on your page. Use a class instead.
Really, ID's must be unique, but you don't need 2 ID's. You'll only monitor changes in one radio. For example - "Yes" value
<label for="completeSw"><span>Completed?</span></label>
<input type="radio" id="completeSw" name="completeSw" value="1"/>Yes
<input type="radio" name="completeSw" value="0" checked="checked"/>No<br/>
And the you'll process the checked attribute of only this element. True - "Yes", False - "No"
Some browsers don't do anything when alert(message), message=null. And since an unchecked field has no checked-attribute, that could be the thing :).
Try:
alert('Checked: '+$(this).attr("checked"));
This is separate, but you're kinda using the label wrong also. The label is meant to extend the click area so someone could click on the word 'Yes' and the radio button will activate. Hopefully this helps you out a little.
<span>Completed?</span>
<input type="radio" id="completeSwYes" name="completeSw" value="1"/><label for="completeSwYes">Yes</label>
<input type="radio" id="completeSwNo" name="completeSw" value="0" checked="checked"/><label for="completeSwNo">No</label><br/>
<script type="text/javascript" charset="utf-8">
// If the radio button value is one then this evaluates to true.
var completeSW;
jQuery("input[type='radio'][name='completeSw']").change(function() {
completeSW = (jQuery(this).val() == 1);
alert("completeSW checked? " + completeSW);
});
</script>

Categories