ASP.NET MVC 3 - Ajax update table - model - javascript

I am trying to update a record list with ajax, represented on a table, where each record as an javascript delete link. If I preload the table, the RemoveLink works fine, but once the div "RecordListPartialView" is updated via ajax, It no longer works.
I checked with firebug that the generated html code is correct for each row. It looks like the browser isn't aware of the new code and so it doesn't trigger the javascript links.
Can someone please explain me what is going on?
(1) Here is the View code:
$(".RemoveLink").click(function () {
var _id = $(this).attr("data-id");
var recordToDelete = { id: _id };
var json = $.toJSON(recordToDelete);
$.ajax({
url: '/MortagePayment/RemoveMortageRecord',
type: 'POST',
dataType: 'json',
data: json,
contentType: 'application/json; charset=utf-8',
success: function (data) {
$("#RecordListPartialView").empty();
$("#RecordListPartialView").html(data.Message);
}
});
});
$(".AddLink").click(function () {
var _year = $("#NewRecord_year").val();
var _month = $("#NewRecord_month").val();
var _mortageValue = $("#NewRecord_mortageValue").val();
var newRecord = { year: _year, month: _month, mortageValue: _mortageValue };
var json = $.toJSON(newRecord);
$.ajax({
url: '/MortagePayment/AddMortageRecord',
type: 'POST',
dataType: 'json',
data: json,
contentType: 'application/json; charset=utf-8',
success: function (data) {
$("#RecordListPartialView").empty();
$("#RecordListPartialView").html(data.Message);
$("#NewRecord_year").val(0);
$("#NewRecord_month").val(0);
$("#NewRecord_mortageValue").val(0);
}
});
});
<div id="RecordListPartialView">
#Html.Partial("MortageRecordList", Model.MortageRecordList)
</div>
(2) the Partial View
<table id="mortageRecordListTable">
<tr>
<th colspan=4>Current reductions</th>
</tr>
<tr>
<th>Year</th>
<th>Month</th>
<th>Value</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr id="row-#item.mortageRecordId">
<td>
#item.year
</td>
<td>
#item.month
</td>
<td>
#item.mortageValue
</td>
<td>
<p class="RemoveLink" data-id="#item.mortageRecordId">Remove</p>
</td>
</tr>
}
</table>
(3) and the Controller:
[HttpPost]
public ActionResult AddMortageRecord(MortageRecord newRecord) {
var mortageRecordSet = MortageRecordSet.GetMortageSet(this.HttpContext);
if (ModelState.IsValid)
mortageRecordSet.AddMortageRecord(newRecord);
string partialViewHtml = RenderPartialViewToString("MortageRecordList", mortageRecordSet.GetMortageItems());
return Json(new { Success = true, Message = partialViewHtml });
}
[HttpPost]
public JsonResult RemoveMortageRecord(int id) {
var mortageRecordSet = MortageRecordSet.GetMortageSet(this.HttpContext);
mortageRecordSet.RemoveMortageRecord(id);
string partialViewHtml = RenderPartialViewToString("MortageRecordList", mortageRecordSet.GetMortageItems());
return Json(new { Sucess = true, Message = partialViewHtml });
}

If I understand you correctly.
If I preload the table, the RemoveLink works fine, but once the div
"RecordListPartialView" is updated via ajax, It no longer works.
Change your your .click event with .live
$(".RemoveLink").live("click",function(){
//any click event code comes here
});

I think you might need to call the click handler again in order to reattach it to the new DOM elements, since jQuery iterates through all the elements with the correct class when you actually call the $(".RemoveLink").click() and $(".AddLink").click() functions, not lazily whenever something is clicked.

OK, do you have a jquery event in a separate .js script file and have attached an event to an element inside a PartialView?
well! if yes, whenever the PartialView renders itself again (no matter what is the reason) all of it's bound events will be gone! then you should rebind them again after rendering the PartialView.
there are different approaches, for example:
In the Ajax.ActionLink (or any ajax call that makes the
PartialView re-render ) set OnSuccess to a jquery function that
rebinds PartialView's events.
Move all of your jquery event bindings codes from separate .js
script file to the inside of your PartialView's file (cstml). in
this case every time PartialView has been rendered, those events
will be bound again.

Related

MVC - Use #Html.ActionLInk to fire Ajax to trigger ActionResult

