I have a layout page that has one dropdown box. I created 3 views that will make use of this
layout. The value selected in the dropdown will be used in all 3 views created.
I have actionlinks used for navigation in the layout. Here is what I will like to achieve
Avoid reloading the entire page(layout) when I navigate from view to view since I want to keep
the dropdown value selected.
How can I achieve this such that it is only the content of the views that will be changing
when I navigate from page to page by clicking on the action links. The value of dropdown selected
must always remain the same unless changed by user
#model Company.Domain.Classes.Companyviewmodel
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title</title>
<link href="~/Content/Site.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
</head>
<body>
<div class="page">
#{
ViewBag.Title = "Project Status Maintenance";
}
<div id="MainContent1">
<div id="ProjID">
<label for="SelectProjID">Project:</label>
#Html.DropDownList("ddlprojects", Model.GetProjectInformationActive.ProjectsInfoSelectList, Model.GetProjectInformationActive.SelectedProject)
</div>
<ul>
<li class="pp1">#Html.ActionLink("Section1", "Index", "Home")</li>
<li class="pp2">#Html.ActionLink("Section2", "GetSection1Data", "Home")</li>
<li class="pp3">#Html.ActionLink("Section3", "GetSection2Data", "Home")</li>
</ul>
<hr class="divide" />
#RenderBody()
</div>
<footer>
<div class="ftrcontent">
<p>Got it !!</p>
</div>
</footer>
</div>
</body>
</html>
You can use ajax to do partial page loads. To start, give a css class to your links so that we can use those as our jQuery selectors when wiring up the ajax behavior.
#Html.ActionLink("Section1", "Index", "Home",null, new {#class="ajaxLink"})
#Html.ActionLink("Section2", "GetSection1Data", "Home", new {#class="ajaxLink"})
#Html.ActionLink("Section3", "GetSectionwData", "Home", new {#class="ajaxLink"})
Now you should have a container div in your page to which we will load the partial view content. May be your current view (index ?) , you can add a container view like this
<div id="pageContent"></div>
Now, let's listen to the click event on our links, get the content of the target page's via ajax and load to the container div. Assuming you have jQuery loaded to your page, we can use jQuery load() method.
$(function(){
//Load the first link's content on document ready
var firstLinkHref=$("a.ajaxLink").eq(0).attr("href");
$("#pageContent").load(firstLinkHref);
$("a.ajaxLink").click(function(e){
e.preventDefault();
$("#pageContent").load($(this).attr("href"));
});
});
Since we are loading partial page content to our placeholder div, we do not need to return the full markup(including layout) from your action methods, We just need to the partial view content. You may use the PartialView() method instead of View() method to achieve this.
public ActionResult GetSection1Data()
{
if(Request.IsAjaxRequest())
{
return PartialView();
}
return View();
}
Related
On our website we use a HubSpot registration form with custom styling that loads in a fancybox popup.
This is how it should look
Our problem is that we need to add an 'on click trigger' (see HTML and JS below) to load the dropdown with the right styling We want to form to work properly without the trigger. Without the click trigger it looks like below:
Also the dropdown isn't working when this form appears.
Our code looks like:
<div class="popup-mask">
<div class="popup sm" id="popup-gartner-get-in-touch">
<h4 class="section-title blue">Get in touch</h4>
<div class="download-form">
<div class="hubpop">
<div class="download-form">
<!--[if lte IE 8]>
<script charset="utf-8" type="text/javascript" src="//js.hsforms.net/forms/v2-legacy.js"></script>
<![endif]-->
<script charset="utf-8" type="text/javascript" src="//js.hsforms.net/forms/v2.js"></script>
<script>
$('a[href="#popup-gartner-get-in-touch"]').click(function() {
hbspt.forms.create({
portalId: "538005",
formId: "190bdb23-c363-4d93-8189-9c7d28782017",
target:'.hubpop',
});
});
</script>
</div>
</div>
</div>
</div><!-- end popup -->
</div><!-- end popup-mask -->
My guess is that you are using some kind of jQuery plugin to style the dropdown. The problem is, your code for that is trying to style something that doesn't exist in the DOM until that trigger is clicked. What you should do is put that jQuery plugin code into the forms onReady function.
hbspt.forms.create({
portalId: '',
formId: '',
onFormReady: function($form) {
// YOUR CODE TO MODIFY THE SELECT DROPDOWN SHOULD GO HERE
console.log($form.find('select'));
}
});
If you're just looking to style the form selects without using a jQuery plugin, you can use this tool to get the css needed to do that.
I have created a web application which should take input from website and display it on a new page. I notice that my code is not getting called at all.
Routes file - I call localhost:9000 first. test method in Data controller is called which displays an input box and a submit button. Problem is on clicking submit, nothing happens
GET /data controllers.Data.test
GET /data/post controllers.Data.post
Model - what I enter in input should get mapped to User object using a form and get displayed in new page
case class User (name:String)
Controller code
object Data extends Controller {
val userForm = Form((mapping("name"->text))(User.apply)(User.unapply))
//this gets called for url localhost:9000/data
def test = Action {
Ok(views.html.dataIndex(None))
}
//PROBLEM - this should get called on clicking submit button but it doesn't get called
def post = Action { implicit request =>
println("in post")
val u:User = userForm.bindFromRequest().get
Ok(views.html.dataIndex(Some(u)))
}
}
View
#(u:Option[User])
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" media="screen" href="#routes.Assets.at("stylesheets/main.css")">
<link rel="shortcut icon" type="image/png" href="#routes.Assets.at("images/favicon.png")">
<script src="#routes.Assets.at("javascripts/jquery-1.9.0.min.js")" type="text/javascript"></script>
</head>
<body>
#u match {
case Some(user) => {
<h1> You entered </h1>
<ul id="hardcode-list" >
<li>#user.name</li>
</ul>
}
case None => {
<h1>Feed User Data</h1>
<form action="/data/post" method="get">
<input type="text" name="name"/>
<input type="button" name="send" value="Submit"/>
</form>
}
}
</body>
</html>
What am I doing wrong?
Found the mistake. The button type should be 'submit'
Here is what i am trying
Layout
<!DOCTYPE html>
<html lang="en">
<head>
<title>WebApp Name</title>
<meta charset="utf-8" />
</head>
<body>
<div id="menuContainer">
#{Html.RenderPartial("~/Views/CustomPartials/_MainMenuPartial.cshtml");} #*Works*#
#*#{Html.RenderAction("GetMenuStructure", "Custom");}*# #*Not working*#
</div>
<div>
#RenderBody()
</div>
</body>
</html>
Controller and Action method
namespace Webappl.Controllers
{
[Authorize]
public class CustomController : Controller
{
[AllowAnonymous]
[ChildActionOnly]
public ActionResult GetMenuStructure()
{
return PartialView("~/Views/CustomPartials/_MainMenuPartial.cshtml");
}
}
}
_MainMenuPartial.cshtml
<ul id="ul_MainMenuStructure">
<li>Guest Pg1</li>
<li>Guest Pg2</li>
<li>Guest Pg3</li>
</ul>
The problem is
#{Html.RenderPartial("~/Views/CustomPartials/_MainMenuPartial.cshtml");}
Renders the contents of _MainMenuPartial.cshtml into the layout perfectly.
While
#{Html.RenderAction("GetMenuStructure", "Custom");}
Does nothing. No errors. No exceptions. Just blank. If i place a break-point at
return PartialView("~/Views/CustomPartials/_MainMenuPartial.cshtml");
The break-point is getting hit. I press F5 and it goes forward without any error/exceptions but menu structure does not get rendered in the layout. All I have is a blank
<div id="menuContainer">
</div>
in the final rendered page when I view it in the browser.
I need to do it through the action method for certain custom logic to be executed. Thats why a render partial is not sufficient.
I was not able to find similar behavior reported any where including stackoverflow. It could be bad binging/googling skills.
Some help will be so greatly appreciated. Banging my head on it for 3 days now.
I simply changed
#Html.RenderAction("X", "Y")
To
#Html.Action("X", "Y")
I've got a new solution that contains several project 'groups'. Each group contains a Cloud Project, a Web Role Project and a Test Project. All Web Role Projects are MVC4.
One of the Web Roles is the entry point for the visitor. Parts of what the visitor will see, should come from the other Web Roles from within the solution. I cannot get it working and after spending several hours googling, I still cannot solve it. Maybe anyone can be helpful on this issue.
For example, I need to fill the header content with data that I can get from one of the other Web Roles. Let's call that controller HeaderController. The controller in the main project (HomeController) looks like this:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
//var headerController = new Generic.HeaderFooterContainer.Controllers.HeaderController();
//var foo = headerController.Index().ExecuteResult();
//ViewBag.Header = headerController.;
return View();
}
In the comments are some things I've tried to debug some things.
Here's the page layout of the main project. The body is still empty, as this problem is just about the page header which could be placed as html from the ViewBag or ViewData or even with an own #section.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="headerHolder">
<div class="innertube">
<div id="header">
#ViewBag.Header
</div>
</div>
</div>
<div class="contentHolder">
<div class="innertube">
<div id="content">
#RenderBody()
</div>
</div>
</div>
<div class="footerHolder">
<div class="innertube">
<div id="footer">
</div>
</div>
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bms")
#RenderSection("scripts", required: false)
</body>
</html>
The problem I face is that I just can't find out how I should make this work. How do I get the data in the header? A few things I've noticed are:
If I run the HeaderFooterContainer project in its dedicated solution, it works alright (I can get /Header and get the expected response displayed in the browser window)
If I run the Main project, I can see the home page, but if I ask for /Header, it can find the controller, but not the view. It's probably looking for the view in the main project although it is located in the HeaderFooterContainer project.
I read a lot about how to add stuff dynamically in jquery mobile, but I couldn't figure out how to add links.
Currently my solution looks like this:
Add a new Page - with id (id="list-1")
Creating a Link for it (href="#list-1")
This solution works perfectly in static pages, but I want to do it dynamically. I have tried a lot with page() and stuff like that but nothing helped me.
My questions are:
How do I add dynamic links & pages?
Did I choose the right way to use ids & anchors (#list-1) as links or is there another solution for jquery mobile?
Let me know if you need more information
To add dynamic links, I have found the easiest way is to just have an event listener waiting for a click on those links. This event listener then saves any parameters you want to pass into the next page you are visiting. You pass the parameters from the list element to the event listener by just specifying parameters within each "li" element.
(create the HTML for a list dynamically & store it into list-1-html)
$("div#my-page div[data-role=content]").html(list-1-html);
$("div.list-1 ul").listview();
$("div.list-1 ul").listview('refresh');
Then your event listener would look something like:
$('#my-page').delegate('li', 'click', function() {
passedParameter = $(this).get(0).getAttribute('passed-parameter');
});
When jQuery Mobile loads your next page, you'll probably want to load this page dynamically and you'll have this passedParameter variable available to you. To load the page dynamically, just add a listener that waits for JQM to try to load the page:
$('[data-role=page]').live('pageshow',function(e, ui){
page_name = e.target.id;
if (page_name == 'my-page-2'){
(do something with passedParameter)
}
});
This is the workflow I use with jQuery Mobile and it has been working just fine. I'm guessing in future releases, though, that they'll build in some kind of support for passing dynamic parameters to pages.
Any new enhancement to the DOM should be done before the page initializes. But by default JQM automatically initializes the page once the page is load in browser.
Hence first you need to set autoInitializePage property to false and then call initializePage() method after the new page and links are add to the document. Hope this helps.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script>
$(document).bind("mobileinit", function(){
$.mobile.autoInitializePage = false;
});
</script>
<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
<script>
$(document).ready(function() {
//add a link.
$("#page1 div[data-role='content']").append('Next Page');
//add a page.
$('body').append(' <div data-role="page" id="page2" data-title="next page"><header data-role="header" class="header"> <h5>Page 2</h5></header><div data-role="content"><h3>Good Morning...</h3>Back</div><footer data-role="footer" data-position="fixed"><h5>© All rights reserved</h5></footer></div>');
});
window.onload = function() {
$.mobile.initializePage();
};
</script>
</head>
<body>
<div data-role="page" id="page1">
<header data-role="header" class="header">
<h5>jQuery Mobile</h5>
</header>
<div data-role="content">
<form method="get" action="" data-transition="slideup">
<label for="email">Email:</label>
<input type="email" name="email" id="email" value=""/>
</form>
</div>
<footer data-role="footer" data-position="fixed"><h5>© All rights reserved</h5></footer>
</div>
</body>
</html>