Reputation: 594
I am new to MVC, I am trying to edit a row and sending edited data to a controller method via jQuery and AJAX, when I click on edit
the specific row becomes textboxes and save
ActionLink appears instead of edit
, but when I save it it gives me an exception because null is going in data
jQuery/Ajax Code:
$(document).ready(function () {
function toggleEditability() {
$(this).closest('tr')
.find('a.Edit, a.Save, .displayText, input[type=text]')
}
$('a.Edit').click(toggleEditability);
$('a.Save').click(function () {
toggleEditability.call(this);
var data = $(this).closest('tr').serialize();
alert(data);
//var url = $(this).attr('href');
var actionURL = '@Url.Action("Edit", "Holiday")';
$.ajax({
url: actionURL, // Url to send request to
data:data, // Send the data to the server
type: "POST", // Make it a POST request
dataType: "html", // Expect back HTML
success: function (html) {
$("#dialog-edit").dialog('open');
}
});
});
});
alert(data)
is showing this
chtml code:
<div id="details">
<table>
<tr>
@*<th>
@Html.Label("ID")
</th>*@
<th>
@Html.Label("Name")
</th>
<th>
@Html.Label("Description")
</th>
<th>
@Html.Label("Date")
</th>
<th></th>
</tr>
@foreach (var item in Model)
{
if (Convert.ToDateTime(item.Holiday_date).Year.ToString() == DateTime.Now.Year.ToString())
{
<tr>
@* <td>
@Html.TextBoxFor(modelItem => item.Holiday_Id, new { style = "display: none; width:170px; height:15px" })
<div class="displaytext">
@Html.DisplayFor(modelItem => item.Holiday_Id)
</div>
</td>*@
<td>
<div class="HolidayName">
@Html.TextBoxFor(modelItem => item.Holiday_Name, new { id = "", style = "display: none; width:170px; height:15px" })
</div>
<div class="displaytext">
@Html.DisplayFor(modelItem => item.Holiday_Name)
</div>
</td>
<td>
<div class="HolidayDescription">
@Html.TextBoxFor(modelItem => item.Holiday_Description, new { id = "", style = "display: none; width:170px; height:15px" })
</div>
<div class="displaytext">
@Html.DisplayFor(modelItem => item.Holiday_Description)
</div>
</td>
<td>
<div class="HolidayDate">
@Html.TextBoxFor(modelItem => item.Holiday_date, new { id = "", style = "display: none; width:170px; height:15px" })
</div>
<div class="displaytext">
@Html.DisplayFor(modelItem => item.Holiday_date)
</div>
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.Holiday_Id }, new { @class = "Edit", Href="#" })
@Html.ActionLink("Save", "Save", new { id = item.Holiday_Id}, new { @class = "Save", Href = "#", style = "display:none" } ) |
@Html.ActionLink("Delete", "Delete", new { id = item.Holiday_Id }, new { @class = "lnkDelete" })
@Html.ActionLink("Cancel", "Cancel", new { id = item.Holiday_Id}, new { @class = "Cancel", Href = "#", style = "display:none" } )
</td>
</tr>
}
}
</table>
</div>
Controller Method Code:
public ActionResult Edit(tbl_HolidayList tbl_holidaylist)
{
if (ModelState.IsValid)
{
db.Entry(tbl_holidaylist).State = EntityState.Modified;
db.SaveChanges();
TempData["Msg"] = "Data has been updated succeessfully";
return RedirectToAction("Index");
}
return PartialView(tbl_holidaylist);
}
tbl_HolidayList.cs
namespace OTESSystem.Models
{
using System;
using System.Collections.Generic;
public partial class tbl_HolidayList
{
public int Holiday_Id { get; set; }
public string Holiday_Name { get; set; }
public string Holiday_Description { get; set; }
public Nullable<System.DateTime> Holiday_date { get; set; }
}
}
Can you tell me how to get the textboxes values in data
for jQuery to save it?
exception and data coming null in method:
Upvotes: 2
Views: 4960
Reputation: 3237
You're getting null
for alert(data)
because you're trying to serialize the entire content of the closest tr
and it contains non-input controls as well. So try to serialize just the input controls like below
var data = $(this).closest('tr').find('input').serialize();
alert(data);
and your alert should return you the tr
data as shown below in the image.
If your AJAX posted model data returns null
at the Save
action then an alternate would be to build your data array from the serialized data object and take only what you would require something like below (all the below code within your $('a.Save').click(function () { ...
)
var dataArray = $(this).closest('tr').find('input').serialize();
dataObj = {};
// loop through and create your own data object
$(dataArray).each(function (i, field) {
dataObj[field.name] = field.value;
});
var data = {};
data.Holiday_Id = dataObj['item.Holiday_Id'];
data.Holiday_Name = dataObj['item.Holiday_Name'];
data.Holiday_Description = dataObj['item.Holiday_Description'];
data.Holiday_date = dataObj['item.Holiday_date'];
var actionURL = '@Url.Action("Save", "Holiday")';
$.ajax({
url: actionURL, // Url to send request to
data: JSON.stringify({ model: data }), // Send the data to the server
type: "POST", // Make it a POST request
dataType: "html", // Expect back HTML
contentType: 'application/json; charset=utf-8',
success: function (html) {
$("#dialog-edit").dialog('open');
}
});
And now you should see the posted data at the controller's Save
action.
UPDATE 1:
Based on the error noted in your comment it seems like your primary key is coming as null
to the controller's action method. You can add a hidden input field to the markup as shown below.
.....
<td>
@Html.DisplayFor(modelItem => item.Holiday_Id)
@Html.HiddenFor(modelItem => item.Holiday_Id);
</td>
....
Upvotes: 4
Reputation: 6849
Jquery serialize() won't serialize the value in which element name
attribute is not set. Make sure you have specified name attribute to all input element.
You have to specify name attribute too in your razor code.
@Html.TextBoxFor(modelItem => item.Holiday_Name,
new { id = "", name="HolidayName",
style = "display: none; width:170px; height:15px" })
According to JQuery documentation
Only "successful controls" are serialized to the string. No submit button value is serialized since the form was not submitted using a button. For a form element's value to be included in the serialized string, the element must have a name attribute. Values from checkboxes and radio buttons (inputs of type "radio" or "checkbox") are included only if they are checked. Data from file select elements is not serialized.
Checkout this fiddle
And one more thing you need to modify in your code is following line.
var data = $(this).closest('tr').find('input').serialize();
because only those element can be serialized which has name attribute and you have only input elements in your code.
Upvotes: 1
Reputation: 66
Try this, first modify your view to have some identifiers for the fields you need in the rows.
@Html.TextBoxFor(modelItem => item.Holiday_Id, new { @class = "holidayId"})
@Html.TextBoxFor(modelItem => item.Holiday_Name, new { @class = "holidayName" })
@Html.TextBoxFor(modelItem => item.Holiday_Description, new { @class = "holidayDescription" })
@Html.TextBoxFor(modelItem => item.Holiday_date, new { @class = "holidayDate" })
Then change your ajax calls data to be this:
var data = {};
data.Holiday_Id = $(this).closest('tr').find(".holidayId").val();
data.Holiday_Name = $(this).closest('tr').find(".holidayName").val();
data.Holiday_Description = $(this).closest('tr').find(".holidayDescription").val();
data.Holiday_Date = $(this).closest('tr').find(".holidayDate").val();
Test the alert, and if the alert has the data, then set a break point on your controllers action method and see if the parameter is coming through filled in.
Upvotes: 0
Reputation: 6423
since serialize isn't returning anything I would recommend you grab the fields you want instead of serializing the row. change
data = $(this).closest('tr').serialize();
to this in your ajax call
data: {
Holiday_id : $(this).closest('tr').find(".Holiday_id").val(),
Holiday_Name : $(this)...
},
Upvotes: 1
Reputation: 21430
Sounds like your public ActionResult Edit(tbl_HolidayList tbl_holidaylist)
method is supposed to be accepting JSON and returning it back.
Try something like this and walk through your code to see where you fail:
public JsonResult Edit(tbl_HolidayList model)
{
var hlist = db.tbl_holidaylists.Where(x => x.Id = model.Id).FirstOrDefault();
hlist = model; // something like this to overwrite the existing values...
db.SaveChanges();
return Json(hlist);
}
Lastly, change your AJAX success callback to see what you get back like so:
success: function (html) {
console.log(html);
}
Upvotes: 0