ASP.NET MVC3: Ajax postback doesnot post complete data from the view - asp.net-mvc-3

Hi Greetings for the day!
(1) The view model (MyViewModel.cs) which is bound to the view is as below...
public class MyViewModel
{
public int ParentId { get; set; } //property1
List<Item> ItemList {get; set;} //property2
public MyViewModel() //Constructor
{
ItemList=new List<Item>(); //creating an empty list of items
}
}
(2) I am calling an action method through ajax postback (from MyView.cshtml view) as below..
function AddItem() {
var form = $('#MyForm');
var serializedform = form.serialize();
$.ajax({
type: 'POST',
url: '#Url.Content("~/MyArea/MyController/AddItem")',
cache: false,
data: serializedform,
success: function (html) {$('#MyForm').html(html);}
});
}
The below button click will call the ajax postback...
<input type="button" value="Add" class="Previousbtn" onclick="AddItem()" />
(3) I have an action method in the (MyController.cs controller) as below...
public ActionResult AddItem(MyViewModel ViewModel)
{
ViewModel.ItemList.Add(new Item());
return View("MyView", ViewModel);
}
Now the issue is, after returning from the action, there is no data in the viewmodel. But i am able to get the data on third postback !! Can you pls suggest the solution..
The complete form code in the view is below...
#model MyViewModel
<script type="text/javascript" language="javascript">
function AddItem() {
var form = $('#MyForm');
var serializedform = form.serialize();
$.ajax({
type: 'POST',
url: '#Url.Content("~/MyArea/MyController/AddItem")',
cache: false,
data: serializedform,
success: function (html) {
$('#MyForm').html(html);
}
});
}
function RemoveItem() {
var form = $('#MyForm');
var serializedform = form.serialize();
$.ajax({
type: 'POST',
url: '#Url.Content("~/MyArea/MyController/RemoveItem")',
cache: false,
data: serializedform,
success: function (html) {
$('#MyForm').html(html);
}
});
}
function SaveItems() {
var form = $('#MyForm');
var serializedform = forModel.serialize();
$.ajax({
type: 'POST',
url: '#Url.Content("~/MyArea/MyController/SaveItems")',
cache: false,
data: serializedform,
success: function (html) {
$('#MyForm').html(html);
}
});
}
</script>
#using (Html.BeginForm("SaveItems", "MyController", FormMethod.Post, new { id = "MyForm" }))
{
#Html.HiddenFor(m => Model.ParentId)
<div>
<input type="button" value="Save" onclick="SaveItems()" />
</div>
<div>
<table>
<tr>
<td style="width: 48%;">
<div style="height: 500px; width: 100%; overflow: auto">
<table>
<thead>
<tr>
<th style="width: 80%;">
Item
</th>
<th style="width: 10%">
Select
</th>
</tr>
</thead>
#for (int i = 0; i < Model.ItemList.Count; i++)
{
#Html.HiddenFor(m => Model.ItemList[i].ItemId)
#Html.HiddenFor(m => Model.ItemList[i].ItemName)
<tr>
#if (Model.ItemList[i].ItemId > 0)
{
<td style="width: 80%; background-color:gray;">
#Html.DisplayFor(m => Model.ItemList[i].ItemName)
</td>
<td style="width: 10%; background-color:gray;">
<img src="#Url.Content("~/Images/tick.png")" alt="Added"/>
#Html.HiddenFor(m => Model.ItemList[i].IsSelected)
</td>
}
else
{
<td style="width: 80%;">
#Html.DisplayFor(m => Model.ItemList[i].ItemName)
</td>
<td style="width: 10%">
#if ((Model.ItemList[i].IsSelected != null) && (Model.ItemList[i].IsSelected != false))
{
<img src="#Url.Content("~/Images/tick.png")" alt="Added"/>
}
else
{
#Html.CheckBoxFor(m => Model.ItemList[i].IsSelected, new { #style = "cursor:pointer" })
}
</td>
}
</tr>
}
</table>
</div>
</td>
<td style="width: 4%; vertical-align: middle">
<input type="button" value="Add" onclick="AddItem()" />
<input type="button" value="Remove" onclick="RemoveItem()" />
</td>
</tr>
</table>
</div>
}

