MVC Updating Partial View with Ajax.BeginForm - ajax

The Ajax form does update selected div, but instead of just reloading a partial view in that div it inserts the whole page content into that div.
.cshtml file
<fieldset>
<legend>File(s)</legend>
<div id="filesBody">
#Html.Action("Action", "Controller", new {id=Model.Id})
</div>
<br />
#using (Ajax.BeginForm("UploadFile", "Controller", null, new AjaxOptions { UpdateTargetId="filesBody"}, new { enctype = "multipart/form-data", #id = "myForm" }))
{
#Html.HiddenFor(model => model.ComplaintId)
<div>
<label for="File">Add File:</label>
<input type="file" name="FileAttachment" />
<input type="submit" value="Upload" />
#Html.ValidationMessage("FileAttachment")
</div>
}
</fieldset>
Controller
public PartialViewResult GetFilesData(long? Id)
{
Model Model = new Model(Id);
TryUpdateModel(Model);
return PartialView(Model);
}
Partial view
#model Models
<div id="reloadField">
#foreach (var ph in Model.docs)
{
///code
}
</div>

In your partial view set the Layout equal to null.
#model Models
#{
Layout = null;
}
UPDATE
Change your Ajax.BeginForm to call the GetFilesData action.

Related

HttpPost not getting triggered

I have a website where I need to redirect the users according to their role. On button click, if the user is admin, redirect to another page; else reload the same page. On button click, the index page is loaded no matter who logs in. On debugging I found out, the [HttpPost] attribute is not triggered at all.
View:
#model namespace.ViewModels.LoginVM
#{
ViewBag.Title = "Login";
}
<h1>User Login</h1>
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
<br />
<div style="background-color: skyblue; width: 50%">
<div style="padding-left: 1em">
<div class="display-label" style="font-size: large">
Enter User Info<br />
<br />
</div>
<div>
<div class="editor-label">#Html.LabelFor(model => model.empID)</div>
<div class="editor-field">#Html.TextBoxFor(model => model.empID)
#Html.ValidationMessageFor(model => model.empID)
</div>
<br />
</div>
<br />
<div>
<input id="submit" type="submit" value="Submit" />
</div>
</div>
</div>
<br />
}
Controller:
public class LoginController : Controller
{
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(LoginVM model)
{
MySQL msql = new MySQL();
var empID= model.empID
var role = msql.Select("Select `role` from empDB where `eID` = '" + empID + "'");
if(role == "admin")
{
return RedirectToAction("Index","Home");
}
else
{
return View();
}
}
}
Your HttpPost action method name is Login. But your razor view, you used Index!
Update your Html.BeginForm method call to have the correct action method name and controllername values. Then when you click on submit, it will post the form data to /Login/Login
#using (Html.BeginForm("Login", "Login", FormMethod.Post))
{
}

Passing Viewbag Data from View to Controller in ASP.Net MVC3 Razor

