How to make UpdateTargetId work in Ajax.ActionLink? - c#

I have this method in the controller
[HttpDelete]
public void DeleteDocument(int id)
{
//Here I do the deletion in the db
}
In the view I have this, calling a method that returns a partial view
#{ Html.RenderAction("GetDocumentsByMember"); }
The GetDocumentsByMember method
public ActionResult GetDocumentsByMember()
{
var companyGuid = HttpContextHelper.GetUserCompanyGuid();
var documents = _service.GetUploadedDocumentsByMember(companyGuid);
return PartialView(documents);
}
And the partial view
#model IEnumerable<GradientCapital.DomainModel.Entity.Document.Document>
<div id="uploadeddocuments">
#*Here there's a table and at one of the columns there's the next link*#
<td id="delete">
#Ajax.ActionLink("Delete", "DeleteDocument", new { id = document.Id },
new AjaxOptions
{
Confirm = "Are you sure you want to delete?",
HttpMethod = "DELETE",
OnComplete = "deleteComplete"
})
</td>
</div>
And deleteComplete just refresh everything
<script type="text/javascript">
function deleteComplete() {
window.location.reload();
}
</script>
Quite long (is correctly formatted?) code for a simple question, I can't make the ajaxoption UpdateTargetId work here instead of having to call this deleteComplete function. Any idea?
Thanks

Instead of reloading the entire page you could call the GetDocumentsByMember action using AJAX and update only the portion of the DOM that has actually changed:
<script type="text/javascript">
function deleteComplete() {
$.ajax({
url: '#Url.Action("GetDocumentsByMember")',
type: 'GET',
cache: false,
success: function(result) {
$('#uploadeddocuments').html(result);
}
});
}
</script>
Also you'd better use OnSuccess = "deleteSuccess" instead of OnComplete = "deleteComplete" because you should update only if the Delete call actually succeeded. Don't forget that the OnComplete callback is always invoked, no matter whether the AJAX call succeeded or not.

Related

Call Action Method in controller on Ajax success function to Render partial view

I am trying to call controller action method to render partial view to update the part of big web page. I am trying to do this on Ajax success function.
Code Control Flow:
Jquery Ajax calls a web api to add something to database, on the success function of the Ajax call, I am calling controller action method that returns partial view.
Jquery Script
$(document).ready(function () {
$("#sendMessage").on("click", function (e) {
e.preventDefault();
var MessageReplyParam = $('#messageToBeSent').val();
var FromUserNameParam = $('#FromUserName').val();
var FromUserIDParam = $('#FromUserID').val();
var ToUserNameParam = $('#ToUserName').val();
var ToUserIDParam = $('#ToUserID').val();
var button = $(this);
$.ajax({
//url: "/api/messages/SendMessages?MessageID=" + button.attr("data-message-id"),
url: "/api/messages/SendMessages",
method: "POST",
data: {
lngMessageID: button.data("message-id"),
Reply: MessageReplyParam,
FromUserID: FromUserIDParam,
FromUserName: FromUserNameParam,
ToUserID: ToUserIDParam,
ToUserName: ToUserNameParam
},
dataType: 'html',
success: function (data) {
$.ajax({
url: "/Booking/SendMessagesTest",
method: "POST",
data:
{
MessageID:2
}
});
}
});
});
});
Controller method to update Partial View
public ActionResult SendMessagesTest(int? MessageID)
{
var messagesReplies = from mrp in _context.MessageReply
where mrp.lngMessageID == MessageID
select mrp;
List<MessageReply> MessageReplies = new List<MessageReply>();
MessageReplies = messagesReplies.ToList();
BookingViewModel bvm = new BookingViewModel();
bvm.MessageReplies = MessageReplies;
return PartialView("_MessagesView", bvm);
}
_MessagesView.cshtml
#model DatabaseMVCPractice.ViewModels.BookingViewModel
#if (Model.MessageReplies != null)
{
foreach (var msg in Model.MessageReplies)
{
<p class="chatMessage">#msg.FromUserName: #msg.Reply</p>
}
}
Main View that has other html and also render partial view of _MessageView
<div id="partial">
<div class="messages">
<div class="bg-dark rounded padding-x4">
#{
Html.RenderPartial("_MessagesView", Model);
}
</div>
<p>#Html.DisplayFor(model => model.Messages.Message)</p>
</div>
</div>
When I debug the code, control flow works properly, at last, it goes to _MessageView but it never goes to MainView to render the partial view on Ajax success function. What am I doing wrong?
you are returning partial view return PartialView("_MessagesView", bvm); from ajax, partial view is returning only that part contains in it not main view, if your requirement is render partial view from ajax then you can get partial view response in your ajax success and replace your main view div with partial response.
your controllers action SendMessagesTest(int? MessageID) return partial view string in your ajax response.
like below is your Main View
<div id="partial">
<div class="messages">
<div id="divMessages" class="bg-dark rounded padding-x4">
#{
Html.RenderPartial("_MessagesView", Model);
}
</div>
<p>#Html.DisplayFor(model => model.Messages.Message)</p>
</div>
</div>
and your ajax only for your return partial view is like
$(document).ready(function () {
$("#sendMessage").on("click", function (e) {
e.preventDefault();
var MessageReplyParam = $('#messageToBeSent').val();
var FromUserNameParam = $('#FromUserName').val();
var FromUserIDParam = $('#FromUserID').val();
var ToUserNameParam = $('#ToUserName').val();
var ToUserIDParam = $('#ToUserID').val();
var button = $(this);
$.ajax({
//url: "/api/messages/SendMessages?MessageID=" + button.attr("data-message-id"),
url: "/api/messages/SendMessages",
method: "POST",
data: {
lngMessageID: button.data("message-id"),
Reply: MessageReplyParam,
FromUserID: FromUserIDParam,
FromUserName: FromUserNameParam,
ToUserID: ToUserIDParam,
ToUserName: ToUserNameParam
},
dataType: 'html',
success: function (data) {
$.ajax({
url: "/Booking/SendMessagesTest",
method: "POST",
data:
{
MessageID: 2
},
success: function (response) {
$("#divMessages").html("");
$("#divMessages").html(response);
}
});
}
});
});
});
i hope it should helps you let me know if require more information.

