how to count the number of selecte/unselected checkbox items using angularjs?
my html
<label class="col-xs-5 pull-left" style="font-weight: bold; margin-left: 4px; margin-top: -17px;" >You have choose <font size="3" color="green">{{checkedResult}}</font> Customer(s)</label>
<tr ng-repeat="item in $data " >
<td width="30" style="text-align: left" header="\'smsChkbx\'">
<label>
<input type="checkbox" class="ace" name="someList[]" value="{{item.somename}}" ng-model="checkboxes.items[item.somename]" />
checkbox function
$scope.$watch('checkboxes.items', function(values) {
if (!$scope.mydata) {
return;
}
var checked = 0,
unchecked = 0,
total = $scope.mydata.length;
angular.forEach($scope.mydata, function(item) {
checked += ($scope.checkboxesSms.items[item.somename]) || 0;
unchecked += (!$scope.checkboxesSms.items[item.somename]) || 0;
});
if ((unchecked == 0) || (checked == 0)) {
$scope.checkboxes.checked = (checked == total);
}
**if(checked != 0 && unchecked != 0){
$scope.checkedResult++;
}**
$scope.tableParamsSms.reload();
console.log($scope.checkedResult);
console.log((checked != 0 && unchecked != 0));
angular.element(document.getElementById("select_Sms")).prop("indeterminate", (checked != 0 && unchecked != 0));
}, true);
counts properly when i check for first time, the issue is it wlll also count when i uncheck the checked one
also want to count when its checked by multiple check option
You should make an ng-click in the checkbox and fire an event.
e.g:
ng-click="selectOrDeselect(item)"
Then in that function do something like this to add or remove it from the list.
$scope.selectOrDeselect = function(item) {
var index = $scope.selectedItems.indexOf(item);
if (index === -1) {
$scope.selectedItems.push(item);
} else {
$scope.selectedItems.splice(index, 1);
}
};
Then have a var count = $scope.selectedItems.length
I could not modify your code but you can use something like this:
Html
<div ng-app>
<h2>Sample</h2>
<div ng-controller="MyCtrl">
<div ng-repeat="item in Items">
{{item.name}} <input type="checkbox" ng-model="item.selected" ng-change="Checked(item)" />
</div>
</div>
</div>
AngularJS
function MyCtrl($scope) {
$scope.SelectedItems = [];
$scope.Items = [
{
id: 1,
name: "ABC",
selected: false
},
{
id: 2,
name: "DEF",
selected: false
},
{
id: 3,
name: "GHI",
selected: false
}
]
$scope.Checked = function(item) {
if (item.selected) {
$scope.SelectedItems.push(item);
}
else {
var index = $scope.SelectedItems.indexOf(item);
if (index > -1) {
$scope.SelectedItems.splice(index, 1);
}
}
console.log($scope.SelectedItems) //array of selected items
}
}
Related
This code is a part of my function that creates selectbox and put the index to each option value.My question is how can i add all these fields (textboxes and selectboxes) value into a specific input type hidden based on submit the form ?
here is my code :
$(function() {
var createChildDropdown = function(i) {
var $childDropdown = $('<div />', {
'class': 'childs'
});
$childDropdown.append($('<label />', {
'for': 'childDropdown-' + i
}).text('Child age ' + i));
$childDropdown.append($('<select />', {
'name': 'childDropdown'
}));
var options = [' 1 years old', '2 years old', '3 years old'];
options.forEach(function(option, index) {
$childDropdown.find('select').append($('<option />').text(option).attr('value', `,${index}`));
});
return $childDropdown;
};
var destroyChildDropdown = function($el, i) {
$el.find('div.childs').get(i).remove();
};
$(".button-click-child a").on("click", function() {
var button = $(this);
var oldVal = parseInt(button.closest("ul").prev().val());
var newVal = (button.text() == "+") ? oldVal + 1 : (oldVal > 0) ? oldVal - 1 : 0;
var total_value = "";
if(newVal >= 5) return;
button.closest("ul").prev().val(newVal);
$(".cat_textbox").each(function() {
var cat = $(this).prev('span').text();
});
if (oldVal < newVal) {
$('.childDropdowns').append(createChildDropdown(newVal));
} else if (oldVal > newVal) {
destroyChildDropdown($('.childDropdowns'), newVal);
}
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<form method="post" action="">
<input type="text" class="cat_textbox" name="child" value="0" />
<ul class="button-group button-click-child">
<li><span class="hide">+</span></li>
<li>-</span></li>
</ul>
<div class="childDropdowns"></div>
<button type="submit">SEND</button>
</form>
From your question, I assume you wanted to give an individual ID to each select box. If that's the case, you can just add a unique ID value for each selectbox like this:
$childDropdown.append($('<select />', {
'id': 'childDropdown-' + i
'name' : 'childDropdown-' + i
}));
I want a jquery condition which will handle the following scenarios -
1) Some of the checkboxes selected
2) All of the checkboxes selected
I want them both in a single loop. Currently, I've the following code to select all checkboxes only -
$('.check-all').click(function() {
var selector = $(this).is(':checked') ? ':not(:checked)' : ':checked';
var ids = [];
$('#chkall input[type="checkbox"]' + selector).each(function() {
$(this).trigger('click');
ids.push($(this).attr('value'));
});
var id = [];
id = JSON.stringify(ids);
document.cookie = "ids="+id;
});
And taking checkboxes in my PHP code as -
echo '<ul class="list-unstyled" id="chkall">';
foreach ($contacts as $contact) {
echo '<li>
<div class="checkbox" id="checkboxes">
<label><input type="checkbox" class="case" name="case" value="'.$contact['cust_id'].'" id="'.$contact['cust_id'].'">'.$contact['cust_fname'].' '.$contact['cust_lname'].'</label>
</div>
</li>';
}
So, how should I handle both scenarios in a single loop ? I've send a cookie when checking is done.
I found a solution & now doing this in a following way -
PHP Code -
echo '<ul class="list-unstyled" id="chkall">';
foreach ($contacts as $contact) {
echo '<li>
<div class="checkbox" id="checkboxes" onclick="getID('.$contact['cust_id'].')">
<label><input type="checkbox" class="check-all" name="case" value="'.$contact['cust_id'].'" id="'.$contact['cust_id'].'">'.$contact['cust_fname'].' '.$contact['cust_lname'].'</label>
</div>
</li>';
}
<div class="checkbox" onclick="getID('0')">
<?= Html::checkbox(null, false, [
'id' => 'selectall',
'label' => 'Select all',
'class' => 'check-all',
]);?>
</div>
</div>
And the respective script is -
var ids = [];
function getID(id) {
var checkboxlist = document.getElementsByName('case');
var itr = 0, checkedFlag = 0, uncheckedFlag = 0;
var inputElements = document.getElementsByClassName('check-all');
if (id == 0) {
$(".check-all").prop("checked", $("#selectall").prop("checked"))
}
else {
for (var i = 0; inputElements[i]; ++i) {
if (inputElements[i].value == id) {
if (inputElements[i].checked == true) {
inputElements[i].checked = false;
break;
}
else {
inputElements[i].checked = true;
break;
}
}
}
while (itr < checkboxlist.length) {
if (checkboxlist[itr].checked == true) {
checkedFlag++;
}
else {
$("#selectall").prop("indeterminate", true);
uncheckedFlag++;
}
itr++;
}
if (checkedFlag == checkboxlist.length) {
$("#selectall").prop("indeterminate", false);
$("#selectall").prop("checked", true);
}
if (uncheckedFlag == checkboxlist.length) {
$("#selectall").prop("indeterminate", false);
$("#selectall").prop("checked", false);
}
}
}
That's it !!!
I have ul li element, where is written users list.
and I have one input, where users can write and filter users list.
and this ul element is hidden by default. after focus on input I'm showing this ul element and on blur I'm hiding this ul.
<input type="text" autocomplete="off" ng-model="checkData[key]" />
<ul>
<li ng-repeat="user in users | identification:checkData[key]">{{user}}</li>
</ul>
And my filter:
return (items: Array<string|number>, value: string|number) =>
{
if(typeof items !== 'undefined')
{
var filtered: Array<string|number> = [];
for(var i: number = 0, length: number = items.length; i < length; i++)
{
var element: string|number = items[i];
if((((element + '').indexOf(value + '') === 0) && element !== value) || typeof value === 'undefined')
{
filtered.push(element);
}
}
return filtered;
}
}
This works excelent, but I've one issue. When user enters some value in input, user list in ul element will be filtered.
so when user will focus again on input, in ul shows filtered data. I want to on every focus, show full list and don't delete input value.
How can Achieve this?
You can just disable the filter on focus by passing in an argument to the filter method, in this way:
<ul>
<li ng-repeat="user in users | identification:checkData[key]:isEnabled" ng-focus="isEnabled = false;">{{user}}</li>
</ul>
Modify your filter:
return (items: Array<string|number>, value: string|number, isEnabled: boolean) =>
{
if (!isEnabled) {
return items; // Return the unfiltered list ...
}
if(typeof items !== 'undefined')
{
var filtered: Array<string|number> = [];
for(var i: number = 0, length: number = items.length; i < length; i++)
{
var element: string|number = items[i];
if((((element + '').indexOf(value + '') === 0) && element !== value) || typeof value === 'undefined')
{
filtered.push(element);
}
}
return filtered;
}
}
This will do the trick. Try this one.
<input type="text" autocomplete="off" ng-model="checkData[key]" ng-focus="filterKey[key] = ''" ng-blur="filterKey[key] = checkData[key]"/>
<!-- hidden field to save search text -->
<input type="hidden" ng-model="filterKey[key]"/>
<ul>
<li ng-repeat="user in users | identification:filterKey[key]">{{user}}</li>
</ul>
I have a table with some dynamic data, and columns as Name,Location, Salary. Problem i am facing in Step 2 i.e multiple condition check. Heres the step by step code.
JS Fiddle Demo
Step 1-
Auto generate Filters i.e dynamically add Checkboxes, depend on table row values
autoFilterItem("filterDiv");
Above function generate dynamic checkboxes, logic is it loop over table, read values row by row and return unique value array and generate checkbox respectively, currently am doing for 2 cols having class loc,sal.
Step 2-
Checkbox change event, depend on status (checked/unchekced) table rows will be hide/show .
The problem i am facing is, if user checked 100 ( class as sal), and Kerala ( class as loc) is unchecked then row having kerala should be hide.
For hide and show am adding/removing class .hideRow
///STEP TWO
// On any checkbox clicked returns desired out
$("body").on('change', '.chk', function () {
var arrObj = [],
arrCheckedValueCLass = [];
var objCheckedData = {};
$("#filterDiv .chk").each(function (index, val) {
var sf = $(this);
if (sf.is(":checked")) {
var sf = $(this);
arrObj.push({
dataValue: $(sf).attr('data-value'),
dataClass: $(sf).attr('data-class')
});
}
});
var self = $(this);
var getClassName = self.attr("data-class");
var matchTextValue = $.trim(self.attr("data-value"));
if (self.is(":checked")) {
if (matchTextValue == "All") {
$(".chk").prop('checked', true);
}
$("." + getClassName).each(function () {
var innerSelf = $(this);
var gVal = $.trim(innerSelf.html());
if (matchTextValue == "All") {
innerSelf.closest("tr").removeClass("hideRow");
} else {
if (matchTextValue === gVal) {
console.log("checked and matchTextValue");
var i = 0,
lg = arrObj.length;
var flagSet = false;
for (i; i < lg; ++i) {
var objValue = arrObj[i].dataValue;
var objClass = arrObj[i].dataClass;
if (getClassName != objClass) {
var prevDataCheck = $.trim(innerSelf.closest("tr").find("." + objClass).html());
if (prevDataCheck == objValue) {
flagSet = true;
return true;
}
}
}
if (!flagSet) {
innerSelf.closest("tr").removeClass("hideRow");
innerSelf.closest("tr").addClass(getClassName + "_X");
}
}
}
});
} else {
if (matchTextValue == "All") {
$(".chk").prop('checked', false);
}
$("." + getClassName).each(function () {
var innerSelf = $(this);
var gVal = $.trim(innerSelf.html());
if (matchTextValue === gVal) {
innerSelf.closest("tr").addClass("hideRow");
innerSelf.closest("tr").removeClass(getClassName + "_X");
}
});
}
});
<div id="filterDiv"></div>
<button>Click</button>
<br>
<div id="tableContainer">
<table id="myTable">
<thead>
<tr>
<th data-name='name'>Name</th>
<th data-loc='Location'>Location</th>
<th data-sal='salary'>Salary</th>
<th data-sts='Active'>Active</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name">James</td>
<td class="loc">Mumbai</td>
<td class="sal">500</td>
<td class="sts">Yes</td>
</tr>
<tr>
<td class="name">Joseph</td>
<td class="loc">Kerala</td>
<td class="sal">100</td>
<td class="sts">No</td>
</tr>
<tr>
<td class="name">Jack</td>
<td class="loc">Delhi</td>
<td class="sal">500</td>
<td class="sts">Yes</td>
</tr>
<tr>
<td class="name">Andrea</td>
<td class="loc">Mumbai</td>
<td class="sal">1000</td>
<td class="sts">No</td>
</tr>
<tr>
<td class="name">David</td>
<td class="loc">Delhi</td>
<td class="sal">100</td>
<td class="sts">No</td>
</tr>
<tr>
<td class="name">David</td>
<td class="loc">Delhi</td>
<td class="sal">99900</td>
<td class="sts">No</td>
</tr>
</tbody>
</table>
</div>
I have created the fiddle from the things that you noted and able to produce the result( that is, if user checked 100 ( class as sal), and Kerala ( class as loc) is unchecked then row having kerala should be hide.)
I do not how efficient the solution is.There may be more efficient way to acheive that but anyway below is the js code.
$(document).ready(function () {
//STEP ONE STARTS
// This function generate checkbox from table data, which will be used for filteration
autoFilterItem("filterDiv");
function autoFilterItem(idOfHolderDiv) {
$("#" + idOfHolderDiv).empty();
var arr1 = [];
$(".sal").each(function () {
arr1.push($.trim($(this).html()));
});
var arrNew = unique(arr1).sort(function (a, b) {
return a - b
});
$.each(arrNew, function (i, val) {
$("<input/>", {
"type": "checkbox",
"class": "chk",
"data-class": "sal",
"data-value": val,
"id": "chk" + val,
"checked": "checked"
}).appendTo("#" + idOfHolderDiv).wrap("<div></div>").after(val);
});
$("#" + idOfHolderDiv).append("<hr>");
var arr2 = [];
$(".loc").each(function () {
arr2.push($.trim($(this).html()));
});
var arr2New = unique(arr2).sort();
$.each(arr2New, function (i, val) {
$("<input/>", {
"type": "checkbox",
"class": "chk",
"data-class": "loc",
"data-value": val,
"id": "chk" + val,
"checked": "checked"
}).appendTo("#" + idOfHolderDiv).wrap("<div></div>").after(val);
});
$("#" + idOfHolderDiv).append("<hr>");
function unique(array) {
return $.grep(array, function (el, index) {
return index == $.inArray(el, array);
});
}
}
// STEP ONE ENDS
///STEP TWO
// On any checkbox clicked returns desired out
var selectedSalaryArr = [];
var selectedLocationArr = [];
$("body").on('change', '.chk', function () {
var selectedVal = $(this).attr('data-value');
$('#filterDiv div').each(function () {
var checkedval = $(this).find('input.chk').attr('data-value');
var isChecked = $(this).find('input.chk').is(':checked');
var dataClass = $(this).find('input.chk').attr('data-class');
if (selectedVal === checkedval) {
if (dataClass === 'sal') {
var isExists = $.inArray(checkedval, selectedSalaryArr);
if (isExists === -1) {
selectedSalaryArr.push(checkedval);
} else {
selectedSalaryArr.splice($.inArray(checkedval, selectedSalaryArr), 1);
}
} else {
var isExists = $.inArray(checkedval, selectedLocationArr);
if (isExists === -1) {
selectedLocationArr.push(checkedval);
} else {
selectedLocationArr.splice($.inArray(checkedval, selectedLocationArr), 1);
}
}
}
});
$('#myTable tbody tr').each(function () {
var currentSalary = $(this).find('.sal').text();
var currentLocation = $(this).find('.loc').text();
var matchedSalaryValueExists = $.inArray(currentSalary, selectedSalaryArr);
var matchedLocationValueExists = $.inArray(currentLocation, selectedLocationArr);
if (selectedSalaryArr.length > 0 && selectedLocationArr.length > 0) {
if (matchedSalaryValueExists !== -1 && matchedLocationValueExists !== -1) {
if (!($(this).hasClass('hiderow'))) {
$(this).addClass('hiderow');
}
} else {
if ($(this).hasClass('hiderow')) {
$(this).removeClass('hiderow');
$(this).show();
}
}
}
else {
if (matchedSalaryValueExists !== -1 || matchedLocationValueExists !== -1) {
if (!($(this).hasClass('hiderow'))) {
$(this).addClass('hiderow');
}
} else {
if ($(this).hasClass('hiderow')) {
$(this).removeClass('hiderow');
$(this).show();
}
}
}
});
$('#myTable tbody tr.hiderow').hide();
});
});
Below is the jsfiddle link:
https://jsfiddle.net/shrawanlakhe/v8gyde77/
I'm trying to sort a list of physicians on a page by name. There is a dropdown and the user can select ascending or descending. Neither one is working. The UI is not updating at all.
EDIT: I've changed the sort code to follow the example on the KO website.
When i step into the code i get an error when I hover over left and it says "'left' is not defined"
function SortDownloadPhysicians(){
var sortDirection = getSortDirection()
var sortByParam = getSortByParam()
if(sortByParam === "name"){
if(sortDirection === "ascending"){
self.physicians().sort(function (left, right) { return left.name == right.name ? 0 : (left.name < right.name ? -1 : 1) });
}else{
self.physicians().sort(function (left, right) { return left.name == right.name ? 0 : (left.name > right.name ? -1 : 1) });
}
}
else{ //date of birth
if(sortDirection === "ascending"){
self.physicians().sort(function (left, right) { return left.dateOfBirth == right.dateOfBirth ? 0 : (left.dateOfBirth < right.dateOfBirth ? -1 : 1) });
}else{
self.physicians().sort(function (left, right) { return left.dateOfBirth == right.dateOfBirth ? 0 : (left.dateOfBirth > right.dateOfBirth ? -1 : 1) });
}
}
Here's my sort function
function sortDownloadPage() {
var sortDirection = getSortDirection();
var sortBy = getSortBy();
// sort by name
if (sortDirection === "ascending") {
self.physicians().sort(function (a, b) {
if (a.name().toLowerCase() > b.name().toLowerCase()) {
return 1;
}
if (a.name().toLowerCase() < b.name().toLowerCase()) {
return -1;
}
// a must be equal to b
return 0;
});
} else {
self.physicians().sort(function (a, b) {
if (a.name().toLowerCase() < b.name().toLowerCase()) {
return 1;
}
if (a.name().toLowerCase() > b.name().toLowerCase()) {
return -1;
}
// a must be equal to b
return 0;
});
}
};
and here's part of the view model
var ViewModels = ViewModels || {};
(function (ViewModels) {
var DownloadVM = function (options) {
options = $.extend({
physicians: ko.utils.unwrapObservable(options.physicians || [])
}, options);
//********************************************************************************
// Private properties
var self = this,
_physicians = ko.observableArray([]),
_page = 1,
_pageSize = 2;
//********************************************************************************
// Public properties
self.physicians = ko.computed(function () {
return ko.utils.unwrapObservable(_physicians);
});
UI code
<div class="grid-list-group" data-bind="template: { name: 'physicianDownloadTemplate', foreach: physicians }">
<script type="text/html" id="physicianDownloadTemplate">
<div class="group-item clearfix" data-bind="fxVisibility: visible">
<div class="item-col selector">
<input type="checkbox" data-bind="checked: checked">
</div>
<div class="item-col photo hidden-sm hidden-xs" data-bind="click: $root.toggleOpenState">
<img class="rounded" title="Profile Picture" src="#Url.Content("~/Content/Images/profile-default.png")">
</div>
<div class="item-col field name" onclick="$(this).parent().children('.group-item-drawer').slideToggle();">
<div class="caption">Physician Name</div>
<div class="value" data-bind="text: name">{NAME}</div>
</div>
<div style="float: right;">
<div class="item-col field date-of-birth">
<div class="caption">Date of Birth</div>
<div class="value" data-bind="text: dateOfBirth">{DATE OF BIRTH}</div>
</div>
</div>
<div class="group-item-drawer clearfix" style="display: none; clear: both;" data-bind="template: { name: 'downloadItemTemplate', foreach: files }"></div>
</div>
</script>
I typically solve this problem using a computed function. The computed can subscribe to the "sorting" variable, so when it changes, it will recompute based on the new variable. From there, it is simply a matter of returning the appropriate sorting.
function vm() {
var physicians = [
'smith',
'grant',
'foreman'
];
this.sorting = ko.observable();
this.sortingOptions = ['A-Z', 'Z-A'];
this.physicians = ko.computed(function() {
var sorting = this.sorting(),
sorted = physicians.slice().sort();
if (sorting == 'Z-A')
sorted.reverse();
return sorted;
});
}
ko.applyBindings(new vm());
and in the view
<select data-bind="options: sortingOptions, value: sorting"></select>
<select data-bind="options: physicians"></select>