I am creating a dynamic user profile. I want to render partials using ajax (to avoid page reloads).
When I am rendering partial via ajax, for example Profile/sections/skills I am getting partial (my controller returns partial view) and rendering #partials div.
The problem is when I hit the route directly by manually typing in the browser Profile/sections/skills it returns only partial html.
I want both to work correctly: render partial via call with ajax and when I type in the url it can be found.
html
<div class="profile-navbar">
<ul class="ul-menu">
<li class="space"></li>
<li class="active"> <i class="fa fa-user"></i> About </li>
<li>
<a href="#" id="skills"> <i class="fa fa-robot"></i> Skills/a>
</li>
<li> <i class="fa fa-images"></i> Portfolio</li>
<li> <i class="fa fa-address-card"></i> CV</li>
<li> <i class="fa fa-briefcase"></i> Experience </li>
</ul>
</div>
<div id="partials"> </div>
js
$('.profile-navbar ul li a').click(function (e) {
e.preventDefault();
$.ajax({
url: '#Url.Action("Skills", "Profile")',
type: "POST",
success: function (response, status) {
$("#partials").html(response);
}
});
});
Controller
[Route("Profile/Skills")]
public IActionResult Skills()
{
return PartialView("Skills");
}
You already have a partial view defined for your [Route("Profile/Skills")].
To accomplish what you want you need to do the following:
Define a regular view for the same route
This view will contain a reference to your partial so the partial is rendered within the larger HTML of the full view (when the route is called directly).
Modify Controller Action to check for Ajax
Once you have a regular view and the partial view then you can modify your controller action to conditionally decide whether to:
renderpartial (if the caller is Ajax)
or render the full view (if it is not an ajax call)
IsAjaxRequest() method
In past versions of ASP.NET MVC there was a method on the Request object called IsAjaxRequest(). When this method is available your controller action code could be as simple as:
[Route("Profile/Skills")]
public IActionResult Skills()
{
if (Request.IsAjaxRequest())
return PartialView("Skills");
else
return View();
}
ASP.NET Core is missing IsAjaxRequest() method
Unfortunately it seems that this method was overlooked in ASP.NET Core (as best as as I tell at the present time). But it also seems that the underlying code was simple enough that many people have managed to duplicate its behavior without much trouble.
If Request.IsAjaxRequest() is not available to you because of ASP.NET core you should be able to duplicate its behavior in your controller action something like this:
[Route("Profile/Skills")]
public IActionResult Skills()
{
bool isAjaxCall = Context.Request.Headers["x-requested-with"]=="XMLHttpRequest";
if (isAjaxCall)
return PartialView("Skills");
else
return View();
}
A more formalized and reusable approach to the dealing with missing IsAjaxRequest() method is described in this post
Related
I would like to visualize data from my model in my layout page - specifically when user adds an item to the shopping cart I would like to count number of items in the shopping cart and display it in the navbar next to the image of shopping cart.
User can add the product from more then 1 page (e.g. from Index page, or Product/index page etc.).
Anyone dealt with something similar?
I would like my navbar to look like this :
Navbar
<div class="navbar-collapse collapse show" id="navbarColor01" style="">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a asp-page="/Index" class="nav-link" >Home <span class="sr-only">(current)</span></a>
</li>
<li>
<a asp-page="/ShoppingCart/Index"> <i class="fas fa-shopping-cart fa-1x fa-cog "></i></a>
<div class="badge badge-danger badge-pill">5</div> //here is the number to be displayed
</li>
</ul>
</div>
There are different ways to achieve this, evaluate your options then decide what to do.
You can achieve this by:
Using view bags. This would cause code reputation throughout your project. Because you are going to set the view bag for each page visit.
Using partial views. By calling Ajax request to the action, and then return partial view. Partial views usually intended to be part of the Controller/Page, which wouldn't make sense to have GetCart from different controller/page. Also it is best for avoiding view reputation.
View Component. This is usually the ideal way to do it, since you need to do work behind the scene then return the value. View Components can live in their own, which is good for SoC.
My personal recommendation would be View Component, it is a new feature in asp.net core (replacing ChildAction).
Having problems getting angularJS routing to work in my asp.net application.
Note: AngularJS routing basically allows multiple views to be inserted interchangeably into the same page without page refresh.
Are their any connection settings or http settings that need to be adjusted in order for routing to work? Can AngularJS routing work with the ASP settings "right out of the box" (after of course including the angular.min.js/angular-route.js scripts)?
Just implementing a plain ASP.NET Web Application
I found a few tutorials on the web like this one, however they don't help with routing, and sometimes use templates that are not available.
https://www.pluralsight.com/blog/software-development/angularjs-for-asp-net-applications
For Clarification
This post is asking if any additional settings are required, or if routing works right out of the box with an ASP Web Application as long as the required angular scripts(angular.min.js/angular-route.js) are included.
Angular Example
--Index.aspx--
<div ng-app="AngularStore" class="col-lg-12 col-md-12 col-sm-12 col-xs-12" style="min-height:400px;">
<div ng-controller="mainController">
<nav class="navbar navbar-default">
<div class="container">
<ul class="nav navbar-nav navbar-right">
<li>Cart</li>
<li>Store</li>
</ul>
</div>
</nav>
<div id="main">
<div ng-view></div>
</div>
</div>
<%--//javascript scripts--%>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script src="/scripts/angular.min.js"></script>
<script src="/scripts/angular-route.js"></script>
<script src="script.js"></script>
</div>
--script.js--
var storeApp = angular.module('AngularStore', ['ngRoute']).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/store', {
templateUrl: "partials/store.html",
controller: 'HomeController'
}).
when('/products/:productSku', {
templateUrl: 'partials/product.html',
controller: 'HomeController'
}).
when('/cart', {
templateUrl: 'partials/shoppingCart.html',
controller: 'cartController'
}).
otherwise({
redirectTo: '/cart'
});
}]);
//I have tried including $route in function dependencies here.
storeApp.controller('HomeController', function ($scope) {
// create a message to display in our view
$scope.message = 'Everyone come and see how good I look!';
});
storeApp.controller('cartController', function ($scope) {
$scope.message = 'Look! I am a cartController page.';
});
storeApp.controller('mainController', function ($scope) {
$scope.message = 'Look! I am a mainController page.';
});
I have implemented this before with minimal issues. Cant recall any special settings that needed to be set. Form validation can be tricky as the web application wraps most of the page in a form. Without more information on your specific problems that is all I am able to provide.
These additional steps made it work.
Add #/ before the hrefs:
<li><i class="fa fa-home"></i> Home</li>
<li><i class="fa fa-shield"></i> About</li>
<li><i class="fa fa-comment"></i> Contact</li>
Add this locationProvider config before your routeProvider.
scotchApp.config(['$locationProvider', function ($locationProvider) {
$locationProvider.hashPrefix('');
}]);
I have a page with partial view that contains DevEx ComboBox with Add button and DevEx GridView ( I omitted GridView code). Page is showing properly with that partial view, only I have a problem with refreshing it.
//_ProductAppsGridViewPartial
<div class="form-horizontal">
<h4>Apps</h4>
#using (Html.BeginForm("AppsGridViewPartialAddNew", "Products", new { ProductID = ViewBag.ProductID }))
{
<div class="form-group">
<h5>Add new App:</h5>
#Html.DevExpress().ComboBox(settings =>
{
//..do some settings for ComboBox - some code omitted
settings.Properties.ValueField = "ApplicationID";
settings.Properties.TextField = "Name";
}).BindList(Model.AppsNotInProduct).GetHtml()
<input type="submit" value="Add" class="btn btn-default" />
</div>
}
</div>
I have action on my controller that adds selected app in database and returns a PartialView with the same (but refreshed) model, but response shows only that partial View. Here is a part of Controller's action that returns PartialView after updating database:
public ActionResult ProductAppsGridViewPartialAddNew(int ProductID)
{
//....update DB code - WORKS FINE
..
var model = GetProductAppsPartialModel(ProductID);
ViewBag.ProductID = ProductID;
ViewBag.CanEdit = true;
return PartialView("_ProductAppsGridViewPartial", model);
}
Is it possible to refresh a partial view wihout AJAX, maybe something i wrote above? So the main problem here is that i get new page showing only a partial view.
To refresh part of a page you will need to use ajax to replace only the needed content. You will also need to use JavaScript to re-render the HTML contained in the partial. MVC comes with some ajax helpers or you can do it yourself with jquery. At the moment the action result is returning the partial as requested but the browser is being told it is receiving a whole new page and is displaying as such.
Adding this link to Microsoft ajax to show some of your options.
I would use jquery and do this yourself. Also try to remember that mvc is a server side framework to help you return http messages to the browser. You are trying to manipulate things client side. Live client side updates always need ajax to get data. Replacing items in the DOM needs some form of JavaScript. Libraries like jquery make this a lot easier. Have a look at jquery ajax here.
I think you need to try this code.
Note here we need to keep ajax call for update the partial view
#using (Ajax.BeginForm("ActionName", "Controller", new { model = #Model.ID },
new AjaxOptions
{
OnSuccess = "onSuccessRefresh "
}))
{
<table>
<td>
</td>
<td> <input type="button" value="AddValue" /> </td>
</table>
}
Handle the code onsuccess event using jquery:-
function onSuccessRefresh {
// refersh your page or table
}
This is not the full code. but I think it will help to you
I have the following which show the navigation path of the user inside my _layout share view:-
<ul class="breadcrumb">
<li>
<a href="#">#ViewContext.Controller.ValueProvider.GetValue("controller").RawValue
</a> <span class="divider">/</span>
</li>
<li>
#ViewContext.Controller.ValueProvider.GetValue("action").RawValue
</li>
</ul>
but i have the following two questions:-
Is using ViewContext.Controller.ValueProvider.GetValue("controller").RawValue the right way to get the controller name
how i can build the href of the a links to point to the required path ?
Regards
You can get the controller name using the RouteData:
var controller = ViewContext.RouteData.Values["Controller"].ToString();
You can then build an ActionLink like so:
#Html.ActionLink("Click me", "View", controller)
I'm struggling with a very basic feature. I want to refer another view from the current view to load the content from that view by applying very basic ajax. here is the code:
<div>
<ul id="biographies">
<li> Ajax</li>
<li> Index </li>
</ul>
<div id="biography">
The ajax content will appear here...
</div>
<script type="text/javascript">
$("#biography").load('Ajax.cshtml');
</script>
</div>
Both the page is in the same directory that is: views/home
Question 1: how to pass the parameter for load event?
Question 2: how to link to other pages using the anchor tag?
Thanks.
Use the Url.Action helper method:
$("#biography").load('#Url.Action("Ajax")');
Similarly, you can use Html.ActionLink to get an a tag for actions or routes:
#Html.ActionLink("Go to Index", "Index")
#Html.ActionLink("Go to Home:Index", "Index", "About")
The output will be like <a href='/About/Index'>Go to Home:Index</a>.
Remember, with MVC the idea is that URLs point to resources and routes, not to specific files. It's best to use these helper methods (rather than writing out hard-coded URLs) as they specify the route precisely.
Use Html.ActionLink to generate links and then use jquery for ajax loading. Off course, you need to write actions in controller for returning partial views. Jquery code: jsfiddle