Angularjs controller call looping - javascript

I have a controller which is as following
var app = angular.module('StudentProgram', []);
app.controller('mycontroller', function($scope){
$scope.details=[
{name1:"TIER 1 - CORE FOUNDATIONS", subcategory1:[
{name2:"Critical Reading and Writing", subcategory2:[
{course:"HIST 1301",term:"Spring 2012",credit:"3.0",grade:"B"},
{course:"ENGL 1301",term:"Spring 2012",credit:"3.0",grade:"A"}
]},
{name2:"Speaking and Listening", subcategory2:[
{course:"HIST 1301",term:"Spring 2012",credit:"3.0",grade:"B"},
{course:"ENGL 1301",term:"Spring 2012",credit:"3.0",grade:"A"}
]}
]},
{name1:"TIER 2 - CORE DOMAINS", subcategory1:[
{name2:"Critical Reading and Writing", subcategory2:[
{course:"HIST 1301",term:"Spring 2012",credit:"3.0",grade:"B"},
{course:"ENGL 1301",term:"Spring 2012",credit:"3.0",grade:"A"}
]}
]}
];
});
I have defined a div to call the json above in loops using ng-repeat:
<div ng-controller="mycontroller" class="panel panel-primary">
<div ng-repeat="title in details">
<div class="panel-heading">
<h3 class="panel-title">{{title.name1}}</h3>
</div>
<div ng-repeat="subtitle in details" class="panel-body">
<div class="container">
<h4><strong>{{subtitle.name2}}</strong></h4>
<table class="table table-hover" style="width:700px;">
<tr>
<th>Course</th>
<th>Term</th>
<th>Credit</th>
<th>Grade</th>
</tr>
<tr ng-repeat="detail in details">
<td>{{detail.course}}</td>
<td>{{detail.term}}</td>
<td>{{detail.credit}}</td>
<td>{{detail.grade}}</td>
</tr>
</table>
</div>
</div>
</div>
</div>
I would like to call the div using ng-repeat in such a way that it looks like the following:
Please help!

