What is wrong with the following code: I`m having the error message
Error 1 ; expected
<%if (Model.ReferenceFields != null)
{%>
<%int count = 1; %>
<%foreach (var referenceName in Model.ReferenceFields)
{%>
<%var value = "value"; %>
<%count++; %>
<%value = value + count.ToString(); %>
<tr>
<td><input type="hidden" name="Tests.Index" value='<%value%>' /></td>
<td><input type="text" name="Tests['<%value%>'].Value"/></td>
<td><input type="button" value= "Add" /></td></tr>
<%}
%>
<%}
%>
The basic problem is lines like this
<input type="hidden" name="Tests.Index" value='<%value%>' />
So you're wanting to write out the contents of value into the html but thats not the way to do it. It should be
<input type="hidden" name="Tests.Index" value='<% Response.Write(value); %>' />
or a shortcut for Response.Write is <%= so
<input type="hidden" name="Tests.Index" value='<%= value %>' />
ASP101 - Writing Your First ASP.NET Page
The other problem is that the formatting of your code is, quite frankly butt ugly and you're making it hard work for yourself when trying to read it. Try this instead.
<%
if (Model.ReferenceFields != null)
{
int count = 1;
foreach (var referenceName in Model.ReferenceFields)
{
var value = "value";
count++;
value = value + count.ToString();
%>
<tr>
<td><input type="hidden" name="Tests.Index" value='<%= value %>' /></td>
<td><input type="text" name="Tests['<%= value %>'].Value"/></td>
<td><input type="button" value= "Add" /></td></tr>
<%
}
}
%>
Related
As shown in my post here the GET action method Test(..) works fine when using foreach loop in the corresponding Test.chtml view but the POST action method Test(...) returns null. But, as mentioned by many users, the foreach is not reliable for POST method. So, I decided to use the for loop as shown below. But that returned unexpected results in the view since, according to this post, in a foreachloop type casting is done automatically but in for loop you have to type cast the objects Model[i].BlogID etc to a proper class object type.
So, I decided to type cast the objects Model[i].BlogID etc to a BlogsWithRelatedPostsViewModel class object type as shown in the second version of Test.cshml view below; and this time the Test.cshtml view is displayng the correct records. But although the submit button in the view is sending a a valid model (ModelState.IsValid is true) the Model.Count is 0 that results in no update to database. Why Model.Count is 0 and how to correct it? As you can see below the html page source of the view is showing the name attributes of the tags matching the property values in the View Model.
Note: For complete code, please see this OP. I'm using ASP.NET Core with EF Core and Tag Helpers.
Test.cshtml view with for loop - without type casting the loop objects:
#model IList<ASP_Core_Blogs.Models.BlogPostViewModels.BlogsWithRelatedPostsViewModel>
#using ASP_Core_Blogs.Models.BlogPostViewModels
#{ ViewData["Title"] = "Index"; }
<div class="row">
<div class="col-md-12">
<form asp-controller="Blogs" asp-action="Test" asp-route-returnurl="#ViewData["ReturnUrl"]" method="post">
#{
IEnumerable<SelectListItem> yearsList = (IEnumerable<SelectListItem>)ViewBag.YearsList;
var currentlySelectedIndex = 0; // Currently selected index (usually will come from model)
}
<strong>Select a Post Year</strong>
<h6>Choose a year and a URL to begin:</h6>
<label>Year:</label><select asp-for="#currentlySelectedIndex" asp-items="yearsList"></select><input type="submit" class="btn btn-default" name="GO" value="GO" />
<table class="table">
<thead>
<tr>
<th></th>
<th></th>
<th>Url</th>
<th>Title</th>
<th>Content</th>
</tr>
</thead>
<tbody>
#for (int i=0; i< Model.Count(); i++)
{
<tr>
<td><input type="hidden" asp-for="#Model[i].BlogID" /></td>
<td><input type="hidden" asp-for="#Model[i]).PostID" /></td>
<td>
<input type="text" asp-for="#Model[i].Url" style="border:0;" readonly />
</td>
<td>
<input asp-for="#Model[i].Title" />
</td>
<td>
<input asp-for="#Model[i].Content" />
</td>
</tr>
}
</tbody>
</table>
<button type="submit" class="btn btn-default">Save</button>
</form>
</div>
</div>
Test.cshtml view with for loop objects being casted as BlogsWithRelatedPostsViewModel class objects:
#model IList<ASP_Core_Blogs.Models.BlogPostViewModels.BlogsWithRelatedPostsViewModel>
#using ASP_Core_Blogs.Models.BlogPostViewModels
#{ ViewData["Title"] = "Index"; }
<div class="row">
<div class="col-md-12">
<form asp-controller="Blogs" asp-action="Test" asp-route-returnurl="#ViewData["ReturnUrl"]" method="post">
#{
IEnumerable<SelectListItem> yearsList = (IEnumerable<SelectListItem>)ViewBag.YearsList;
var currentlySelectedIndex = 0; // Currently selected index (usually will come from model)
}
<strong>Select a Post Year</strong>
<h6>Choose a year and a URL to begin:</h6>
<label>Year:</label><select asp-for="#currentlySelectedIndex" asp-items="yearsList"></select><input type="submit" class="btn btn-default" name="GO" value="GO" />
<table class="table">
<thead>
<tr>
<th></th>
<th></th>
<th>Url</th>
<th>Title</th>
<th>Content</th>
</tr>
</thead>
<tbody>
#for (int i=0; i< Model.Count(); i++)
{
<tr>
<td><input type="hidden" asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).BlogID" /></td>
<td><input type="hidden" asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).PostID" /></td>
<td>
<input type="text" asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).Url" style="border:0;" readonly />
</td>
<td>
<input asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).Title" />
</td>
<td>
<input asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).Content" />
</td>
</tr>
}
</tbody>
</table>
<button type="submit" class="btn btn-default">Save</button>
</form>
</div>
</div>
A Portion of html generated by View after Submit:
<tr>
<td><input type="hidden" data-val="true" data-val-required="The BlogID field is required." id="BlogID" name="BlogID" value="1" /></td>
<td><input type="hidden" data-val="true" data-val-required="The PostID field is required." id="PostID" name="PostID" value="1" /></td>
<td>
<input type="text" style="border:0;" readonly id="Url" name="Url" value="blog1#test.com" />
</td>
<td>
<input type="text" id="Title" name="Title" value="Title1" />
</td>
<td>
<input type="text" id="Content" name="Content" value="Content1" />
</td>
</tr>
I create one app about product that has name, price and description. In index.html.erb, I wanna add textbox to each of them and click edit link can edit don't need go to /products/id/edit.
How can I edit the product data?
<% #products.each do |product| %>
<tr>
<form action="/products/<%= product.id %>" class="edit_person_<%= product.id %>" id="edit_person_<%= product.id %>" method="post">
<input name="_method" type="hidden" value="patch" />
<input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
<td><input id="product_name" name="product[name]" type="text" value="<%= product.name %>" /><br /></td>
<td><input id="product_price" name="product[price]" type="text" value="<%= product.price %>" /><br /></td>
<td><input id="product_descr" name="product[descr]" type="text" value="<%= product.descr %>" /><br /></td>
<td><input name="commit<%= product.id %>" type="submit" value="edit" /></td>
</form>
</tr>
<% end %>
You need to use AJAX if you want to update your data without reloading the edit.html.erb file. Below, I'm gonna show it how to this for one field, rest you can assume yourself.
<input id="product_price" name="product[price]" type="text" value="<%= product.price %>" />
In your js.erb file, you can write:
$("#product_price").focusout(function() {
var productPrice = $(this).val();
$.ajax({
url: "/products/<%= product.id %>/edit",
type: "POST",
data: { product_price: productPrice}, // same way, other attributes
success: function() {
console.log("The result successfully came back from ther server.");
// Now, here you can show a notice to the user that he has successfully update the record without reloading the page.
}
});
});
I am new to MVC and would like some help.
I have a view (below) which displays the products, next to each other. Till here everything is fine.
#foreach (var item in Model)
{
<a href="#Url.Action("showProductDetails", "Shared", new { ProductID = item.ProductID }, null)">
<div class='OutsideDiv' >
<table class='DivBorder'>
<tr >
<td class='title'>
#item.ProductName
</td>
</tr>
<tr >
<td class='imageBox'>
<img alt='' src="#item.ImageURL" />
</td>
</tr>
<tr>
<td class='title'>
#Html.Action("showAverageRating", "Rating" , new { ProductID = item.ProductID } ) *************
</td>
</tr>
<tr>
<td class='desc'>
#item.Description
</td>
</tr>
<tr>
<td class='price'>
€ #item.Price
</td>
</tr>
</table>
</div>
<script type='text/javascript'> $('.DivBorder').mouseover(function () { $(this).css('border-color', '#0953cb'); $(this).css('background-color', '#eaeaea'); }); $('.DivBorder').mouseout(function () { $(this).css('border-color', '#bdbdbd'); $(this).css('background-color', '#f6f6f6'); });</script>
</a>
}
In the line marked with '****' above I am calling another view (showAverageRating) which for now is just displaying 5 rating stars with the first 3 starts selected.
<input class="star " name="adv1" type="radio" />
<input class="star " name="adv1" type="radio" />
<input checked="checked" class="star " name="adv1" type="radio" />
<input class="star " name="adv1" type="radio" />
<input class="star " name="adv1" type="radio" />
The problem is that on the second item, when the rating stars view (above partial view) is called again, the stars are displayed next to the stars of the first product, picture below.
I think I have to use something else rather than Html.Action?
EDIT : showAverageRating Code
public ActionResult showAverageRating(int ProductID)
{
decimal averageRating = new RatingsService.RatingsClient().getAverageRating(ProductID);
ViewData["averageRating"] = averageRating;
return PartialView();
}
The problem was that the name of the stars where identical, so I included the productID with their name, like below.
showAverageRating partial view
#{decimal averageRating = ViewBag.averageRating;}
#{int productID = ViewBag.productID;}
<div id="averageRating" >
<input class="star" name="star+#productID" type="radio" />
<input class="star " name="star+#productID" type="radio" />
<input checked="checked" class="star " name="star+#productID" type="radio" />
<input class="star " name="star+#productID" type="radio" />
<input class="star " name="star+#productID" type="radio" />
</div>
i am increment i in this code which i am not able to parse. what is wrong with i in the code below?
#{
int i=0;
}
#foreach (var item in Model.PortServiceTariffIncluded)
{
<tr id="#("sp" + item.ServiceId)">
<td>#item.ServiceName <input type="hidden" name="QuotationDetailList[i].ServiceId" value="#item.ServiceId" /></td>
<td>#item.ServiceCriteria</td>
<td>#item.ItemBasis</td>
<td>#Html.DropDownListFor(model => model.Currency, ViewBag.CurrencyDd as SelectList) <input type ="text" id="Amount#i" name="QuotationDetailList[i].Amount" /></td>
<td><input type="hidden" value="#item.ServiceId" class="serviceslist" name="serviceslist" /><input type ="button" id="#item.ServiceId" name="btnremove" value="Remove" class="clsremove" /></td>
</tr>
i = i + 1;
}
Use the following, instead:
#foreach (var item in Model.PortServiceTariffIncluded.Select((value, i) => new { i, value })
{
<tr id="#("sp" + item.value.ServiceId)">
<td>#item.ServiceName <input type="hidden" name="QuotationDetailList[item.i].ServiceId" value="#item.value.ServiceId" /></td>
<td>#item.value.ServiceCriteria</td>
<td>#item.value.ItemBasis</td>
<td>#Html.DropDownListFor(model => model.Currency, ViewBag.CurrencyDd as SelectList) <input type ="text" id="Amount#item.i" name="QuotationDetailList[item.i].Amount" /></td>
<td><input type="hidden" value="#item.value.ServiceId" class="serviceslist" name="serviceslist" /><input type ="button" id="#item.value.ServiceId" name="btnremove" value="Remove" class="clsremove" /></td>
</tr>
}
Basically, this causes your item variable to be an object consisting of an iterator (item.i) and the actual item (item.value).
First, I would set a variable to contain your QuotationDetailList :
#{ var QuotationDetailList = Model.QuotationDetailList;}
Then, use a for here instead of a foreach :
#for (var ListIndex = 0; ListIndex < Model.PortServiceTariffIncluded.Count(); ListIndex++)
Now you can reference items using your variable and the index :
<td>#QuotationDetailList[ListIndex].ServiceName <input type="hidden" name="#QuotationDetailList[ListIndex].ServiceId" value="#QuotationDetailList[ListIndex].ServiceId" /></td>
Just need to if i can use to form=post in the mvc view , below is the example which uses to form post , which currently doesnt works:
Edited: the jquery is submiting the form with id frmWorldPay when the image is clicked
$("#pay").click(function () {
// $("#frmWorldPay").(function () {
if ($("#terms").attr("checked")) {
$("#frmWorldPay").submit();
alert("sss");
// return true;
} else {
alert("Please agree to the terms and conditions.");
return false;
}
});
<% using (Html.BeginForm()) {%>
<table id="cart" border="0" cellpadding="0" cellspacing="0">
<tr>
<th>
Event
</th>
<th>
Item
</th>
<th>
Quantity
</th>
</tr>
<%
foreach (var bookingItem in Model.BookingItems)
{%>
<tr>
<td>
<%: ViewBag.Name %>
</td>
<td>
<%: Product.Description %>
</td>
<td>
<%: bookingItem.Quantity%>
</td>
</tr></table>
<% } %>
<% { %> if (ViewBag.mode == "confirm")
{ %>
<input type="submit" value="Confirm" />
<% } %>
<form method="post" action="https://secure.wp3.rbsworldpay.com/wcc/purchase" id="frmWorldPay">
<input type="hidden" name="instId" value="01" />
<input type="hidden" name="cartId" value="<%: Model.GUID %>" />
<input type="hidden" name="currency" value="GBP" />
<input type="hidden" name="testMode" value="100" />
</form> if (ViewBag.mode == "Checkout")
{ %>
<div id="worldPayBtnWrap">
<p> <%: Html.CheckBox("terms") %> by ticking this box you are agreeing to our <%: Html.ActionLink("terms & conditions", "Terms", "About")%></p>
<input type="image" src="/content/images/btnWorldPay.png" alt="Pay via World Pay" id="pay" />
</div>
<% } %>
You can have multiple forms in one web page, but you can't nest them.
Your external form is nested inside the MVC form (the using (Html.BeginForm()) { }), so it won't work.
I have sorted out the issue , actually my input was in same post method , therfore only one form was posting while the other input was not posting , the above is modified which works fine , although it is not a clean solution , for the time being i will be happy to use , will clean it later on .:)