Treeview checkbox act as radiobutton - angularjs

Sample diagram:
I want this specific group of nodes to act as radiobutton(only 1 should be checked). I know I can handle this by hard coding conditions but I want to make it expandable in the future(adding more checkbox) by changing its json column 'Group'.
sample data:
[
{ id:"1", text: "Items", expanded: true, List: [
{ id:"2",text: "book" ,group: 1},//group for radiobutton actions
{ id:"3",text: "chair",group: 1 },
{ id:"4",text: "table",group: 1 },
{ id:"5",text: "mat", group: 0 },
{ id:"6",text: "decor", group: 0}
] }
]
I found this jsfiddle exmaple about group attribute for references.

This is the best(I think) way to do this:
1. Declare array of IDs w/c you want to grouped by:
var group = ["2","3","4"]; //in my example above
2. In the check event:
if (group.indexOf(dataItem.ID) > -1) { //if the ID you clicked exists in the group
group.splice(group.indexOf(dataItem.ID), 1); //remove the ID from the group
for (var i = 0, j = treeview.length; i < j; i++) {
for (var x = 0, y = treeview[i].List.length; x < y; x++) {
if (group.indexOf(treeview[i].List[x].ID) > -1) {
treeview[i].List[x].set("checked", false); //uncheck the members of the group
}
}
}
}

Related

How to get the checked items from kendo treeview

HTML CODE:
<div>
<md-button ng-click="getCheckedItems()">TEST</md-button>
</div>
<div kendo-tree-view="tree"
k-data-source="treeData"
k-on-change="selectedItem = dataItem">
<span k-template>
<md-checkbox !important ng-click='click(dataItem)'>{{ dataItem.text}}</md-checkbox>
</span>
</div>
I want to get the checked items from the treeview and save it as string with ',' between 2 texts using the get function $scope.getCheckedItems = function(){}
Your question is not very clear, but in case if you want to get all the selected checkboxes inside your controller you can do like following.
$scope.getCheckedItems = function () {
var data = $scope.tree.dataSource._data;
for (var i = 0, j = data.length; i < j; i++) {
if (data[i].checked) {
//Item is checked
//You can get the properties using data[i]
console.log(data[i]);
}
}
};
I found out that i need to specify 'items' as child. Here is the working code:
for (var i = 0, j = data.length; i < j; i++) {
for (var x = 0, y = data[i].items.length; x < y; x++)
{
if (data[i].items[x].checked) {
//Item is checked
//You can get the properties using data[i]
console.log(data[i].items[x].text);
}
}
}
Sample data:
dataSource: [
{ text: "foo", expanded: true, items: [
{ text: "bar" }
] },
{ text: "baz", expanded: true, items: [
{ text: "qux" }
] }]

AngularJS filter list based on array properties

