how to create new td's from user input dynamically - javascript

I am trying to make a data table from user input. i found out this solution that i am making objects from user input and pushing them to an array. after that, I am doing a for loop to make td. but somehow those datas are re writing in the same raw. and previous raw datas are getiing replaced by new input datas.what I am doing wrong here and every time I am refreshing the page the array is getting empty how to prevent this help me out tnx.
const form = document.getElementById("form");
const tdbody = document.getElementById("data");
const carDatas = [];
let count = 0;
class Car {
constructor(plate, carMaker, carModel, carOwner, carPrice, carColor) {
(this.plate = plate),
(this.carMaker = carMaker),
(this.carModel = carModel),
(this.carOwner = carOwner),
(this.carPrice = carPrice),
(this.carColor = carColor);
}
}
form.addEventListener("submit", (e) => {
const plate = document.getElementById("plate").value;
const carMaker = document.getElementById("carMaker").value;
const carModel = document.getElementById("carModel").value;
const carOwner = document.getElementById("carOwner").value;
const carPrice = document.getElementById("carPrice").value;
const carColor = document.getElementById("carColor").value;
const carDetails = new Car(
plate,
carMaker,
carModel,
carOwner,
carPrice,
carColor
);
carDatas.push(carDetails);
for (let i = 0; i < carDatas.length; i++) {
document.getElementById("data").innerHTML = document.createElement(
"tr"
).innerHTML = `<td>${carDatas[i].plate} </td>
<td>${carDatas[i].carMaker} </td>
<td>${carDatas[i].carModel} </td>
<td>${carDatas[i].carOwner} </td>
<td>${carDatas[i].carPrice} </td>
<td>${carDatas[i].carColor} </td> `;
}
e.preventDefault();
});
here is my html for table
<div class="database">
<h1>Cars Database</h1>
<table>
<thead>
<tr>
<th>LICENCE</th>
<th>MAKER</th>
<th>MODEL</th>
<th>OWNER</th>
<th>PRICE</th>
<th>COLOR</th>
</tr>
</thead>
<tbody id="data"></tbody>
</table>
</div>

Your for loop is bad!
I don't know if this part of your code is working, but if you have an array of objects you should see a function for arrays that is called map
arr.map((object) => {
return <td>{object.plate}</td>
})
this function is example, try to look for documentation

Related

How do I let a user edit the textcontent of a specific cell in a table?

