Im using this awesome angular material, now what im trying to do is when the angular checkbox 1 is click then all the input checkbox that has a class of "column_1" will be check, same as the angular checkbox 2 and 3, clicking in any of them will then checked the corresponding input checkbox that was bind for the clicked angular checkbox e.g if click checkbox2 then all the input checkbox that has a class of "column_2" will be check, click checkbox3 then all the input checkbox that has a class of "column_3" will be check. Any help, clues, ideas, recommendation and suggestion to achieve it?
here's my html
<div ng-app="j_app">
<div ng-controller="j_controller">
<md-checkbox ng-model="check">
</md-checkbox>
<table>
<thead>
<th><md-checkbox class="checkbox1"></md-checkbox></th>
<th><md-checkbox class="checkbox2"></md-checkbox></th>
<th><md-checkbox class="checkbox3"></md-checkbox></th>
</thead>
<tbody>
<tr class="row_1">
<td class="column_1"><md-checkbox></md-checkbox></td>
<td class="column_2"><md-checkbox></md-checkbox></td>
<td class="column_3"><md-checkbox></md-checkbox></td>
</tr>
<tr class="row_2">
<td class="column_1"><md-checkbox></md-checkbox></td>
<td class="column_2"><md-checkbox></md-checkbox></td>
<td class="column_3"><md-checkbox></md-checkbox></td>
</tr>
</table>
</div>
</div>
and my script (module and controller)
var app = angular.module('j_app', ['ngMaterial']);
app.controller('j_controller', function($scope) {
$scope.check = {
value1 : true,
value2 : false
};
});
Here is a plunker that looks to the behavior you want :
I basically dynamically created the checkboxes to have a better control on it.
<th ng-repeat="(column,columnindex) in [1,2,3]">
<md-checkbox ng-change="checkColumnCheckBoxes(columnindex,checkBoxesHeader[columnindex])"
ng-model="checkBoxesHeader[columnindex]" class="checkbox1">
</md-checkbox>
</th>
<tr class="row_{{$index}}" ng-repeat="(row,rowindex) in [1,2,3]">
<td class="column_{{$index}}"
ng-repeat="(column,columnindex) in [1,2,3]">
<md-checkbox ng-init="checkBoxes[rowindex][columnindex] = false"
ng-model="checkBoxes[rowindex][columnindex]">
</md-checkbox>
</td>
</tr>
You can replace "[1,2,3]" with any other counter.
My js "checkColumnCheckBoxes" function :
$scope.checkColumnCheckBoxes = function(index,value){
angular.forEach($scope.checkBoxes, function(checkBox,key){
$scope.checkBoxes[key][index] = value;
})
}
I'm pretty sure you will have to rework this to your "real" needs (as you don't need a table that display only checkboxes) but it could be a solid start. If you need some help to adapt it to your needs feel free to ask.
Hope it helped.
Since your HTML is pre-generated here is how it should look like :
<table>
<thead>
<th><md-checkbox ng-change="checkColumnCheckBoxes(0,checkBoxesHeader[0])" class="checkbox1" ng-model="checkBoxesHeader[0]"></md-checkbox></th>
<th><md-checkbox ng-change="checkColumnCheckBoxes(1,checkBoxesHeader[1])" class="checkbox2" ng-model="checkBoxesHeader[1]"></md-checkbox></th>
<th><md-checkbox ng-change="checkColumnCheckBoxes(2,checkBoxesHeader[2])" class="checkbox3" ng-model="checkBoxesHeader[2]"></md-checkbox></th>
<tbody>
<tr class="row_1">
<td class="column_1"><md-checkbox ng-init="checkBoxes[0][0] = false" ng-model="checkBoxes[0][0]"></md-checkbox></td>
<td class="column_1"><md-checkbox ng-init="checkBoxes[1][0] = false" ng-model="checkBoxes[0][1]"></md-checkbox></td>
<td class="column_1"><md-checkbox ng-init="checkBoxes[2][0] = false" ng-model="checkBoxes[0][2]"></md-checkbox></td>
</tr>
<tr class="row_2">
<td class="column_1"><md-checkbox ng-init="checkBoxes[0][1] = false" ng-model="checkBoxes[1][0]"></md-checkbox></td>
<td class="column_1"><md-checkbox ng-init="checkBoxes[1][1] = false" ng-model="checkBoxes[1][1]"></md-checkbox></td>
<td class="column_1"><md-checkbox ng-init="checkBoxes[2][1] = false" ng-model="checkBoxes[1][2]"></md-checkbox></td>
</tr>
</table>
I also updated the plunker to match the exemple.
Related
So I have a table where the users can filter out specific rows, by checking a checkbox. If a checkbox is selected then, some rows will get the hidden state.
I want to create a array with all the rows that isn't hidden, but I can't seem to get the state of the <td>.
The tables id is ftp_table and the rows I need the data from has the class name download. I tried to so something like this, to get the visibility value, but without any luck. The function is triggered after a hide row function has run.
function download_log() {
var rows = document.getElementsByClassName("download");
var log = [];
for (var i = 0; i < rows.length; i++) {
// Check if item is hidden or not (create a if and push into array)
console.log(getComputedStyle(rows[i]).visibility);
// append new value to the array IF NOT HIDDEN
log.push(rows.item(i).innerHTML);
}
}
The output I get when i hide something is everything is visible?:
Here is a example of the table, where all info rows has been hidden:
<table class="ftp_table" id="ftp_table">
<tbody>
<tr class="grey">
<th>Log</th>
</tr>
<tr class="info" hidden>
<td class="download">2021-10-06 12:38:15.946 INFO [conftest:101] -------------- Global Fixture Setup Started --------------</td>
</tr>
<tr class="debug">
<td class="download">2021-10-06 12:38:16.009 DEBUG [Geni:37] Initializing</td>
</tr>
<tr class="info" hidden>
<td class="download">2021-10-06 12:38:16.059 INFO [Wrapper:21] Downloading</td>
</tr>
<tr class="info grey" hidden>
<td class="download">2021-10-06 12:38:16.061 INFO [Handler:55] AV+</td>
</tr>
<tr class="debug grey">
<td class="download">2021-10-06 12:38:16.063 DEBUG [Session:84] GET'</td>
</tr>
</tbody>
</table>
You could use the following selector :
document.querySelectorAll("#ftp_table tr:not([hidden]) td.download");
It will select the td.download elements in tr that are not hidden in your table.
var visibleTds = document.querySelectorAll("#ftp_table tr:not([hidden]) td.download");
var arr = [];
for(let i = 0; i < visibleTds.length; i++){
arr.push(visibleTds[i].innerText);
}
console.log(arr);
<table class="ftp_table" id="ftp_table">
<tbody>
<tr class="grey">
<th>Log</th>
</tr>
<tr class="info" hidden>
<td class="download">2021-10-06 12:38:15.946 INFO [conftest:101] -------------- Global Fixture Setup Started --------------</td>
</tr>
<tr class="debug">
<td class="download">2021-10-06 12:38:16.009 DEBUG [Geni:37] Initializing</td>
</tr>
<tr class="info" hidden>
<td class="download">2021-10-06 12:38:16.059 INFO [Wrapper:21] Downloading</td>
</tr>
<tr class="info grey" hidden>
<td class="download">2021-10-06 12:38:16.061 INFO [Handler:55] AV+</td>
</tr>
<tr class="debug grey">
<td class="download">2021-10-06 12:38:16.063 DEBUG [Session:84] GET'</td>
</tr>
</tbody>
</table>
Why don't you use classList instead of style props ?
Like :
rows[i].classList.contains("hidden")
I want to create a table which contains dynamic Content. When clicking on an element, the Details should Show up in the next line. So i creatied the following:
<table ng-controller="TestCtrl">
<tr ng-repeat-start="word in ['A', 'B', 'C']">
<td><!-- Some Information, Image etc --></td>
<td ng-click="showDetails(word)">{{word}}</td>
</tr>
<!-- This is only visible if necessary -->
<tr ng-repeat-end ng-show="currentDetail == word">
<td colspan="2" ng-attr-id="{{'Details' + word}}"></td>
</tr>
</table>
And I have the following js code:
angular.module('maApp', []).controller("TestCtrl", function($scope, $document, $compile){
$scope.showDetails = function(word){
var target = $document.find("Details" + word);
//I checked it - target is NOT null here
//target.html("<div>Test</div>");
//target.append("<div>Test</div>");
var el = $compile("<div>Test</div>")($scope);
target.append(el);
//Show tr
$scope.currentDetail = word;
};
});
I also tried the commented Solutions above but nothing of it works (The tr is showing up however). I guess there is something wrong with $document.find("Details" + word) but I don't know what.
Ultimately I want to add an <iframe> and the source would contain the word.
Does anybody see what I'm doing wrong here?
No need for weird non-angulary DOM manipulation: All you need is this.
HTML:
<table ng-controller="TestCtrl">
<tr ng-repeat-start="word in ['A', 'B', 'C']">
<td><!-- Some Information, Image etc --></td>
<td ng-click="showDetails(word)">{{word}}</td>
</tr>
<tr ng-show="currentDetail==word" ng-repeat-end>
<td colspan="2">Details {{word}}</td>
</tr>
</table>
JS:
angular.module('myApp', []).controller("TestCtrl", function($scope, $document, $compile){
$scope.showDetails = function(word) {
$scope.currentDetail = word;
};
});
http://jsfiddle.net/HB7LU/20074/
$document.find in jqlite is limited to tag name only. You have to add jquery for anything more.
See what is suported in the docs.
you have all you need built into angular already, you don't need the Javascript at all.
see this plunker example
<table style="width:100%;">
<thead style="background-color: lightgray;">
<tr>
<td style="width: 30px;"></td>
<td>
Name
</td>
<td>Gender</td>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="person in people">
<td>
<button ng-if="person.expanded" ng-click="person.expanded = false">-</button>
<button ng-if="!person.expanded" ng-click="person.expanded = true">+</button>
</td>
<td>{{person.name}}</td>
<td>{{person.gender}}</td>
</tr>
<tr ng-if="person.expanded" ng-repeat-end="">
<td colspan="3">{{person.details}}</td>
</tr>
</tbody>
</table>
I would like to have keyup function that would show only rows matching the input text by cell that spans on multiple rows.
Consider following table:
<table border='1'>
<tr>
<td rowspan='2'>Key1</td>
<td name='Key1'> dummy1 </td>
</tr>
<tr>
<td name='Key1'> dummy2 </td>
</tr>
<tr>
<td rowspan='2'>Key2</td>
<td name='Key2'> dummy3 </td>
</tr>
<tr>
<td name='Key2'> dummy4 </td>
</tr>
</table>
jsfiddle
Here each row has second td tag with name that matches its "parent" column text. So when I type 'Key1' at the input field I would like it to show only dummy1 and dummy2. Is it possible in jquery?
I understand that you want to display the rows that has a matching name. If this is wrong, please elaborate more, then I can update it.
Here is a demo: https://jsfiddle.net/erkaner/gugy7r1o/33/
$('input').keyup(function(){
$('tr').hide();
$("td").filter(function() {
return $(this).text().toLowerCase().indexOf(keyword) != -1; }).parent().show().next().show();
});
});
Here's my take on your issue, assuming you always want the first column to show. https://jsfiddle.net/gugy7r1o/2/
<input type="text" id="myInput" />
<table border='1'>
<tr>
<td rowspan='2'>Key1</td>
<td name='Key1' class="data"> dummy1 </td>
</tr>
<tr>
<td name='Key1' class="data"> dummy2 </td>
</tr>
<tr>
<td rowspan='2'>Key2</td>
<td name='Key2' class="data"> dummy3 </td>
</tr>
<tr>
<td name='Key2' class="data"> dummy4 </td>
</tr>
</table>
.data{
display:none;
}
var theData = $('td.data');
var input = $('#myInput').on('keyup', function(){
theData.hide();
var value = input.val();
var matches = theData.filter('[name="'+value+'"]');
matches.show();
});
Firstly, I would recommend using <ul> to wrap each key in as tables should be used for data structure (Forgive me if that is what it is being used for).
Secondly, just attach an on keyup event to the search box and then find matches based on the id. See example below:
JS Fiddle Demo
It is also worth mentioning that it could be useful attaching a timeout to the keyup event if you end up having large amounts of rows so that only one filter is fired for fast typers!
I'm creating a dynamic angular js application wherein I want to use a textbox as a searchtext for the filter of a table. Here's a preview on what I am doing:
As of now, my code looks like this
<table>
<thead>
<tr class="filterrow">
<td data-ng-repeat="col in items.Properties">
<input id="{{col.DatabaseColumnName}}" type="text"
data-ng-model="search_{{col.DatabaseColumnName}}"/>
<!-- Above Here I want to dynamically assign the ng-model based on Databasecolumnname property-->
</td>
</tr>
<tr>
<th data-ng-repeat="col in items.Properties">{{col.ColumnTitle}}</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="content in items2.Contents | filter: search_{{col.DatabaseColumnName}}: search_{{col.DatabaseColumnName}}">
<td data-ng-repeat="col in items.Properties">
{{content[col.Databasecolumnname ]}}
</td>
</tr>
</tbody>
</table>
I already tried the approach of using $compile but I wasn't able to implement it. Any ideas in an approach? Thanks!
EDIT: Plnkr - plnkr.co/edit/5LaRYE?p=preview
You can do this by setting a base object for your ng-Models. So in your controller you will have:-
$scope.search = {};
and in your view do:-
<input ng-attr-id="{{col.DatabaseColumnName}}" type="text"
data-ng-model="search[col.DatabaseColumnName]"/>
With this your dynamic ng-model will be assigned to the search base object, ex:- if col.DatabaseColumnName is col1 then ngModel would be $scope.search.col1
I have a list of items of different types and I would like to display them in a table.
The items of one type will have two columns and items of another type just one. Any suggestions how to change conditionally the colspan on the <> tag on fly?
<div ng-init="items = [
{name:'item1', old:1, new:2},
{name:'item2', old:2, new:2},
{name:'item3', msg: 'message'},
{name:'item4', old:0, new:2}
]">
<table border=1>
<tr ng-repeat="item in items" >
<th>{{item.name}}</th>
<td>{{item.old}}</td>
<td colspan='2'>{{item.msg}}</td>
<td>{{item.new}}</td>
</tr>
</table>
Here is the example to play in jsfiddle: http://jsfiddle.net/38LXt/1/
Thanks!
You can use conditional directives, such as ng-show, to do something like this:
<table border=1>
<tr ng-repeat="item in items" >
<th>{{item.name}}</th>
<td>{{item.old}}</td>
<td colspan="2" ng-show="item.type == 'typeA'">{{item.msg}}</td>
<td ng-show="item.type == 'typeB'">{{item.msgB1}}</td>
<td ng-show="item.type == 'typeB'">{{item.msgB2}}</td>
<td>{{item.new}}</td>
</tr>
</table>
More info about ng-show:
ngShow directive