your ng-repeat usage was wrong on many part...
here is fixed HTML
<div ng-repeat="detail in details">
<div class="panel-heading">
<h3 class="panel-title">{{detail.name1}}</h3>
</div>
<div ng-repeat="subcategory in detail.subcategory1" class="panel-body">
<div class="container">
<h4>
<strong>{{subcategory.name2}}</strong>
</h4>
<table class="table table-hover" style="width:700px;">
<tbody>
<tr>
<th>Course</th>
<th>Term</th>
<th>Credit</th>
<th>Grade</th>
</tr>
<tr ng-repeat="subcategory2 in subcategory.subcategory2">
<td>{{subcategory2.course}}</td>
<td>{{subcategory2.term}}</td>
<td>{{subcategory2.credit}}</td>
<td>{{subcategory2.grade}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
and here is working PLUNKER...

Related

How to render html data from JSON in a modal angular 8

I have a html table stored in a database table. I am fetching the html table using a get request, but for some reason, I cant seem to render the html from the api to the modal.
How I am fetching the html table from the api
async loadReportData(eaCode): Promise<void> {
this.html_content = this.service.getHtmlReport(code);
//this.teamMembersData = await this.re.getTeamMembers(this.currentProjectId, teamId);
console.log(this.service.getHtmlReport(code))
}
my angular modal where am trying to render the html table
<ng-template #viewTeamModal let-modal>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-11">
<h4 class="card-title" style="color: black;"><span class="lstick"></span>Report</h4>
</div>
<div class="col-1">
<button type="button" class="close" label="Close" (click)="modal.dismiss('Cross click');">
<span aria-hidden="true">×</span>
</button>
</div>
</div>
<div class="row">
<div class="table-responsive">
</div>
</div>
</div>
</div>
</div>
</div>
</ng-template>
the html table being fetched from the api
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
</table>
when I try to console log I get
Observable
operator: MapOperator {thisArg: undefined, project: ƒ}
source: Observable {_isScalar: false, source: Observable, operator: MapOperator}
_isScalar: false
__proto__: Object
what am I doing wrong. Thank you in advance
Nothing wrong, just that it seems like the method this.service.getHtmlReport(code) returns an Observable.
This will log the actual value:
this.service.getHtmlReport(code).subscribe(code => {
console.log(code);
})
Is it recommended where possible to handle the subscription using the async pipe. I put it inside OnInit but that is just for the sake of example, you can use it where you need:
public code: Observable;
ngOnInit() {
...
this.code = this.service.getHtml(code);
}
and inside the template:
<div class="table-responsive" [innerHTML]="code | async"></div>
If you haven't read about observables these resources might be useful for start:
https://angular.io/guide/observables
https://angular.io/guide/observables#subscribing
https://malcoded.com/posts/angular-async-pipe/
https://gist.github.com/staltz/868e7e9bc2a7b8c1f754

Responsive resize with input search box on top

I have the following problem: I am using datatables with multi column filtering on top. If you watch the video at this link you can understand the problem:
https://www.dropbox.com/s/0k900m3tyxse756/screencast.mov?dl=0
When I resize the browser window, the input search fields are still visible causing an overflow in the table.
Obviously the datatable ha been initialized via javascript with the responsive option.
Here's the HTML:
<section class="content">
<div class="container-fluid">
<div class="block-header">
<h2>
VISUALIZZAZIONE OFFERTE ABITATIVE
<small>Qui potrai visualizzare e ricercare qualsiasi offerta abitativa.</small>
</h2>
</div>
<div class="row clearfix">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="card">
<div class="body">
{$sizeOffers = count($offers)}
{if $sizeOffers gt 0}
{include file=$smarty.const.DEFAULT_RESOURCES_PATH|cat:'inc/offers.tpl'}
{else}
<div class="alert alert-warning">
Non c'è nessuna offerta abitativa da visualizzare. Clicca sul pulsante in basso per inserirne una ora.
</div>
{/if}
<hr>
<div class="text-center">
Aggiugi un'offerta
{include file=$smarty.const.DEFAULT_RESOURCES_PATH|cat:'inc/back_button.tpl'}
</div>
</div>
</div>
</div>
</div>
{include file=$smarty.const.DEFAULT_RESOURCES_PATH|cat:'inc/token_field.tpl'}
</div>
As you can see, offers.tpl is an included file and contains:
<table id="{$id|default:'offers-table'}" class="table table-striped table-bordered table-hover dt-responsive">
<thead>
<tr>
<th>Azioni</th>
<th>Identificativo</th>
{if !isset($from_contact)}
<th>Offerente</th>
{/if}
<th>Affitto/Vendita</th>
<th>Comune</th>
<th>Telefono</th>
<th>Provenienza</th>
<th>Tipologia</th>
<th>Prezzo</th>
</tr>
<tr>
<th>Azioni</th>
<th>Identificativo</th>
{if !isset($from_contact)}
<th>Offerente</th>
{/if}
<th>Affitto/Vendita</th>
<th>Comune</th>
<th>Telefono</th>
<th>Provenienza</th>
<th>Tipologia</th>
<th>Prezzo</th>
</tr>
</thead>
<tbody>
......
</tbody>
Can you help me?
Create responsive tables by wrapping any .table in .table-responsive :
<div class="table-responsive">
<table class="table">
...
</table>
</div>

HTML Table, retrieving data from row and displaying it elsewhere

I'm trying to make it so when you click on a row in the table, depending what row you press, it will display that data into the other panel. So when I click the first row, the Number in the table fills out the number in the other panel, under "Readings". As well as the Name in the table, filling out the Name field under "Readings". How would I go about doing this?
<!-- begin row -->
<div class="row">
<!-- begin col-2 -->
<div class="col-md-2">
<!-- begin panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<div class="panel-heading-btn">
<i class="fa fa-expand"></i>
</div>
<h4 class="panel-title">Table</h4>
</div>
<div class="panel-body">
<table id="data-table" class="table table-striped table-bordered nowrap" width="100%">
<thead>
<tr>
<th>Number</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr class="gradeA">
<td>1</td>
<td>First</td>
</tr>
<tr class="gradeA">
<td>2</td>
<td>Second</td>
</tr>
<tr class="gradeA">
<td>3</td>
<td>Third</td>
</tr>
<tr class="gradeA">
<td>4</td>
<td>Fourth</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- end panel -->
</div>
<!-- begin col-2 -->
<div class="col-md-6">
<!-- begin panel -->
<div class="panel panel-inverse" data-sortable-id="form-stuff-2">
<div class="panel-heading">
<div class="panel-heading-btn">
<i class="fa fa-expand"></i>
</div>
<h4 class="panel-title">Form</h4>
</div>
<div class="panel-body">
<form class="form-horizontal" action="/" method="POST">
<legend>Readings</legend>
<div class="form-group">
<label class="col-md-4 control-label">Number:</label>
<div class="col-md-8">
<input type="text" class="form-control" placeholder="1" disabled />
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label">Name:</label>
<div class="col-md-8">
<input type="device" class="form-control" value="Name here" />
</div>
</div>
</div>
</div>
<!-- end panel -->
</div>
<!-- end col-10 -->
</div>
<!-- end row -->
There you go pal
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<!-- begin row -->
<div class="row">
<!-- begin col-2 -->
<div class="col-md-2">
<!-- begin panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<div class="panel-heading-btn">
<i class="fa fa-expand"></i>
</div>
<h4 class="panel-title">Table</h4>
</div>
<div class="panel-body">
<table id="data-table" class="table table-striped table-bordered nowrap" width="100%">
<thead>
<tr>
<th>Number</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr class="gradeA">
<td>1</td>
<td>First</td>
</tr>
<tr class="gradeA">
<td>2</td>
<td>Second</td>
</tr>
<tr class="gradeA">
<td>3</td>
<td>Third</td>
</tr>
<tr class="gradeA">
<td>4</td>
<td>Fourth</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- end panel -->
</div>
<!-- begin col-2 -->
<div class="col-md-6">
<!-- begin panel -->
<div class="panel panel-inverse" data-sortable-id="form-stuff-2">
<div class="panel-heading">
<div class="panel-heading-btn">
<i class="fa fa-expand"></i>
</div>
<h4 class="panel-title">Form</h4>
</div>
<div class="panel-body">
<form class="form-horizontal" action="/" method="POST">
<legend>Readings</legend>
<div class="form-group">
<label class="col-md-4 control-label">Number:</label>
<div class="col-md-8">
<input
type="text"
id="numberInput"
class="form-control"
placeholder="Number"
disabled />
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label">Name:</label>
<div class="col-md-8">
<input
type="text"
id="deviceInput"
class="form-control"
value="Name here" />
</div>
</div>
</div>
</div>
<!-- end panel -->
</div>
<!-- end col-10 -->
</div>
<script src="https://code.jquery.com/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<!-- end row -->
<script>
(function () {
var table = document.querySelector('#data-table');
var number = document.querySelector('#numberInput');
var device = document.querySelector('#deviceInput');
table.addEventListener('click', onTableClick);
function onTableClick (e) {
//console.log(e.currentTarget);
var tr = e.target.parentElement;
//console.log(tr.children);
var data = [];
for (var td of tr.children) {
data.push(td.innerHTML)
}
number.value = data[0];
device.value = data[1];
}
})();
</script>
</body>
</html>
With vanilla Javascript (there are data-binding libraries that can handle this), table rows do have click events. So you can create a function that handles that click event.
You can either use the onclick attribute or addEventListener method of HTML elements. You can explicitly state the input to the function or calculate it. So say the function name is updateOther, you could do updateOther(1,'First') or updateOther(this). The latter will pass the row element that was clicked and you can extract the pertinent information.
$(document).ready(function(){
$(".gradeA").click(function(){
var currentRow = this;
var number = $(this).find("td")[0].innerText;
var name = $(this).find("td")[1].innerText;
$("form input[type='text']").val(number);
$("form input[type='device']").val(name);
})
});

Bootstrap Accordion in Angular with dynamic length

I am learning Angular 4 in combination with Bootstrap.
The idea is to receive an array of lists from my backend server, which works fine, and to display each list in one single accordion (collapse).
My problem is the following: As the array of lists varies in length, I have to create the elements dynamically, which creates this error:
zone.js:569 Unhandled Promise rejection: Template parse errors:
Can't bind to 'target' since it isn't a known property of 'tr'. (" <tbody>
<tr *ngFor="let listObj of lists" class="panel panel-default" data-toggle="collapse" [ERROR ->]data-target="#collapse{{listObj.index}}">
<td><div class="panel-group">
<div class="p"): ng:///AppModule/TestComponent.html#8:90 ; Zone: <root> ; Task: Promise.then ; Value: Error: Template parse errors:
Can't bind to 'target' since it isn't a known property of 'tr'. (" <tbody>
<tr *ngFor="let listObj of lists" class="panel panel-default" data-toggle="collapse" [ERROR ->]data-target="#collapse{{listObj.index}}">
<td><div class="panel-group">
<div class="p"): ng:///AppModule/TestComponent.html#8:90
How it should look like:Tested with hardcoded HTML
My HTML:
<table class="table table-hover ">
<thead>
<tr>
<th>Description</th>
<th>Author</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let listObj of lists" class="panel panel-default" data-toggle="collapse" data-target="#collapse{{listObj.index}}">
<td><div class="panel-group">
<div class="panel-heading">
{{listObj.list.listDescription}}
{{listObj.index}}
</div>
<div id="collapse{{listObj.index}}" class="panel-collapse collapse">
<ul class="list-group">
<li *ngFor="let item of listObj.list.listItems" class="list-group-item col-lg-12">{{item}}</li>
</ul>
</div>
</div>
</td>
<td>{{listObj.list.listAuthorName}}</td>
<td>
<div class="input-group">
<input type="text" class="form-control" #listAdd>
<span class="input-group-btn">
<button (click)="onClickAddItem(list.listId, listAdd.value)" class="btn btn-default" type="button">add</button>
<button class="btn btn-danger" type="button">Delete</button>
</span>
</div>
</td>
</tr>
</tbody>
</table>
The array of list-objects is in standard JSON-format
also exuse my english and thank you for your help
I guess you are looking for attribute binding like
[attr.data-target]="'#collapse' + listObj.index"

Bootstrap table responsive grey line

I have grey line under my responsive table. I don't know from where it comes. How it gets created. Here a pic:
My html code:
<div class="container">
<div class="row">
<div ng-app="appGenerator" ng-controller="MainCtrl">
<div ng-repeat="table in tablenames">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
</thead>
<tbody>
<tr ng-repeat="ttable in table.table" ng-click="setSelect(ttable)">
<td>{{ttable}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
My js code:
var app = angular.module('appGenerator', ['ngRoute']).controller('MainCtrl', function ($scope, $http) {
$http.get('GeneratedFiles/RelationsBC.bbTable').success(function (tableResponse) {
$scope.tablenames = tableResponse.table;
});
$scope.setSelect = function (ttable) {
alert(ttable);
}
});

Categories

Resources