I have a table with bound data (KnockoutJS) like this:
...
<tr>
<th class="rotated">Row 1</th>
<!-- ko foreach: Dog-->
<td>
<p data-bind="text: Name">
</p>
</td>
<!-- /ko -->
</tr>
...
Problem is that I'd like to have fixed number of columns, for example 5, but sometimes there isn't much data so there are less than 5 columns generated. I'd like to know what is the best way how to add the columns so they are always 5.
I made a Javascript function which goes through all the rows, counts the <td> tags and add <td> tags if needed. Is there other option?
You should always use an array with 5 items even though it has empty values in it.
For example:
var Dog = [{Name:"dog1"},{Name:"dog2"},{Name:""},{Name:"dog3"},{Name:""}];
Related
Sorry if you find this question's solution is simple or silly.
Need suggestions or solution on this angular part.
I have an object containing array("value"), as shown below.
scope.resp.DefaultData.graphRowData = [
{YName:"Mary", value:[1,4], points:1},
{YName:"Tom", value:[2,5], points:1}
];
My Code viewer uses this style to render the array.
<table>
<tbody>
<tr ng-repeat="rowLabels in resp.DefaultData.graphRowData track by $index">
<th>
<input type="text" value="{{rowLabels.YName}}" ng-model="rowLabels.YName"/>
</th>
<td ng-repeat="value in rowLabels.value track by $index">
<input type="text" ng-model="value"/>
</td>
</tr>
</tbody>
</table>
The html viewer would render like below way:
<table>
<tbody>
<th>Mary</th><td>1</td><td>4</td>
<th>Tom</th><td>2</td><td>5</td>
</tbody>
</table>
Now to my question:
The table displays the data as per the model but if i try to update the table with custom or edit the values, doesn't update the model and the value remains same
For example: Mary has two tags of 1 and 4 values, if I try to change the 1 to 2 and 4 to 5, the data inside the model remains same without update.
Is there any way to fix in my code or should I change the array into array of objects like below
value:[{val:1},{val:4}]
and so ... for other objects under resp.DefaultData.graphRowData? Then it would work fine. Just confused why for array not working in angular js in my code! :(
You need to pass a reference of array instead of value in ng-model
<tr ng-repeat="rowLabels in resp.DefaultData.graphRowData track by $index">
<th>
<input type="text" value="{{rowLabels.YName}}" ng-model="rowLabels.YName"/>
</th>
<td ng-repeat="value in rowLabels.value track by $index">
<input type="text" ng-model="rowLabels.value[$index]"/>
</td>
</tr>
check this working plunker
New to angular, still working out the many kinks that I hit. I've got a question to pose to you all.
I currently have a table that is being populated on load with ng-repeat. The data itself is a bunch of sums of money. One particular entry, is a collection of those sums. I have an ng-onclick on it to run my function getLadders() when clicked. I would like it to basically pan out below wherever that element is in the chart, and create new rows of the data that is in that particular element.
A mini - drawing of the data it, as I can not paste the exact data.
ID Name Total
1 Single $20
2 Single $35
3 Combination $60***
4 Single $10
That is the current chart, with combination being the data with the many breakdowns within it. On click of that row, I want it to do something like this.
ID Name Total
1 Single $20
2 Single $35
3 Combination $60***
3.1 Single $20
3.2 Single $20
3.3 Single $20
4 Single $10
Basically, break out into everything inside that one piece. I have the function written with the extracted data, I have, right now, plain old jQuery to select that row, and append a tablerow after it, but it ends up attaching it to the end of the whole table instead of at that line.
Any help?
Also, for added benefits, I also have an icon on that row that I am looking to alter as well. It's a plus sign, that I want to be a minus sign when the data is being shown, and then back to a plus sign afterwards.
<tbody ng-controller="myCDsController">
<tr ng-repeat="holding in holdings" ng-if="holding.type !== 'Ladder'" data-type="{{holding.typeClass}}" data-id="{{holding.id}}">
<td>{{holding.type}}</td>
<td contenteditable="true">{{holding.name}}</td>
<td>{{holding.maturityDate}}</td>
<td>{{holding.amount | currency:"$"}}</td>
<td>{{holding.rate | percentage:2}}</td>
</tr>
<tr ng-repeat="holding in holdings" ng-if="holding.type == 'Ladder'" ng-controller="openLaddersController" data-type="{{holding.typeClass}}" data-id="{{holding.id}}">
<td><i ng-class="{'icon-dislike': !icon, 'icon-plus':icon}" ng-click="openLadders(holding.id)" >dfgh</i> {{holding.type}}</td>
<td contenteditable="true">{{holding.name}}</td>
<td>{{holding.maturityDate}}</td>
<td>{{holding.amount | currency:"$"}}</td>
<td>{{holding.rate | percentage:2}}</td>
</tr>
</tbody>
Here's some guidance based on what you have above. You should probably simplify the table structure into something like this:
<tbody ng-controller="myCDsController">
<tr ng-repeat="holding in holdings" data-type="{{holding.typeClass}}" data-id="{{holding.id}}">
<td><i ng-if="holding.type === 'Ladder'" ng-class="{'icon-dislike': !icon, 'icon-plus':icon}" ng-click="openLadders(holding)" >dfgh</i>{{holding.type}}</td>
<td contenteditable="true">{{holding.name}}</td>
<td>{{holding.maturityDate}}</td>
<td>{{holding.amount | currency:"$"}}</td>
<td>{{holding.rate | percentage:2}}</td>
</tr>
<tr ng-show="!icon" ng-if="holding.type === 'Ladder'>
<td colspan="5">
<table>
<tbody>
<tr ng-repeat="child in holding.children">
<td><!-- insert child content here --></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
There is probably a better way to handle the data-id / data-type attributes above, but I need more context.
Also, notice that I removed one of your controllers; I somehow doubt you need two controllers for this use case. Your controller should look something like this, probably:
app.controller('myCDsController', function(holding) {
$scope.openLadders = function() {
holding.children = getChildRows(holding)
}
})
I have a table which displays the column "air segments". The air segments come as a JSON array from the server(see picture), I need to display the contents of the air segments column one per line in a table cell. Right now its getting displayed as a complete string with a comma(See picture below).
.
So the HTML code is as follows:
<!-- ko foreach: $parents[0].outputsToDisplay($data) -->
<td>
<span data-bind="foreach: $data, visible: $parents[2].outputs()[$parent.index()].internalname ==='air_segments', text: splitAirSegments($data)"><br></span>
</td>
<!-- /ko -->
The outer 'for each' supplies the $data to the td, which are the results to be populated in the table.
The visible binding property makes sure that only column air_segments gets populated.
The outputs() is an observable array in the js file.
I need to code a JS method "splitAirSegments" such that it returns the air segments one by one and with help of 'br' I break the line which would eventually make the air segments appear one per line in a single table cell.
What I tried:
self.splitAirSegments = function (arr) {
return arr;
}
The way I understood it was, the 'for each' from the 'span' would send each of the air segment to this function and the HTML will display it with line breaks as soon as the function returns the value.
What can be the correct approach? Are there any other ways to split the air segments(with delimiter as a comma) which is now displaying all the air segments together with a comma.
Kindly help.
On the lines of user #Origineil's fiddle the below worked for me:
<!-- ko foreach: $parents[0].outputsToDisplay($data) -->
<td>
<span data-bind="if: $parents[1].Outputs()[$index()].InternalName === 'air_segments'">
<span data-bind="foreach: $data">
<span data-bind="text: $data"></span>
<br/>
</span>
</span>
</td>
<!-- /ko -->
I have an angularjs application that basically takes JSON and creates a HTML table, with the keys in the <thead> and the values as table rows.
I have a JSFiddle here where I take the JSON and create table rows based on the values. But I can't figure out how to take the keys and align them with the values as table headers.
My angular code:
<tr ng-repeat='row in rows'>
<td ng-repeat="data in row.data">
{{data}}
</td>
</tr>
and:
function TableController($scope){
$scope.rows = data;
}
Take a look here: How can I iterate over the keys, value in ng-repeat in angular
<tr ng-repeat="(key, value) in data">
<td> {{key}} </td> <td> {{ value }} </td>
</tr>
====EDIT==== Since you're doing it all in the same table, you'll need to do it a different way. You need to separate the header values while you're still in the controller so that you have a clean way to iterate over your list. Here the fiddle: http://jsfiddle.net/L93v5/1/
Your revised way looks bad because there are two different tables and the cell sizes are different. This will keep it all in the same table and make things a bit cleaner.
I've been struggling to find an answer to this question. That is, how would I have a static row that doesn't sort or move up and down? The reason for this is to have repeated headers in a very large table. The multiple headers Would anyone be able to help?
http://tablesorter.com/docs/
$("#dataTable").tablesorter({
sortList: [[0, 0], [1, 0]],
widgets: ['zebra', 'rowHover'],
widgetZebra: { css: ["even", "odd"] },
widgetRowHover: { css: 'rowhover' }
});
..
<table>
<tr>
<td>
Row 1
</td>
</tr>
<tr>
<td>
Row 2
</td>
</tr>
<tr>
<td>
Static Row
</td>
</tr>
<tr>
<td>
Row 3
</td>
</tr>
</table>
I was asked by #patmortech to add my comment above as an answer. So here is my comment verbatim.
I realise that this is ~4 months old now, but I ran into a similar problem and created a widget for Tablesorter that allows you to mark any rows as static. Take a look if you're still interested: http://asciisoup.wordpress.com/2011/02/20/static-rows-widget-for-jquery-tablesorter/
It sounds like you might want to break this table into 2 tables and adjust the columns widths if possible. Especially if you are not grouping rows.