You must return PartialViewResult and then you can do something like
$.post('/controller/GetMyPartial',function(html){
$('elem').html(html);});
[HttpPost]
public PartialViewResult GetMyPartial(string id
{
return PartialView('view.cshtml',Model);
}

In my project i get state data with country id using json like this
in my view
<script type="text/javascript">
function cascadingdropdown() {
var countryID = $('#countryID').val();
$.ajax({
url: "/City/State",
dataType: 'json',
data: { countryId: countryID },
success: function (data) {
alert(data);
$("#stateID").empty();
$("#stateID").append("<option value='0'>--Select State--</option>");
$.each(data, function (index, optiondata) {
alert(optiondata.StateName);
$("#stateID").append("<option value='" + optiondata.ID + "'>" + optiondata.StateName + "</option>");
});
},
error: function () {
alert('Faild To Retrieve states.');
}
});
}
</script>
in my controller return data in json format
public JsonResult State(int countryId)
{
var stateList = CityRepository.GetList(countryId);
return Json(stateList, JsonRequestBehavior.AllowGet);
}
i think this will help you ....

I resolved the issue as below...
Issue:
The form code i have shown here is actually part of another view page
which also contains a form. So, when i saw the page source at
run-time, there are two form tags: one inside the other, and the
browser has ignored the inner form tag.
Solution:
In the parent view page, earlier i had used Html.Partial to render
this view by passing the model to it.
#using(Html.BeginForm())
{
---
---
#Html.Partial('/MyArea/Views/MyView',MyViewModel)
---
---
}
But now, i added a div with no content. On click of a button, i'm
calling an action method (through ajax postback) which then renders
the above shown view page (MyView.cshmtl) into this empty div.
#using(Html.BeginForm())
{
---
---
<div id="divMyView" style="display:none"></div>
---
---
}
That action returns a separate view which is loaded into the above
div. Since it is a separate view with its own form tag, i'm able to
send and receive data on each postback.
Thank you all for your suggestions on this :)

Related

Ajax loaded submit form not working

