Angularjs - how to add a row dynamically when clicked on parent row - javascript

I am new to angularjs and stuck with the below problem.
There will be a table of rows created which reads data from JSON. Say there are 6 rows displayed.But in real time number rows will vary.
Each row has an accordion(+ symbol) in its first td. If this accordian is clicked then the children rows of that row should be displayed by reading the data from one more different JSON.
Similarly for the remaining 5 rows as well it should display the children rows for the respective row's accordion is clicked.
I have created the table with the 6 rows displayed.
But the challenge I am facing is how to link child rows to the existing rows dynamically when clicked. Here is the plunkr - https://plnkr.co/edit/FTbjn9ZbAOTqc3b6j52h?p=preview
Any help is appreciated.
<html>
<head>
<script src="angular.min.js"></script>
<script src="script.js"></script>
<link rel="stylesheet" href="style.css"/>
<link rel="stylesheet" href="font-awesome.min.css"/>
<link rel="stylesheet" href="bootstrap.min.css" />
</head>
<body data-ng-app="testApp" data-ng-controller="treeTable">
<hr>
<button type="button" class="btn btn-success" data-dismiss="modal" data-ng-click="save()">SaveFilter</button>
<button type="button" class="btn btn-Default" data-dismiss="modal" data-ng-click="delete()">Delete</button>
<div class="row">
<div class="col-md-9">
<div style=" margin-left:50px;" class="tableheight">
<table class="table-nested ">
<thead>
<tr>
<!-- <th >
<input data-ng-checked="(list | selected).length == list.length" data-ng-click="toggleAllCheckboxes($event)" type="checkbox" />
</th> -->
<th>
Repository
</th>
<th >
Version
</th>
<th >
Size
</th>
<th >
Modified By
</th>
<th >
Labels
</th>
<th >
Description
</th>
</tr>
</thead>
<tbody style="font-size:12px" data-ng-repeat="item in list">
<tr >
<td ><button style="background-color: #fff;" class="accordion"></button>
{{item.name}}
</td>
<td >
{{item.Version}}
</td>
<td >
{{item.Size}}
</td>
<td >
{{item.ModifiedBy}}
</td>
<td >
{{item.Labels}}
</td>
<td >
{{item.Description}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>

See the Plunkr solution
You want a 2nd <tr> with ng-repeat following the first:
<tr ng-if="item.Labels==child.Labels" ng-show="item.opened" ng-repeat="child in children">
<td>{{child.name}}</td>
...etc
</tr>
This will build additional rows where the bundle .Labels matches the repo .Labels and will be shown only when the repo's opened property is true. The + button will toggle the opened property for each item. You'll need two minor edits to your data to make this work:
Add children data to the $scope (for access in the 2nd ng-repeat).
Add default opened: false property to all repos (except the first, which is true).
This won't show the components, but hopefully you get the idea.
See the Plunkr solution

If you want to inset row after row clicked use this:
<style>
#tableid {
font-size: 14px;
}
#tableid .childRow {
font-size:10px;
}
#tableid .childRow td:first-of-type {
padding-left:10px;
}
</style>
<table id="tableid">
<tr onclick="AddRow(this)">
<td>abcd</td>
</tr>
</table>
<script>
function AddRow(e)
{
for (var i = 0; i < 5; i++)
{
var index = e.rowIndex;
var table = document.getElementById("tableid");
var row = table.insertRow(index + 1 + i);
row.setAttribute('class', 'childRow');
var cell = row.insertCell(0);
cell.innerHTML = "efgh";
}
}
</script>

Related

View and Controller MVC 5

