I'm new to angular and would like to create a table with an unknown amount of columns. Additionally the table contains a second row of header columns, also with a different and unknown amount of columns. I have to use colspan in the second line, but don't know how. What would be a good way, maybe to create a directive? Or is there a simpler solution?
For a better understanding I created: http://jsfiddle.net/uyLrjgyz/2/.
I get all the data in JSON format like:
{
"header": {
"columns": [
{
"name": "0ColHeader",
"subcolumns": [
{
"name": ""
}
]
},
{
"name": "1ColHeader",
"subcolumns": [
{
"name": "1Col1SubColHeader"
},
{
"name": "1Col2SubColHeader"
},
{
"name": "1Col3SubColHeader"
}
]
},
{
"name": "2ColHeader",
"subcolumns": [
{
"name": "2Col1SubColHeader"
}
]
},
{
"name": "3ColHeader",
"subcolumns": [
{
"name": "3Col1SubColHeader"
},
{
"name": "3Col2SubColHeader"
}
]
}
]
},
"rows": {
"data": [
[
{
"value": "text"
},
{
"value": "0"
},
{
"value": "0"
},
{
"value": "1"
},
{
"value": "0"
},
{
"value": "1"
},
{
"value": "0"
}
],
[
{
"value": "more text"
},
{
"value": "1"
},
{
"value": "0"
},
{
"value": "1"
},
{
"value": "1"
},
{
"value": "0"
},
{
"value": "1"
}
]
]
}
}
I can modify the json, as long as I don't have to convert it to much at the backend.
This angularjs and template table is related to my problem, but it's a little bit skimped.
You're there almost. Here is the Working fiddle
For colspan its simple like this colspan="{{col.subcolumns.length}}"
But for next sub-headers we should write handler like below in controller after $scope.table
$scope.subHeaders = function () {
var subs = [];
$scope.table.header.columns.forEach(function (col) {
col.subcolumns.forEach(function (sub) {
subs.push(sub);
});
});
return subs;
};
Markup for second row:
<tr>
<th ng-repeat="col in subHeaders()">{{col.name}}</th>
</tr>
Full Table:
<div ng-app="tableApp" ng-controller="tableController">
<table>
<tr>
<th colspan="{{col.subcolumns.length}}" ng-repeat="col in table.header.columns">{{col.name}}</th>
</tr>
<tr>
<th ng-repeat="col in subHeaders()">{{col.name}}</th>
</tr>
<tr ng-repeat="row in table.rows.data">
<td ng-repeat="cell in row">{{cell.value}}</td>
</tr>
</table>
</div>
Related
I want to show the Object wordCounts,which stores a series of words with a value that is the number of times a word is repeated in a string, what happens is that I want to show that variable in order by the number of repetitions that word has, and I just want the 20 most repeated words to be shown. The main problem I have is that as far as I have the code it returns a JSON, which does not allow me to put in a div to give it a style.
project-details.ts
getWordCount(str) {
let arrayOfWords = str.split(/\s+/);
var wordCounts = Object.create(null);
for(let i = 0; i<arrayOfWords.length; i++){
let word = arrayOfWords[i];
if(!wordCounts[word]){
wordCounts[word] = 1;
}else{
wordCounts[word] ++;
}
}
return wordCounts;
};
project-details.html
<p>{{getWordCount(str) | keyvalue | json}}</p>
representation
[ { "key": "También", "value": 1 }, { "key": "Un", "value": 1 }, { "key": "algoritmo", "value": 1 }, { "key": "aunque", "value": 1 }, { "key": "caracteres", "value": 1 }, { "key": "cifrado", "value": 1 }, { "key": "codificados", "value": 1 }, { "key": "composición", "value": 2 }, { "key": "cualquier", "value": 1 }, { "key": "de", "value": 5 }, { "key": "descifrado", "value": 1 }, { "key": "destinatario", "value": 1 }, { "key": "en", "value": 1 }, { "key": "es", "value": 2 }, { "key": "escritura", "value": 1 }, { "key": "forma", "value": 1 }, { "key": "generados", "value": 1 }, { "key": "imprimibles", "value": 1 }, { "key": "no", "value": 1 }, { "key": "original.", "value": 1 }, { "key": "para", "value": 1 }, { "key": "persona,", "value": 1 }, { "key": "por", "value": 2 }, { "key": "puede", "value": 1 }, { "key": "que", "value": 1 }, { "key": "que,", "value": 1 }, { "key": "sentido", "value": 1 }, { "key": "sentido.", "value": 1 }, { "key": "ser", "value": 1 }, { "key": "signos", "value": 1 }, { "key": "sistema", "value": 1 }, { "key": "su", "value": 1 }, { "key": "sí", "value": 1 }, { "key": "texto", "value": 1 }, { "key": "tienen", "value": 1 }, { "key": "un", "value": 2 }, { "key": "una", "value": 3 }, { "key": "unidad", "value": 1 } ]
And with that result I can't give it any style.
You could assign the value to a variable, remove the json pipe and loop the value directly in the HTML. Try the following
Controller
export class WordComponent {
wordCount: any;
getWordCount(str) {
let arrayOfWords = str.split(/\s+/);
let wordCounts = Object.create(null);
for(let i = 0; i < arrayOfWords.length - 1; i++){
let word = arrayOfWords[i];
wordCounts[word] ? wordCounts[word]++ : wordCounts[word] = 1;
}
return wordCounts;
};
onMouseUp(str: string) {
this.wordCount = this.getWordCount(str);
}
}
Template
<button (mouseup)="onMouseUp('str')">Get word count</button>
<ng-container *ngIf="wordCount">
<p class="style" *ngFor="let word of wordCount | keyvalue">{{ word.key }} : {{ word.value }}</p>
</ng-container>
You can then modify and render as per you wish. Also note the loop condition should be arrayOfWords.length - 1 because index starts from zero.
It sounds like what you need is a ShowWordCounts component which takes your object as an #Input and generates the corresponding template.
I am saving data in localstorage temporary, because of user have to go to another page before submit the form, But i have problem to display data in form again.
Here is my code
$('#ip_range').click(function(e) {
var data = $('#Demoform').serializeArray();
// localStorage.setItem('formData', JSON.stringify(data));
var formData = JSON.parse(localStorage.getItem('formData'));
$.each(formData, function(i, val) {
var data = $("input[name='"+val.name+"']").val(val.value);
console.log(data);
});
});
This is the json data that i want to display
[{
"name": "timezone",
"value": "America/New_York"
}, {
"name": "fiscal_year",
"value": "1"
}, {
"name": "first_day",
"value": "0"
}, {
"name": "highest_level",
"value": "393"
}, {
"name": "company_administrator",
"value": "393"
}, {
"name": "ip_restrictions",
"value": "1"
}, {
"name": "ip_range",
"value": "4"
}, {
"name": "languages_enabled",
"value": "0"
}, {
"name": "language",
"value": ""
}, {
"name": "enable_single_sign",
"value": "0"
}, {
"name": "user_sign_off",
"value": "0"
}, {
"name": "widgets_sort_order",
"value": "Links,Training,Task"
}, {
"name": "confirm",
"value": "1"
}]
You are close here, but this part $("input[name='"+val.name+"']").val(val.value) is what I think your problem is. Try the code below. I think this is what you are trying to do.
I would structure the input like such: var data = $('<input name="'+ val.name +'" value="'+ val.value +'" />');
I'd put a stack snippet up, but it doesn't work well with localStorage, so click on the jsfiddle link and click the IP Range button to see the form get the inputs with the proper names.
Demo: https://jsfiddle.net/ygh8pdk1/
var data = [
{
"name": "timezone",
"value": "America/New_York"
}, {
"name": "fiscal_year",
"value": "1"
}, {
"name": "first_day",
"value": "0"
}, {
"name": "highest_level",
"value": "393"
}, {
"name": "company_administrator",
"value": "393"
}, {
"name": "ip_restrictions",
"value": "1"
}, {
"name": "ip_range",
"value": "4"
}, {
"name": "languages_enabled",
"value": "0"
}, {
"name": "language",
"value": ""
}, {
"name": "enable_single_sign",
"value": "0"
}, {
"name": "user_sign_off",
"value": "0"
}, {
"name": "widgets_sort_order",
"value": "Links,Training,Task"
}, {
"name": "confirm",
"value": "1"
}
];
localStorage.setItem('formData', JSON.stringify(data));
$('#ip_range').click(function(e) {
var formData = JSON.parse(localStorage.getItem('formData'));
$.each(formData, function(i, val) {
var data = $('<input name="'+ val.name + '" value="'+ val.value +'" />');
$('#form-data').append(data);
});
});
Group the table cells based on the decimal points.
Plunker
Sample JSON:
[
{
"data1": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.1.2"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3"
},
{
"name": "Download",
"id": "1.4"
}
]
},
{
"data2": [
{
"name": "Download",
"id": "2.1"
},
{
"name": "Download",
"id": "2.2"
}
]
},
{
"data3": [
{
"name": "Download",
"id": "3.1.1"
},
{
"name": "Download",
"id": "3.1.2"
},
{
"name": "Download",
"id": "3.2"
}
]
},
{
"data4": [
{
"name": "Download",
"id": "4.1.1"
},
{
"name": "Download",
"id": "4.1.2"
}
]
}
]
HTML:
<table border="0" class="table table-bordered">
<tbody ng-repeat="(key,result) in results">
<tr ng-repeat="r in result['data'+[key+1]]">
<td rowspan="5">{{r.id}}</td>
</tr>
</tbody>
</table>
using ng-repeat to display each id in single cell of the table.
Actual Result:
Expected Result
Because of ng-repeat the cell are displaying next to each other. The expected result is to divide the table cell using the decimal points.
Example:
Row1 => 1.1.1, 1.1.2, 1.2, 1.3, 1.4
Row2 => 2.1, 2.2
The Row2 first cell(2.1) should take the width of row1(1.1.1 and 1.1.2). And 2.2 should take the rest of the width of 1.2, 1.3 and 1.4
Thanks in advance.
your data structure not clear, seems need to review and refactor it.
but for now this plunker can help you. (i hope!)
link:
plunker
First to introduce to my table structure:
<div class="col-md-9">
<table class="table table-bordered">
<thead>
<tr>
<th>Date</th>
<th>Pair</th>
<th id="{{odds.id}}" ng-repeat="odds in list">{{odds.odd.name}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="match in matches ">
<td>{{match.sd | parseMomentDate}}</td>
<td>{{match.h}}-{{match.a}}</td>
<td>{{match.odds.drawNoBet.value}}<span ng-if="!match.drawNoBet.value">--</span></td>
</tr>
</tbody>
</table>
</div>
I am listing odd names, and therefore setting up id attr for the element.
So my problem is how to populate the rest of the table, the table data based on the Id from the table head, every table head to have rows and columns populated based on that id?
I have the next structure of receiving the data:
"id": 4413011,
"sd": "2017-04-27T23:30:00.000+0400",
"h": "Athletic Bilbao",
"a": "Betis Sevilla",
"odds": {
"bothToScore": [
{
"name": "no",
"value": 1.85,
"id": 552240303
},
{
"name": "yes",
"value": 1.95,
"id": 552240338
}
],
"doubleChance": [
{
"name": "12",
"value": 1.22,
"id": 552240012
},
{
"name": "x2",
"value": 2.98,
"id": 552240003
},
{
"name": "1x",
"value": 1.11,
"id": 552240079
}
],
"drawNoBet": [
{
"name": "1",
"value": 1.15,
"id": 552240007
},
{
"name": "2",
"value": 6.15,
"id": 552240267
}
],
"totalGoals": [
{
"name": "under",
"value": 2.15,
"id": 552235662
},
{
"name": "over",
"value": 1.7,
"id": 552235663
}
]
}
},
So for example in the odds object there is a list "bothToScore", therefore "bothToScore" is the id for the table head, and based on that id need to populate the rest of the columns, meaning ;Yes' or 'No'.
Any suggestions?
At this case id mapping is not needed - just ensure same order of <th>s and <tr>s:
angular.module('app', []).controller('ctrl', ['$scope', function($scope) {
$scope.matches = [{
"id": 4413011,
"sd": "2017-04-27T23:30:00.000+0400",
"h": "Athletic Bilbao",
"a": "Betis Sevilla",
"odds": {
"bothToScore": [{
"name": "no",
"value": 1.85,
"id": 552240303
},
{
"name": "yes",
"value": 1.95,
"id": 552240338
}],
"doubleChance": [{
"name": "12",
"value": 1.22,
"id": 552240012
},
{
"name": "x2",
"value": 2.98,
"id": 552240003
},
{
"name": "1x",
"value": 1.11,
"id": 552240079
}],
"drawNoBet": [{
"name": "1",
"value": 1.15,
"id": 552240007
},
{
"name": "2",
"value": 6.15,
"id": 552240267
}],
"totalGoals": [{
"name": "under",
"value": 2.15,
"id": 552235662
},
{
"name": "over",
"value": 1.7,
"id": 552235663
}]
}
}];
$scope.matches.push(JSON.parse(JSON.stringify($scope.matches[0])));
}]);
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller="ctrl">
<table>
<thead>
<tr>
<th>Date</th>
<th>Pair</th>
<th ng-repeat-start='(key, value) in matches[0].odds' hidden></th>
<th ng-repeat-end ng-repeat='item in value'>{{item.name}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat='match in matches'>
<td>{{match.sd | date}}</td>
<td>{{match.h}} - {{match.a}}</td>
<td ng-repeat-start='(key, value) in match.odds' hidden></td>
<td ng-repeat-end ng-repeat='item in value'>{{item.value}}</td>
</tr>
</tbody>
</table>
</div>
I am trying to render DataTable-rows from a json file, placed on the same directory. But unfortunately, the DataTable-Body stays empty, and no error is displayed in the console.
Here is the (reduced) HTML-Code:
<table id="opTable">
<thead>
<tr><th class="partner_id">ID</th><th>ShortName</th><th>DisplayName</th><th>LogoUrl</th><th>Incent</th><th>JTS-URL</th></tr>
</thead>
<tbody>
</tbody>
</table>
Here is the JavaScript I am using to load the data from the json file:
<script>
$(document).ready(function() {
$('#onlinePartnerTable').DataTable({
"ajax" : "../test2.json",
"columns": [{
"data": "pId"
}, {
"data": "shrName"
}, {
"data": "DplayName"
}, {
"data": "lgo"
}, {
"data": "inc"
}, {
"data": "featured"
}]
});
});
</script>
and here is a sample of my json file:
{
"partnerList": [
{
"shrname": "bchan",
"Dplayname": "bchang-Shop",
"pId": "id12345",
"featured": "0",
"lgo": "https://url.here.com/url",
"inc": "1 to 1",
"dets": {
"tmage": "someUrl/here",
"desp": "desciption",
"jturl": "jtUrl/here",
"jtbut": "Shop",
"termy": [
{
"heady": "",
"body": ""
}
]
}
},
{
"shrname": "hereIsIt",
"Dplayname": "HereIs-Shop",
"pId": "id65432",
"featured": "0",
"lgo": "https://url.here.com/url",
"inc": "2 to 1",
"dets": {
"tmage": "someUrl/here",
"desp": "desciption",
"jturl": "jtUrl/here",
"jtbut": "Shop",
"termy": [
{
"heady": "",
"body": ""
}
]
}
}
]
}
I am becomming this error now.. See the image below.
try this
var t = [{
"shrname": "bchan",
"Dplayname": "bchang-Shop",
"pId": "id12345",
"featured": "0",
"lgo": "https://url.here.com/url",
"inc": "1 to 1",
"dets": {
"tmage": "someUrl/here",
"desp": "desciption",
"jturl": "jtUrl/here",
"jtbut": "Shop",
"termy": [{
"heady": "",
"body": ""
}]
}
}, {
"shrname": "hereIsIt",
"Dplayname": "HereIs-Shop",
"pId": "id65432",
"featured": "0",
"lgo": "https://url.here.com/url",
"inc": "2 to 1",
"dets": {
"tmage": "someUrl/here",
"desp": "desciption",
"jturl": "jtUrl/here",
"jtbut": "Shop",
"termy": [{
"heady": "",
"body": ""
}]
}
}];
$(document).ready(function() {
$('#opTable').DataTable({
"aaData": t,
"columns": [{
"data": "pId"
}, {
"data": "shrname"
}, {
"data": "Dplayname"
}, {
"data": "lgo"
}, {
"data": "inc"
}, {
"data": "featured"
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdn.datatables.net/1.10.11/css/jquery.dataTables.min.css" />
<script src="https://cdn.datatables.net/1.10.11/js/jquery.dataTables.min.js"></script>
<table id="opTable">
<thead>
<tr>
<th class="partner_id">ID</th>
<th>ShortName</th>
<th>DisplayName</th>
<th>LogoUrl</th>
<th>Incent</th>
<th>JTS-URL</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Based on one of the links Turnip provided in the comments, Datatables Ajax Data Source (objects), your data should look like this:
{
"data": [
{
"shrname": "bchan",
"Dplayname": "bchang-Shop",
"pId": "id12345",
"featured": "0",
"lgo": "https://url.here.com/url",
"inc": "1 to 1",
},
{
"shrname": "hereIsIt",
"Dplayname": "HereIs-Shop",
"pId": "id65432",
"featured": "0",
"lgo": "https://url.here.com/url",
"inc": "2 to 1",
}
]
}
I'm not sure what you're trying to do with the "dets" part of your data though