I am using Ajax to replace a part of my page with a partial view containing multiple submit forms. This normally works when I use a normal Html.BeginForm and reload the entire page (the submit forms loaded work). However, when using Ajax to load the submit form, they display normally on the page but are not working.
I have looked around for information, but the information I have found mainly concerns submitting form through Ajax call, not loading submit forms.
This is the main View containing the javascript.
#model List<SrrManager.Models.User>
#{
ViewBag.Title = "Create";
}
<script>
$(function () {
$('Body').keypress(function (e) {
if (e.which == 13) {
$('#nomButton').trigger('click');
}
});
$('#nomButton').keyup(function (e) {
if (e.which == 13) {
$('#nomButton').trigger('click');
}
});/*
$('#prenomButton').keypress(function (e) {
if (e.which == 13) {
$('#nomButton').trigger('click');
}
});*/
$("#nomButton").on('click', function () {
var givenName = $("#prenomBox").val();
var nom = $("#nomBox").val();
$.ajax({
url: '#Url.Action("Create", "ManageUser")', //+ "?firstname=" + givenName + "&lastname=" + lastname,
type: 'GET',
data: { prenom: givenName, nomFamille: nom },
success: function (result) {
$('#liste-user').replaceWith(result);
}
});
});
});
</script>
<body>
<h2>Add an user</h2>
<p>
<label class="label-form">Prenom :</label>#Html.TextBox("prenomBox")
<br />
<label class="label-form">Nom :</label> #Html.TextBox("nomBox")
<br />
<input type="button" value="Filter" id="nomButton" />
</p>
#Html.Partial("_Create", Model)
<div>
#Html.ActionLink("Back to List", "Index")
</div>
</body>
The _Create PartialView is as follow :
#model List<SrrManager.Models.User>
<div id="liste-user">
<table>
<tr>
<th>
First Name
</th>
<th>
Last Name
</th>
<th>
Email
</th>
<th>
Admin
</th>
<th></th>
</tr>
#foreach(var item in Model)
{
<tr>
<td>
#item.Name
</td>
<td>
#item.LastName
</td>
<td>
#item.email
</td>
#Html.Partial("__create", item)
</tr>
}
</table>
</div>
The last PartialView is used to create the submit form. The model is not a List but only User, and it is included once in each loop :
#model SrrManager.Models.User
#using(Html.BeginForm()){
<fieldset>
<legend>User</legend>
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#Html.HiddenFor(x => x.Name)
#Html.HiddenFor(x => x.LastName)
#Html.HiddenFor(x => x.email)
#Html.HiddenFor(x => x.account)
<td>
#Html.EditorFor(x => x.IsAdmin)
</td>
<td>
<input type="submit" value="save" />
</td>
</fieldset>
}
The list of user and the submit form is displayed normally using Ajax call or synchronous JQuery call when clicking on the Filter button, and the controller method is called as intended. However, the buttons work when loaded with synchronous JQuery calls, but not when loaded through Ajax.
The controller method is :
public ActionResult Create(string prenom ="", string nomFamille ="")
{
List<User> listeUser = new List<User>();
if (prenom.Equals("") && nomFamille.Equals(""))
{
}
else if (prenom.Equals(""))
{
string search = "*" + nomFamille + "*";
listeUser = SearchDirectory(search, 1);
}
else if (nomFamille.Equals(""))
{
string search = "*" + prenom + "*";
listeUser = SearchDirectory(search, 2);
}
else
{
string search = "*" + prenom + "*" + nomFamille + "*";
listeUser = SearchDirectory(search, 3);
}
if (Request.IsAjaxRequest())
{
return PartialView("_Create", listeUser);
}
return View(listeUser);
}
I am a beginner using Ajax, and I am at lost as to why it does not work. If any one has any lead, it would be very appreciated.
Try adding a jQuery handler for form submits.
$('form').submit(function () {
var givenName = $("#prenomBox").val();
var nom = $("#nomBox").val();
$.ajax({
url: '#Url.Action("Create", "ManageUser")', //+ "?firstname=" + givenName + "&lastname=" + lastname,
type: 'GET',
data: { prenom: givenName, nomFamille: nom },
success: function (result) {
$('#liste-user').html(result);
}
});
});

update model with ajax in razor