In my ASP.Net MVC3 Razor project i have to pass value from view to controller.The view contains one submit button that is used to pass selected image file and two other input data.This two input data is from a controller named "FileUpload"(ViewBag.Data1 = CusId;ViewBag.Data2 = Name;).When submitting the button i have to pass these three (Image,CusId,Name) to another controller to upload the image file.
Controller Code
public ActionResult FileUpload(int CusId, string Name)
{
ViewBag.Data1 = CusId;
ViewBag.Data2 = Name;
return View();
}
[HttpPost]
public ActionResult UploadPhoto(ElixiCustPro elixi, HttpPostedFileBase file)
{
//return null;
try
{
if (file != null && file.ContentLength > 0)
{
if ((file.ContentType == "image/jpeg") || (file.ContentType == "image/gif") || (file.ContentType == "image/png"))//check allow jpg, gif, png
{
elixi.Image = new byte[file.ContentLength];
file.InputStream.Read(elixi.Image, 0, file.ContentLength);
var filename = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/ElixirFiles/UploadImagesElixir/"), filename);
file.SaveAs(path);
ecp.Image = new byte[file.ContentLength];
ecp.ImageUrl = path;
ment.ElixiProData.Add(ecp);
ment.SaveChanges();
return RedirectToAction("ImageResult");
}
}
}
catch (Exception ex)
{
return View(ex.Message.ToString());
}
return View();
}
View Code
#using (Html.BeginForm("UploadPhoto", "Home", FormMethod.Post, new { #enctype = "multipart/form-data" }))
{
#* <div class="form-group">
<label class="col-lg-2 control-label">
Customer ID</label>
<div class="col-lg-10">#Html.TextBoxFor(model => model.CusId, new { #class = "form-control" })</div>
<label class="col-lg-2 control-label">
Customer Name</label>
<div class="col-lg-10">#Html.TextBoxFor(model => model.Name, new { #class = "form-control" })</div>
</div>*#
<input type="hidden" id="id" />
<div class="col-md-6">
<div class="form-group">
<label class="col-lg-2 control-label">
DMIT Image</label>
<div class="col-lg-10">
#ViewBag.Data1
#ViewBag.Data2
<input type="file" id="file" name="file">
<input type="submit" class="btn btn-success" value="Upload" />
</div>
</div>
</div>
}
ViewBag can't pass data back to controller. You should post those values back inside the form. Easiest thing would be to not to use ViewBag and add the data to model type.
Then you can pass them with hidden inputs using HTML helpers like this:
#Html.HiddenFor(item => item.CustomerId)
#Html.HiddenFor(item => item.ImageId)
If that's not possible, you can add the hidden inputs manually. Just keep in mind that the name attributes are important for model binding.
<input type="hidden" name="CustomerId" value="#ViewBag.Data1" />
Yes you cannot pass a Viewbag from view to controller.
But you can pass them using TempData.
Add this to your View.
#{TempData["Data1"]=ViewBag.Data1}
#{TempData["Data2"]=ViewBag.Data2}
But this TempData passes the information as an object.
So typecasting is necessary in your Controller.
int x=Convert.ToInt32(TempData["Data1"]);
string y=(TempData["Data2"]).ToString();
I tried,it is working.
or you can send TempData from Controller in get method,and use the same to pass from view to post method instead of Viewbag.

form post not working due to #HiddenFor in mvc3

for some reason, my form post does not work when i have the hidden field in mvc3 razor. It works fine if i remove the hidden field but i need that field.
Below are my ProductsController post method and razor view
#model CCSPurchasing_MVC.Models.AddNewProductModel
#using CCSPurchasing_MVC.Models
#using (Html.BeginForm("editImage", "Products", FormMethod.Post))
{
#Html.ValidationSummary(true)
#Html.HiddenFor(m => m.ImadeId)
<div class="editor-field">
<p style="margin-left: 300px; margin-right: 20px;">
#Html.LabelFor(m => m.ImageFile)
<input type="file" name="file" id="file" data-val="true" data-val-required="Product Image is required"/>
</p>
</div>
<input type="submit" value="Edit" />
}
[HttpPost]
public ActionResult editImage(AddNewProductModel newP, HttpPostedFileBase file)
{
db = new DBConnection();
if (file != null && file.ContentLength > 0)
{
newP.ImageName = Path.GetFileName(file.FileName);
newP.ImageType = file.ContentType;
newP.ImageSize = file.ContentLength;
newP.ImageFile = new byte[file.ContentLength];
file.InputStream.Read(newP.ImageFile, 0, file.ContentLength);
newP.ImageHeight = 200;
newP.ImageWidth = 200;
}
string result = db.editImage(newP);
return View("editImageUpdate");
}
Just make your form tag like this and I am sure it will work for you also as it worked for me when I tested your code:
#using (Html.BeginForm("EditImage", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
}
You need to add enctype = "multipart/form-data" also in your code if you want to submit the file with your fileupload control.

pass a value of the form from view to controller

