Can i load a partial view with load jquery function? - asp.net-mvc

I am trying to load a partial view on the page like below
$('#logindisplay').load('#Url.Content("/../../Shared/_LogOnPartial.cshtml")');
but every time it says the specified not found, while many times i changed the path and all work fine.
Does this type of partial view loading is supported by jquery or i have to calan action method every time
Seeing the second answer i come to conclustion that every time i need to load a apartial view i have to call a action methid that will return the partial view, but it doesn't accept the whole path mentioned int the load function hard coded for the partial view to be loaded.

but every time it says the specified not found... Does this type of
partial view loading is supported by jquery or i have to calan action method every time
Yes it is supported by jquery. But you have to remember that load do a "server call" and that is why you have to call an action method.
$('#logindisplay').load('#Url.Action("MethodName","Controller")');

HTML
<div id="MyDiv" attr-Url="#Url.Action("ActionName", "ControllerName",
new { area = "Area Name" })">
</div>
JQuery
MyDiv.load($('#MyDiv').attr('attr-Url'), function () {
//Success Callback
});
Edit - 1 (Alternatives)
#
{
Html.RenderPartial("~/Views/AnotherFolder/PView", ViewData.Model);
}
#Html.Partial("../MyViewFolder/Partials/_PartialView", Model.MyObject)
#Html.Partial("~/Views/ControllerB/Index.cshtml")

Related

How to pass a data value to a stimulus controller upon a load event

I have a Stimulus controller
# app/javascript/controllers/clubs_controller.js
// handles micropost javascripts
import { Controller } from "stimulus"
import Rails from '#rails/ujs';
export default class extends Controller {
connect() {
}
wait_for_clubs(event) {
event.preventDefault()
console.log("in wait_for_clubs", event.target)
const id = event.target.dataset.value
console.log("id", id)
}
}
}
and html code
<div data-controller="clubs">
<span data-action="load#window->clubs#wait_for_clubs" data-value='<%= #user.id %>'>Waiting for Clubs to be prepared</span>
</div>
with the idea that when the page is loaded, the controller has the id of the user. When I reload the page, I see the following error in the console
TypeError: Cannot read property 'value' of undefined
which is triggered by the var id = event.target.dataset.value; statement.
However if I change the event from load#window to click, then when I click the span, the code works and retrieves the id. How do I fix this?
If you are trying to pass data to a Stimulus controller that exists on the DOM when it loads, the Stimulus docs recommend using the built-in data API.
In your case, that would mean adding a data-clubs-my-value attribute to the DOM element where you assign the data-controller attribute, like so:
<div data-controller="clubs"
data-clubs-my-value="<%= #user.id %>">
</div>
and then you can get this value from your Stimulus controller by calling this.data.get("myValue")
As to why data-action didn't work...
The Stimulus docs do allow for Global Events so this event is being triggered. But when this happens, the triggering event.target is window, not your <span>, so when you call event.target.dataset, it is looking for the dataset of the window, which does not have your value.
If you want an action in your Stimulus controller to fire upon page load, the best way to handle this is generally by using the connect() method.

Loading JQuery scripts to a partial view rendered by ajax call

Following is my view which contains a div in which partial views are rendered based on actions performed in the view.
//Boiler Plate HTML
<div id="PartialViewHolder">
#Html.Partial(Model.PartialView, Model)
</div>
//Boiler Plate HTML
The partial views are rendered via an ajax call which is as follows
//The url is supplied based on some actions in the main view
function AjaxCall(url){
$.ajax({
url: url,
cache: false,
success: function (html) {
$("#PartialViewHolder").empty();
$("#PartialViewHolder").html(html);
},
error: function (result) {
alert("Error: " + result.status + ": " + result.statusText);
}
});
}
The main page also loads a few other scripts which are common to the partial views. These scripts work when the page is first rendered, i.e when the default partial view is rendered. However these scripts stop working for partial views which are loaded by the ajax call. I believe that these scripts need to be reloaded when the DOM elements change. I am looking for a clean way to reload those scripts when the partial view div is reloaded.
You need to do a bit of reading about Event binding. http://api.jquery.com/on/
Tricky to understand at first but worth it once you do.
Assuming you've got some code like this.
<div class="container">
<div class="partial">
Click here to do stuff
</div>
</div>
JS Code like the example below will only work for objects present when you do the binding (usually document.ready()) It seems like this is the situation you are describing.
$(".magic-link").click(function(){
alert("Magic link clicked");
return false;
})
If you want the event to fire on objects that haven't yet been loaded onto the page then you need to bind an event handler to the container div i.e. the bit which doesn't change.
Like this
$(".container").on("click", ".magic-link", function(){
alert("Magic link clicked");
return false;
});
The event bubbles up to the event handler and fires the event. This has another advantage that one event handler and potentially handle events from hundreds of objects.
As a guideline try to bind the listener to the nearest parent object that will not change. In the case of the example this is the Container div. This keeps the bubbling to a minimum.

ASP MVC + AJAX, trying to Update a div asynchronously