i write this code with ajax to delete some info after that i update my updateAjax div with ajax for refreshing content and this view have masterpage.in picture u see what happen.
this is my code
#using Common.UsersManagement.Entities;
#model IEnumerable<VwUser>
#{
Layout = "~/Views/Shared/Master.cshtml";
}
<form id="userForm">
<div id="updateAjax">
#if (string.IsNullOrWhiteSpace(ViewBag.MessageResult) == false)
{
<div class="#ViewBag.cssClass">
#Html.Label(ViewBag.MessageResult as string)
</div>
<br />
}
<table class="table" cellspacing="0">
#foreach (VwUser Item in Model)
{
<tr class="#(Item.IsActive ? "tRow" : "Disable-tRow")">
<td class="tbody">
<input type="checkbox" id="#Item.Id" name="selected" value="#Item.FullName"/></td>
<td class="tbody">#Item.FullName</td>
<td class="tbody">#Item.Post</td>
<td class="tbody">#Item.Education</td>
</tr>
}
</table>
</div>
<br />
<br />
<div class="btnContainer">
delete
<br />
<br />
</div>
<script>
$(function () {
// function for delet info and update #updateAjax div
$("#DeleteUser").click(function (event) {
var list = [];
$('#userForm input:checked').each(function () {
list.push(this.id);
});
$.ajax({
url: '#Url.Action("DeleteUser", "UserManagement")',
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: "html",
traditional: true,
data: JSON.stringify(list),
success: function (data, textStatus, jqXHR) {
$('#updateAjax').html(data);
// window.location.reload()
},
error: function (data) {
//$('#updateAjax').html(data);
window.location.reload()
}
}); //end ajax
});});
</script>
</form>
this my controller code
public ActionResult View1()
{
ViewBag.PageTittle = "user list";
ViewBag.FormTittle = "user list";
SetUserManagement();
var Result = userManagement.SearchUsers(null);
if (Result.Mode == Common.Extensions.ActionResultMode.Successfully)
{
return View(Result.Data);
}
else
{
return View(new VwUser());
}
}
public ActionResult DeleteUser(string[] userId)
{
SetUserManagement();
string message = "", CssClass = ""; ;
foreach (string item in userId)
{
//TODO:show Message
var Result = userManagement.DeleteUser(int.Parse(item));
if (Result.Mode != Common.Extensions.ActionResultMode.Successfully)
{
var messageResult = XmlReader.FindMessagekey(Result.Mode.ToString());
message += messageResult.MessageContent + "<br/>";
CssClass = messageResult.cssClass;
}
}
if (string.IsNullOrEmpty(message))
{
SetMessage(Common.Extensions.ActionResultMode.Successfully.ToString());
}
else
{
ViewBag.MessageResult = message;
ViewBag.cssClass = CssClass;
}
//
{
var Result = userManagement.SearchUsers(null);
if (Result.Mode == Common.Extensions.ActionResultMode.Successfully)
{
return View("~/Views/UserManagement/View1.cshtml", Result.Data);
}
else
{
return View("~/Views/UserManagement/View1.cshtml", new VwUser());
}
}
}
It looks to me that your view ViewUserList.cshtml is using a Layout that would either be set through Layout or through the _ViewStart.cshtml file. Make sure you're not using any of these.
For disabling the use of your Layout, you could take a look at this question. Or just set Layout = null

Passing Id from javascript to Controller in mvc3