how do i pass the value of the form, which is (i assume) a string of date to the controller...
here is my view:
<script type="text/javascript" language="javascript">
$(function () {
$(".datepicker").datepicker({ onSelect: function (dateText, inst) { $("FORM").submit(); },
altField: ".alternate"
});
});
</script>
#model IEnumerable<CorReservation.Models.Reservation>
#{
ViewBag.Title = "Index";
}
<div class="divRightSide">
<div>
<div class="datepicker">
</div>
<form action="/" title="fff">
<input type="text" class="alternate" readonly="readonly" />
</form>
</div>
// do something eg. foreach (var item in Model)
{ #Html.DisplayFor(modelItem => item.Date)}
here is my controller: i want to pass the date selected from the datepicker to the controller and then the controller would return an Ienumerable of reservations...
DateTime date = System.DateTime.Now;
private ReservationEntities db = new ReservationEntities();
public ViewResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(string dateInput)
{
date = Convert.ToDateTime(dateInput);
var reservations = db.Reservations.Where(r=> r.Date ==date).Include(r => r.Employee).Include(r => r.Room).OrderByDescending(r => r.Date);
return View(reservations);
}
There are 2 ways to do this. Make the form input name attribute match the expected attribute in your controller.
For example:
<input type="text" class="alternate" readonly="readonly" name="dateInput" />
Or if there's going to be a lot of input values, use a Model.
It's automatically done based on the 'name' attribute of the HTML fields you want to submit.
Change your form to
<form action="/" title="fff">
<input name="dateInput" type="text" class="alternate" readonly="readonly" />
</form>
And it should work just like that.
Also, as you are using Razor syntax, you could use the Razor HTML helpers like so
#model IEnumerable<CorReservation.Models.Reservation>
#{
ViewBag.Title = "Index";
}
<div class="divRightSide">
<div>
<div class="datepicker">
</div>
#using(#Html.BeginForm("<your controller name>", "<your action name e.g. Index>"){
Html.TextBox("dateInput", "", new { #readonly="readonly", #class="alternate" })
}
</div>
// do something eg. foreach (var item in Model)
{ #Html.DisplayFor(modelItem => item.Date)}

How i can submit multiple objects inside the form post values to be added

i have a create view to add answers to a question, currently the user can only add one answer at the same time when he clicks on the submit button, instead of this i want the user to be able to insert multiple answers objects into the same view and then the system to add all these new answer objects to the database after the user click on the submit button, my current view looks as the follow:-
#model Elearning.Models.Answer
#{
ViewBag.Title = "Create";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<div id = "remove">
#using (Ajax.BeginForm("Create", "Answer", new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "remove"
}))
{
<div id = "returnedquestion">
#Html.ValidationSummary(true)
<fieldset>
<legend>Answer</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
</fieldset>
<input type= "hidden" name = "questionid" value = #ViewBag.questionid>
<input type= "hidden" name = "assessmentid" value = #ViewBag.assessmentid>
<input type="submit" value="Add answer" />
</div>
}
</div>
and the action methods look as the follow:-
public ActionResult Create(int questionid)//, int assessmentid)
{
ViewBag.questionid = questionid;
Answer answer = new Answer();
return PartialView("_answer",answer);
}
//
// POST: /Answer/Create
[HttpPost]
public ActionResult Create(int questionid, Answer a)
{
if (ModelState.IsValid)
{
repository.AddAnswer(a);
repository.Save();
return PartialView("_details",a);
}
return View(a);}
so how i can modify the above code to be able to insert multiple answer objects at the same view and then submit these answers objects at the same time when the user click on the submit button?
Try Post a List
Add input by javascript when user click "Add Answer".
And when submit the form ,it will post all answer data to binding to List
<script>
$(document).ready(function () {
var anwserCount = 1;
$("#addbutton").click(function () {
$("#AnwsersDiv")
.append("<input type='text' name='Anwsers[" + anwserCount + "]'/>");
anwserCount += 1;
});
});
</script>
#using (Html.BeginForm())
{
<div id="AnwsersDiv">
<input type="text" name="Anwsers[0]" />
</div>
<input id="addbutton" type="button" value="Add answer" />
<input type="submit" value="submit" />
}
Model
public class Answer
{
public List<String> Anwsers { get; set; }
}
When submit the form
I think this is what you are looking for
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Conclusion: you should make the post action with ICollection<Answer> Parameter, then it will be easy to get them when you post your main form, and create the appropriate QUESTION object, then save them all with only one submit.

Resources