I've done a lot of research on this. I can't find anything that really fits my situation. I'm a new programmer. I'm working on getting better with JavaScript but it's my weak spot.
I have two databases - employees and breaks. I attached a picture to make this make more sense:
The break list from the database is the list you see in the table in the image. The dispatcher dropdown contains all employee names. Drop the name down, hit submit - it adds to the database and displays here. Works great.
Now I'm trying to use #Html.ActionLink to make the names clickable. That needs to fire another JavaScript event to enter DateTime.Now into the TimeCleared field to essentially delete the break from the list.
I'm doing something wrong, though (or a lot of things wrong). Either it doesn't update the database and time stamp that TimeCleared field, I get a "This request has been blocked because sensitive information could be disclosed to third-party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet." error or other errors based on what I try.
Part of the View:
<div class="container_lists">
<div class="container_break col-md-6">
#*start the break list table*#
<h5 style="text-align:center">Break List</h5>
<table class="table-bordered col-lg-12">
#*populate the table with only those breaks that lack a TimeCleared value*#
#if (Model != null)
{
foreach (var item in Model)
{
if (item.TimeCleared == null)
{
<tr>
#*Make each name clickable to fire JavaScript which activates ActionResult DeleteBreak*#
<td class="breakIdNumber">
#Html.ActionLink(item.DisplayName, "DeleteBreak", new { id = item.BreakId }, new { onclick = "return confirm('Remove from the break list?');" })
</td>
</tr>
}
}
}
</table>
Part of the controller:
public ActionResult DeleteBreak(BreakModels breakmodels)
{
try
{
breakmodels.TimeCleared = DateTime.Now;
db.SaveChanges();
return Json(new { success = true});
}
catch (Exception ex)
{
return Json(new { success = false});
}
}
Ajax:
#*Activate the DeleteBreak ActionResult*#
<script>
$(document).ready(function () {
$("#RemoveBreak").click(function () {
var model = {};
model.BreakId = Number($("#breakIdNumber").val());
console.log("model", model);
$.ajax({
type: "POST",
url: "/Home/DeleteBreak",
dataType: 'json',
data: JSON.stringify(model),
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.success)
window.location.href = "/Home/Index";
else
alert("Something went wrong");
},
error: function () {
alert("Something went wrong");
}
});
});
});
</script>

How to submit dynamic data without form?

I am getting data as form of Java Bean and I am inserting each value into a table.
Values are retrieved as common way at first.
But I added some Javascript source, so that I can modify the value if I click any area near it.
Now I would like to save the data in database as well if there was any change after I modify.
How can I do that?
Here is my HTML code
<table class="bg-light table table-hover" style="overflow:hidden">
<th>Word</th>
<th>Dialogue</th>
<th>Practice</th>
<c:forEach items="${list}" var="engboardVO">
<tr>
<td data-editable>${engboardVO.word}</td>
<td data-editable>${engboardVO.dialogue}</td>
<td data-editable>${engboardVO.practice}</td>
</tr>
</c:forEach>
</table>
And Javascript
$("body").on("click", "[data-editable]", function() {
var $el = $(this);
/* var $input = $('<input style="width:500px; height:100px"/>').val( $el.text() ); */
var $input = $('<textarea rows=5 style="width:500px"/>').val($el.text());
$el.replaceWith($input);
var save = function() {
var $td = $("<td data-editable />").text($input.val());
$input.replaceWith($td);
};
$($input).blur(function() {
save();
})
});
You can use ajax for submitting data without form.
I can see you are using jQuery library. So I am writing code based on this library.
In HTML:
<table class="bg-light table table-hover" style="overflow:hidden">
<th>Word</th>
<th>Dialogue</th>
<th>Practice</th>
<c:forEach items="${list}" var="engboardVO">
<tr>
<td data-name="word" data-editable>${engboardVO.word}</td>
<td data-name="dialogue" data-editable>${engboardVO.dialogue}</td>
<td data-name="practice" data-editable>${engboardVO.practice}</td>
</tr>
</c:forEach>
</table>
In javascript:
$("body").on("click", "[data-editable]", function() {
var $el = $(this);
var $input = $('<textarea rows=5 style="width:500px"/>').val($el.text());
$el.html($input);
var field_name = $el.attr('data-name');
var save = function() {
var $val= $input.val();
$.ajax({
type: "POST",
url: "update-url",
data: {fieldname: field_name, fieldvalue:$input.val()},
dataType: "json",
success: function(msg) {
// do something on success
$el.html($val);
},
error: function(msg){
// do something on error
}
});
};
$($input).blur(function() {
save();
})
});
Then in server side, you can save fieldvalue as value of fieldname in your database.
Basically what we are doing here is:
Added an attribute data-name in td tag, its value can be related to your field name in table.
Get the name of attribute in javascript using var field_name = $el.attr('data-name');.
Using post request in ajax call passed the field_name and and value of this field to server.
$.ajax({
type: "POST",
url: "update-url",
data: {fieldname: field_name, fieldvalue:$input.val()},
dataType: "json",
success: function(msg) {
// do something on success
$el.html($val);
},
error: function(msg){
// do something on error
}
});
Now in server side, you need to fetch this data as you fetch normally for post request in submit of a form and save this data in database.
url is same as action you provide in form tag.
Edit:
Check now. You were replacing the td, whereas you had to replace html inside td.
Don't worry if you don't have a form or can't have it for some reasons
You can still read the inputs of your web page and use them or send them to the server.
See below a simple example:
var inputs = document.getElementsByTagName('input');
var data = []
for (index = 0; index < inputs.length; ++index) {
// deal with inputs[index] element.
data.push(inputs[index].value)
}
var json = JSON2.stringify(data);
$.ajax({
type: "POST",
url: "your-api-url",
data: json,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
// done code
}
});

