I am trying to add razor to my HTML but now I am getting a Parser Error and do not understand why I get this error:
HTML:
#model ServingTeam.DAL.Members
#{
ViewBag.Title = "New Member";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm("AddMember", "Home", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { role = "form" }))
{
<div class="row">
<div class="col-md-2">
</div>
<div class="col-sm-6">
<h2>
New Member</h2>
<form class="form-horizontal" role="form" id="memberForm">
<div class="form-group">
<label for="inputName" class="col-sm-2 control-label" />
Name</label>
<div class="col-sm-10">
#Html.TextBoxFor(m => m.Email, new { #class = "form-control", placeholder = "Name", type = "text", required = "required " })
</div>
</div>
<div class="form-group">
<label for="inputName" class="col-sm-2 control-label">
Surname</label>
<div class="col-sm-10">
#Html.TextBoxFor(m => m.Surname, new { #class = "form-control", placeholder = "Surname", type = "text", required = "required " })
</div>
</div>
<div class="form-group">
<label for="inputName" class="col-sm-2 control-label">
Cell</label>
<div class="col-sm-10">
#Html.TextBoxFor(m => m.Cell, new { #class = "form-control", placeholder = "Cell", type = "text" })
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">
Email</label>
<div class="col-sm-10">
#Html.TextBoxFor(m => m.Email, new { #class = "form-control", placeholder = "Enter email address", type = "email", required = "required " })
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-info">
Submit</button>
</div>
</div>
</form>
</div>
<div class="col-md-4">
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
<script>
$("#memberForm").validate();
</script>
This is the error I get:
Encountered end tag "div" with no matching start tag. Are your start/end tags properly balanced? All works fine when I remove Razor.
Any help please?
I did find one error in your markup, don't know if it has anything to do with your current error though.
<form class="form-horizontal" role="form" id="memberForm">
</form>
the using(Html.BeginForm) will actually create a form for you, now you have a form within the form, which is not wizely
<label for="inputName" class="col-sm-2 control-label" />
Name</label>
There you go. the label gets cancelled out twice.
Related
I have the following form:
<form asp-controller="Manage" asp-action="RemoveDetails" method="post" class="form-horizontal">
#if (Model.RequirePassword)
{
<div id="password-container">
<div class="col-md-6">
<div class="form-group">
<label asp-for="Password"></label>
<input asp-for="Password" class="form-control" id="password" autocomplete="current-password" aria-required="true" />
<small>
<span asp-validation-for="Password" class="text-danger"></span>
</small>
</div>
</div>
</div>
}
<div class="col-6">
<hr class="mt-2 mb-3">
<button type="submit" class="btn btn-style-1 btn-danger">Confirm</button>
</div>
<div class="row">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
</div>
</form>
If I leave the password empty, a validation message (the model uses DataAnnonations) is displayed right below the control. This is fine.
If I enter the wrong password, the Post action validates it and adds an error to the ModelState. This error is displayed below the form.
Is it possible to display such model errors below the relevant controls?
Try this code in Controller: ModelState.AddModelError("Password", "validation summary error."); The error message won't display in <div asp-validation-summary="ModelOnly"></div>, but it can display error message in #Html.ValidationSummary(false, "", new { #class = "text-danger" }).
<form asp-controller="Home" asp-action="RemoveDetails" method="post" class="form-horizontal">
<div id="password-container">
<div class="col-md-6">
<div class="form-group">
<label asp-for="Password"></label>
<input asp-for="Password" class="form-control" id="password" autocomplete="current-password" aria-required="true" />
<small>
#*<span asp-validation-for="Password" class="text-danger"></span>*#
#Html.ValidationSummary(false, "", new { #class = "text-danger" })
</small>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="Description"></label>
<input asp-for="Description" class="form-control" id="description" autocomplete="current-password" aria-required="true" />
<small>
<span asp-validation-for="Description" class="text-danger"></span>
</small>
</div>
</div>
</div>
<div class="col-6">
<hr class="mt-2 mb-3">
<button type="submit" class="btn btn-style-1 btn-danger">Confirm</button>
</div>
<div class="row">
<div asp-validation-summary="ModelOnly"></div>
</div>
</form>
[HttpPost]
public IActionResult RemoveDetails(RemoveDetail rdl)
{
if(ModelState.IsValid)
{
var pwd = rdl.Password;
//do something here and find the password is wrong
//code below won't display error message in <div asp-validation-summary="ModelOnly" class="text-danger">
//but can display error message in #Html.ValidationSummary(false, "", new { #class = "text-danger" })
ModelState.AddModelError("Password", "validation summary error.");
return View(rdl);
}
return View(rdl);
}
I am tryingto populate a DropDownlist with the viewbag defined in the controller and i used a modal popup :
ProductController.cs
public IActionResult Create()
{
List<Category> categories = _dbcontext.Category.ToList();
ViewBag.bpCategories = new SelectList(categories, "CategoryId", "CategoryName");
Product product = new Product();
return PartialView("_AddProductPartialView",product);
}
_AddProductPartialView.cshtml:
#model WebApplication1.Models.Product
<div class="modal fade" role="dialog" tabindex="-1" id="addProduct" aria-labelledby="addProductLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addProductLabel">Products</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form asp-action="Create" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
......
<div class="form-group">
<label asp-for="CategoryId" class="control-label">CategoryId</label>
#Html.DropDownListFor(m => m.CategoryId, ViewBag.bpCategories as IEnumerable<SelectListItem>, "--Select ---", new { #class = "form-control" })
</div>
...
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
</div>
But i got this error:
The ViewData item that has the key 'CategoryId' is of type
'System.Int32' but must be of type 'IEnumerable'.
So what is the correct way to populate a DropDownlist in a modal popup??
EDIT
I tried also this code but i got an empty Dropdownlist:
<select asp-for="CategoryId" class="form-control" asp-items="ViewBag.bpCategories"></select>
Following code snippet with testing data can populate dropdown well, you can refer to it.
List<Category> categories = new List<Category>
{
new Category
{
CategoryId = 1,
CategoryName = "Category1"
},
new Category
{
CategoryId = 2,
CategoryName = "Category2"
},
new Category
{
CategoryId = 3,
CategoryName = "Category3"
}
};
ViewBag.bpCategories = categories.AsQueryable().Select(s => new SelectListItem { Value = s.CategoryId.ToString(), Text = s.CategoryName }).ToList();
In view page
<select asp-for="CategoryId" class="form-control" asp-items="ViewBag.bpCategories as List<SelectListItem>"></select>
Test Result
In Controller :
List<CollectionDetails> CollectionData = new List<CollectionDetails>();
CollectionData = GetCollectionDetails();
TempData["Department"] = new SelectList(CollectionData, "CollectionId",
"CollectionName");
In ViewModal :
#Html.DropDownListFor(model => model.CollectionId, new SelectList(TempData["Department"] as System.Collections.IEnumerable, "value", "text"), ---please select---, new { #tabindex = 13, #class = "form-control" })
I am trying to get the response data from my REST API and to display it in my vue.js application as follows:
var database = new Vue({
el: '#database',
data: {
databaseConfiguration: {
type: '',
url: '',
port: '',
username: '',
password: ''
},
errors: []
},
created: function () {
axios.get('/config/database')
.then(function (response) {
this.databaseConfiguration = response.data;
console.log(response.data);
})
.catch(function (error) {
this.errors.push(error);
console.log(error);
})
}
}
)
If I debug it, I see that the response is correctly fetched from the REST API. But unfortunately the data is not displayed on the html page.
The html code looks as follows:
<div id="database" class="panel panel-default panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Database Configuration</h3>
</div>
<div class="panel-body">
<form class="form-horizontal">
<div class="form-group">
<label for="inputType" class="col-sm-2 control-label">Type</label>
<div class="col-sm-10">
<input type="text" v-model="databaseConfiguration.type" class="form-control" id="inputType"
placeholder="Database type">
</div>
</div>
<div class="form-group">
<label for="inputUrl" class="col-sm-2 control-label">Url</label>
<div class="col-sm-10">
<input type="text" v-model="databaseConfiguration.url" class="form-control" id="inputUrl"
placeholder="Url">
</div>
</div>
<div class="form-group">
<label for="inputPort" class="col-sm-2 control-label">Port</label>
<div class="col-sm-10">
<input type="number" v-model="databaseConfiguration.port" class="form-control" id="inputPort"
placeholder="Port">
</div>
</div>
<div class="form-group">
<label for="inputUsername" class="col-sm-2 control-label">Username</label>
<div class="col-sm-10">
<input type="text" v-model="databaseConfiguration.username" class="form-control"
id="inputUsername" placeholder="Password">
</div>
</div>
<div class="form-group">
<label for="inputPassword" class="col-sm-2 control-label">Password</label>
<div class="col-sm-10">
<input type="password" v-model="databaseConfiguration.password" class="form-control"
id="inputPassword" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Save</button>
</div>
</div>
</form>
</div>
</div>
All the code can be found here.
Your this is pointing to the wrong object in your callbacks. Try using an arrow function, a closure, or bind.
Here is an example using an arrow function.
axios.get('/config/database')
.then(response => {
this.databaseConfiguration = response.data;
console.log(response.data);
})
.catch(error =>{
this.errors.push(error);
console.log(error);
})
See How to access the correct this inside a callback.
This is my part of code . Here i can add and submit the values. But while editing submit is not working. Can anyone help me on this. What can be the Issue over here.
#using (Html.BeginForm("LenseAdd", "Stock", FormMethod.Post, new { #class = "form-horizontal form-bordered" }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.LenseId)
#Html.HiddenFor(m => m.MaterialId)
<div class="form-group">
<label class="control-label col-lg-3 col-sm-3">Lense Code<span class="text-danger">*</span></label>
<div class="col-lg-6 col-sm-8">
<div class="input-group">
#*<input type="text" class="form-control" />*#
#Html.TextBoxFor(m => m.LenseCode, new { #class = "form-control", #placeholder = "Lense Code", #id = "LenseCode" })
<span class="input-group-addon"><span class="fa fa-money"></span></span>
</div>
#Html.ValidationMessageFor(m => m.LenseCode, null, new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-3 col-sm-3">BrandName<span class="text-danger">*</span></label>
<div class="col-lg-6 col-sm-8">
<div class="input-group">
#Html.DropDownListFor(m => m.BrandId, (IEnumerable<SelectListItem>)ViewBag.BrandList, "--select--", new { #class = "form-control", #id = "ddlbranchId" })
<span class="input-group-addon"><span class="fa fa-money"></span></span>
</div>
#*#Html.ValidationMessageFor(m => m.SalaryTo, null, new { #class = "text-danger" })*#
</div>
</div>
<div class="form-group">
#if (Model != null)
{
if (Model.CategoryList != null)
{
<label class="control-label col-lg-3 col-sm-3">Material</label>
foreach (var item in Model.CategoryList)
{
if (item.CategoryName == "MATERIAL")
{
<div class="col-lg-1 col-sm-3">
<div class="c-form__group -radio -inline">
<label class="c-form__control-text radio_heading">
<label>#item.Name</label>
#if (Model.MaterialId == item.ID)
{
#Html.RadioButtonFor(m => m.MaterialId, true, new { #checked = "checked", #class = "MATERIAL", #id = "MATERIAL_"+item.ID.ToString() })
}
else
{
#Html.RadioButtonFor(m => m.MaterialId, false, new { #class = "MATERIAL", #id = "MATERIAL_" + item.ID.ToString() })
}
<div class="-indicator"></div>
</label>
</div>
</div>
}
}
}
}
</div>
<div class="panel-footer">
<div class="row">
<div class="col-md-10 text-right">
<div class="btn-group">
<button type="submit" class="btn btn-custom fa fa-save -blue" >Save & New</button>
<button type="submit" class="btn btn-custom fa fa-save -skyblue" id="btn_submit">Save</button>
Cancel
</div>
</div>
</div>
</div>
}
I didn't copy the full cshtml page. here if you see any div mismatching please ignore. Any help will be appreciated.
I'm trying to validate a changed password partial view in my Index page of my Manage section. Like so,
#inject UserManager<ApplicationUser> UserManager
#model IndexViewModel
#{
ViewData["Title"] = "Manage your account";
}
<div class="row settings">
<div class="col-sm-6">
<h4>Basic information</h4>
#await Html.PartialAsync("BasicInformation", new BasicInformationViewModel(UserManager))
</div>
<div class="col-sm-6">
<h4>Change Password</h4>
#await Html.PartialAsync("ChangePassword", new ChangePasswordViewModel())
</div>
Controller code
[HttpPost("ChangePassword")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ChangePassword(ChangePasswordViewModel model)
{
if (!ModelState.IsValid)
{
return PartialView(model);
}
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(3, "User changed their password successfully.");
ViewData["StatusMessage"] = TranslationService.TranslateManageMessage(_context, ManageMessageId.ChangePasswordSuccess, "Your password has been changed.");
return PartialView();
}
AddErrors(result);
return PartialView(model);
}
ViewData["StatusMessage"] = TranslationService.TranslateManageMessage(_context, ManageMessageId.Error, "An error has occured.");
return PartialView();
}
So when the user changes his password, the thing I actually want to happen is that the Action get completed and the statusmessage of the partialview ges updated with what happend (succes, error, etc..). So how i have implemented it now it's work as I want it to but the only thing that is bad about this setup is that this happens.
My layout just disappears and I have no idea why. I thought returning a partial view would just reload the page but seems like it's not that.
Could anyone point me in the right direction ? Or give a suggestion how to do this better ?
EDIT:
ChangePassword Partial
#model ChangePasswordViewModel
<form asp-controller="Manage" asp-action="ChangePassword" method="post" class="form-horizontal">
<p class="text-success">#ViewData["StatusMessage"]</p>
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="OldPassword" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="OldPassword" class="form-control" />
<span asp-validation-for="OldPassword" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="NewPassword" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="NewPassword" class="form-control" />
<span asp-validation-for="NewPassword" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="ConfirmPassword" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="ConfirmPassword" class="form-control" />
<span asp-validation-for="ConfirmPassword" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default">Change password</button>
</div>
</div>
#section Scripts {
#{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}
The thing is you are initially loading the partialview inside index view on a get request, when you post to changepassword action it is not an ajax partial post it is a full post and it is not the Index action so it is not using the index view and you are returning a partialview that is not inside any other view so there is no outer view and no layout
UPDATE: since you requested in comments to show how to make it use ajax:
In your index view wrap a div with an id around the partial like this:
<div id="changepassword">
#await Html.PartialAsync("ChangePassword", new ChangePasswordViewModel())
</div>
and you need to include jquery unobtrusive ajax
in the Scripts section which should be in the index view not in the partial
#section Scripts {
#{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
<script src="~/path-to-jqueryajaxunobtrusive"></script>
}
In your ChangePassword view change like this:
#model ChangePasswordViewModel
<form asp-controller="Manage" asp-action="ChangePassword" method="post" class="form-horizontal"
data-ajax="true"
data-ajax-method="POST"
data-ajax-mode="replace"
data-ajax-update="#changepassword">
<p class="text-success">#ViewData["StatusMessage"]</p>
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="OldPassword" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="OldPassword" class="form-control" />
<span asp-validation-for="OldPassword" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="NewPassword" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="NewPassword" class="form-control" />
<span asp-validation-for="NewPassword" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="ConfirmPassword" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="ConfirmPassword" class="form-control" />
<span asp-validation-for="ConfirmPassword" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default">Change password</button>
</div>
</div>
by including the jquery unobtrusive ajax script and adding the data-* attributes as shown that should wire up the form to do an ajax post and the result should update the contents of the div with the id indicated