Right now I'm trying to add a feature to my table.
It's being done inside a cshtml C# MVC ASP.NET Enviroment.
#{
dt_Table = ds_Set.Tables[1];
foreach (System.Data.DataRow dr in dt_Table.Rows)
{
int autoincrement = 0;
string nombre = dr["Nombre"].ToString();
<tr>
<td align="center">#(autoincrement++)</td>
<td align="center">#nombre</td>
</tr>
}
}
How do I add auto increment or ++ to the value?
Right now like that it just prints "1" on each row of the table :(
How can I solve this?
The variable autoincrement is scoped to the foreach loop block so it is allocated and released each iteration. Declare the variable outside of the foreach loop (or you can use a for loop):
for( var i = 0; i < dt_Table.Rows.Count; ++i )
{
var dr = dt_Table.Rows[i];
var nombre = dr["Nombre"].ToString();
<tr>
<td align="center">#i</td>
<td align="center">#nombre</td>
</tr>
}
Thanks for the quick answer, can't believe I could't figure this out
#{
int autoincrement = 1;
dt_Table = ds_Set.Tables[1];
foreach (System.Data.DataRow dr in dt_Table.Rows)
{
string nombre = dr["Nombre"].ToString();
<tr>
<td align="center">#(autoincrement++)</td>
<td align="center">#nombre</td>
</tr>
}
}
Related
Player.Scores is a Dictionary<int, int?>. This code renders the correct value from the dictionary. But when the input value changes, hole variable is the same as the for loop ended at. If the course has 18 holes, the loop ends when reaching 19. All bindings goes to player.Scores[19] and that adds an extra key to the dictionary.
How do I bind the dictionary to it's key when inside a loop?
<tbody>
#for (int hole = 1; hole <= Course.Holes; hole++)
{
<tr>
<td>#hole</td>
#foreach (var player in Players)
{
<td><input #bind="player.Scores[hole]" /></td>
}
</tr>
}
</tbody>
#for (int hole = 1; hole <= Course.Holes; hole++)
{
int holeCopy = hole; // let holeCopy be captured instead of hole
<tr>
<td>#hole</td>
#foreach (var player in Players)
{
<td><input #bind="player.Scores[holeCopy]" /></td>
}
</tr>
}
#bind uses a lambda function when it is compiled to C#.
The problem is called 'capturing the loop var', you can google that.
And it won't hurt to use <tr #key="hole">
I created an sample c# blazor (server-side) app to practice a little.
I try to generate table rows dynamically for a calendar but i run into a problem there.
<table class="table">
<thead>
<tr>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
</thead>
<tbody>
<tr>
#* currentDateTimeValues is a list with DateTime objects *#
#foreach (var item in currentDateTimeValues)
{
#if (counter % 7 == 0 && counter > 0)
{
#:</tr><tr>
}
counter++;
<td>#item.ToString("dd.MM.yyyy")</td>
}
</tr>
</tbody>
</table>
After 7 cells a new row should be created but it doesn't. The cells go straight ahead without linebreak.
Maybe you guys have any idea.
UPDATE:
In the meantime I've created a workaround because I think that blazor can't handle the </tr><tr>
My currentDateTimeValues-List now contains week objects
<tbody>
#* currentDateTimeValues is a list with Week objects *#
#foreach (var week in currentDateTimeValues)
{
<tr>
<td>#week.Monday</td>
<td>#week.Tuesday</td>
<td>#week.Wednesday</td>
<td>#week.Thursday</td>
<td>#week.Friday</td>
<td>#week.Saturday</td>
<td>#week.Sunday</td>
</tr>
}
</tbody>
I think the solution you are trying isn't possible in Blazor at the moment. Why not use two loops to create the calendar. Something like:
#while (counter < currentDateTimeValues.Length)
{
<tr>
#{
var i = 0;
if (i < 7 && counter + i < currentDateTimeValues.Length)
{
<td>#currentDateTimeValues[counter + i].ToString("dd.MM.yyyy")</td>
i++;
}
}
</tr>
counter += 7;
}
I have multiple tables and Location Value is given in different index order.
How can I get location value if previous cell string is "Location" when I loop through table. On below example it is cells[7] but on other table it will be 9. How can I conditionally get values after cells inner text is "Location"? Basically find the cell "Location" get inner text of next cell.
Html Table:
<table class="tbfix FieldsTable"">
<tbody>
<tr>
<td class="name">Last Movement</td>
<td class="value">Port Exit</td>
</tr>
<tr>
<td class="name">Date</td>
<td class="value">26/06/2017 00:00:00</td>
</tr>
<tr>
<td class="name">From</td>
<td class="value">HAMBURGE</td>
</tr>
<tr>
<td class="name">Location</td>
<td class="value">EUROGATE HAMBURG</td>
</tr>
<tr>
<td class="name">E/F</td>
<td class="value">E</td>
</tr>
</tbody>
Controller Loop Through:
foreach (var eachNode in driver.FindElements(By.XPath("//table[contains(descendant::*, 'Last Movement')]")))
{
var cells = eachNode.FindElements(By.XPath(".//td"));
cd = new Detail();
for (int i = 0; i < cells.Count(); i++)
{
cd.ActionType = cells[1].Text.Trim();
string s = cells[3].Text.Trim();
DateTime dt = Convert.ToDateTime(s);
if (_minDate > dt) _minDate = dt;
cd.ActionDate = dt;
}
}
In your foreach loop you could use this:
var location = eachNode.FindElement(By.XPath(".//td[contains(text(),'Location')]/following-sibling::td));
Assuming your data is always structured like that I would loop over all the tags and add the data to a dictionary.
Try something like this:
Dictionary<string,string> tableData = new Dictionary<string, string>();
var trNodes = eachNode.FindElements(By.TagName("tr"));
foreach (var trNode in trNodes)
{
var name = trNode.FindElement(By.CssSelector(".name")).Text.Trim();
var value = trNode.FindElement(By.CssSelector(".value")).Text.Trim();
tableData.Add(name,value);
}
var location = tableData["location"];
You would have to add validation and checks for the dictionary and the structure but that is the general idea.
How can I parse HTML using LINQ on a webpage to get the innerhtml values from the table?
I am using the HtmlAgilityPack and would like to parse some values as good as possible.
the number you see(00000, 00001, 00002..), are unique numbers from the agents.
So maybe there is a way to use LINQ to parse those numbers and get the following values from td's
(Name, 123, state, and info) => 00000, John, 123, IDLE, coffee for each
so I can call them separately and work with them - maybe in a array?
</TH>
</TR>
<TR ALIGN=RIGHT>
<TD ALIGN=LEFT>00000</TD>
<TD ALIGN=LEFT>John</TD>
<TD ALIGN=CENTER>123</TD>
<TD ALIGN=LEFT>IDLE</TD>
<TD ALIGN=LEFT>coffee</TD>
</TR>
<TR ALIGN=RIGHT>
<TD ALIGN=LEFT>00001</TD>
<TD ALIGN=LEFT>Lisa</TD>
<TD ALIGN=CENTER>123</TD>
<TD ALIGN=LEFT>IDLE</TD>
<TD ALIGN=LEFT>coffee</TD>
</TR>
<TR ALIGN=RIGHT>
<TD ALIGN=LEFT>00002</TD>
<TD ALIGN=LEFT>Mary</TD>
<TD ALIGN=CENTER>123</TD>
<TD ALIGN=LEFT>IDLE</TD>
<TD ALIGN=LEFT>coffee</TD>
</TR>
<TR ALIGN=RIGHT>
<TD ALIGN=LEFT>00003</TD>
<TD ALIGN=LEFT>Tim</TD>
<TD ALIGN=CENTER>123</TD>
<TD ALIGN=LEFT>IDLE</TD>
<TD ALIGN=LEFT>coffee</TD>
</TR>
....
Thanks in advance!
This seems a lot like a "please give me the code I need question", which I seriously dislike. Have a look at the following and make sure you understand it:
var doc = ... // Load the document
var trs = doc.DocumentNode.Descendants("TR"); // Give you all the TRs
foreach (var tr in trs)
{
var tds = tr.Descendants("TD").ToArray(); // Get all the TDs
// Turn them into our datastructure
var data = new {
Name = tds[1].InnerText,
Number = tds[2].InnerText,
State = tds[3].InnerText,
Info = tds[4].InnerText,
};
// Do something with data
}
Doing it with LINQ only:
var data = from tr in doc.DocumentNode.Descendants("TR")
let tds = tr.Descendants("TD").ToArray()
select new {
Name = tds[1].InnerText,
Number = tds[2].InnerText,
State = tds[3].InnerText,
Info = tds[4].InnerText,
};
#flindeberg makes a perfectly reasonable answer (+1 to he/she), you could avoid the ToArray like this.
private class Row
{
public string Name { get; set; }
public int Number { get; set; }
public string State { get; set; }
public string Info { get; set; }
}
...
var mappings = new Action<string, Row>[]
{
(value, row) => row.Name = value,
(value, row) => row.Number = int.Parse(value),
(value, row) => row.State = value,
(value, row) => row.Info = value
};
var doc = ... // Load the document
var trs = doc.DocumentNode.Descendants("TR"); // Give you all the TRs
foreach (var tr in trs)
{
var row = new Row();
tr.Descendants("TD").Zip(mappings, (td, map) =>
{
map(td.InnerText, row);
return true;
});
// You now have a populated row.
}
I have a number of fields in my model which are named as such model.var_1, model.var_2, ... model.var_30.
I am trying to put these in a table so I am using a for loop as so.
<table>
<tr>
<th>Category</th>
<th>Description</th>
#for (int i = 1; i <= Model.Total; i++)
{
<th class="ali_day#(i)">Day #i</th>
}
</tr>
<tr>
<th>Intubated</th>
<th></th>
#for (int i = 1; i <= Model.Total; i++)
{
<th>#Html.EditorFor(model => model.var_#(i))
#Html.ValidationMessageFor(model => model.var_#(i))</th>
}
</tr>
</table>
However, var_#(i) doesn't seem to be valid. Is there a way to append this loop counter so I can get my variable name while using an html helper?
Use the editor helper overload that takes a string, that way you can use string concatenation to create the variable name.
#Html.Editor("var_" + i)
and the same for the validation message
#Html.ValidationMessage("var_" + i)