So I'm new to programming, and I'm creating a website where a user can enter information about their favourite books into a table.
However I've been trying to add an edit button feature where a user can click a button on a specific cell of the table and then be prompted to write in the replacement information.
So for example if they've already entered in the name of an author, they can click the edit button next to the info in the cell and they'll be prompted to enter in the replacement author's name, and it'll then reset the info in the cell in the table.
function addBooks() {
//Below is adding the users input information to the table.
let info = document.getElementById("author").value;
let info2 = document.getElementById("title").value;
let info3 = document.getElementById("genre").value;
let info4 = document.getElementById("review").value;
document.getElementById("author").value = "";
document.getElementById("title").value = "";
document.getElementById("genre").value = "";
document.getElementById("review").value = "";
let obj = {
author: info,
title: info2,
genre: info3,
review: info4,
};
let table = document.getElementById("table");
const row = table.insertRow(1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
var cell4 = row.insertCell(3);
//Below is the delete button which deletes a specific book/row.
var deleteButton = document.createElement("button");
deleteButton.classList.add("delete");
deleteButton.type = "button";
deleteButton.textContent = "Delete Book";
deleteButton.addEventListener("click", (event) => {
var row = deleteButton.parentNode.parentNode;
row.parentNode.removeChild(row);
});
cell1.innerHTML = `${obj.author}<button class="edit">Edit</button>`;
cell2.innerHTML = `${obj.title}<button class="edit">Edit</button>`;
cell3.innerHTML = `${obj.genre}<button class="edit">Edit</button>`;
cell4.innerHTML = `${obj.review}<button class="edit">Edit</button>`;
cell4.appendChild(deleteButton);
//Below here I am trying to addEvent listeners to the edit buttons that activate a function where the user can re-edit and enter new information into a specific cell.
const editButtons = document.getElementsByClassName("edit");
for (var i = 0; i < editButtons.length; i++) {
editButtons[i].addEventListener("click", (e) => {
editButtons.parentNode.innerHTML = prompt("Enter corrected info:");
});
}
}
Above is the Javascript code, but when I click on an edit button I get this error in the console :
books.js:47 Uncaught TypeError: Cannot set properties of undefined (setting 'innerHTML')
at HTMLButtonElement.<anonymous> (books.js:47:40)
I'm not sure what this means, but I was trying to be able to edit the text content of the parentNode. Is this the right way to to access and rewrite the text in the tables cells?
Here is also my html for reference.
<body>
<div class="container">
<h1 class="heading">Your Books</h1>
<p class="subHeading">Author</p>
<input type="text" id="author" />
<p class="subHeading">Title</p>
<input type="text" id="title" />
<p class="subHeading">Genre</p>
<input type="text" id="genre" />
<p class="subHeading">Reviews</p>
<input type="text" id="review" />
</div>
<button class="btn" onclick="addBooks()" id="button">Submit</button>
<table id="table">
<tr>
<th>Author</th>
<th>Title</th>
<th>Genre</th>
<th>Reviews</th>
</tr>
</table>
<script src="books.js"></script>
</body>
I hope that I've phrased things clear enough. Thanks a lot!
Never use innerHTML from unsanitized user inputs. Use textContent instead.
Function addBooks should be named addBook. Singular.
Use <thead> and specifically <tbody> as your target table element to insert rows into
Assign events on Element creation.
Create a separate ELNew_TD function to ease repetitive tasks
(TODO: don't use prompt() )
Here's a quick remake using some nifty DOM helper functions to make the code more readable:
// DOM utility functions
const ELNew = (tag, prop) => Object.assign(document.createElement(tag), prop);
const ELS = (sel, par) => (par || document).querySelectorAll(sel);
const EL = (sel, par) => (par || document).querySelector(sel);
// TASK:
const EL_author = EL("#author");
const EL_title = EL("#title");
const EL_genre = EL("#genre");
const EL_review = EL("#review");
const EL_table = EL("#table tbody");
const EL_add = EL("#button");
const ELNew_TD = (val) => {
const EL_td = ELNew("td");
const EL_span = ELNew("span", {
textContent: val
});
const EL_edit = ELNew("button", {
type: "button",
className: "delete",
textContent: "Edit",
onclick() {
val = prompt("Enter corrected info:");
val && (EL_span.textContent = val);
}
});
EL_td.append(EL_span, EL_edit);
return EL_td;
};
const addBook = () => {
const EL_tr = ELNew("tr");
const EL_btnDel = ELNew("button", {
type: "button",
textContent: "Delete",
onclick() { EL_tr.remove(); },
});
const EL_td5 = ELNew("td");
EL_td5.append(EL_btnDel);
EL_tr.append(
ELNew_TD(EL_author.value),
ELNew_TD(EL_title.value),
ELNew_TD(EL_genre.value),
ELNew_TD(EL_review.value),
EL_td5,
);
EL_table.append(EL_tr);
// Clear form
EL_author.value = "";
EL_title.value = "";
EL_genre.value = "";
EL_review.value = "";
};
EL_add.addEventListener("click", addBook);
label {display: block; padding: 5px 0;}
label span {display: inline-block; min-width: 100px;}
<div class="container">
<h1 class="heading">Your Books</h1>
<label><span>Author</span><input type="text" id="author"></label>
<label><span>Title</span><input type="text" id="title"></label>
<label><span>Genre</span><input type="text" id="genre"></label>
<label><span>Reviews</span><input type="text" id="review"></label>
</div>
<button class="btn" id="button">Add Book</button>
<table id="table">
<thead>
<tr>
<th>Author</th><th>Title</th><th>Genre</th><th>Reviews</th><th></th>
</tr>
</thead>
<tbody></tbody>
</table>
In the end I managed to fix the edit button so that it would remain functional no matter how many times it was used.
const editButtons = document.getElementsByClassName("edit");
for (var i = 0; i < editButtons.length; i++) {
editButtons[i].addEventListener("click", (e) => {
editButtons.parentNode.firstChild.innerHTML = prompt("Enter corrected info:");
});
}
}
This is the code that was used for the edit button function!
In your loop, use the “e” parameter you are passing into the event handler function to reference the elements (e.target).

How to create reordering functionality for rows in a table using JavaScript

I'm currently refactoring a project that is using Python widgets along with JavaScript. It currently uses a table with a reorder feature that could use some major improvements. When using the "reorderRowDown" button, it works correctly the current row moves down and the previous and next row adjust accordingly.
However, on the "reorderRowUp" button the current row simply alternates back and forth between the current and previous row. (I hope I'm explaining this well, my apologies) It's very clunky moving the current row up the table.
I would like to achieve the functionality similar to "reorderRowDown" where when clicking "reorderRowUp" the current row moves up and the previous and next row adjust accordingly. In summary, I would like to know how to implement reordering of the rows in the table either up or down the correct way. Any help would be greatly appreciated.
(Here are gifs posted below to better demonstrate the scenarios I'm referencing)
reorderRowDown Example:
https://media.giphy.com/media/8WHiGw57pPTK9Zdibk/giphy.gif
reorderRowUp Example:
https://media.giphy.com/media/Wp7x9GtYDX29cFLT6I/giphy.gif
Here's my code (please let me know if you require more)
PathContext.js
'use strict';
module.exports = () => {
window.reorderRowUp = function(ruleSetIdPriority) {
let ruleSetId;
ruleSetId = ruleSetIdPriority.split('-priority')[0];
const row = document.getElementById(ruleSetId);
const table = row.parentNode;
const prevRow = row.previousElementSibling;
table.insertBefore(row, prevRow);
};
window.reorderRowDown = function(ruleSetIdPriority) {
let ruleSetId;
ruleSetId = ruleSetIdPriority.split('-priority')[0];
const row = document.getElementById(ruleSetId);
const table = row.parentNode;
const nextRow = row.nextElementSibling;
table.insertBefore(nextRow, row);
};
};
reorder_row_widget.html
<button class="reorder-btn" type="button" onclick=reorderRowUp("{{widget.name}}")>Up</button>
<button class="reorder-btn" type="button" onclick=reorderRowDown("{{widget.name}}")>Down</button>
<input id="{{ widget.name }}" type="hidden" name="{{ widget.name }}" value="{{ widget.value }}"></input>
Here's the html of the actual table row from the console in my browser
<table>
<tbody>
<tr class="form-row row1 has_original dynamic-rule_set" id="rule_set-0">
<td class="original">
<p>
Rule object (84)
</p>
<input type="hidden" name="rule_set-0-id" value="84" id="id_rule_set-0-id">
<input type="hidden" name="rule_set-0-path_context" value="6" id="id_rule_set-0-path_context">
</td>
<td class="field-priority">
<button class="reorder-btn" type="button" onclick="reorderRowUp("rule_set-0-priority")">Up</button>
<button class="reorder-btn" type="button" onclick="reorderRowDown("rule_set-0-priority")">Down</button>
<input id="rule_set-0-priority" type="hidden" name="rule_set-0-priority" value="-301">
</td>
<td class="field-pattern">
<input type="text" name="rule_set-0-pattern" value="^/$" id="id_rule_set-0-pattern">
</td>
<td class="field-value">
<input class="tgl" id="rule_set-0-value" name="rule_set-0-value" type="checkbox" checked="">
<label class="tgl-btn" for="rule_set-0-value"></label>
</td>
<td class="field-experience">
<select name="rule_set-0-experience" id="id_rule_set-0-experience">
<option value="">---------</option>
<option value="modal" selected="">Modal</option>
<option value="sticky_cta">Sticky CTA</option>
</select>
</td>
<td class="delete"><input type="checkbox" name="rule_set-0-DELETE" id="id_rule_set-0-DELETE"></td>
</tr>
</tbody>
</table>
admin.py (python code if needed)
class ReorderRowWidget(forms.Widget):
template_name = 'admin/reorder_row_widget.html'
def get_context(self, name, value, attrs=None):
return {'widget': {
'name': name,
'value': value,
}}
def render(self, name, value, attrs=None, renderer=None):
context = self.get_context(name, value, attrs)
template = loader.get_template(self.template_name).render(context)
return mark_safe(template)
Here is the implementation I used to resolve my issue and create a better UI. I refactored the PathContext.js file.
function replaceReorderFunction() {
const reorderRowUp = window.reorderRowUp || function() {};
const reorderRowDown = window.reorderRowDown || function() {};
// when page gets rendered, django creates a hidden row with a special ruleSetId with id __prefix__
// once 'add new row' is clicked, a real ruleSetId is given to the row
// need to replace the reorder function of that row so that it uses the proper ruleSetId so the row can be reordered properly
// should only need to happen once, on the first reordering after the row is added
// therefore I assume that the row in question is always at the bottom of the table
const tableWrapper = document.getElementById('rule_set-group');
const tbody = tableWrapper.querySelector('tbody');
const rowToUpdate = tbody.lastElementChild.previousElementSibling.previousElementSibling;
const priorityField = rowToUpdate.getElementsByClassName('field-priority')[0];
const buttons = priorityField.getElementsByTagName('button');
buttons[0].onclick = () => {reorderRowUp(rowToUpdate.id);};
buttons[1].onclick = () => {reorderRowDown(rowToUpdate.id);};
return rowToUpdate.id;
}
window.reorderRowUp = function(ruleSetIdPriority) {
let ruleSetId;
// it's a new row, ruleSetId is not correct
if (ruleSetIdPriority.match(/__prefix__/)) {
// get the proper ruleSetId and replace existing onclick functions
ruleSetId = replaceReorderFunction();
} else {
ruleSetId = ruleSetIdPriority.split('-priority')[0];
}
const row = document.getElementById(ruleSetId);
const table = row.parentNode;
const prevRow = row.previousElementSibling;
if (!prevRow) {
return;
}
table.insertBefore(row, prevRow);
// swap priority values
const prevPriorityValue = getPriorityValueFromRow(prevRow);
const curPriorityValue = getPriorityValueFromRow(row);
setPriorityValueOfRow(row, prevPriorityValue);
setPriorityValueOfRow(prevRow, curPriorityValue);
};
window.reorderRowDown = function(ruleSetIdPriority) {
let ruleSetId;
// it's a new row, ruleSetId is not correct
if (ruleSetIdPriority.match(/__prefix__/)) {
ruleSetId = replaceReorderFunction();
} else {
ruleSetId = ruleSetIdPriority.split('-priority')[0];
}
const row = document.getElementById(ruleSetId);
const table = row.parentNode;
const nextRow = row.nextElementSibling;
if (!nextRow || nextRow.className === 'add-row' || nextRow.id.includes('empty')) {
return;
}
table.insertBefore(nextRow, row);
// swap priority values
const nextPriorityValue = getPriorityValueFromRow(nextRow);
const curPriorityValue = getPriorityValueFromRow(row);
setPriorityValueOfRow(row, nextPriorityValue);
setPriorityValueOfRow(nextRow, curPriorityValue);
};

Using local storage to add user inputted rows permanently on HTML

I am creating a website that takes two inputs a topic and a link and it appends them as a row to the HTML table. On clicking a '+' button it must do the needful. I wanted to use local storage so as to store these links and topics on the page permanently. Since I am new to the concept on local storage, any type of help would be appreciated.
This is my code snippet:
let table = document.querySelector('table');
let topicInput = document.querySelector('#topic');
let linkInput = document.querySelector('#link');
function getTopic () {
return localStorage.getItem("mytopic");
}
function getLink () {
return localStorage.getItem("mylink");
}
function updatePage () {
let topic = topicInput.value;
let link = linkInput.value;
let template = `
<tr>
<td>${topic}</td>
<td>${link}</td>
<td><input type="button" id="buttonDelete" value="-" onclick="deleteRow(this)"></td>
</tr>`;
table.innerHTML += template;
}
function addFunction () {
var rTopic = document.getElementbyId("topic").value;
var rLink = document.getElementbyId("link").value;
localStorage.setItem("mytopic", rTopic);
localStorage.setItem("mylink", rLink);
updatePage();
};
<input type="text" id="topic" placeholder="Add topic" size="50">
<input type="text" id="link" placeholder="Add link" size="50">
<button id="buttonAdd" onclick="addFunction()">+</button>
The basic idea is you would need to store a stringified array into local storage and parse it back out when the page loads. You append to the array when you add new rows.
const table = document.querySelector('table tbody');
const topicInput = document.querySelector('#topic');
const linkInput = document.querySelector('#link');
// grab the records from local storage.
const records = JSON.parse(localStorage.getItem("data") || '[]');
const rowIndex = 0;
function addRecord(topic, link) {
const template = `
<tr>
<td>${topic}</td>
<td>${link}</td>
<td><input type="button" class="buttonDelete" value="-"></td>
</tr>`;
table.innerHTML += template;
}
function addFunction() {
const rTopic = document.getElementById("topic").value;
const rLink = document.getElementById("link").value;
// add to the array
records.push({
topic: rTopic,
link: rLink
});
updateLocalStorage();
addRecord(rTopic, rLink);
};
function updateLocalStorage() {
// save updated records array
localStorage.setItem("data", JSON.stringify(records));
}
table.addEventListener("click", function (evt) {
const delButton = evt.target.closest(".buttonDelete");
if (delButton) {
const row = delButton.closest("tr");
const index = Array.from(row.parentNode.children).indexOf(row);
records.splice(index, 1);
row.remove();
updateLocalStorage();
}
})
// loop over the records in localstorage.
records.forEach(function(record) {
addRecord(record.topic, record.link);
});
<input type="text" id="topic" placeholder="Add topic" size="50">
<input type="text" id="link" placeholder="Add link" size="50">
<button id="buttonAdd" onclick="addFunction()">+</button>
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tbody></tbody>
</table>
And as I stated before, localstorage is not permanent. It can be easily cleared and it is also limited to the amount of data it can store.

Get the id of object in a tablerow - javascript

Hey i'm trying to get the id of the specific object so that i can send it to the backend for now. I'm having a hard time get the individual object and not the whole list at once.
If anything looks funky it's because I'm pretty new at this and it's been alot of trial and error
my javascript looks like this:
//waits for the html doc to be ready before atempting to run any js.
$(document).ready( () =>{
// jquery getting our json order data from API
$.get("http://localhost:8888/orderslist", (data) => {
// loops through our orderlist api
let rows = data.map(item => {
let $clone = $('#frontpage_new_ordertable tfoot tr').clone();
$clone.find('.customer_name').text(item.customer_name);
$clone.find('.date').text(item.date);
$clone.find('.time').text(item.time);
$clone.find('.pickup').text(item.pickup);
$clone.find('.comments').text(item.comments);
$clone.find('.total').text(item.total + ' Kr.');
let foo = function(){
//gets id from object and sends it to backend using get method
};
// accept and cancel buttons
$clone.find('.order_status').html(
`<button id = "acceptOrder" type="button" onclick="${foo()}">Accept</button>` +
`<button id = "cancelOrder" type="button" onclick="${foo()})">Cancel</button>`
);
// loops through orders product name
let productsName = item.products.map(prod => `${prod.name}`);
$clone.find('.products').html(productsName.join('<br />'));
// loops through orders product price
let productsPrice = item.products.map(prod => `${prod.price} Kr.`);
$clone.find('.price').html(productsPrice.join('<br />'));
return $clone;
});
//appends to our frontpage html
$("#frontpage_new_ordertable tbody").append(rows);
});
});
This is the json data i get from my route.
{
id: "3JBBdJdBUP7QyDvCnmsF",
date: "30/04-2020",
time: "13:40:41",
total: 40,
products: [
{
name: "Caffe Latte",
price: 40
}
]
}
My html looks like this:
<!-- this is the table of new orders -->
<table id="frontpage_new_ordertable">
<tbody>
<tr>
<th>Customer</th>
<th>Date</th>
<th>Ordered at</th>
<th>Wished pickup time</th>
<th>Order</th>
<th>Comments</th>
<th>Price</th>
<th>Total</th>
<th>Order Status</th>
</tr>
</tbody>
<tfoot>
<tr>
<td class="customer_name"></td>
<td class="date"></td>
<td class="time"></td>
<td class="pickup"></td>
<td class="products"></td>
<td class="comments"></td>
<td class="price"></td>
<td class="total"></td>
<td class="order_status"></td>
</tr>
</tfoot>
</table>
After edit it looks like this. I'm not seeing the accept button
// loops through our orderlist api
let rows = data.map(item => {
let $clone = $('#frontpage_new_ordertable tfoot tr').clone();
$clone.data("id", item.id);
$clone.find('.date').text(item.date);
$clone.find('.time').text(item.time);
$clone.find('.pickup').text(item.pickup);
$clone.find('.comments').text(item.comments);
$clone.find('.total').text(item.total + ' Kr.');
$(function() {$(document).on("click", ".acceptOrder", foo);
function foo() {
var btn = $(this);
var row = btn.closest("tr");
var id = row.data("id");
var name = row.find(".customer_name").text();
};
$clone.find('.order_status').html(
`<button type="button" class='acceptOrder">Accept</button>`
);
});
The relevant parts of the code are:
$(function() {
$.get("http://localhost:8888/orderslist", (data) => {
// loops through our orderlist api
let rows = data.map(item => {
let $clone = $('#frontpage_new_ordertable tfoot tr').clone();
let foo = function(){
//gets id from object and sends it to backend using get method
};
$clone.find('.order_status').html(
`<button id="acceptOrder" type="button" onclick="${foo()}">Accept</button>`
);
return $clone;
});
//appends to our frontpage html
$("#frontpage_new_ordertable tbody").append(rows);
});
});
First step is to remove the duplicate id: and onclick=
$(function() {
$(document).on("click", ".acceptOrder", foo);
function foo() {
}
...
$clone.find('.order_status').html(
`<button type="button" class='acceptOrder">Accept</button>`
);
...
});
Now, clicking the Accept button will call 'foo' as an event, with this as the button. You can get the original JSON ID by either putting this on the button as a data-id or on the parent tr:
let rows = data.map(item => {
let $clone = $('#frontpage_new_ordertable tfoot tr').clone();
$clone.data("id", item.id);
then, in foo, you can get this as:
function foo() {
var btn = $(this);
var row = btn.closest("tr");
var id = row.data("id");
var name = row.find(".customer_name").text();
...
}
the alternative is to add to the button in the same way - I tend to use it on the tr as you'll probably need to get the tr anyway and it means it's available from any element (eg another button).
`<button type="button" data-id="${item.id}" ...
To include some more context:
$(document).ready(() =>{
// add event listener here
$(document).on("click", ".acceptOrder", foo);
// add the event handler at the top-level inside doc.ready
function foo() {
var btn = $(this);
var row = btn.closest("tr");
var id = row.data("id");
var name = row.find(".customer_name").text();
...
}
// original code
$.get("http://localhost:8888/orderslist", (data) => {
// loops through our orderlist api
let rows = data.map(item => {
let $clone = $('#frontpage_new_ordertable tfoot tr').clone();
// add ID to the row as a data-id
$clone.data("id", item.id);
// original code
$clone.find('.customer_name').text(item.customer_name);
...etc
// remove let foo =
// let foo = function(){
// update accept/cancel buttons
// accept and cancel buttons
$clone.find('.order_status').html(
`<button class="acceptOrder" type="button">Accept</button>` +
`<button class="cancelOrder" type="button">Cancel</button>`
);

How do I match two arrays in C# like in Javascript?

To make sure two arrays are the same in Javascript, this is what I do:
(inserting zeroes where there is missing data in item1)
var viewModel = #Html.Raw(Json.Encode(Model));
var items = viewModel.Date1;
var items2 = viewModel.Date2;
items = items2.map( row =>
//is there a matching row in items?
items.filter( r => r.theString == row.theString).length == 0 ?
//if not, fill with zeros
{theString:0, theCount:0} :
//if there is, return the items' row
items.filter( r => r.theString == row.theString)[0] );
I use that data for the barchart as percentages. I need to display the results in table form with the actual count numbers like this:
<div style="padding-top: 30px">
<table id="table_id" class="display">
<thead>
<tr>
<th>Month</th>
<th>Cancelled</th>
<th>Total</th>
</tr>
</thead>
<tbody>
#using (var e1 = Model.Date1.Reverse().GetEnumerator())
{
using (var e2 = Model.Date2.Reverse().GetEnumerator())
{
while (e1.MoveNext() && e2.MoveNext())
{
var item1 = e1.Current;
var item2 = e2.Current;
<tr>
<td>#item1.theDate.Value.ToString("MMMM-yyyy") </td>
<td>#item1.theCount</td>
<td>#item2.theCount</td>
</tr>
}
}
}
</tbody>
</table>
</div>
Problem is that those arrays haven't been fixed to match eachother, so the data it's displaying is incorrect. The dates (theDate) are not matching the values.
Or could I just use items and items2 from the javascript to make a table?
Something like this should work:
#foreach (var item1 in Model.Date1.Reverse())
{
var item2Count = Model.Date2.Where(i2 => i2.theDate == item1.theDate)
.Select(i2 => i2.theCount)
.FirstOrDefault();
<tr>
<td>#item1.theDate.Value.ToString("MMMM-yyyy") </td>
<td>#item1.theCount</td>
<td>#item2Count</td>
</tr>
}
This has the same n² asymptotic complexity as the JavaScript you posted, so if you had a very large number of items there's a chance you'd see slow performance. This could be resolved by creating a lookup of the Date2 values, like so:
#{
var item2CountsByDate = Model.Date2.ToLookup(i => i.theDate, i => i.theCount);
foreach (var item1 in Model.Date1.Reverse())
{
var item2Count = item2CountsByDate[item1.theDate]
.FirstOrDefault();
<tr>
<td>#item1.theDate.Value.ToString("MMMM-yyyy") </td>
<td>#item1.theCount</td>
<td>#item2Count</td>
</tr>
}
}

Categories

Resources