I'm new to Asp MVC, and I'm trying to accomplish a little async update (I'm using MVC3 RC2, with Razor, but I can manage with ASPX solutions too).
I have a Master page, which renders a shopping cart box on every page by calling Html.RenderAction("Cart","Shop"). The Cart action of the ShopController calls the database, etc, and outputs the results. This works.
First problem: if I put an ActionLink in this partial view (like Html.ActionLink("Remove")), then even if I call PartialView() from the Remove action, it renders only the shopping cart, and nothing else (in essence, my page disappears).
Second problem: There is a div called "cartContent" inside this partial view. I want to be able to put a link ANYWHERE (not just on the Master page or in the partial view), which when pressed calls a controller Action, and then updates ONLY the cartContent div based on the results. I've tried Ajax.ActionLink but it does the same as Html.ActionLink, even though I imported the Microsoft.MvcAjax js libs.
Also, if I solve the first problem, I want that to be async as well.
What solution do I use? I've tried setting UpdateTargetID to "cartContent", I've tried wrapping the cartContent into an Ajax.BeginForm, nothing. Do I HAVE to use jQuery (which I know nothing of)? Do I serialize some response to JSON, and update the div manually in Javascript? (I'm not really good at JS, I'm coming from the C# side of things)
You put a link wherever you want:
#Html.ActionLink("remove item", "remove", "somecontroller",
new { id = Model.Id }, new { #class = "remove" })
And then in a separate javascript file:
$(function() {
$('.remove').click(function() {
// when the link is clicked
// perform an ajax request:
$.ajax({
url: this.href,
type: 'delete',
success: function(result) {
// when the AJAX call succeed do something with the result
// for example if the controller action returned a partial
// then you could show this partial in some div
$('#someDivId').html(result);
}
});
// don't forget to cancel the default action by returning false
return false;
});
});
Remark: if the div you are updating contains also the link then you might need to use the .live() function or the click event handler will not work the second time because the DOM will be modified:
$('.remove').live('click', function() {
...
});

View Master Page and PostBack

I have a dropdown list on my master page that needs to postback after being changed. After the postback, whatever page initiated the postback needs to be re-displayed.
My question is where do I handle this? Obviously I do not want to have to modify every Action in my project... My guess is to maybe postback to some other fixed action and have that action redirect back to the page that is the referrer. Am I correct? Any thoughts?
Thanks.
Jason
In Site.Master, I ended up wrapping the dropdown within its own form that posted back to a dedicated controller/action.
<% Using Html.BeginForm("ChangeRole", "Home")%>
<div id="roleSelector">Change Role: <%=Html.DropDownList("Role", DirectCast(ViewData.Item("Roles"), SelectList), New With {.onchange = "this.form.submit();"})%></div>
<% End Using%>
In the controller I used the following code to change the mode and then redirected back to the referring URL.
<AcceptVerbs(HttpVerbs.Post)> _
Public Function ChangeRole() As ActionResult
Me.CurrentUser.SetRole(DirectCast([Enum].Parse(GetType(Models.ApplicationRoles), Me.Request.Item("Role")), Models.ApplicationRoles))
Return Redirect(Request.UrlReferrer.ToString())
End Function
I am unsure if this is the recommended way but I have been unable to think of another solution.
When you post back from the dropdown list change what are you doing? Can you maybe handle this in a jQuery call thus eliminating the need to re-display the page at all?
Calls to Action Methods can be asynchronous as griegs says, as such, you can post whatever information you need from the radio buttons to an action method without needing to reload the page.
If you need to update a part of the page, you can replace it with the contents of a rendered action method. If you use the jQuery ajax methods, you can post specific information to your methods.
For example, something like this:
$(document).ready(function()
{
$("#myRadioButton").change(function()
{
//Post to your action method, with the value of the radio button, function to call on success
$.post('yourActionMethodUrl', $(this).val(), function()
{
//Update some part of the page
});
});
});
This is based on memory, so you may need to check the syntax.

ASP.Net MVC Loading In Progress Indicator

I have an MVC Controller that runs through a process, sets some View Data, and then returns the results of this data back to the user in a View. The process time is dependent on the amount of data that is being processed. I need a good way to display an animated .gif within the View while the process is running, letting the user know that something is going on.
I've looked at various AJAX methods and partial views but still cannot find a good way to accomplish this. What I really wished I could do was have an ActionFilter that would return a View or Partial View during the OnActionExecuting event that displays this animated .gif, then once the Controller completed processsing and returned the ViewData, the view or partial view with the actual View Data could be displayed.
It also seems like jQuery would be able to provide a nice asynchronous way to call the controller action in the background and then render the View. Any help would be appreciated.
In your controller:
public JsonResult GetSomething(int id)
{
return Json(service.GetSomething(id));
}
In the view (javascript, using JQuery):
$('#someLink').click(function()
{
var action = '<%=Html.ResolveUrl("~/MyController.mvc/GetSomething/")%>' + $('#someId').val() + '?x=' + new Date().getTime();
$('#loading').show()
$.getJSON(action, null, function(something)
{
do stuff with something
$('#loading').hide()
});
});
Note that this assumes a route where 'id' comes after action. The 'x' parameter on the action is to defeat aggressive caching in IE.
In the view (markup):
<img id="loading" src="images/ajax-loader.gif" alt=""/>
<!-- use a css stlye to make display:none -->
Get loader gifs here.
Also note that you do not have to do this with Json. You can fetch other things like HTML or XML from the controller action if you prefer.

Resources