ASP.NET MVC 3 RenderPartial / Razor and the iframe - asp.net

I want to render a PartialView inside a <iframe src=''></iframe> The rendered partial view has its own JavaScript code and the CSS sheet. I tried two ways to get this work (none of them worked):
1)
<iframe src="http://localhost:54351/Box/19"></iframe>
public PartialViewResult Box(int id)
{
return PartialView(GetBox(id));
}
Result: the plain text (string), there is no the CSS sheet and the JavaScript code doesn't work
====================================
2)
<iframe src="#{ Html.RenderPartial("~/Views/Box.cshtml", #Model); }"></iframe>
Result: Obviously it's doesnt work,
nothing shows inside the iframe
In the first solution, I was wondering if is it possible to return maybe a RazorView object (or something) which will have working JavaScript code and the CSS sheet. Any ideas ?

I believe you need to return a full View rather than a PartialView. Partial views don't automatically pick up the layout (because they are designed to slot into an existing page). Since an IFrame is completely independant of the parent page, it will need it's own stylesheet and script reference tags.
public ActionResult Box(int id)
{
return View(GetBox(id));
}

I think you are misunderstanding both partial views and iframes.
An iframe renders an entire web page, not just a partial one, inside of another web page. The iframe must have a complete URL that is a different page from the current page (if it was the same page, it would try to render the iframe within itself over and over creating an infinite loop).
What you need to do is specify the URL of a different action that returns a full view. If you render a partial view, there is no <head> tag, and therefore no script tags typically associated in a head tag. no <link> tags, no title, etc...

Related

PartialViews in ASP.NET MVC4

I've noticed there are several ways to use Views and PartialViews:
RenderAction, RenderPartial, and "return PartialView"
RenderAction when placed inside HTML, will simply call an Action and Render the View returned (the View returned can be partial view or view?)
RenderPartial will simply retrieve the contents of a View without executing any Controller action
Finally, what's the difference between "Return View" and "Return PartialView"?
Thanks
return View() returns the view with a Layout enabled so you get full HTML page with <html> and <body> tags. return PartialView() on the other hand disables the Layout and you get only the HTML fragment contained in this view. Actually when working with the Razor view engine I prefer to talk about templates and not views and partial views. That's because a view is a template and a partial view is a template without a layout. But in both cases it's a Razor template.

Hide content in master page from view page

I have a master page which is shared between about 20 views. In just one view, I need to make one small adjustment to the master page (I need to hide a textbox).
How can I include css or javascript in my view to acheive this?
Or is there some clever trick like including a conditional <% if (View.Name = "blah") { ... } %> that I can stick in my master page?
Thanks for any hints.
As you said you can write a JavaScript code to achieve your goal and include it only in one view. In one of my projects I do the same: I have jQuery AJAX request only at one view, so I just used script tags to include it

Best placement for javascript in Asp.net MVC app that heavily uses partial views

What is the best place for javascript that is specific to a partial view? For example, if I have a partial view (loaded via ajax call) with some divs and I want to turn those divs into an accordian, would it be better put the $("#section").accordion() in script tags inside of the partial view, or in a .js file in the function that retrieves that partial view and inserts it into the DOM?
Obviously, common methods I will be keeping in a .js file, however I am more talking about javascript very specific to the partial view itself.
Most things I find on the net seem to say to put all javascript into a separate .js but nothing addresses the idea of partial views.
You can think of partial views as just more html in your web page, if that will help. The browser makes no distinction between html within the partial view, and the rest of the html surrounding it.
By that logic, the best place to put Javascript (including references to outside scripts) in a web page (whether it contains html that is part of a partial view or not) is in its canonical location at the bottom of the page, although there are exceptions.
If it will help the organization of your code, feel free to put the Javascript code that is specific to the partial view html in its own script file, and reference it in the web page at the bottom, with the rest of the script. Doing this will make no difference to the browser.

MVC: capture route url's and pass them to javascript function