How to create the following filter using AngularJS?
Here's a visual diagram explaining the question. I've been trying to figure this out for a bit and would really appreciate some help.
I have a list of companies:
$scope.companies = [
{
id:"company_01",
ratings: [ 5, 5, 5, 5, 0, 5, 4, 4, 1, 3, 0, 0 ]
},
{
id:"company_02",
ratings: [ 5, 4, 5, 4, 0, 5, 4, 4, 1, 3, 0, 0 ]
}
...
];
where each company has a property called ratings —- an array of numeric values (1-5) that represent scores for a given set of issues:
$scope.issues = [
{
label:'Carbon Footprint',
selected: true,
value: 3
},
...
{
label:'Consumer Health',
selected: false,
value: null
},
...
{
label:'Employee Satisfaction',
selected: true,
value: 5
},
...
];
The indices of $scope.companies[i].ratings correspond to the indices of $scope.issues.
Each issue has:
a selected property, a boolean toggled by a UI checkbox
a value property, a number (1-5) adjusted by a UI slider
I'd like to filter $scope.companies based on whether company.ratings[i] >= issue[i].value for each selected issue[i]. If an issue is not selected, it shouldn't affect the filter.
A related question is what the best way to watch for changes on $scope.issues would be. e.g. when a user selects/deselects an issue or adjusts a slider.
Thanks very much!
The Filter
Here's a goodRatingsOnly filter that filters the $scope.companies array based on the contents of the $scope.issues array. With several loops, it searches for a reason to not return the record i.e. when a poor rating is found.
app.filter("goodRatingsOnly", function thisFilter() {
return function(companies, issues){
return companies.filter(function(comp){
var poorRatingFound = false;
issues.forEach(function(issue, i){
if (issue.selected){
if (!poorRatingFound){
poorRatingFound = comp.ratings[i] < issue.value;
console.log(poorRatingFound);
}
}
});
return !poorRatingFound;
});
}
});
Sample Usage
In the controller:
$scope.filteredCompanies = $filter("goodRatingsOnly")($scope.companies, $scope.issues);
Or on ng-repeat in the view:
ng-repeat="comp in companies | goodRatingsOnly: issues"
Demo
CodePen: Using an array to filter another array in a custom filter
i managed to solve it this way as well.
not sure how ideal of a solution it may be.
app.filter('issue', function($filter) {
return function(list, filterList) {
nullify();
return $filter("filter")(list, function(listItem){
if (listItem.ratings_ordered[0] >= filterList[0].value &&
listItem.ratings_ordered[1] >= filterList[1].value &&
listItem.ratings_ordered[2] >= filterList[2].value &&
listItem.ratings_ordered[3] >= filterList[3].value &&
listItem.ratings_ordered[4] >= filterList[4].value &&
listItem.ratings_ordered[5] >= filterList[5].value &&
listItem.ratings_ordered[6] >= filterList[6].value &&
listItem.ratings_ordered[7] >= filterList[7].value &&
listItem.ratings_ordered[8] >= filterList[8].value &&
listItem.ratings_ordered[9] >= filterList[9].value &&
listItem.ratings_ordered[10] >= filterList[10].value &&
listItem.ratings_ordered[11] >= filterList[11].value
) {
return listItem;
}
});
function nullify() {
filterList.forEach(function(issue) {
if (!issue.selected) {
issue.value = null;
}
});
}
}
});
where list = $scope.companies and filterList = $scope.issues.

How to remap array only on changes?

I have component Page which contains components Editor and Preview.
Page contains array items.
[
{
value: 0,
text: 'Item 1'
},
...
]
Array items is passed to Editor & Preview like this:
<editor [items]="items"></editor>
<preview [items]="items"></preview>
Editor can add/delete/edit/reorder items.
Issue is preview needs this array in another format.
[
{
index: 0,
label: 'Item 1'
},
...
]
If I do like this
getRadioItems(): any[] {
const items = [];
for (let i = 0; i < this.items.length; i++) {
items.push({ index: this.items[i].value,
label: this.items[i].text });
}
return items;
}
and then
<radio-list [radioItems]="getRadioItems()"></radio-list>
It refreshes radio list hundreds times per second. You can't even change value because it will be reset on every refresh.
If it were without remapping - it would work fine.
What is correct way to remap items to radioItems in such case?
Have you tried setting the ChangeDetectionStrategy of the preview component to OnPush? Then change detection should only be run when the #Input() items is updated.
It is stupid solution, but it works.
getRadioItems(): any[] {
const newJson = JSON.stringify(this.items);
if (this.json === newJson) {
return this.cachedItems;
}
this.json = newJson;
this.cachedItems = [];
for (let i = 0; i < this.items.length; i++) {
this.cachedItems.push({ index: this.items[i].value,
label: this.items[i].text });
}
return this.cachedItems;
}

filtering in angularjs using or operator