Updating a div based on a select event from KendoUI Widget

I have a KendoUI search bar that has a drop down of autocompleted items based on what I type. When I type into I get a drop down menu. When I click on an item in the drop downlist, I want two things to happen. One which works, and that is loading a partial view. But, the other thing deals with updating a div element that is also in that partial view.
The partial view
#{
ViewBag.Title = "Client";
}
<div id="update">#ViewBag.name</div>
<p id="ahhh"></p>
External Javascript function
function onSelect(e) {
$("#navResult").load('/Home/Client');
var value = e.item.text();
alert(value);
$.ajax({
type: "POST",
url: "Home/someStuf",
dataType: "json",
data: {n: value },
success: function (result) {
alert("IT WORKED");
},
error: function (result) {
alert("FAILED");
}
})
}
In the HomeController there is a method called someStuf. I am sending that item that is clicked on the event into the someStuf method.
Now here are the two controller methods that I'm working with.
Secretary s = new Secretary();
public ActionResult Client()
{
ViewBag.name = s.Client;
return PartialView();
}
[HttpPost]
public JsonResult someStuf(String n)
{
s.Client = n;
return Json(n, JsonRequestBehavior.AllowGet);
}
So then I update a class with that value that was passed from javascript. I then add that new value to the viewbag for the partial view Client.
Sorry for the misleading variables. Client is a type of model. Then I always have a partial view that is called client.
When I try this. The ViewBag is not showing the result that I would like. I can get the client side to send to the server. But I can't get the server to send to the client.... I bet it's something simple. But I'm trying to understand this step so I can use the same method to update id and class elements.
<p class="CompanySearchBar">
#(Html.Kendo().AutoComplete()
.Name("companyComplete") //The name of the AutoComplete is mandatory. It specifies the "id" attribute of the widget.
.DataTextField("company") //Specify which property of the Product to be used by the AutoComplete.
.BindTo(Model)
.Filter("contains")
.Placeholder("Company name")
.Events(e => { e.Select("onSelect"); })
)
</p>
The above code allows for a search bar with autocomplete. While typing for an item a drop down list shows up with results having the same substring. When clicking one of the results the onSelect method is activated.
you can give like this and on change event just assign a value using jquery like
function onSelect(e) {
$("#navResult").load('/Home/Client');
var value = e.item.text();
alert(value);
$.ajax({
type: "POST",
url: "Home/someStuf",
dataType: "json",
data: {n: value },
success: function (result) {
$('#ahhh').text(result.NAME); //the object which you returns from the controller
},
error: function (result) {
alert("FAILED");
}
})
}
<label id=ahhh></label>

Binding table in MVC 4 after Ajax call