How to pass Id from javascript to Controller action in mvc3 on ajax unobtrusive form submit
My script
<script type="text/javascript">
$(document).ready(function () {
$("#tblclick td[id]").each(function (i, elem) {
$(elem).click(function (e) {
var ID = this.id;
alert(ID);
// var url = '#Url.Action("Listpage2", "Home")';
var data = { Id: ID };
// $.post(url,data, function (result) {
// });
e.preventDefault();
$('form#myAjaxForm').submit();
});
});
});
</script>
the how to pass Id on using $('form#myAjaxForm').submit(); to controller
instead of
$.post(url,data, function (result) {
// });
My View
#using (Ajax.BeginForm("Listpage2", "", new AjaxOptions
{
UpdateTargetId = "showpage"
}, new { #id = "myAjaxForm" }))
{
<table id="tblclick">
#for (int i = 0; i < Model.names.Count; i++)
{
<tr>
<td id='#Model.names[i].Id'>
#Html.LabelFor(model => model.names[i].Name, Model.names[i].Name, new { #id = Model.names[i].Id })
<br />
</td>
</tr>
}
</table>
}
</td>
<td id="showpage">
</td>
I would avoid using the Ajax Beginform helper method and do some pure handwritten and Clean javascript like this
<table id="tblclick">
#foreach(var name in Model.names)
{
<tr>
<td id="#name.Id">
#Html.ActionLink(name.Name,"listpage","yourControllerName",
new { #id = name.Id },new { #class="ajaxShow"})
</td>
</tr>
}
</table>
<script>
$(function(){
$(".ajaxShow")click(function(e){
e.preventDefault();
$("#showpage").load($(this).attr("href"));
});
});
</script>
This will generate the markup of anchor tag in your for each loop like this.
<a href="/yourControllerName/listpage/12" class="ajaxShow" >John</a>
<a href="/yourControllerName/listpage/35" class="ajaxShow" >Mark</a>
And when user clicks on the link, it uses jQuery load function to load the response from thae listpage action method to the div with id showPage.
Assuming your listpage action method accepts an id parameter and returns something
I am not sure for $.post but I know window.location works great for me.
Use this instead and hopefully you have good results :)
window.location = "#(Url.Action("Listpage2", "Home"))" + "Id=" + ID;
replace $('form#myAjaxForm').submit(); with this code and nothing looks blatantly wrong with your jscript.
Just use a text box helper with html attribute ID.
#Html.TextBox("ID")
You can do this too:
var form = $('form#myAjaxForm');
$.ajax({
type: "post",
async: false,
url: form.attr("action"),
data: form.serialize(),
success: function (data) {
// do something if successful
}
});

partial view refresh using jQuery

On my main edit view I have 3 partial views that contain child data for the main view model. I also have html text boxes for entering and saving related data such as notes etc.
After an item is entered or select and passed to a controller action, how do I refresh my partial views? Here is the code I have so far but it does not work. I think I need to pass a model back with my partial view?
I am using ajax to call my controller method.
Partial View:
#model cummins_db.Models.CaseComplaint
<table width="100%">
<tr>
<td>
#Html.DisplayFor(modelItem => Model.ComplaintCode.ComplaintCodeName)
</td>
<td>
#Html.DisplayFor(modelItem => Model.ComplaintCode.ComplaintType)
</td>
</tr>
</table>
This is the html where the partial view is located:
<div class="editor-label">
#Html.Label("Search and select a complaint code")
</div>
<div class="textarea-field">
<input id = "CodeByNumber" type="text" />
</div>
#Html.ActionLink("Refresh", "Edit", new { id = Model.CasesID })
<table width="100%">
<tr>
<th>Complaint Code</th>
<th>Complaint Description</th>
</tr>
#try
{
foreach (var comp_item in Model.CaseComplaint)
{
<div id="complaintlist">
#Html.Partial("_CaseComplaintCodes", comp_item)
</div>
}
}
catch
{
}
</table>
Here is the controller method that returns the partial view.
public ActionResult SelectForCase(int caseid, int compid, string compname)
{
if (ModelState.IsValid)
{
CaseComplaint c = new CaseComplaint
{
CasesID = caseid,
ComplaintCodeID = compid
};
db.CaseComplaints.Add(c);
db.SaveChanges();
}
return PartialView("_CaseComplaintCodes");
}
jQuery ajax calling the controller, it is part of an autocomplete function select.
$('#CodeByNumber').autocomplete(
{
source: function (request, response) {
$.ajax({
url: "/Cases/CodeByNumber", type: "GET", dataType: "json",
data: { searchText: request.term, maxResults: 10 },
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data, function (item) {
return {
label: item.ComplaintType,
value: item.ComplaintCodeName,
id: item.ComplaintCodeID
}; //return
}) //map
); //response
} //success
}); //ajax
}, //source
select: function (event, ui) {
var url = "/Cases/SelectForCase";
$.ajax({
type: "GET",
dataType: "html",
url: url,
data: { caseid: $('#CaseID').val(), compid: ui.item.id, compname: ui.item.label },
success: function (result) { $('#complaintlist').html(result); }
});
},
minLength: 1
});
Should the partial view not be as below:
#model cummins_db.Models.CaseComplaint
<table width="100%">
<tr>
<td>
#Html.DisplayFor(m => m.ComplaintCodeName)
</td>
<td>
#Html.DisplayFor(m => m.ComplaintType)
</td>
</tr>
</table>
This is what I ended up doing to make it work. I changed by controller action to this:
public ActionResult SelectForCase(int caseid, int compid)
{
if (ModelState.IsValid)
{
CaseComplaint c = new CaseComplaint
{
CasesID = caseid,
ComplaintCodeID = compid
};
db.CaseComplaints.Add(c);
db.SaveChanges();
var m = from d in db.CaseComplaints
where d.CasesID == caseid
select d;
return PartialView("_CaseComplaintCodes", m);
}
return PartialView("_CaseComplaintCodes");
}
It works now

Using jQuery and ASP.NET MVC together. Ajax post is not working?

