At the moment I am working on razor view, where I'd like to create a table as follows:
<tbody>
<tr>
<td rowspan="5">data</td>
<td rowspan="5">data</td>
<td rowspan="5">data</td>
<td rowspan="5">data</td>
#for (int i = 0; i < Model.AvailableCodes.Count; i++)
{
<td>#Model.AvailableCodes[i]</td>
#if ((i % 6) == 0)
{
</tr><tr>
}
}
</tr>
</tbody>
But I am getting a parse error (Parser Error Message: The for block is missing a closing "}" character.), at the beginning of the #for... a bit clueless why. Any help is really appreciated.
When you are in the for you don't need to pre-fix with an # for the if.
Also in order to ouput un-balanced tags you can use #:
#for (int i = 0; i < Model.AvailableCodes.Count; i++)
{
<td>#Model.AvailableCodes[i]</td>
if ((i % 6) == 0)
{
#:</tr><tr>
}
}
Related
I have a specific question relating a foreach loop in C# and Blazor Web Assembly.
This is my foreach loop containing a keyvaluepair:
`
#foreach (KeyValuePair<int, string> pair in detail.Years2Value.OrderBy(x => x.Key))
{
<td colspan="1"><input type="text" class="radius form-control" style="background-color:transparent; border:0.1px" readonly="readonly" value=#pair.Value></td>
}
<td colspan="1" class="border-left border-right"></td>
`
I want to display all values in a range and in a Region. After each region it should create an empty row to make it look better and more organized. Thats why I am adding a td after the foreach.
This creates following problem: --> See Picture below!
after the last foreach in my last Region is done, I don't want to create a new td but I don´t know how to achieve this.
If I just delete the line of code with the td after the foreach then all regions will stick more or less together and it don´t look so good anymore because the missing "separation" of each region.
Is there a way to break the foreach only after the 3rd region is done and then don´t do the new td with an if sentence or something similar?
I hope you guys can help me here. Sorry if there is any information missing or something is not clear. I will try to explain it again if something is not clear.
Thank you
Here is the sample code
int i = 1;
#foreach (KeyValuePair<int, string> pair in detail.Years2Value.OrderBy(x => x.Key))
{
<td colspan="1"><input type="text" class="radius form-control" style="background-color:transparent; border:0.1px" readonly="readonly" value=#pair.Value></td>
if(i < detail.Years2Value.Count)
{
<td colspan="1" class="border-left border-right"></td>
}
i++;
}
I hope I understand your example well:
You could use for-loop and iterate through the items with index like the following.
#*Loop through all the KeyValuePairs in the Dictionary<int,string> *#
#for (int i = 1; i < orderedYearsToValue.Count(); i++)
{
<td colspan="1">
#*Select element and its value at the current index*#
<input type="text" class="radius form-control" style="background-color:transparent; border:0.1px" readonly="readonly" value=#orderedYearsToValue.ElementAt(i).Value>
</td>
#*If the current index is not at the last item, add an empty line *#
#if (i != orderedYearsToValue.Count()-1)
{
<td colspan="1" class="border-left border-right"></td>
}
}
#code {
private Dictionary<int, string> orderedYearsToValue;
... your code
private void OrderValues() {
orderedYearsToValue = detail.Years2Value.OrderBy(x => x.Key);
}
}
UPDATE after update of the original code:
The empty TD is done after every region. Therefore the for-loop should be done on the top level and TD only added after region is finished, instead of the nested loop.
Simplified code (use the logic from above):
for (int i = 0; i < myOrderedCountries.Count(); i++)
{
if(detail != null)
{
if(isSpecialist)
{
foreach(KeyValuePair<int, string> in myOrderedYearsToValue)
{
<td colspan="1"><input type="text" ...></td>
}
}
else
{
foreach(KeyValuePair<int, string> in myOrderedYearsToValue)
{
<td colspan="1"><input type="different text" ...></td>
}
}
if(i < myOrderedCountries.Count() - 1) {
<td colspan="1" class="border-left border-right"></td>
}
}
}
and even nicer would be to move the if part into the nested for-loop like this:
for (int i = 0; i < myOrderedCountries.Count(); i++)
{
if(detail != null)
{
foreach(KeyValuePair<int, string> in myOrderedYearsToValue)
{
if(isSpecialist)
{
<td colspan="1"><input type="text" ...></td>
}
else
{
<td colspan="1"><input type="different text" ...></td>
}
if(i < myOrderedCountries.Count() - 1) {
<td colspan="1" class="border-left border-right"></td>
}
}
}
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 a "DOM" list in MVC 4 using jQuery to add elements dynamically but at the moment of removing all the elements
The table no longer allows me to add more elements, I have tried to use length and comparisons but it does not work.
Am probably missing something obvious but can't see what it is. Any ideas?
Example
Here is my table code
<div><img src="~/Images/splus.png" alt="Add Product" style="border:0"/></div>
<table id="dataTable" border="0" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th></th>
<th></th>
<th>Product</th>
<th>Quantity</th>
<th></th>
</tr>
</thead>
<tbody>
#if (Model != null && Model.Count > 0)
{
int j = 0;
int index = 1;
foreach (var i in Model)
{
<tr>
<td>#index</td>
<td>#Html.HiddenFor(a => a[j].SEQ_NO, new { id = "nrow", Value = index })</td>
<td>#Html.DropDownList("PRODUCTS", "Select Product")</td>
<td>#Html.TextBoxFor(a => a[j].QUANTITY)</td>
<td>
<img src="~/Images/sminus.png" alt="Add Product" style="border:0"/>
</td>
</tr>
index += 1;
j++;
}
}
</tbody>
</table>
Here is my jQuery Code when i click on Add New
$("#addNew").click(function (e) {
e.preventDefault();
var last = $('#dataTable>tbody>tr:last');
if (last.length > 0) {
var name = last.children().find('input,select')[0].name;
var index = Number(name.replace(/[^0-9]/gi, '')) + 1;
var tr = ('<tr>' + last.html().replace(/[0-9]+__/gi, index + '__') + '</tr>').replace(/\[[0-9]+\]+[.]/gi, '[' + index + '].');
numberRows($('#dataTable tbody').append(tr));
}
});
UPDATE:
Add "REMOVE CODE"
$(document).on('click', '#remove', function (e) {
e.preventDefault();
$(this).parent().parent().remove();
numberRows($('#dataTable tbody'));
});
Am probably missing something obvious but can't see what it is. Any ideas?
var name = last.children().find('input,select')[0].name;
This line of code requires one last child, which means after you removed the last under , the name will be undefined. In fact, the Add New function won’t even pass the if (last.length > 0) since when the last got removed, the last.length becomes 0.
You can debug in devtools, and will see:
BEFORE the last got removed:
AFTER the last got removed:
Thus, to fix this issue, the simplest solution is to not remove the last but hide it. Please check below code:
$(document).on('click', '#remove', function (e) {
e.preventDefault();
if ($('#dataTable>tbody>tr').length > 1) {
$(this).parent().parent().remove();
//numberRows($('#dataTable tbody'));
}
else {
$(this).parent().parent().hide();
}
});
Ps. Not sure what happens in numberRows() function so I commented it.
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)
I have a loop on the server ( C# ) that does this:
for(i=0;i<=Request.Files.Count - 1; i++)
{
// tell the client that the upload is about to happen
// and report useful information
Update(percent, message, i, 0);
System.Threading.Thread.Sleep(1000);
// tell the client that upload succeeded
// and report useful information
Update(percent, message, i, 1);
}
The function "Update" writes to the client-side javascript function "PublishUpdate".
The row parameter is the row in the table containing the uploading file. The 'status' tells us if the file is about to be uploaded (0) or completed (1).
THE PROBLEM is that I can't seem to get the count correct. The loop seems to
start 2 or 3 rows into the table or (after playing with the row value) it ends before the
final row. I am very new to jQuery. Does anything look obviously wrong to you?
function PublishUpdate(percent, message, row, status)
{
var bodyRows = $("#picTableDisplay tbody tr");
bodyRows.each(function(index){
if (index == row && status == 0)
$('#status'+index).html("<img alt='inproc' src='images/loading.gif' />");
else if (index == row && status == 1)
$('#status'+index).html("complete");
});
}
Finally, the table looks like this:
<table width="100%" cellspacing="0" cellpadding="3" border="0" align="center" id="picTableDisplay" summary="" class="x-pinfo-table">
<tbody id="files_list" class="scrollContent">
<tr class="evenRow">
<td class="numCol" id="num0">
</td>
<td class="fnameCol" id="fname0">
</td>
<td class="statusCol" nowrap="" id="status0">
</td>
<td class="remCol" id="rem0">
</td>
</tr>
<tr class="oddRow">
<td class="numCol" id="num1">
</td>
<td class="fnameCol" id="fname1">
</td>
<td class="statusCol" nowrap="" id="status1">
</td>
<td class="remCol" id="rem1">
</td>
</tr>
<tr class="evenRow">
<td class="numCol" id="num2">
</td>
<td class="fnameCol" id="fname2">
</td>
<td class="statusCol" nowrap="" id="status2">
</td>
<td class="remCol" id="rem2">
</td>
</tr>
AND SO ON ...
Thanks in advance.
The C# is using zero indexing, and typically HTML authors use indexing starting from one. Check to see if you need to correct the index from 0 to 1-based, like this:
$('#status' + (index + 1))
Also refactoring your code to something simpler can often fix hidden errors, or at least make the error more obvious. I'd suggest something along these lines:
if (index == row)
{
if (status == 0) {
html = "<img alt='inproc' src='images/loading.gif' />";
} else {
html = "complete";
}
$('#status'+index).html(html);
}
You should also use C# idiom for looping, < x not <= x - 1:
for(i=0; i < Request.Files.Count; i++)
I'm not entirely sure what you're trying to do as it's not clear where the #status elements are. However, assuming they're cells within the row it might be better to give them a class "status" and then write something like
function PublishUpdate(percent, message, row, status) {
$('#picTableDisplay tbody tr:eq('+row+') .status').html(
status==0 ? '<img alt="inproc" src="images/loading.gif"/>' : 'complete'
);
}