I have below code in my GetCourseList.cshtml file (view) that show fetched information from database :
#model IEnumerable<WebApplication8.Models.Courses>
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<meta name="viewport" content="width=device-width" />
<title>GetCourseList</title>
<style>
.table thead th,
.table tbody td {
text-align: center;
}
</style>
</head>
<body>
<table class="table table-striped">
<thead>
<tr>
<th scope="col" class="border-top-0 text-center">course name</th>
<th scope="col" class="border-top-0">unit</th>
<th scope="col" class="border-top-0">term</th>
<th scope="col" class="border-top-0">choose</th>
<th scope="col" class="border-top-0"></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td class="align-middle">#item.name</td>
<td class="align-middle">#item.unit</td>
#if (item.term == 0)
{
<td class="align-middle">custom</td>
<td>
<input class="btn btn-success" type="checkbox" value=#item.name id=#item.course_id/>
</td>
}
else
{
<td class="align-middle">#item.term</td>
<td><input type="checkbox" value=#item.name id=#item.course_id /></td>
}
<td class="text-right align-middle">
#*<button type="button" class="btn btn-success">choose</button>*#
</td>
</tr>
}
</tbody>
</table>
</body>
</html>
and I get below result from this view when I run the project :
I want that user choose favorite records , with those checkboxes , and then when pressed final button (this button is out of frame in my picture), id of this checkboxes insert in my database(related table).
think I should get checked checkboxes id's from my html page (but I don't know how?! please help me!) and pass this id's to the action and then execute insert query in my action .
so : I should pass each checked checkboxes id to the specific controller and collect them (for example collect all elements id's in an array) some one tell's me that i can map my view elements to the this array . but I don't give result from this approach . this is issue!
please help me to find out how can I do this . thank you
you can add property IsSelect in Model
Public bool IsSelect {get;set;}
and used
#Html.CheckBoxFor(m => m.IsSelect)
and in server checked which one of items selected
var idList = items.Where(x=>x.IsSelect).Select(x=>x.Id).ToList();

AngularJs - Populate the tables by checking header names

I have two objects one contains selected records and another contains selected fields. Now I need to populate the table dynamically by checking the column header name or value.
I referred Populate table with ng-repeat and check matching header data
Completed:
I able to add the headers dynamically to the table/columns.
Working code is in Plunker
HTML
<table class="dataTable no-footer leadTable">
<thead>
<tr role="row">
<th>
<input type="checkbox" ng-model="selectedSObject[key]" class="select_tertiary_selectAll" />
</th>
<th ng-repeat="k in sFields[key]" ng-value="{{k.name}}" style="font-weight: 400; border-right: none; background-color: #0070d2; padding: 10px 18px;">
<div> {{k.label}} </div>
</th>
</tr>
</thead>
<tbody>
<tr role="row" ng-class="odd" ng-repeat="record in value.filtered">
<td>
<input type="checkbox" ng-model="record.checked" />
</td>
<td ng-repeat="(key_1, value_1) in record" style="padding: 10px 18px;">
<div> {{value_1}} </div>
</td>
</tr>
</tbody>
</table>
JS
$scope.sFields = getSFields($scope.sObjectCSVData);
$scope.iterableRecords = getiterableRecords($scope.sObjectCSVData, allRecords)
function getiterableRecords(sCSVData, allRecords) {
var sObjectRecords = {};
if (allRecords) {
Object.entries(sCSVData).forEach(function(key) {
if (sCSVData[key[0]].filtered.length != 0) {
if (sObjectRecords[key[0]]) {
sObjectRecords[key[0]].push(sCSVData[key[0]].filtered)
} else {
sObjectRecords[key[0]] = []
sObjectRecords[key[0]].push(sCSVData[key[0]].filtered)
}
}
});
}
return sObjectRecords
}
function getSFields(sCSVData) {
var fields = {};
Object.entries(sCSVData).forEach(function(key) {
if (sCSVData[key[0]].filtered.length != 0) {
for (var i = 0; i < sCSVData[key[0]].sObjectFields.length; i++) {
if (fields[key[0]]) {
fields[key[0]].push(sCSVData[key[0]].sObjectFields[i])
} else {
fields[key[0]] = []
fields[key[0]].push(sCSVData[key[0]].sObjectFields[i])
}
}
}
});
return fields
}
Need to do:
Now I have to populate the table with the respective values by checking the column name.
I'm working in AngularJS 1.6.9
By adding small changes, Now I can able to populate the table,
The code I followed is as below,
<tbody>
<tr role="row" ng-class="odd" ng-repeat="record in value[0]">
<td>
<input type="checkbox" ng-model="record.checked" />
</td>
<td ng-repeat="k in sFields[key]" style="padding: 10px 18px;">
{{record [k.name]}} </div>
</td>
</tr>
The working code is in the below mentioned plunker,
Populate the table by checking the header name
For ref.

Ng-show button only on specific pages

I have 2 buttons which I only want to show when it's on any other page other than the index page, is there a way to do that?
Index.html:
<body>
<header ng-include="'views/header.html'"></header>
<main ng-view></main>
</body>
Sub Page.html:
<div>
<table id="tabletodownload" ng-show="auditoriums === 'none'" style="border:1px solid #000;">
<tr>
<th> Customer Name </th>
<th> Order Value </th>
<th> Ordered On</th>
</tr>
<tr ng-repeat="audit in auditoriums| limitTo: 1 - auditoriums.length">
<td>{{audit.NAME}}</td>
<td>{{audit.ADDRESSBLOCKHOUSENUMBER}}</td>
<td>{{audit.ADDRESSPOSTALCODE}}</td>
<td>{{audit.ADDRESSSTREETNAME}}</td>
</tr>
</table>
<br/>
</div>
<button type="button" id="btnDownload"> Download as CSV</button>
I need to place the button in my index page but only shows when in my sub page.html. Why? Because I have no idea why my button function (download table to csv function) doesn't work when I place it any other place other than the index page.

Angular2 Table does not build properly after filtering

I have got a problem with filtering a table in angular2.
Filtering works perfectly fine, but deleting the filter this does happen.
EDIT
When I start the program the filter is empty and the view is okay. When I filter for something everything is fine too. If I remove the filter again the elements are there but not in the table anymore... as you can see here.
The table does not rebuild as planned. The Lines are all over the place but not in the table anymore.
I have tried to simplify the html code. If you need to see more, please ask!
<table class="visible-lg-inline visible-md-inline visible-sm-inline table table-condensed">
<!-- the table head is defined here-->
<!--TABLE BODY-->
<tbody *ngFor="let detail of filteredDetails; let posi = index">
<tr>
<td (click)="showDetail(detail.itemId)">
<div><b>{{detail.itemName}}</b></div>
<div>{{detail.itemId}}</div>
</td>
<!-- the other cells as seen in picture-->
</tr>
<!-- only shown if showDetail is true -->
<tr *ngIf="detail.showDetail">
<td colspan="5">
<!-- some other divs and another table -->
</td>
</tr>
</tbody>
<!--FILTER-->
<tbody>
<tr>
<td>
<!-- some divs -->
</td>
<td colspan="3">
<input value="" [(ngModel)]="searchValue" (ngModelChange)="filterDetails()"/>
</td>
<td>
<!-- the button has nothing to do with the filter -->
</td>
</tr>
</tbody>
</table>
<table class="table table-condensed visible-xs-inline fixed">
<!-- the table head is defined here-->
<!--TABLE BODY-->
<tbody *ngFor="let detail of filteredDetails; let posi = index">
<tr>
<td (click)="showDetail(detail.itemId)">
<div><b>{{detail.itemName}}</b></div>
<div>{{detail.itemId}}</div>
</td>
<!-- the other cells as seen in picture-->
</tr>
<!-- only shown if showDetail is true -->
<tr *ngIf="detail.showDetail">
<td colspan="5">
<!-- some other divs and another table -->
</td>
</tr>
</tbody>
<!--FILTER-->
<tbody>
<tr>
<td>
<!-- some divs -->
</td>
<td colspan="3">
<input value="" [(ngModel)]="searchValue" (ngModelChange)="filterDetails()"/>
</td>
<td>
<!-- the button has nothing to do with the filter -->
</td>
</tr>
</tbody>
</table>
Here is the simplified Typescript Code (works more less like javascript - thats why I used that tag - hope that´s fine)
public filteredDetails: POSStockDetailWeb[];
public searchValue: string;
//the constructor an the init functions
filterDetails() {
if (this.searchValue == null || this.searchValue == "")
this.filteredDetails = this.POSStock.safePOSStockDetails;
else {
console.log(this.searchValue);
this.filteredDetails = [];
for (let detail of this.POSStock.safePOSStockDetails) {
if ((detail.itemId.indexOf(this.searchValue) !== -1) ||
(detail.itemName.indexOf(this.searchValue) !== -1)) {
this.filteredDetails[this.filteredDetails.length] = detail;
}
}
}
}
Thank you for your help!
If you need more input please ask!
I have tried it and it works When I change the filter it filters. The code I have tried is:
html:
<table>
<!-- the table head is defined here-->
<!--TABLE BODY-->
<tbody *ngFor="let detail of filteredDetails; let posi = index">
<tr>
<td>
<div><b>{{detail.itemName}}</b></div>
<div>{{detail.itemId}}</div>
</td>
<!-- the other cells as seen in picture-->
</tr>
</tbody>
<!--FILTER-->
<tbody>
<tr>
<td colspan="3">
<input value="" [(ngModel)]="searchValue"
(ngModelChange)="filterDetails()"/>
</td>
<td>
<!-- the button has nothing to do with the filter -->
</td>
</tr>
</tbody>
</table>
Ts code:
public filteredDetails: any[] = [];
public safePOSStockDetails: any[] = [{itemName: 'a', itemId: '1'},
{itemName: 'eea', itemId: '45'}, {itemName: 'eia', itemId: '12'}];
public searchValue = '';
filterDetails() {
if ( this.searchValue === '')
this.filteredDetails = this.safePOSStockDetails;
else {
this.filteredDetails = [];
for (const detail of this.safePOSStockDetails) {
if ((detail.itemId.indexOf(this.searchValue) !== -1) ||
(detail.itemName.indexOf(this.searchValue) !== -1)) {
this.filteredDetails.push(detail);
}
}
}
Found the problem.
To solve another problem with my normal table being too large for smartphones, I have used the css visible-sx-inline and for the large table: visible-sm-inline visible-md-inline...
I dont´t realy know why, but they have caused the problem.
#kimy82
Thank you for your help!
I would be interested in the results of the simple version with the classes in it.
(if you still have it and the time for doing so)

How to select col id using jquery to hide via css

I have a table (and couldn't use because the header is offset by 1 when trying to hide the column) with each column having its own col id="". I want to use jquery in the following code to select the columns within the table and toggle them off and on.
Here is the table :
<article class="technical">
<div id="technical-container">
<h1><span id="technology">Technologies</span> / <span id="compliance">Compliance</span> / <span id="certification">Certification</span></h1>
<table id="tech-table" cellspacing="0">
<colgroup>
<col>
<col id="type" class="type">
<col id="name">
<col id="startdate">
<col id="currentenddate">
<col id="elapsed">
<col id="version">
<col id="rating">
<col id="project">
</colgroup>
<tbody>
<tr>
<td>type</td>
<td>Name</td>
<td>Start Date</td>
<td>Current/End Date</td>
<td>Elapsed</td>
<td>Version(s)</td>
<td>Personal Rating</td>
<td>Project</td>
</tr>
<tr>
<td>technology</td>
<td>J2EE</td>
<td>November, 2011</td>
<td><span id="current"></span></td>
<td>TODO</td>
<td>1.5, 1.6, 1.7</td>
<td>2</td>
<td>Contractor Optimization</td>
</tr>
<tr>
<td>technology</td>
<td>JS</td>
<td>April, 2012</td>
<td><span id="current"></span></td>
<td>TODO</td>
<td>?</td>
<td>1</td>
<td>Resume Builder</td>
</tr>
<tr>
<td>compliance</td>
<td>CIP</td>
<td>May, 2008</td>
<td>August, 2011</td>
<td>TODO, 3 years, 4 mos</td>
<td>n/a</td>
<td>2</td>
<td>Protection</td>
</tr>
<tr>
<td>certification</td>
<td>Red Cross</td>
<td>May, 2007</td>
<td>April, 2013</td>
<td>TODO, 6 years</td>
<td>n/a</td>
<td>3</td>
<td>Life Saving</td>
</tr>
</tbody>
</table>
</div>
</article>
here are the buttons that get clicked to do the hiding:
<article>
<header>
<h1>What</h1>
<div class="mydiv">
<p1>this sections involves what I work with</p1>
</div>
</header>
<section>
<div class="mydiv">
<span id="what1"><button type="button" class="button" id="clickTech">Technologies</button></span> <span id="what2"><button type="button" class="button" id="clickComp">Compliance</button></span> <span id="what3"><button type="button" class="button" id="clickCert">Certifications</button></span>
<!-- <input type="button" class="btn" value="Technologies" id="clickTech" / -->
</div>
</section>
<section>
<h3><span id="whatsel2"><button type="button" class="button-vert" id="clickStart">Start Date</button></span></h3>
<h3><span id="whatsel3"><button type="button" class="button-vert" id="clickEnd">Current/End Date</button></span></h3>
<h3><span id="whatsel4"><button type="button" class="button-vert" id="clickElapsed">Elapsed Time</button></span></h3>
<h3><span id="whatsel5"><button type="button" class="button-vert" id="clickVersion">Version(s)</button></span></h3>
<h3><span id="whatsel6"><button type="button" class="button-vert" id="clickRating">Personal Rating</button></span></h3>
<h3><span id="whatsel7"><button type="button" class="button-vert" id="clickProject">Project</button></span></h3>
</section>
<!-- <footer>
<h2>footer</h2>
<p>footer</p>
</footer> -->
</article>
here is the working selector for hiding the rows:
var rowSelector = function (args) {
$("#"+args.data.type).toggle();
$("#tech-table tr").each(function(){
if ($($(this).children()[0]).text()==args.data.type) {
$(this).toggle();
}
});
};
// $("#clickTech").click({type:"technology"},generalSelector);
// assoc array is id:type
var hiders = {"#clickTech":"technology", "#clickComp":"compliance", "#clickCert":"certification"};
for (var id in hiders) {
$(id).click({type:hiders[id]}, rowSelector);
}
and this is what I have so far with the column selector, but need help with lines 3, 4, and 5:
var colSelector = function (args) {
$("#"+args.data.type).toggle();
$("#tech-table col").each(function(){
if ($($(this)).text()==args.data.type) {
$(this).toggle();
}
});
};
// $("#clickTech").click({type:"technology"},generalSelector);
// assoc array is id:type
var colHiders = {"#clickStart":"Start Date", "#clickEnd":"Current/End Date", "#clickElapsed":"Elapsed Time", "#clickVersion":"Version(s)", "#clickRating":"Personal Rating", "#clickProject":"Project"};
for (var id in hiders) {
$(id).click({type:colHiders[id]}, colSelector);
}
I appreciate your guidance and help.
Here's a javascript answer for you though if you don't want to use #jatrim's css solution
var colSelector = function (args) {
var num = 0;
var i = 0;
$($("#tech-table tr")[0]).find('td').each(function(){
if ($(this).text() == args.data.type)
num=i;
i++;
});
if (num!=0){
$("#tech-table tr").each(function(){
var tds = $(this).find('td');
$(tds[num]).toggle();
});
}
};
// $("#clickTech").click({type:"technology"},generalSelector);
// assoc array is id:type
var colHiders = {"#clickStart":"Start Date", "#clickEnd":"Current/End Date", "#clickElapsed":"Elapsed Time", "#clickVersion":"Version(s)", "#clickRating":"Personal Rating", "#clickProject":"Project"};
for (var id in colHiders) {
$(id).click({type:colHiders[id]}, colSelector);
}
Also the fiddle to test is here http://jsfiddle.net/ueKcL/
I think what you want is here: show/hide html table columns using css.
I particularly like this: $('td:nth-child(2)').hide(); Where 2 is the index of the column you'd like to hide.
You can probably do something like - add title (or another attribute to col tag) to col tag, and the value of title is the index of the column. So col id="name" would be
<col id="name" title="2">
ignoring the first empty col tag. then you will have to target the td using :nth-child (the title attribute) and hide them all.
You don't need to add title and still be able to figure out the index of the col but it simplifies the script using an attribute
OR
you can even pass the column index on the click of the buttons, there are a number of ways to do that as well. But eventually you still need to use :nth-child to hide the td

Categories