Short:Is there a way to have a route-definition that will pass the "CONTROLLER/ACTION" string value to a JavaScript function in stead of actually going straight for the controller action?
More:I have a masterpage which contains the navigation of the site. Now, all the pages need this navigation wrapped around it at all times, but because I didn't want the navigation to constantly load with each pagecall, I changed all my pages to partialviews.
These partial views are loaded via the JQuery.Load() method whenever a menu item is clicked in the navigation.
This all worked very good, up till now because I noticed it's also a requirement of the website to be able to link directly to page X, rather then default.aspx.
So, as an example:The main page is my "default.aspx" page, this utilizes my master page with the navigation around it. And each call to a new page uses a javascript function that loads that particular partial view inside a div that is known in my masterpage. So, the url never changes away from "default.aspx", but my content changes seemlesly.
The problem is, those url's also need to be available when typed directly into the address bar. But, they're partial views, so loading them directly from the address bar makes them display without any masterpages around them. Therefore my question if it might be possible to capture the route typed into the address bar and pass that on to my JavaScript function that will load that route in the content div.
(I hope I explained it ok enough, if not, feel free to ask more information)
You are 100% correct to not want to hard code your URLs in your javascript code as it demolishes one of the primary tenants of MVC to do so. I'm one of those "separation of concerns" guys who will not write a single line of javascript outside of a dedicated .js file so I cannot dynamically specify the URL the way tuanvt has. What I do is use MVCs Url.Action method to emit my service URLs into hidden inputs on the master page (or the specific page if it is not used in multiple places). Then my script file simply pulls the value out of that hidden input and uses it just fine.
ASP.NET MVC View Source
<input id="serviceUrl" type="hidden" value="<%= Url.Action("Action", "Controller") %>" />
JS Source
$.getJSON($("#serviceUrl").val(), function(data) {
//write your JS success code here to parse the data
});
First challenge, as you are using AJAX to load the partial pages you need client accessible URLs for the javascript to call. Second challenge, you need URLs that will load the HomeController and pass the 'page' portion of the URL into the javascript.
For the first aspect I'd create some abstracted routes, i.e. "/ajaxaccess/{controller}/{action}/{id}" for the partial pages. That would be the first registered route. A second route would accept any controller/action reference and always get processed by the HomeController Index action.
In the /Home/Index action you grab the requested URL and slice it up, take the /{controller}/{action}/... section and pass that into your default.aspx using TempData. In your page check for the existence of the TempData and if it exists use the value therein to trigger your AJAX page load for the partial page (don't forget that you'll need to prepend '/ajaxaccess' (or whatever you choose) to the URL before it's passed to your page.
I'm not going to provide code here as I think the information you'll gain from working through this yourself will be invaluable to you moving forward.
You could use hash anchor (#) on your url and read it with javascript.
var url = document.location.toString();
if (url.match('#')) {
anchor = url.split('#');
// do whatever with anchor[1] ..
}
You can do something like this, put this in your javascript code on the view:
var szUrl=<%= ViewContext.RouteData.Route.ToString()%>;
Then the current route will be stored on the variable szUrl.

Parent.FindControl() not working?

I have a page that has an iframe
From one of the pages within the iframe I want to look back and make a panel on the default page invisible because it is overshadowing a popup
I tried using Parent.FindControl but it does not seem to be working. I am positive I have the right id in the findcontrol because I used Firebug to inspect the panel and I copied the id from there
Does anyone know what I am missing?
I didn't completely follow your problem, but I'll take my best shot.
It sounds like you have an ASP.NET page, that has an iframe in it that refers to another ASP.NET page, and in that page that was requested by the iframe you want to modify the visibility of the item contained in the page that contains the iframe.
If my understanding of your problem is correct, then you have some somewhat nasty problems here.
What's actually happening at the browser level is the first page gets loaded, and that page has an iframe in it that is making a second request to the server.
This second request can't FindControl your control, because it isn't in the same page, and isn't alive during that request.
So you have some alternatives here:
Get rid of the iframe and use a panel. This will put them both in the same request, and able to find each other.
(Additionally) When you do this you are going to want to use Page.FindControl() not Parent.FindControl() as the FindControl method just searches through the Control's child control collection, and I presume your control will be somewhere else on the page.
On the client side in the iframe you could use some javascript code to access the outer page's DOM, and set the visibility of it there.
Parent document:
<body>
<input type="text" id="accessme" value="Not Accessed" />
...
</body>
Document in iframe:
<head>
...
<script type="text/javascript">
function setValueOfAccessme()
{
window.parent.document.getElementById("accessme").value = "Accessed";
}
</script>
</head>
<body onload="setValueOfAccessme();">
</body>
The document inside the iframe accesses the document object on the window object on load, and uses the getElementId() function to set the value of the input inside the body of the parent document.
For starters, FindControl isn't a function in Javascript.
Alternatively here's a more helpful find control routine...
Public Shared Function MoreHelpfulFindControl(ByVal parent As UI.Control, ByVal id As String) As UI.Control
If parent.ID = id Then Return parent
For Each child As UI.Control In parent.Controls
Dim recurse As UI.Control = MoreHelpfulFindControl(child, id)
If recurse IsNot Nothing Then Return recurse
Next
Return Nothing
End Function

Resources