I have this issue, have search a lot but with now correct answer.
I have a contact form in the footer, on my _Layout page, but when I clicked the button the partial view is open in a new page.
I have remember to include the jquery.unobtrusive-ajax.js. Here is what I have.
Controller :
[HttpGet]
public ActionResult Call()
{
return PartialView("_PartialFooter");
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Call(CallMe callMe)
{
if(ModelState.IsValid)
{
}
return PartialView("_PartialFooter");
}
_Layout the scripts is above the Body tag in the bottom
#using (Ajax.BeginForm("Call", "Home", new AjaxOptions { UpdateTargetId = "result" }))
{
<div id="result" class="margin-bottom-5">
#Html.Action("Call", "Home")
</div>
<button class="btn btn-common-small margin-bottom-10 pull-right" type="submit">Send</button>
}
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#Scripts.Render("~/bundles/myscripts")
#RenderSection("scripts", required: false)
#section Scripts {
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
}
_PartialFooter (the partial view)
#model servicemadsen.Models.CallMe
#Html.AntiForgeryToken()
<div class="row">
<div id="result" class="margin-bottom-5">
<div class="col-md-6">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control", #placeholder = "Navn" } })
</div>
<div class="col-md-6">
#Html.EditorFor(model => model.Phone, new { htmlAttributes = new { #class = "form-control", #placeholder = "Telefon" } })
</div>
<div class="col-md-12">
#Html.TextAreaFor(model => model.CallMeMessage, new { #class = "form-control", #placeholder = "Besked", #cols = 80, #rows = 7 })
</div>
<div class="col-md-12">
#Html.ValidationMessageFor(model => model.Name, string.Empty, new { #class = "field-validation-error" })
#Html.ValidationMessageFor(model => model.Phone, string.Empty, new { #class = "field-validation-error" })
#Html.ValidationMessageFor(model => model.CallMeMessage, string.Empty, new { #class = "field-validation-error" })
</div>
</div>
</div>
Hope someone could help, its probaly some dummy thing that I need
have you installed the microsoft jquery unobstrusive ajax? if not try with that. i do some tests with your code and works.
EDIT : i also change some code for the tests
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Call(CallMe callMe)
{
if (ModelState.IsValid)
{
ModelState.Clear();
callMe.CallMeMessage = callMe.CallMeMessage + " i was on the server";
}
return PartialView("_PartialFooter", callMe);
}
and
#using (Ajax.BeginForm("Call", "Home", new AjaxOptions { UpdateTargetId = "result", InsertionMode = InsertionMode.Replace}))
{
<div id="result" class="margin-bottom-5">
#Html.Action("Call", "Home")
</div>
<button class="btn btn-common-small margin-bottom-10 pull-right" type="submit">Send</button>
}
so you can see the changes.
Related
i am bit new in asp.net mvc. i am facing problem for very basic things that my Partial view not rendering. here is the details
i have a main page and one partial view
main page action look like
public ActionResult Index()
{
return View();
}
main index view look like
#model Testing.Models.Employee
#{
ViewBag.Title = "Home Page";
}
<div class="row">
</div>
<div class="row">
<div id="formsIndex">
#{
Html.Partial("_TestForm");
}
</div>
</div>
#section scripts {
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
}
here i am showing a partial view like this way Html.Partial("_TestForm"); but no UI comes for partial view.
partial view code look like
#model Testing.Models.Employee
#using (Ajax.BeginForm("Index", "Home", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "formsIndex" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.City, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.City, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.City, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Address, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Address, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Address, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</div>
</div>
}
when i pass model to partial view this way Html.Partial("_TestForm", Model); then also no UI comes.
please tell me where i made the mistake ?
use in method return PartialView() and try this
#Html.Partial("_TestForm");
Using Html.Partial inside a #{ ... } block will just call the method and throw the result away.
You should call it outside of a #{ ... } block, prefixed with #, and remember to pass in the model:
<div id="formsIndex">
#Html.Partial("_TestForm", Model);
</div>
Render like this
#Html.Action("_Partialview", "controllerName")
also create action methode of partial view
public ActionResult _Partialview
{
Employee _objModel= new Employee ()
return PartialView(_objModel);
}
In my view, I have an image element as follows:
<img id="ImageDisplay" class="img-thumbnail" width="280" height="280"
src="#Url.Action("GetFileFromHttpPostedFile", "Image", new { File = Model.File })"/>
When I debug my code, I can see that my Model.File is not null. But when I pass it to the action method, the action method receives the parameter as null. Here is my action method:
public FileContentResult GetFileFromHttpPostedFile(HttpPostedFileBase File)
{
byte[] imageData = new byte[File.ContentLength];
File.InputStream.Read(imageData, 0, File.ContentLength);
return GetFileFromData(imageData, File.ContentType);
}
Am I missing something? Can we not pass an HttpPostedFileBase to a method? Help please.
Edit:
I also have the following element in the view that allows the user to populate Model.File property:
<input type="file" name="File" id="File" onchange="loadFile(event)" />
loadFile(event) simply shows a preview of the picture on the view.
Edit 2: Here is the full code for the view:
#model MyProject.Models.ViewModels.ChangeProfileModel
#{
ViewBag.Title = "Change Your Profile";
}
<script>
$(document).ready(function () {
$('textarea').keyup(updateCount);
$('textarea').keydown(updateCount);
function updateCount() {
var cs = [500 - $(this).val().length];
$('#characters').text(cs);
}
});
var loadFile = function (event) {
var output = document.getElementById('ImageDisplay');
if (output != null) {
output.src = URL.createObjectURL(event.target.files[0]);
}
};
</script>
<h2>Change Your Profile Info</h2>
#using (Html.BeginForm("ChangeProfile", "Account", FormMethod.Post, new { #class = "form-horizontal", role = "form", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
if (ViewBag.ChangesSaved == true)
{
<div class="alert alert-success">
Your changes have been saved successfully!
×
</div>
}
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.City, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.City, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.City, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Country, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Country, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Country, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2">Select an Image </label>
<div class="col-md-10">
<input type="file" name="File" id="File" onchange="loadFile(event)" />
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2"></label>
<div class="col-md-10">
#if (Model.File == null)
{
<img id="ImageDisplay" class="img-thumbnail" width="280" height="280"
src="#Url.Action("GetImageByUser", "Image", new { id = Model.Id })"/>
}
else
{
<img id="ImageDisplay" class="img-thumbnail" width="280" height="280"
src="#Url.Action("GetFileFromHttpPostedFile", "Image", new { File = Model.File })"/>
}
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.About, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextAreaFor(m => m.About, new { #class = "form-control", #rows = "5", #maxlength = 500 })
<span id="characters" style="color:#999;">500</span> <span style="color:#999;">characters left</span>
#Html.ValidationMessageFor(model => model.About, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
#Html.ActionLink("Cancel", "Index", "Manage", null, new { #class = "btn btn-default" })
</div>
</div>
</div>
}
In my HomeController, I have the following methods:
public ActionResult ChangeProfile()
{
var userId = User.Identity.GetUserId();
var loggedInUser = UserManager.FindById(userId);
ChangeProfileModel viewModel = new ChangeProfileModel
{
Id = userId,
City = loggedInUser.City,
Country = loggedInUser.Country,
About = loggedInUser.About
};
return View(viewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ChangeProfile(ChangeProfileModel viewModel)
{
if (!ModelState.IsValid)
{
return View(viewModel);
}
var userId = User.Identity.GetUserId();
var loggedInUser = UserManager.FindById(userId);
byte[] imageData = null;
if (viewModel.File != null)
{
imageData = new byte[viewModel.File.ContentLength];
viewModel.File.InputStream.Read(imageData, 0, viewModel.File.ContentLength);
}
_aspNetUserRepository.EditUserInfo(userId, viewModel.City, viewModel.Country, viewModel.About,
imageData, (viewModel.File == null) ? null: viewModel.File.ContentType);
ViewBag.ChangesSaved = true;
return View(viewModel);
}
Lastly, here is my last relevant action method inside ImageController:
public FileContentResult GetFileFromHttpPostedFile(HttpPostedFileBase File)
{
byte[] imageData = new byte[File.ContentLength];
File.InputStream.Read(imageData, 0, File.ContentLength);
return GetFileFromData(imageData, File.ContentType);
}
my controller
public ActionResult Create()
{
return PartialView();
}
//
// POST: /User/Create
[HttpPost]
public ActionResult Create(User user)
{
if (ModelState.IsValid)
{
db.User.Add(user);
db.SaveChanges();
TempData["Message"] = "Data has been saved successfully!";
return RedirectToAction("Index");
}
return View(user);
}
my view
<div class="row">
#Html.ActionLink("Create New", "Create", null, new { #class = "modal-with-form btn btn-default", href = "#modalForm" })
<!-- Modal Form -->
<div id="modalForm" class="modal-block modal-block-primary mfp-hide">
#Html.Partial("Create", new jQuery_CRUD.DAL.User())
</div>
</div>
my partial view
#using (Ajax.BeginForm("Create", "User", null, new AjaxOptions { UpdateTargetId = "modalForm", InsertionMode = InsertionMode.Replace }))
{
<section class="panel">
<header class="panel-heading">
<h2 class="panel-title">Create</h2>
</header>
<div class="panel-body">
<div class="form-group mt-lg">
#Html.LabelFor(model => model.Name, new { #class = "col-sm-3 control-label" })
<div class="col-sm-9">
#Html.TextBoxFor(model => model.Name, new { name = "name", #class = "form-control", placeholder = "Type your name..."})
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Address, new { #class = "col-sm-3 control-label" })
<div class="col-sm-9">
#Html.TextBoxFor(model => model.Address, new { name = "address", #class = "form-control", placeholder = "Type your Address..." })
#Html.ValidationMessageFor(model => model.Address)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ContactNo, new { #class = "col-sm-3 control-label" })
<div class="col-sm-9">
#Html.TextBoxFor(model => model.ContactNo, new { name = "contactno", #class = "form-control", placeholder = "Type your Contact No..." })
#Html.ValidationMessageFor(model => model.ContactNo)
</div>
</div>
</div>
<footer class="panel-footer">
<div class="row">
<div class="col-md-12 text-right">
<input type="submit" value="Create" class="btn btn-primary" />
<button class="btn btn-default modal-dismiss" id="btnCancel">Cancel</button>
</div>
</div>
</footer>
</section>
}
when i click the button , modal pops up,upon validation fail on post action, the view returns to full view. where could be the problem????..
i'm new to mvc help me with this..
Add in the beginning of your partial view
{
Layout = null;
}
And return partialView in Validation Error not View
[HttpPost]
public ActionResult Create(User user)
{
if (ModelState.IsValid)
{
db.User.Add(user);
db.SaveChanges();
TempData["Message"] = "Data has been saved successfully!";
return RedirectToAction("Index");
}
return PartialView(user);
}
So I am using jQuery Time picker plugin from here. When I pick the time in my view (ex: 11:48 PM) and submit it in debug mode, I don't see the value being passed to the controller. It is always a null value. I assume that I have problem in my code here, but can't figure it out. Any help is appreciated.
#Html.EditorFor(model => model.MonStart, new { htmlAttributes = new { #class = "form-control time_element", #name = "timepicker", #id = "monStart" } })
Model:
public string MonStart { get; set; }
View:
#model test.Models.Employee
#using Microsoft.AspNet.Identity
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.MonStart, "Monday: ", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.MonStart, new { htmlAttributes = new { #class = "form-control time_element", #name = "timepicker", #id = "monStart" } })
#Html.ValidationMessageFor(model => model.MonStart, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default"/>
</div>
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script src="#Url.Content("~/Scripts/timepicki.js")" type="text/javascript"></script>
<link href="#Url.Content("~/Content/timepicki.css")" rel="stylesheet" type="text/css" />
<script type="text/javascript">
$(document).ready(function () {
$("#monStart").timepicki();
});
</script>
}
I need to get the selected dropdown value from partial view and included in the CategoryID in the Book class...
[Authorize]
public PartialViewResult GetAllCategory()
{
ProcessSVC.Category newCategory = new ProcessSVC.Category();
newCategory.ChildCategories = obj1.GetAllCategories(String.Empty);
return PartialView(newCategory);
}
GetAllCategory.cshtml (PartialView)
#model MvcAdminTemplate.ProcessSVC.Category
#Html.DropDownListFor(m => m.ParentID, new SelectList(Model.ChildCategories, "ID", "DisplayName"), new { #class = "form-control" })
Create View:
[Authorize]
[HttpPost]
public ActionResult Create()
{
MvcAdminTemplate.ProcessSVC.Book oBook = new ProcessSVC.Book();
return View(oBook);
}
Create.cshtml
#model MvcAdminTemplate.ProcessSVC.Book
#{
ViewBag.Title = "Create";
}
#Html.Partial("_LeftMenu")
<!-- content -->
<h2>Create</h2>
<div class="col-md-10">
#using (Html.BeginForm("Create", "Books", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="row">
<div class="bootstrap-admin-no-table-panel-content bootstrap-admin-panel-content collapse in">
<form class="form-horizontal">
<fieldset>
<legend>Add Book</legend>
<div class="form-group">
<div class="col-lg-2">
#Html.LabelFor(m => m.BookName, new { #class = "control-label" })
</div>
<div class="col-lg-10">
#Html.TextBoxFor(m => m.BookName, new { #class = "form-control", type = "text" })
<p class="help-block"> </p>
</div>
</div>
<div class="form-group">
<div class="col-lg-2">
#Html.LabelFor(m => m.Description, new { #class = " control-label" })
</div>
<div class="col-lg-10">
#Html.TextBoxFor(m => m.Description, new { #class = "form-control ", type = "text" })
<p class="help-block"> </p>
</div>
</div>
<div class="form-group divCategory">
<div class="col-lg-2">
#Html.Label("Parent Category", new { #class = " control-label" })
</div>
<div class="col-lg-10">
#Html.HiddenFor(m => m.BookId, new { #class = "hdn-id" })
#Html.Action("GetAllCategory","Books")
<span class="help-block"> </span>
</div>
<button type="submit" class="btn btn-primary">Save changes</button>
<button type="reset" class="btn btn-default">Cancel</button>
</div>
</fieldset>
</form>
</div>
</div>
}
After submission of the above form i need to get Book attributes and Category "Selected Category".
[Authorize]
[HttpPost]
public ActionResult Create(ProcessSVC.Book oBook)
{
oBook.LanguageID = 1;
_service.AddBooks(oBook.ActualPrice,oBook.ActualPriceString, oBook.Author, oBook.BookId, oBook.BookName, oBook.CategoryID, oBook.Currency, oBook.CurrentPrice, oBook.CurrentPriceString,
oBook.Description, oBook.DiscountPercentage, oBook.DiscountValue, oBook.LanguageID,
oBook.NativeLanguageName, oBook.Publisher);
TempData.Add("SuccessMessage", " New book " + oBook.BookName + " Added !");
return RedirectToAction("Index");
}
Please suggest me.
To correctly bind your model, you need to create the dropdown in the main view. This line in you partial view
#Html.DropDownListFor(m => m.ParentID, ....
will render a select
<select name="ParentID" ...
but you model is expecting a property named CategoryID
In you Create() method, generate the SelectList and assign to a view model property or to ViewBag and then (instead or #Html.Action("GetAllCategory","Books") use
#Html.DropDownListFor(m => m.CategoryID, ....
use this line in your GetAllCategory.cshtml file
#Html.DropDownList("CategoryID", new SelectList(Model.ChildCategories, "ID", "DisplayName"), new { #class = "form-control" })