Simplest way to get model data/objects in the view from input with an ajax partial view call(s)

Hello i googled to find a solution to my problem, every link brought me to asp forms solution, or solutions that do not ask for form inputs, this problem has form inputs and i cant seem too find a link for help, what im asking for is simple: get the data from user input through models by ajax calls.
View (index.cshtml):
#model UIPractice.Models.ModelVariables
<!-- Use your own js file, etc.-->
<script src="~/Scripts/jquery-1.10.2.js" type="text/javascript"></script>
<div id="div1">
#Html.BeginForm(){ #Html.TextBoxFor(x => x.test1, new { style = "width:30px" })}
<button id="hello"></button>
</div>
<div id="result1"></div>
<script type="text/javascript">
//Job is to load partial view on click along with model's objects
$(document).ready(function () {
$('#hello').click(function () {
$.ajax({
type: 'POST',
url: '#Url.Action("HelloAjax", "Home")',
data: $('form').serialize(),
success: function (result) {
$('#result1').html(result);
}
});
});
});
Model (ModelVariables.cs):
public class ModelVariables
{
//simple string that holds the users text input
public string test1 { get; set; }
}
Controller (HomeController.cs):
// GET: Home
public ActionResult Index()
{
ModelVariables model = new ModelVariables();
return View(model);
}
public ActionResult HelloAjax(ModelVariables model)
{
ViewBag.One = model.test1;`
return PartialView("_MPartial", model);
}
Partial View (_MPartial.cshtml):
#model UIPractice.Models.ModelVariables
#{
<div>
<!--if code runs, i get a blank answer, odd...-->
#Model.test1
#ViewBag.One
</div>
}
So go ahead and copy/paste code to run, you will notice that you get nothing when you click the button, with user text input, odd...
I see a few problems.
Your code which use the Html.BeginForm is incorrect. It should be
#using(Html.BeginForm())
{
#Html.TextBoxFor(x => x.test1, new { style = "width:30px" })
<button id="hello">Send</button>
}
<div id="result1"></div>
This will generate the correct form tag.
Now for the javascript part, you need to prevent the default form submit behavior since you are doing an ajax call. You can use the jQuery preventDefault method for that.
$(document).ready(function () {
$('#hello').click(function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '#Url.Action("HelloAjax", "Home")',
data: $('form').serialize(),
success: function (result) {
$('#result1').html(result);
}
,error: function (a, b, c) {
alert("Error in server method-"+c);
}
});
});
});
Also, you might consider adding your page level jquery event handlers inside the scripts section (Assuming you have a section called "scripts" which is being invoked in the layout with a "RenderSection" call after jQyery is loaded.
So in your layout
<script src="~/PathToJQueryOrAnyOtherLibraryWhichThePageLevelScriptUsesHere"></script>
#RenderSection("scripts", required: false)
and in your indidual views,
#section scripts
{
<script>
//console.log("This will be executed only after jQuery is loaded
$(function(){
//your code goes here
});
</script>
}

Redirect from partial view to view with json data object

I have a json data object which i need to pass from partial view to view with REDIRECT.
Lets say below is my partial view ( _createEmp.cshtml ):-
Note:- This partial view is in different view or page
<script type="text/javascript">
$(document).ready(function () {
LoadData();
});
function LoadData() {
$.ajax({
type: "GET",
url: baseURL + "Employee/GetEmpInfo",
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
success: function (data) {
console.log(data);
**EmpData** = data; // EmpData object
},
error: function (error) {
console.log("Error: " + error);
}
});
}
</script>
<div>
<input type="submit" value="Save" onclick="SetEmpInfo()" />
</div>
And i want to transfer EmpData object to a different view (lets say NewEmp.cshtml), bind something in that view from passed "EmpData object" and open that view (or REDIRECT to view NewEmp.cshtml).
As you are using ajax, you could return the URL from your action and have it redirected in javascript.
Without seeing your controller action you would need to do something like this:
Controller
public ActionResult GetEmpInfo()
{
// Do stuff
return Json(new { success = true, redirecturl = Url.Action("GetEmpInfoSuccess") });
}
Then add something like this to your success handler in javascript:
Javascript (within your success handler)
success: function (data) {
if (data.success == true)
{
window.location = result.redirecturl;
}
}
Issuing a request to Employee/GetEmpInfo for getting the data and on success redirecting to other view - doesn't sound right
I think that you can do all this with one trip to server:
Write an Action that receives all the the parameters that GetEmpInfo receives. Lets call it NewEmployee.
If GetEmpInfo action is your code, reuse it's logic inside NewEmployee action to get EmpData. If it is not your code, you can use issue async request with HttpClient and get EmpData - All this performed on the server
Once you have EmpData you should have everything your need to return a NewEmp view.
In this particular case there is no need in AJAX at all. You can use regular form submit in case that you need to post some data or just a redirect to NewEmployee action.

Call a method without loading a view in MVC

I am currently trying to call a method from my view to change a boolean in my database, the only thing i don't know since i am not really familiar with MVC is that whenever i call my controller method it gives me a blank page. I just want to call the method but stay in the actual view.
Here is the part of code in my view.
<td>Delete</td>
And here is the method in my controller
public void PutInBin(int captureId)
{
QueryCaptureToBin queryCaptureToBin = new QueryCaptureToBin();
queryCaptureToBin.Capture_Id = captureId;
client.PlaceCaptureInBin(queryCaptureToBin, userParams);
}
You could use AJAX:
<td>
#Ajax.ActionLink(
"Delete",
"PutInBin",
"Capture",
new {
captureId = Model.Files.Captures.ElementAt(i).Capture_Id
},
new AjaxOptions {
HttpMethod = "POST",
}
)
</td>
and don't forget to include the jquery.unobtrusive-ajax.js script to your page:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
and your controller action:
[HttpPost]
public ActionResult PutInBin(int captureId)
{
QueryCaptureToBin queryCaptureToBin = new QueryCaptureToBin();
queryCaptureToBin.Capture_Id = captureId;
client.PlaceCaptureInBin(queryCaptureToBin, userParams);
return new EmptyResult();
}
and if you wanted to get notification when the delete finishes:
<td>
#Ajax.ActionLink(
"Delete",
"PutInBin",
"Capture",
new {
captureId = Model.Files.Captures.ElementAt(i).Capture_Id
},
new AjaxOptions {
HttpMethod = "POST",
OnSuccess = "onDeleteSuccess"
}
)
</td>
and then you would have your onDeleteSuccess javascript function:
var onDeleteSuccess = function(result) {
// normally the result variable will contain the response
// from the server but in this case since we returned an EmptyResult
// don't expect to find anything useful in it.
alert('The capture was successfully deleted');
};
To refresh the page. Please use below java script function. It's same as above but removed "alert" and used window.location.reload(true). Use in html or cshtml view. Hats off original owner
<script>
var onDeleteSuccess = function(result) {
// normally the result variable will contain the response
// from the server but in this case since we returned an EmptyResult
// don't expect to find anything useful in it.
window.location.reload(true);
// alert('The capture was successfully deleted');
};
</script>

MVC 3: What's the most common way of asynchronously loading form fields based on previous choices?

Imagine having two list boxes on a form, where the choices in the second depend on what's been picked in the first. What's the most common, or cleanest way of going about this with MVC3?
I would say that you would need two things to accomplish this cleanly; Ajax and a Json ActionResult
$('#listbox').change(function() {
$.ajax({
url: '/ListBoxChange',
method: 'POST',
data: {
listBoxValue: 'The value'
},
success: function(data) {
alert (data.Result);
}
});
});
The Action Result:
[HttpPost]
public ActionResult ListBoxChange(string listBoxValue)
{
string result = GetResult();
return Json(new {
Result = result
});
}
Alternatively can use the MVC framework, directly binding back to view after a partial refresh. I've used the following for complex dynamic searches, works decently.
<script src="<%= Url.Content("~/Scripts/MicrosoftAjax.js") %>" type="text/javascript"></script>
<script src="<%= Url.Content("~/Scripts/MicrosoftMvcAjax.js") %>" type="text/javascript"></script>
<% using (Ajax.BeginForm("/GetProducts",
new AjaxOptions()
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
OnBegin = "beginSearchLoader",
OnComplete = "completeSearchLoader",
UpdateTargetId = "divSelectionResult"
}
))
{ %>
<div id="divSelectionResult">
<% Html.RenderPartial(Html.ProductViewPath("ProductContainer") , Model); %>
</div>
public ActionResult GetProducts(FormCollection form)
{
//search parameters used in Form
ProductModel modelData = Search(form);
ViewData.Model = modelData;
//AJAX Partial View Return
return PartialView(Constants.VIEW_FOLDER + "ProductContainer" + Constants.PARTIALVIEW_EXTENSION);
}
FYI: Some of the code is using custom helpers and etc.

Categories