I have an HTML able, which I bind by using the following Action in MVC controller:
public ActionResult BindTable(int ? page)
{
int pageSize = 4;
int pageNumber = 0;
List<Users> _users = query.ToList();
return View(_users.ToPagedList(pageNumber, pageSize));
}
Below the table I have the following HTML:
<textarea class="form-control" style="resize:none;" rows="9" placeholder="Enter value here..." id="txtValue"></textarea>
<br />
<button style="float:right; width:100px;" type="button" onclick="CallFunction()" class="btn btn-primary">Update specific record</button>
The Javascript function responsible for calling the action is as following:
function CallFunction() {
if ($('#txtValue').val() !== '') {
$.ajax({
url: '/User/UpdateUser',
type: 'POST',
data: { txt: $('#txtValue').val() },
success: function (data) {
$('#txtValue').val('');
alert('User updated!');
},
error: function (error) {
alert('Error: ' + error);
}
});
}
And here is the Action responsible for updating the user:
public ActionResult UpdateUser(string txtValue)
{
var obj = db.Odsutnost.Find(Convert.ToInt32(1));
if(obj!=null)
{
obj.Text= txtValue;
obj.Changed = true;
db.SaveChanges();
return RedirectToAction("BindTable");
}
return RedirectToAction("BindTable");
}
Everything works fine. But the table doesn't updates once the changes have been made ( it doesn't binds ?? )...
Can someone help me with this ???
P.S. It binds if I refresh the website.. But I want it to bind without refreshing the website...
I created a BIND function with Javascript, but it still doesn't binds:
function Bind() {
$(document).ready(function () {
var serviceURL = '/User/BindTable';
$.ajax({
type: "GET",
url: serviceURL,
contentType: "application/json; charset=utf-8",
});
});
}
You're not actually updating the page after receiving the AJAX response. This is your success function:
function (data) {
$('#txtValue').val('');
alert('User updated!');
}
So you empty an input and show an alert, but nowhere do you modify the table in any way.
Given that the ActionResult being returned is a redirect, JavaScript is likely to quietly ignore that. If you return data, you can write JavaScript to update the HTML with the new data. Or if you return a partial view (or even a page from which you can select specific content) then you can replace the table with the updated content from the server.
But basically you have to do something to update the content on the page.
In response to your edit:
You create a function:
function Bind() {
//...
}
But you don't call it anywhere. Maybe you mean to call it in the success callback?:
function (data) {
$('#txtValue').val('');
Bind();
alert('User updated!');
}
Additionally, however, that function doesn't actually do anything. For starters, all it does is set a document ready handler:
$(document).ready(function () {
//...
});
But the document is already loaded. That ready event isn't going to fire again. So perhaps you meant to just run the code immediately instead of at that event?:
function Bind() {
var serviceURL = '/User/BindTable';
$.ajax({
type: "GET",
url: serviceURL,
contentType: "application/json; charset=utf-8",
});
}
But even then, you're still back to the original problem... You don't do anything with the response. This AJAX call doesn't even have a success callback, so nothing happens when it finishes. I guess you meant to add one?:
function Bind() {
var serviceURL = '/User/BindTable';
$.ajax({
type: "GET",
url: serviceURL,
contentType: "application/json; charset=utf-8",
success: function (data) {
// do something with the response here
}
});
}
What you do with the response is up to you. For example, if the response is a completely new HTML table then you can replace the existing one with the new one:
$('#someParentElement').html(data);
Though since you're not passing any data or doing anything more than a simple GET request, you might as well simplify the whole thing to just a call to .load(). Something like this:
$('#someParentElement').load('/User/BindTable');
(Basically just use this inside of your first success callback, so you don't need that whole Bind() function at all.)
That encapsulates the entire GET request of the second AJAX call you're making, as well as replaces the target element with the response from that request. (With the added benefit that if the request contains more markup than you want to use in that element, you can add jQuery selectors directly to the call to .load() to filter down to just what you want.)

Updating the database on click of a table row

I am having a table in which data is being populated through the database.Now what i want is that as soon as i click on one of the row a alert message displays and the READSTATUS of that row become true in my database that is database gets updated .
Now my problem is where to write the code for updating the database as i dont want to move to a different page to do so.
Like my table is something like this :
<input type=hidden name="notifyidd" id="notifyidd" value="<%=messageid%>"/>
<tr bgcolor="#5D1B90" color="#FFFFFF" onmouseover="ChangeColor(this, true,false);" onmouseout="ChangeColor(this, false,false);" onclick="DoNav('shownotification.jsp?mid=<%=messageid%>');">
<td><input type="checkbox" name="" onclick="DoRemove(event);" width="20" class="select_all_mail" value=<%=messageid%>></td>
<td callspan="3" width="1000px"><%=messagesubject%> at <%=sendingtime%></td>
</tr>
and in onclick method of each row i had called the alert.But how to update the database now ?
function DoNav(theUrl)
{
var tt = document.myinbox.notifyidd.value;
alert(tt);
//document.location.href = theUrl;
}
As if i uncomment this line then it will move to next page.But i want to do it on same page only.Please help
EDIT :
I wrote a ajax code to do it.But it gives error.Please help
$(document).ready(function() {
$('#myrow').click(function ()
{
$.ajax({
type: "post",
url: "shownotification.jsp", //this is my servlet
data: {
notifyidd: $('#notifyidd').val()
},
success: function(msg){
if(msg == "success")
alert('Data updated.');
}
});
});
});
Here i assign myrow as id to my table row.Also i removed doNav function now
My error image clicked :
http://postimg.org/image/vix1vzvq5/
Though the error is resolved but this ajax call is not functioning.For test i make my shownotification.jsp as :
<body>
<% String notifyid = request.getParameter("notifyidd");%>
success
</body>
The error message says the server-side code is failing when looking for the attribute "groupid". The post you are sending has notifyidd instead. The server code has no way of knowing if this should map to groupid or not.
Try this. If it doesn't work, update us with the error.
$(document).ready(function() {
$('#myrow').click(function ()
{
$.ajax({
type: "post",
url: "shownotification.jsp", //this is my servlet
data: {
groupid: $('#notifyidd').val()
},
success: function(msg){
if(msg == "success")
alert('Data updated.');
}
});
});
});

Categories