Evening all. Could anyone tell me how to set a radio button to checked in an ng-repeat when it loads? In the table below I have a list of prices with a sort function I created. It sorts from the lowest price down. Is there a way I can set the lowest price radio button to 'checked' each time the table loads?
<table>
<tr ng-repeat="prices in productVariant.prices | orderBy: tcoSort">
<td><strong>{{prices.code }}</strong></td>
<td ng-click="displayFullPricing(prices)">
<input type="radio" name="{{variant.code}}" ng-click="displayFullPricing(prices, $index)">
</td>
</tr>
$scope.tcoSort = function (productVariant) {
return productVariant.nonRecurring.retailPrice + (productVariant.monthly.retailPrice * $scope.productAttributesObj.Term);
};
Thanks
Very simple used $scope.modelName and set its value to any of the value(attribute) of radio button you want to set by default for example:-
Male
Female
now set $scope.one="male" in controller you will get the default value to radio button.
In case of ng-repeat concept is same but you just need to use $parent with the model of ng-repeat because ng-repeat creates its own scope that can not be accessed from controller.
Below is small simulated example:-
<div ng-repeat="check in people">
<input type="radio" name="hello" value="{{check.name}}" ng-model="$parent.human"/> {{check.name}}
</div>
$scope.people=[
{
'name':'rachit'
},
{
'name':'gulati'
},
{
'name':'rocks'
}
]
$scope.human='gulati';//You need to set it to the lowest price from your array .
Here is fiddle
<input type="radio" name="{{variant.code}}" ng-click="displayFullPricing(prices, $index)" checked>
??
An example using checkboxes that you could use:
<tr ng-repeat="content in contents" ng-class="{danger: currentContent.resource_uri === content.resource_uri || checkboxes.isSelected[content.id]}" name="content[{{$index}}]" ng-click="selectContent(content, $index);">
<td class="grid-checkbox"><input type="checkbox" ng-model="checkboxes.isSelected[content.id]" name="checkbox[{{content.id}}]" ng-checked="checkboxes.isSelected[content.id]" ng-change="changeCheckbox(content, $index)"/></td></tr>
this is a snippet from my code I guess what you need is
<input type="checkbox" ng-model="checkboxes.isSelected[content.id]" name="checkbox[{{content.id}}]" ng-checked="checkboxes.isSelected[content.id]" ng-change="changeCheckbox(content, $index)"/>
hope it helps
Related
I have made a simple html table with a column of checkboxes, as well as some other columns. Above that, is a delete button that will call a service function I have already made, but I want it to delete every checked box that the column has. How would I send my delete function an array of checked "projects"?
Below is the delete button code:
<div class="panel-body">
<button class="btn pull-right btn-danger button-project-request form-group" value="Submit" ng-click=deleteCheckedProjects()>Delete</button>
</div>
Below is the table code:
<tbody>
<tr ng-repeat="project in projects">
<td><input type="checkbox" name="checkbox" value="project"/></td>
<td ng-click=editRequestModule(project)>{{project.project.projNm}}</td>
<td>{{convertMilliseconds(project.project.strtDt)}}</td>
<td>{{convertMilliseconds(project.project.endDt)}}</td>
<td>{{project.project.statusId.staDescription}}</td>
</tr>
</tbody>
Any advice on how to go about this? Maybe in Javascript, establish a two way bounded array that holds all the checked boxes?
I think the simplest implementation would be to replace your checkboxes with individual delete buttons:
<tr ng-repeat="proj in projects">
<td><button ng-click="remove(proj)">delete</button><td>
<td>{{proj.name}}</td>
<!-- ... -->
</tr>
Where remove is something to the effect of:
$scope.remove = function(proj){
$scope.projects.splice($scope.projects.indexOf(proj), 1);
}
If you're set on checkboxes, you can include some sort of "staged for delete" flag in your project model:
<tr ng-repeat="proj in projects">
<td><input type="checkbox" ng-model="proj.will_delete"></td>
<td>{{proj.name}}</td>
<!-- ... -->
</tr>
<button ng-click="remove_staged()">delete</button>
Where remove_staged is something like:
$scope.remove_staged = function(){
$scope.projects = $scope.projects.filter(proj=> !proj.will_delete);
}
You could add a 'project-checkbox' class to each checkbox, then use
var checkboxes=document.getElementsByClassName('project-checkbox');
to get every checkbox.
From there you can create an empty array, loop through the checkboxes array and check if it has been checked before adding it to the new array.
var checkboxes=document.getElementsByClassname('project-checkbox');
var checkedProjects=[];
for(var i=0;i<checkboxes.length;i++){
if (checkboxes[i].checked) {
checkedProjects.append(checkboxes[i]);
}
}
Now checkedProjects has every checked checkbox, and you can access the project it is contained in via checkedProjects[i].parentNode
A slightly more efficient way to do it would be to change the class name whenever it is checked or unchecked, then use document.getElementsByClassName() to get the checked class name only.
Here's how I would do it with JS (JQuery)
Add to every checkbox you want to track the class .myCheckboxClass
var deleteCheckedProjects = function() {
// this will return all checked checkboxes with class .myCheckboxClass
var checked = $('.myCheckboxClass:checkbox:checked')
// you can delete the input in the DOM
for (i = 0; i < checked.length; i++) {
checked[i].remove();
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input class="myCheckboxClass" type="checkbox" name="first">Hello Sir!<br>
<input class="myCheckboxClass" type="checkbox" name="first">I am not here</input><br>
<br>
<button onclick="deleteCheckedProjects()" type="button">Click Me!</button>
Alternatively you can just return the array:
var deleteCheckedProjects = function() {
// this will return all checked checkboxes with class .myCheckboxClass
return $('.myCheckboxClass:checkbox:checked')
}
I am trying to update two cascading drop down inside a table there are many answers on SO for drop downs, but I was unable to find help on cascading updates inside a Table with dynamically added rows.
Given the many rows they all have varying Id's filter #Id does'nt work. So, How do I identify which rows Dropdown triggered the change & cascade the update another Dropdown/cell in the next col of the same row?
There are 2 DropDownList (select box) inside a table row cell. To simplify this, the first is Country -> Second is state. So a user is expected to select the country and then the state.
My pseudo algorithm:
find which one was fired, and which row (unsure if its needed, should I wire in place)
then fire an ajax call... to get the values based on country
update the second drop down with value in the same table row.
Case 1 Change country and then change state.
Case 2 Just change State, but first get the Country value in the first dropdown of the same row.
I know how to get the change and value in a regular page, but how do I get those changes and update the adjacent dropdown.
$(document).on('change', 'select', function(){
var data = $(this).val();
alert(data);
});
Edit, Stephen request to show HTML
<tr>
<td>
//DropDown 1 (Imagine Country)
<span class="projectcodeid">
<select class="form-control" id="Records_1__TCode_Project_ID" name="Records[1].TCode.Project.ID"><option value=""></option>
<option value="1">Plumbing</option>
<option value="2">Modeling</option>
</select></span>
</td>
<td>
//DropDown 2 (Imagine State)
<input type="hidden" name="Records.Index" value="1">
<input class="timecodeid" name="Records[1].TCode.ID" type="hidden" value="5">
<span class="timecode timecodeDdlId"> <select class="form-control timecodeDdlId" id="Records_1__TCode_ID" name="Records[1].TCode.ID"><option value=""></option>
</select></span>
</td>
<td>
<input name="Records[1].DataRecords[0].ID" type="hidden" value="">
<input class="hours" name="Records[1].DataRecords[0].Work" type="text" value="">
</td>
<td>
<input class="bs-checkbox" name="Records[1].DeleteRow" type="checkbox" value="true"><input name="Records[1].DeleteRow" type="hidden" value="false">
</td>
</tr>
Sample image for clarification
Assuming that you can't identify dropdwns by class or anything.
Assuming that every time you change the value in a dropdown you want to update the other dropdown on the same row.
Assuming that you have only two dropdowns per row:
$('table').on('change', 'select', function() {
var $current_dropdown = $(this),
$other_dropdown = $(this).closest('tr').find('select').not(this);
/// perform any task you need with current and other dropdown
});
You need to give both your <select> elements class names and use relative selectors to select the associated element in the same row.
Assuming your html is
<table id="table"> // give this an id attribute
<tbody>
<tr>
<td><select class="country" ....> ..... </select></td>
<td><select class="state" ....> ..... </select></td>
</tr>
</tbody>
</table>
Then your script will be
$('#table').on('change', '.country', function() {
var selectedValue = $(this).val();
var row = $(this).closest('tr'); // get the row
var stateSelect = row.find('.state'); // get the other select in the same row
// make you ajax call passing the selectedValue to your controller
// in the success callback, update the options of stateSelect
$.ajax({
url: ...
data { id: selectedValue },
....
success: function(data) {
stateSelect.empty();
$.each(data, function(item, index) {
stateSelect.append($('<option></option>').val(iem.ID).text(item.Name));
}
}
});
}
Refer also better way to load 2 dropdown in mvc for details of the code for populating cascading dropdownlists (consider caching the options as per the 2nd code example to avoid repeated ajax calls)
Here is the code on selection of any one of the radio button i need to get the value
<label ng-repeat="SurveyType in SurveyTypes">
<input type="radio" name="SurveyTypeName" ng-model="surveyData.SurveyTypeName" ng-value="{{surveyData.SurveyTypeName}}" />
{{SurveyType.Name}}
</label>
You should assign value from your repeat-loop not from model value and no need to use {{}} for ng-value
so use ng-value="SurveyType.Name" instead of ng-value="{{surveyData.SurveyTypeName}}" so selected radio button value set to surveyData.SurveyTypeName.
If you want to select anyone by default you can assign value to surveyData.SurveyTypeName like $scope.surveyData={SurveyTypeName: 'second'} then that radio button shown as selected that has value second.
HTML:
<label ng-repeat="SurveyType in SurveyTypes">
<input type="radio" name="SurveyTypeName" ng-model="surveyData.SurveyTypeName" ng-value="SurveyType.Name" />
{{SurveyType.Name}}
</label>
PLUNKER DEMO
Your HTML should be like this.
<input type="radio" name="SurveyTypeName" ng-model="surveyData.SurveyTypeName" ng-value="{{surveyData.SurveyTypeName}}" ng-change="getval($index)"/>
Js
$scope.getval = function (index){
var servetypename =SurveyTypes[index];
var data =servetypename.SurveyTypeName
}
Don't know from surveyData.SurveyTypeName is coming from.
<li ng-repeat="SurveyType in SurveyTypes">
<input type="radio" name="SurveyTypeName" ng-model="$parent.rdoSelected" ng-value="SurveyType.SurveyTypeName" />
{{SurveyType.Name}}
</li>
PLUNKER
I am trying to force a single-selection on checkboxes, similar to a html "select"
I have a html simple table:
<tr ng-repeat="subscription in entities">
<td>
<input type="checkbox" ng-checked="isChecked(subscription)" ng-click="toggleSelection(subscription)"/>
</td>
</tr>
Then I have some simple controller functions for those directives above:
$scope.isChecked = function(entity) {
return $scope.checkedEntity === entity;
};
$scope.toggleSelection = function(entity) {
entity.checked = !entity.checked;
if (entity.checked) {
$scope.checkedEntity = entity;
} else {
$scope.checkedEntity = null;
}
};
Unfortunately it doesn't work, and I think I just discovered why.... the ng-click has 0 priority, vs 100 for ng-checked.
Is there an elegant solution for this problem?
Bind ng-model to subscription.checked, and have ng-click uncheck all subscriptions except the one clicked. Since these are checkboxes, the one clicked will toggle itself.
<tr ng-repeat="subscription in entities">
<td>
<input ng-model="subscription.checked" ng-click="updateSelection($index, entities)" type="checkbox" />
</td>
</tr>
You can use a plain for loop, but angular's forEach allows us to alias each item as subscription and improve readability:
$scope.updateSelection = function(position, entities) {
angular.forEach(entities, function(subscription, index) {
if (position != index)
subscription.checked = false;
});
}
Here is a working demo: http://plnkr.co/edit/XD7r6PoTWpI4cBjdIZtv?p=preview
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
angular.module('app', []).controller('appc', ['$scope',
function($scope) {
$scope.selected = 'other';
}
]);
</script>
</head>
<body ng-app="app" ng-controller="appc">
<label>SELECTED: {{selected}}</label>
<div>
<input type="checkbox" ng-checked="selected=='male'" ng-true-value="'male'" ng-model="selected">Male
<br>
<input type="checkbox" ng-checked="selected=='female'" ng-true-value="'female'" ng-model="selected">Female
<br>
<input type="checkbox" ng-checked="selected=='other'" ng-true-value="'other'" ng-model="selected">Other
</div>
</body>
</html>
I have used the below code to achieve the similar functionality. Trick is to use ng-click which can yield this pretty nicely. checkbox-1 & checkbox-2 are boolean in nature.
<form>
<input type="checkbox" ng-click="checkbox-2 = false" ng-model="checkbox-1" >
<input type="checkbox" ng-click="checkbox-1 = false" ng-model="checkbox-2" >
</form>
Off the top of my head, I'd suggest one of three options for you.
Write a directive that will set up the checkboxes for you and manage the state within them. This isn't ideal, because you're turning a rule about your model (only one subscription should be checked) into DOM manipulation problem.
Structure your model such that only one subscription is ever marked active. This is tricky, because modifying the model on a change will kick off another digest cycle, not what you want.
Use radio buttons instead of checkboxes. That will get you the modality you want. :-P
I'd go with option 3--I'm always a fan of taking advantage of native input elements.
<tr ng-repeat="subscription in entities">
<td><input type="radio"
ng-model="selection"
name="subscriptionRadio"
value="{{subscription}}"/>
</td>
</tr>
I have a variable form list and want to display validation error messages outside of the list elements.
consider this template:
<form name="gForm">
<table>
<tr ng-repeat="invoice in invoices" ng-form="invoiceForm">
<td><input name="amount" type="number" max="200" /></td>
</tr>
</table>
<div ng-show="gForm.invoiceForm.amount.$invalid">you must the money</div>
<button ng-click="addInvoice()">add invoice</button>
</form>
the validation error would only be displayed when the last ng-repeat is invalid. Put another way, gForm.invoiceForm points to the lastly created form in ng-repeat.
I've seen other questions related to this problem but they only suggest repeating the validation messages inside the ng-repeat. I need the message to be outside and displayed once only.
The way you have it, gForm.invoiceForm does refer to the last <tr> in ng-repeat.
If you want to display the error when any of the amounts is invalid, you can use gForm.$invalid. In fact there is no need to use ng-form="invoiceForm" unless there are more requirements not evident from the current question's code.
Another problem is that, in order for Angular to recognize the input and apply its directive (and its magic consequently), the ng-model directive is required as well.
Adding the ng-model directive and changing the condition to gForm.$invalid solves the problem:
...
<tr ng-repeat="invoice in invoices">
<td><input name="amount" type="number" max="200"
ng-model="invoice.amount" /></td>
</tr>
...
<div ng-show="gForm.$invalid">you must the money</div>
...
See, also, this short demo.
Are you looking for something like this? Yes you need to use ng-model, but also you need a unique name:
<div ng-app="pageModule"
ng-controller="parentCtrl">
<form name="gForm">
<table>
<tr ng-repeat="invoice in invoices" ng-form="invoiceForm">
<td>{{invoice.name}}: <input name="invoice.name" required type="number" max="200" ng-model="invoice.amount" /></th>
</tr>
</table>
<div ng-show="gForm.$invalid && showError">you must the money</div>
<button ng-click="addInvoice()">add invoice</button>
</form>
</div>
<script>
var pageModule = angular.module('pageModule',[])
.controller('parentCtrl',function($scope) {
$scope.invoices = [
{ name : 'ford' },
{ name : 'chevy' },
{ name : 'honda' },
]
$scope.showError = false;
$scope.addInvoice = function() {
$scope.showError = true;
console.log('add invoice');
}
})
</script>