Reputation:
I need some advice.
(For those who have already read this before I have re-edited this question heavily)
I have developed some asp.net mvc web pages.
Each page has a master and some ascx controls (between 2 - 6) embedded into it a js and css file.
Up to now every thing was fine.
In order to improve modularity, flexibility and testability the ascx's are now expected to be able to work as stand alone controls.
(Each ascx has also got its own css and js files in some cases it has another control inside it)
In order to meet this requirement we call the controller with a query string.
(Different from the manner that it is called from the page - via Ajax)
The rendered ascx (partial) is presented in the browser without all of the other parts of the original page .
In this case, in order to get the partial to display correctly (css) and act correctly (js/jquery) all of the relevant files need to be added (for example: jquery) to the user control.
This contradicts the concept of positioning the files in the most logical place (could be the master page for example).
How can I overcome this problem?
Keep in mind that this is relevant for each "control" ascx file that is created in the application.
Case 1: In the page case it could be that a page has a few partials that are loaded using ajax while the page is being built. The partials might be called again using ajax according to the users actions. In this case I consider them as controls on a page.
Case 2: In the stand alone case the partial could be called as part of a test directly from the browser. In this case you only see the partial part in the browser.
Case 3: In the third case the partial could be called as part of an iframe within a google chrome extension (for example). In this case you can see the partial in a page that might not have been built in your web application.
For those that celebrate - Happy new year!
Upvotes: 3
Views: 1241
Reputation:
I am adding my own answer, it might be that my question was not clear enough. In any case if someone needs a solution this is where I am at the moment:
This is the bottom section of the partial (Control)
<%--
///-----------------------------------------------------------------------
/// <summary>
/// <title>Java Scripts Section</title>
/// Contains all links to java script files that are used by this
/// partial.
///
/// If the partial is part of a viewpage, only the partial's scripts
/// should be downloaded. (It was called using Ajax)
///
/// In the case that the partial acts as a stand alone control it needs
/// to fetch other scripts that are preloaded by the application.
/// (For example jQuery)
///
/// This is achived by identifying that the partial was not called
/// via Ajax in this case the list of Java Script files that have
/// been included is added to the HTML that then fetches them from
/// the server.
/// <ToDo>
/// A. Need to join and minify scripts to improve performance.
/// B. Consider identifing the Ajax call in the controller:
/// request.IsAjaxRequest().
/// </ToDo>
/// </summary>
///-----------------------------------------------------------------------
--%>
<%
string areaRoot = "~/Areas/Manufactor/";
string areaJsRoot = areaRoot + "JQuery/";
string dataLayer = areaJsRoot + "manufactorAjax.js";
string javaScript = areaJsRoot + "vucManufactorDetails.js";
%>
<% if (HttpContext.Current.Request.Headers.Get("X-Requested-With") != "XMLHttpRequest") { %>
<!-- #Include virtual="~/Include/GenericScripts.inc" -->
<script type="text/javascript" src="<%= ResolveUrl(dataLayer)%>">
</script>
<% }; %>
<script type="text/javascript" src="<%= ResolveUrl(javaScript)%>">
</script>
<%--
///-----------------------------------------------------------------------
/// <end>
/// This ends the ManufactorDetails.ascx file.
/// </end>
///-----------------------------------------------------------------------
--%>
This is the content of the include file:
<%--
///-----------------------------------------------------------------------
/// <summary>
/// <link>System generic Scripts</link>
/// The system generic scripts used to manage controls in the system.
/// </summary>
///-----------------------------------------------------------------------
--%>
<%
string jsRoot = "~/Scripts/";
string jqueryLink = jsRoot + "jquery-1.4.1.min.js";
string jqueryUI = jsRoot + "jquery-ui-1.8.4.custom.min.js";
string jqueryCorner = jsRoot + "jquery.corner.js";
string microsoftAjax = jsRoot + "microsoftAjax.js";
string microsoftMvcAjax = jsRoot + "microsoftMvcAjax.js";
string dataProvider = jsRoot + "dataProvider.js";
%>
<script type="text/javascript" src="<%= ResolveUrl(jqueryLink)%>">
</script>
<script type="text/javascript" src="<%= ResolveUrl(jqueryUI)%>">
</script>
<script type="text/javascript" src="<%= ResolveUrl(jqueryCorner)%>">
</script>
<script type="text/javascript" src="<%= ResolveUrl(microsoftAjax)%>">
</script>
<script type="text/javascript" src="<%= ResolveUrl(microsoftMvcAjax)%>">
</script>
<script type="text/javascript" src="<%= ResolveUrl(dataProvider)%>">
</script>
<%--
///-----------------------------------------------------------------------
/// End of GenericScript.inc
///-----------------------------------------------------------------------
--%>
I have applied similar logic for css files at the top of the partial.
Note:
The include file is always loaded.
In the case of the partial - that is part of the web application it is not processed.
Be happy and enjoy life, Julian
Upvotes: 0
Reputation: 78840
If you need to add content to the hosting page, you can have code in your .ascx file to do this server-side. For example:
<%
var link = new HtmlLink { Href = Url.Content("~/Content/Style/MySheet.css") };
link.Attributes["rel"] = "Stylesheet";
link.Attributes["type"] = "text/css";
Page.Header.Controls.Add(link);
%>
For this example to work, you must have a runat="server"
for your head
tag.
Upvotes: 2