I want to display nested array in table. Array structure:
0:
value1:"something",
...
firstNestedArray:{
value2:"something2",
...
secondNestedArray:{
value3:"something3",
...
thirdNestedArray:{
value4:"something4",
...
}
}
}
Problem is that I don't know how to correctly process this array to display it in table.
I tried this:
<tbody data-ng-repeat="item1 in firstNestedArray">
<tr data-ng-repeat="item2 in item1.secondNestedArray">
<td>{{item1.value1}}</td>
<td>
{{item2.value2)}}
<br>
{{item2.value3)}}
</td>
<!-- Problem appears here: -->
<td>
{{thirdNestedArray.value1}}
</td>
</tr>
</tbody>
How can i display all this thirdNestedArray values that I need? Because all this values from array have to be displayed in one row.
|column1|column2|column3|column4|column5|
|value1 |value2 |value3 |value4 |value5 |
I've tried to do it like this bu this doesn't work:
<tbody data-ng-repeat="item1 in firstNestedArray">
<tr data-ng-repeat="item2 in item1.secondNestedArray">
<td>{{item1.value1}}</td>
<td>
{{item2.value2)}}
<br>
{{item2.value3)}}
</td>
<!-- Does not work: -->
<div data-ng-repeat="item2 in item1.thirdNestedArray">
<td>
{{item2.value4}
</td>
</div>
</tr>
</tbody>
First of all, you can't put a div in the middle of a table like that, Angular or not. Tables have a very specific parent-child tree.
Second, just use ng-repeat on the TD element you want to repeat. You'll have to track what the maximum number of TDs in ANY of the TRs is so that you can compensate in all of the other TRs (which may be shorter). I think the easiest way to do this is to check the source arrays' lengths in the controller, and push empty elements onto the ends of the shorter arrays that you're building from so that they all match the maximum size. This padding means you won't have to deal with more complex markup manipulations.
Related
after reading a lot of posts here, I've come to the conclusion that textContent is faster than innerHTML and outerHTML; but what happens when I have a lot of data that needs to be replaced?
I have a table with dynamic second columns such as follows. Keep in mind a JS function will show/hide metric or imperial <span> when clicked.
When a new variant is selected, data in the second cells will change.
<div class="spec-table" id="SpecTable">
<table class="table">
<tr>
<td>dimension_1_title</td>
<td><span class="spec-table_metric">dimension_1_metric</span><span class="spec-table_imperial">dimension_1_imperial</span></td>
</tr>
<tr>
<td>dimension_2_title</td>
<td><span class="spec-table_metric">dimension_2_metric</span><span class="spec-table_imperial">dimension_2_imperial</span></td>
</tr>
<tr>
<td>Other information</td>
<td><span class="spec-table_metric">Other information metric</span><span class="spec-table_imperial">Other information imperial</span></td>
</tr>
</table>
</div>
Would it make sense if I put the entirety of my HTML table into JS variables for each variant and use getElementById(#SpecTable).innerHTML to replace it or use 6 functions to change each <span> individually by using getElementById(#IDs for Spans).textContent?
I'm confused as I may have 5 variants, which means 30 JS variables to collect and match when needed, whereas only 5 JS variables that contain the whole table.
In addition, is it better or worst if I get rid of the <div> and use outerHTML to change the table?
I'm a beginner at JS, and if you have other recommendations, I appreciate your input.
I am trying to create a table that is created from Lists of different sizes.
I have a list of Cars List<Car>. So in the header I want to place the names of the different companies which I did.
Then I have a List<List<CarSales>> and not all Cars exist in each carSales.
So I want to iterate through the List of List of each tr (also OK)
and then I want to iterate in the td though the List and place the CarSales.sales in the correct td where CarSales.mark=Car.makr of the header.
So if List<Cars> is (I mean Cars.mark)
[BMW, MERCEDES,FIAT]
And List<List<CarSales>> is (I mean object that have mark and sales inside)
[[BMW:5,FIAT:10],[MERCEDES:12]]
I want a table with:
BMW - MERCEDES - FIAT
5 - 0 - 10
0 - 12 - 0
You might be able to do that... but you can make the markup so much simpler if List<List<CarSales>> was instead a List<Map<String, Integer>> instead (where the key is the mark, and the value is the sales). Then you could have something like this:
<table>
<tr>
<th th:each="car: ${cars}" th:text="${car.mark}" />
</tr>
<tr th:each="sale: ${carSales}">
<td th:each="car: ${cars}" th:text="${sale.get(car.mark)} ?: 0" />
</tr>
</table>
If you want to go with your original structure, something like this might work, but it's more confusing to maintain:
<table>
<tr>
<th th:each="car: ${cars}" th:text="${car.mark}" />
</tr>
<tr th:each="sales: ${carSales}">
<td th:each="car: ${cars}" th:with="sale=${sales.^[mark==#root.car.mark]}" th:text="${sale?.sales} ?: 0" />
</tr>
</table>
I'm building a table that is populated by ng-repeat going through a list that comes from the database. This part works fine, but I want to have a checkbox that lets the user select which rows are deleted. I'd also like to have a checkbox on the table header that works as a select all button.
The problem is that, as I understand it, the ng-repeat loop includes everything inside the row in question leaving me unable to insert a manual cell between the loop and the end of the row.
Is there a way to add an additional cell between the loop and the end of the row, for example by using ng-repeat-start and ng-repeat end?
Here is an example of my attempts. This one did not work, obviously.
<table>
<tr><th ng-repeat=" e in poistoavaimet">{{e}}</th></tr>
<tr ng-repeat="i in poistolista | filter:sukunimiVal | filter:etunimiVal">
<td ng-repeat-start=" key in poistoavaimet">{{i[key]}}</td>
<td ng-repeat-end>
<input type="checkbox" ng-model="poistovalinta.{{$index}}">
{{$index}}</input>
</td>
</tr>
</table>
poistoavaimet contains the extracted keys from the array. Poistolista is the array itself from which the keys are extracted and it contains the data from the database. Poistovalinta is a variable for the values of the checkboxes. poistovalinta.{{$index}} was an attempt to create an entry in poistovalinta -array that has the key of the index of the row.
I'll add a snippet of the code responssible for handling these variables from the controller:
$scope.haePoistettavat = function(){
$http.get('/opiskelijahaku', {params: {'optio':2}})
.then(function(res){
$scope.poistolista = res.data.message;
$scope.poistoavaimet = Object.keys($scope.poistolista[0]);
$scope.adminLista = {};
$scope.adminLista['poisto'] = true;
}, function(error){
console.log(error)
});
}
This function sends a http get to the server with an option that tells the server to return the correct list. The response is stored in $scope.poistolista and the keys are extracted in to the array $scope.poistoavaimet. $scope.adminLista contains true/false values which link to ng-show in multiple objects. The idea is to only show one of them at the time. This is not directly linked to the question.
Thank you #RaphaMex for clearing up my misunderstanding about how ng-repeat works!
The solution is exactly what he said. Just add the cell after the repeat and it works.
Here is the fixed version:
<table>
<tr><th ng-repeat=" e in poistoavaimet">{{e}}</th><th><input id="kaikki" type="checkbox" ng-model="kaikkiVal"></th></tr>
<tr ng-repeat="i in poistolista | filter:sukunimiVal | filter:etunimiVal">
<td ng-repeat=" key in poistoavaimet">{{i[key]}}</td>
<td><input type="checkbox" ng-model="poistovalinta"></td>
</tr>
</table>
I'm working with a memory object where I store almost 2,000 <tr> elements. I select certain elements from this object and add them to the page according to the user.
the structure is almost like this but with more <td>s:
<tr attribute1="value" attribute2="value">
<td class="class1">something</td>
<td class="class1">something</td>
<td class="class2">something</td>
<td>
<div class="class1">
somthing
</div>
</td>
</tr>
So I select rows on certain attributes and then want to .show() or .hide() some of the <td>
I tried to use the following:
$(myObject).find("[attribute1=value]").clone().find(".class1").show();
but this statement only returns the <td>s or <div>s that satisfy the class condition.
If these rows where not in memory I could easily use a select statement which will work perfectly:
$(".class1").hide/show()
How can I achieve that in my situation
From within a xhtml page created with JSF, I need to use JavaScript / jQuery for changing the content of a cell of a table. I know how to assign a unique id to the div containing the table, and to the tbody. I can also assign unique class names to the div itself and to the target column. The target row is identified by the data-rk attribute.
<div id="tabForm:centerTabView:personsTable" class="ui-datatable ui-widget personsTable">
<table role="grid">
<tbody id="tabForm:centerTabView:personsTable_data" >
<tr data-rk="2" >
<td ... />
<td class="lastNameCol" role="gridcell">
<div> To Be Edited </div>
</td>
<td ... />
</tr>
<tr ... />
</tbody>
</table>
</div>
I have tried with many combinations of different jQuery selectors, but I am really lost. I need to search my target row and my target column inside that particular div or inside that particular table, because the xhtml page may contain other tables with different unique ids (and accidentally with the same row and column ids).
Something like this?
$("#tabForm\\:centerTabView\\:personsTable tr[data-rk=2] td.lastNameCol div").text("edited");
Or if personsTable is unique enough in the current view
$("[id$=personsTable] tr[data-rk=2] td.lastNameCol div").text("edited");
Please check this fiddle for your new html code
Fiddle without colon
Fiddle with Colon