i have a loop of an array Countries,example (this is in a multi select box)
{Clicked : true, Name:USA,ID:1},
{Clicked :false, Name:China,ID:2},
{Clicked : true, Name:India,ID:4}
when an item(Name value) is checked,the clicked value turns to true.So if i know all the values that are true can i loop through the countries array to get those values?
once i got the true values i want to use the OR operator to pass only one id value and not all, example if its 1 || 4 || 2 then 4 should get passed.
what was attempted
$scope.FilterCountries=function(){
var Clicked=true;
for(var i=0;i<=$scope.model.Countries.length;i++)
{
Clicked= $scope.model.Countries.Clicked[i];
var ID= Clicked || $scope.model.Countries.ID[i];
}
}
the above when i select a value,it sends back a different ID ,it adds its own value.
I am still not sure what you want to do exactly but your code seems to be wrong. I put an example together.
If you mean Bitwise operations see here: MDN Bitwise operations
I hope it helps.
$scope = {
model: {
Countries: [{
Clicked: true,
ID: 1
}, {
Clicked: true,
ID: 2
}, {
Clicked: true,
ID: 4
}]
}
};
$scope.FilterCountries = function() {
var result = 0;
for (var i = 0; i < $scope.model.Countries.length; i++) {
if ($scope.model.Countries[i].Clicked === true) {
//Bitwise operation ID: 1 and 2 and 4 would result in 7
result = result | $scope.model.Countries[i].ID;
}
}
return result;
};
document.write($scope.FilterCountries());
Later you can test if a country was checked by using the &-Operator
(7 & 4) === 4; // true
$scope.FilterCountries = function() {
var result = 0;
for (var i = 0; i < $scope.model.Countries.length; i++) {
if ($scope.model.Countries[i].Clicked === true) {
//Bitwise operation ID: 1 and 2 and 4 would result in 7
result = result[i] | $scope.model.Countries[i].ID;
}
}
return result;
};

append a column as checkbox for wijmogrid

I have data which i am binding to wijmogrid. However i would like to have an additional column for the wijmogrid as checkboxes for each row. My data will not have any value for this. My data has only 3 columns which is getting bound to the grid.I want to have a 4th column for each row with a checkbox.
I tried using like
flex.columns.addnew but there is no property to append the columns
My code:
Angular JS
function getData() {
return [
{ Col1: 'QA', Col2: 1, Col3: true },
{ Col1: 'Dev', Col2: 0, Col3: true },
{ Col1: 'UAT', Col2: 2, Col3: false },
{ Col1: 'Prod', Col2: 3, Col3: false }
];
}
$scope.data = getData();
// formatter to add checkboxes to boolean columns
$scope.itemFormatter = function (panel, r, c, cell) {
//$scope.itemFormatter = function (args) {
if (panel.cellType == wijmo.grid.CellType.ColumnHeader) {
var flex = panel.grid;
var col = flex.columns[c];
// check that this is a boolean column
if (col.dataType == wijmo.DataType.Boolean)
{
// prevent sorting on click
col.allowSorting = false;
// count true values to initialize checkbox
var cnt = 0;
for (var i = 0; i < flex.rows.length; i++) {
if (flex.getCellData(i, c) == true) cnt++;
}
// create and initialize checkbox
cell.innerHTML = '<input type="checkbox"> ' + cell.innerHTML;
var cb = cell.firstChild;
cb.checked = cnt > 0;
cb.indeterminate = cnt > 0 && cnt < flex.rows.length;
// apply checkbox value to cells
cb.addEventListener('click', function (e) {
flex.beginUpdate();
for (var i = 0; i < flex.rows.length; i++) {
flex.setCellData(i, c, cb.checked);
}
flex.endUpdate();
});
}
}
}
HTML
wj-flex-grid items-source="data" item-formatter="itemFormatter">
<wj-flex-grid-column header="Col1" binding="Col1"></wj-flex-grid-column>
<wj-flex-grid-column header="Col2" binding="Col2"></wj-flex-grid-column>
<wj-flex-grid-column header="Col3" binding="Col3"></wj-flex-grid-column>
<wj-flex-grid-column header="Select" dataType="Boolean"></wj-flex-grid-column>
</wj-flex-grid>
I think the same has been replied on this link:
http://wijmo.com/topic/add-checkbox-to-flexgrid-where-there-is-no-data-to-bind-using-angular/
Let me know if you have any further questions

Resources