I have a form submit with an AJAX post. It works fine.
But when I delete the item by clicking the delete link, I have an issue, a get request not post.
But from my javascript function, you can see I use jQuery css selctor to detect the link clicked or not, so I am confused.
Here is my code
My controller:
public class SessionsController : Controller
{
private SessionRepository _repository;
public SessionsController() : this(new SessionRepository()) { }
public SessionsController(SessionRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
var sessions = _repository.FindAll();
//for ajax requests, we simply need to render the partial
if (Request.IsAjaxRequest())
return PartialView("_sessionList2", sessions);
//return View("_sessionList", sessions);
return View(sessions);
}
[HttpPost]
public ActionResult Add(Session session)
{
_repository.SaveSession(session);
if (Request.IsAjaxRequest())
return Index();
return RedirectToAction("index");
}
[HttpPost]
public ActionResult Remove(Guid session_id)
{
_repository.RemoveSession(session_id);
return RedirectToAction("index");
}
}
The session view:
#model IEnumerable<MyMVCDemo.Models.Session>
<h2>Hijax Technique</h2>
<div id="session-list">
#{Html.RenderPartial("_sessionList2");}
</div>
<p>
</p>
#using (Html.BeginForm("add", "sessions", FormMethod.Post, new { #class = "hijax" }))
{
<fieldset>
<legend>Propose new session</legend>
<label for="title">Title</label>
<input type="text" name="title" />
<label for="description">Description</label>
<textarea name="description" rows="3" cols="30"></textarea>
<label for="level">Level</label>
<select name="level">
<option selected="selected" value="100">100</option>
<option value="200">200</option>
<option value="300">300</option>
<option value="400">400</option>
</select>
<br />
<input type="submit" value="Add" />
<span id="indicator" style="display:none"><img src="../../content/load.gif" alt="loading..." /></span>
</fieldset>
}
<label>
<input type="checkbox" id="use_ajax" />
Use Ajax?
</label>
<script src="../../Scripts/Common.js" type="text/javascript"></script>
My Partial View:
#model IEnumerable<MyMVCDemo.Models.Session>
<table id="sessions">
<tr>
<th>Title</th>
<th>Description</th>
<th>Level</th>
<th></th>
</tr>
#if(Model.Count() == 0) {
<tr>
<td colspan="4" align="center">There are no sessions. Add one below!</td>
</tr>
}
#foreach (var session in Model)
{
<tr>
<td>#session.Title</td>
<td>#session.Description</td>
<td>session.Level</td>
<td>
#Html.ActionLink("remove", "remove", new { session_id = session.Id }, new { #class = "delete" })
</td>
</tr>
}
This is my javascript which call the ajax post:
$('.delete').click(function () {
if (confirm('Are you sure you want to delete this item?')) {
$.ajax({
url: this.href,
type: 'POST',
success: function (result) {
$("#session-list").html(result);
}
});
return false;
}
return false;
});
$("form.hijax").submit(function (event) {
if ($("#use_ajax")[0].checked == false)
return;
event.preventDefault(); //prevent the actual form post
hijack(this, update_sessions, "html");
});
function hijack(form, callback, format) {
$("#indicator").show();
$.ajax({
url: form.action,
type: form.method,
dataType: format,
data: $(form).serialize(),
completed: $("#indicator").hide(),
success: callback
});
}
function update_sessions(result) {
//clear the form
$("form.hijax")[0].reset();
//update the table with the resulting HTML from the server
$("#session-list").html(result);
$("#message").hide().html("session added")
.fadeIn('slow', function () {
var e = this;
setTimeout(function () { $(e).fadeOut('slow'); }, 2000);
});
}
It looks to me like you do not rebind the click event after you update the partial.
What happends is that you replace the DOM(which the events are bound to) when you make the ajax call. So after you update post the form all your events are gone.
In jquery there is a live event that would help you here.
The code below is not tested some there might be some problems with it but it should give you an idea.
var sessionList = $('#session-list');
$('.delete', sessionList).live('click', function () {
if (confirm('Are you sure you want to delete this item?')) {
$.ajax({
url: this.href,
type: 'POST',
success: function (result) {
sessionList.html(result);
}
});
return false;
}
return false;
});
The selector $('.delete', sessionList) is to give the live function a context so it doesn't bubble events all the way to the top.

Resources