This is a Razor page.
I'm trying to write a function that can be binded to an event that deletes the current row.
How to write the function?
the html code
#for (int i = 0; i < Count; i++)
{
<th width="250" > #(i + 1)
<MatIconButton Icon="clear" OnClick="#RemoveVariant" class="text-right"></MatIconButton>
</th>
}
</tr>
C# code
private void RemoveVariant(int index)
{
ShouldRender();
l_VKDTI_TSI.Remove(l_VKDTI_TSI[index]);
l_VKDTI_VI.Remove(l_VKDTI_VI[index]);
l_VKDTI_DIMENSIONS.Remove(l_VKDTI_DIMENSIONS[index]);
l_VKDTI_VW.Remove(l_VKDTI_VW[index]);
l_VKDTI_ENGINE.Remove(l_VKDTI_ENGINE[index]);
l_VKDTI_TRANSMISSION.Remove(l_VKDTI_TRANSMISSION[index]);
l_VKDTI_DRIVETRAIN.Remove(l_VKDTI_DRIVETRAIN[index]);
l_VKDTI_TAW.Remove(l_VKDTI_TAW[index]);
l_VKDTI_HUMP.Remove(l_VKDTI_HUMP[index]);
l_VKDTI_WAP.Remove(l_VKDTI_WAP[index]);
l_VKDTI_PEDAL.Remove(l_VKDTI_PEDAL[index]);
l_VKDTI_BOOSTER.Remove(l_VKDTI_BOOSTER[index]);
l_VKDTI_MC.Remove(l_VKDTI_MC[index]);
l_VKDTI_FB.Remove(l_VKDTI_FB[index]);
l_VKDTI_RB.Remove(l_VKDTI_RB[index]);
l_VKDTI_OVI.Remove(l_VKDTI_OVI[index]);
l_ESPTI_VAF_ALL.Remove(l_ESPTI_VAF_ALL[index]);
l_ESPTI_VAF_ALL_SELECTED.Remove(l_ESPTI_VAF_ALL_SELECTED[index]);
StateHasChanged();
}
Call your function with a copy of the loop variable.
#for (int i = 0; i < Count; i++)
{
var iCopy = i;
<th width="250" >
<MatIconButton Icon="clear" OnClick="#(()=>RemoveVariant(iCopy))" class="text-right"></MatIconButton>
</th>
}
Related
I'm trying to read a csv file so that I can load a jQuery DataTable. The csv file might have different headers. I was using the header to create the columns for the jQuery table. Then loading the file in and creating the rows. I was doing this directly from the csv file and all worked okay, but only if the file was small. I needed to move to using Json in order to implement a way using Linq to sort, filter, and query in the Model portion of the code. While trying to move to an MVC model, I got into a position where I can't extract the rows from the Json data.
Here is the ViewFile, which currently has the LoadDataAsJson (which should be in the Model class, I'll bet). The Json it creates is correct.
public IActionResult ViewFile()
{
string fileName = Request.Form["fileName"];
ViewData["name"] = fileName;
ViewData["data"] = LoadDataAsJson(dir + Path.DirectorySeparatorChar + fileName, 100);
return View();
}
private string LoadDataAsJson(string fileName, int limit)
{
string[] headers = new string[8];
StringBuilder bldr = new StringBuilder();
bldr.Append("[");
using (TextReader reader = new StreamReader(fileName))
{
String line = null;
int k = 0;
while ((line = reader.ReadLine()) != null)
{
if (k > limit)
break;
if (k++ != 0)
{
if (k != 2)
bldr.Append(","); // append a comma to the end of previous line
List<string> aRow = FormatAsJsonArray(line);
bldr.AppendLine();
bldr.Append("{");
for (int i = 0; i < headers.Length; i++)
{
bldr.Append(headers[i]);
bldr.Append(":\"");
bldr.Append(aRow[i]);
bldr.Append("\"");
if (i != headers.Length - 1)
bldr.Append(",");
}
bldr.Append("}");
}
else
{
headers = line.Split(',');
}
}
}
bldr.Append(Environment.NewLine + "]" + Environment.NewLine);
return bldr.ToString();
}
private List<string> FormatAsJsonArray(string aLine)
{
int k = 0;
string[] tokens = aLine.Split(',');
List<string> items = new List<string>();
string lastPart = "";
if (tokens.Length > 6)
{
for (int i = 7; i < tokens.Length; i++)
{
lastPart = String.Concat(lastPart, tokens[i]);
if (i != tokens.Length - 1)
lastPart += ",";
}
}
for (int i = 0; i < tokens.Length; i++)
{
if (i > 8)
break;
if (tokens[i].Contains("["))
{
List<string> msecs = MsecColumnAsJson(tokens[i]);
for (int kk = 0; kk < msecs.Count; kk++)
items.Add(msecs[kk]);
}
else if (k < 7)
items.Add(tokens[i]);
k++;
}
if (lastPart != null && lastPart.Length > 0)
items.Add(lastPart);
return items;
}
The ViewFile.cshtml contains in part.
<h2>#ViewData["name"]</h2>
<div class="container">
<br />
<table id="table_id" class="table table-condensed table-striped table-hover display">
<thead>
<tr>
<th>DateTime</th>
<th>Msecs</th>
<th>Thread</th>
<th>Level</th>
<th>Logger</th>
<th>Host</th>
<th>Msg Type</th>
<th>Message</th>
</tr>
</thead>
<tbody>
#{
string logFile = (string)#ViewData["data"];
var k = 0;
}
#foreach (string lf logFile)
{
if (k++ > 50)
{
break;
}
<tr>
#foreach (string item in lf)
{
<td>
#item
</td>
}
</tr>
}
</tbody>
</table>
</div>
I end up getting cannot convert type 'char' to 'string' in each of the foreach statements. I tried using var for the var logFile = #ViewData["data"] line, but then the rest isn't working.
My intention was to extract on Json array line at a time, then break each of those up into a single td. How can I use the LogFileModel to contain the handling of the data, and create a view and controller to do this?
I would suggest going a different approach.
Use TextFieldParser from Microsoft.VisualBasic.FileIO (Yes, you can use that in C#) to read CSV and place it as data model and then use Newtonsoft.Json to create json from that objects.
Here's more on TextFieldParser: https://coding.abel.nu/2012/06/built-in-net-csv-parser/
I'm using this model:
public class ListCoins
{
public Dictionary<string,Dictionary<string,float>> listCoins{ get; set; }
}
when I try to display them in the view using this method:
model IEnumerable<Crytocurrency_Web___Main.JResult.ListCoins>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<h4>Coin Value: #ViewBag.WalletValue</h4>
<table class="table">
<tr>
<th>
#Html.DisplayName("Name"))
</th>
<th>
#Html.DisplayName("CoinValue")
</th>
<th>
#Html.DisplayName("CoinAmmount")
</th>
<th></th>
</tr>
#for (var i = 0; i < Model.ElementAt(i).listCoins.Count; i++)
{
foreach (var coin in Model.ElementAt(i).listCoins)
{
<p>#coin.Key + " " + #coin.Value)</p>
}
}
i get the error on the line:
#for (var i = 0; i < Model.ElementAt(i).listCoins.Count; i++)
but in the controller i have checked that count is over one:
int counter = listOfCoins.Count;
which equals four and all the data is there.
i may just be displaying them wrong but i cant figure it out
controller code:
List<ListCoins> newListCoins = new List<ListCoins>();
foreach (var coin in listOfCoins)
{
using (WebClient client = new WebClient())
{
var json = client.DownloadString(
"https://min-api.cryptocompare.com/data/pricemulti?fsyms=" + queryString + "&tsyms=" +
queryString);
var result = Newtonsoft.Json.JsonConvert
.DeserializeObject<Dictionary<string, Dictionary<string, float>>>(json);
newListCoins.Add(new ListCoins
{
listCoins = result,
});
}
}
return View(newListCoins.ToList());
I don't think you need to use: Model.ElementAt(i). You can do this:
#for (var i = 0; i < Model.listCoins.Count; i++)
rather than this:
#for (var i = 0; i < Model.ElementAt(i).listCoins.Count; i++)
You can then loop through all of the elements in listCoins and display the values in the view.
You are getting ArgumentOutOfRangeException because you are trying to access an item in the collection with an index which does not exist!
This part in your for loop
i < Model.ElementAt(i).listCoins.Count
You are trying to loop until n where n is the Count of your child property listCoins of each item.
Your view is strongly typed to a collection of ListCoins. So Your outer loop should be from 0 to Model.Count
#for (var i = 0; i < Model.Count; i++)
{
foreach (var coin in Model.ElementAt(i).listCoins)
{
<p>#coin.Key + " " + #coin.Value)</p>
}
}
Here , the coin.Value is again another dictionary(Dictionary<string,float>), so you probably want to loop through the items in that as well.
I feel the foreach version could be more readable.
#foreach (var item in Model)
{
foreach (var coin in item.listCoins)
{
<h1>#coin.Key</h1>
foreach (var v in coin.Value)
{
<p>#v.Key - #v.Value</p>
}
}
}
#for (var i = 0; i < 3; i++)
{
if(#Model.lstEmp[i].isTrue==true)
{
<tr bgcolor="red">
}
else
{
<tr>
}
<td>#Model.lstDept[i].DeptId</td>
<td>#Model.lstEmp[i].EmpId</td>
</tr>
}
I am facing an error message that '}' not found. when I write everything inside the if and else block I'm not facing any issue but if I write like above I'm facing the issue. please help me in solving this.
Try the following:
#for (var i = 0; i < 3; i++)
{
if(#Model.lstEmp[i].isTrue==true)
{
#:<tr bgcolor="red">
}
else
{
#:<tr>
}
#:<td>#Model.lstDept[i].DeptId</td>
#:<td>#Model.lstEmp[i].EmpId</td>
#:</tr>
}
I think the only problem is that you have if(#Model). You don't need the # there because it is still in the razor context. Somehow it knows whether or not to interpret it as c# or html (not always perfect).
#for (var i = 0; i < 3; i++)
{
if(Model.lstEmp[i].isTrue==true)
{
<tr bgcolor="red">
}
else
{
<tr>
}
<td>#Model.lstDept[i].DeptId</td>
<td>#Model.lstEmp[i].EmpId</td>
</tr>
}
I am trying to load models and set every model in a separate, <td> when I reach 5 <td> I want to automatically start a new <tr> but it isn't really working with an if statement. Is it possible or should I go for an entire different approach?
Here is my code:
<tr>
#for (int i = 0; i < Model.Count; i++)
{
<td>
<img width="200px" src="#Url.Action("GetImage", "Beheer", new { productId = Model[i].product_id }) " alt="pasfoto"/><br />
<center><b>#Html.ActionLink(Model[i].naam, "PrProduct", "Categorie", new { id = Model[i].product_id }, null)</b></center>
<center>€ #Html.Label(Model[i].prijs)</center>
</td>
}
</tr>
Use the modulo operator %. Each time i%5 == 0, print a row around the td
#for (int i = 0; i < Model.Count; i++)
{
#if(i%5 == 0)
{
<tr>
}
<td>
<img width="200px" src="#Url.Action("GetImage", "Beheer", new { productId = Model[i].product_id }) " alt="pasfoto"/><br />
<center><b>#Html.ActionLink(Model[i].naam, "PrProduct", "Categorie", new { id = Model[i].product_id }, null)</b></center>
<center>€ #Html.Label(Model[i].prijs)</center>
</td>
#if(i%5 == 0)
{
</tr>
}
}
So you're going to have a table row when i is 0, 5, 10, 15, etc.
#for (int i = 0; i < Model.Count; i++)
{
#if(i%5 == 0)
{
<tr></tr>
}
<td>
<img width="200px" src="#Url.Action("GetImage", "Beheer", new { productId = Model[i].product_id }) " alt="pasfoto"/><br />
<center><b>#Html.ActionLink(Model[i].naam, "PrProduct", "Categorie", new { id = Model[i].product_id }, null)</b></center>
<center>€ #Html.Label(Model[i].prijs)</center>
</td>
}
The above code worked for me. Is it not much different from the answer Havelock gave, but it will not close the brackets in the above code if you do not close the html tags within the same if statement. This way may not look as good if you use borders because I think it will display one empty row? But, for me this worked fine:)
I want have a table in my view that is going to put 3 elements from my Model in each row. So the way I was going to do this is to loop through the model and inside of the foreach loop do a check on a count variable I have set up. If count mod 3 == 0 I would do something like </tr><tr> to start a new row. This isn't working the way I want it to because I would have a } following the <tr>. So basically my question is, how would I create a dynamic table inside of a razor view based on the elements in the model where each row has 3 items?
#{
int count = 0;
<div>
<table>
<tr>
#foreach (var drawing in Model)
{
<td style="width:240px;margin-left:30px; margin-right:30px;">
<img src="#Url.Action("GetImage", "Home", new { id = drawing.drw_ID })" alt="drawing" />
</td>
count++;
if(count%3==0)
{
</tr>
<tr>
}
}
</tr>
</table>
</div>
}
Maybe there is a much easier way of doing this that I am not thinking of
How about using two loops - this will make your document be setup much more nicely and make it a bit more readable. Also, it takes care of the problems that occur if the number of rows is not divisible by three:
<div>
<table>
#for(int i = 0; i <= (Model.Count - 1) / 3; ++i) {
<tr>
for(int j = 0; j < 3 && i + j < Model.Count; ++j) {
<td style="width:240px;margin-left:30px; margin-right:30px;">
<img src="#Url.Action("GetImage", "Home", new { id = Model[i + j].drw_ID })" alt="drawing" />
</td>
}
</tr>
}
</table>
</div>
Edited to reflect your pasted code. Note, this assumes the model implements IList or an array
Maybee this is the solution you are looking for works for me
#{
int count = 0;
**
var tr = new HtmlString("<tr>");
var trclose = new HtmlString("</tr>");
**
<div>
<table>
<tr>
#foreach (var drawing in Model)
{
<td style="width:240px;margin-left:30px; margin-right:30px;">
<img src="#Url.Action("GetImage", "Home", new { id = drawing.drw_ID })" alt="drawing" />
</td>
count++;
if(count%3==0)
{
**
trclose
tr
**
}
}
</tr>
</table>
</div>
}
Check this out, this should work for you !!!
<h2>Index</h2>
<table>
<tr>
#{
var index = 0;
}
#foreach (int num in Model)
{
if ((index % 10) == 0)
{
#Html.Raw("</tr>");
#Html.Raw("<tr>");
}
<td>
<h2>#num</h2>
</td>
index++;
}
</tr>
</table>
The #christian solution worked for me.I was not sure of "trclose" and "tr" hence posting here the solution that worked for me in razor view.
<table>
<tr><td><input type="checkbox" id="chkAssetCategories" /> SELECT ALL</td></tr>
<tr>
#{
var count=0;
foreach (var item in Model.AssetCategories)
{
<td><input type="checkbox" class = "Catgories" id='#item.ID' value ='#item.ID' /><label>#item.Name</label></td>
if (count%5 == 0)
{
#:</tr><tr>
}
count++;
}
}
</table>
#{ int counter = 0;}
<div>
<table>
#for(int i = 0; i <= (Model.Count - 1) / 3; ++i) {
<tr>
for(int j = 0; j < 3; ++j) {
<td style="width:240px;margin-left:30px; margin-right:30px;">
#Model[counter]
</td>
counter++;
}
</tr>
}
</table>
</div>