I have searched and searched for an answer to this across the web, yet I have not found a "clearly stated" answer as to why this is happening. And I have re-worked to no avail.
I have a Asp.Net site, with a "Master Page" and few "Content" pages
There is a CSS file which successfully assigns a "background-image" in the body - for all the pages:
body { background-image: url('../Images/TestImage1.jpg'); }
I have another image, say TestImage2.jpg, which sits in same Images folder in the solution, and I want to display this image on a specific "Content Page" when that page loads. Yet, it is not loading on the page, and background just turns white without any image at all - here's my code:
My MasterPage has the correct items for runat="server":
<head runat="server">
<title></title>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
... and also...
<body runat="server">
<form style="height: 906px" runat="server">
Now, here's my code-behind for the content page I wish to have new image appear on Page_Load:
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class TechCall : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
StringBuilder script = new StringBuilder();
script.Append("<script type=\"text/javascript\">");
script.Append("document.body.style.background = \"url('../Images/CPUBack2nd.jpg')\";");
script.Append("document.body.style.backgroundRepeat = 'no-repeat';");
script.Append("</script>");
this.ClientScript.RegisterClientScriptBlock(this.GetType(), "changeBackground", script.ToString());
}
}
CPUBack2nd.jpg is the actual of name of the image in place of TestImage2.jpg, but as far as I can see, I am using the correct path for the image, as like the one in the CSS file which defines the default background image. Yet, when the page loads, no image at all appears for the background - just a white space, and original image appears on other pages correctly.
Can someone examine and tell me what I am missing here? Note: please don't suggest JQuery, as if it can be solved using Javascript, then I wish to stick with this usage, as I just want to learn to make it work with JS.
I'd suggest not using javascript at all. You should have a handy ContentPlaceHolder in the header section. Add the following in there to overide the default body style
<style type="text/style">
body { background-image: url('../Images/TestImage2.jpg'); }
</style>
As this will appear in the page after the head contents of the materpage it will overide the earlier CSS.
I would also consider using Root Releative paths particularly on master pages as it makes the releative location of the calling document and the called resource irrelevant. In which case change the above to:
<style type="text/style">
body { background-image: url('/Images/TestImage2.jpg'); }
</style>
Assuming that the Images directory resides at the root level of your document.
If you really want to persist with javascript. Check the path or use Root Relative. Remember that the path is relevant to the document calling the resorce. So just because a path works in a CSS file does not mean it will work in a page which sits at a diferent level of the website. Use a CSS debug tool Like FireBug for Firefox (a free download) or Developer Tools in Chrome (in built) to check if the image was at the expected location.
After much wrangling, moving some things around and isolating them in the CSS style sheet to clean up the Master page, where I had some stray CSS classes, AND of course building on the "hunch" provided by Jon P on possible root relative with Javascript, here's what did it:
Instead of using this:
script.Append("document.body.style.background = \"url('../Images/TestImage1.jpg')\";");
The answer was to use this:
script.Append("document.body.style.background = \"url('/MyProjectName/Images/TestImage2.jpg')\";");
So, I don't know why I had go all the around the world it seems to figure that out, but I guess that's how it is with programming... the difference ALWAYS lies in the LITTLE THINGS!
Thanks to all who contributed to getting me to think about what was going on here! Hence, the lesson is also THIS CAN BE DONE WITH JAVASCRIPT. :)
Related
I have a problem where I am trying to have a default CSS page, but depending on certain aspects can have their CSS changed. Groups of people can have their CSS changed to their own custom version via database entries, they post a long string that has what the CSS needs to be set to. But, they can also do something simple and simply want to overwrite maybe just the background or the entire site.
<head>
<link href="/static/css/styles.css" rel="stylesheet" />
<style type="text/css">
#{
WebExtensionHelper.CustomCSS();
}
</style>
</head>
WebExtensionHelper.CustomCSS() returns a string with all the CSS in it, as stated previously. I need this to affect every page so I need this on the _Layout.cshtml page. Another thing to consider if it's helpful, I will have about 200 people who would like customcss.
One solution is to generate a custom CSS file at run time. In your layout you can point the stylesheet link to a controller action instead of an actual file:
<link href="#Url.Action("Index", "Style", new { whichStyle = myValue })" rel="stylesheet" type="text/css" />
In the Style controller, create an Index method:
public ActionResult Index(string whichStyle)
{
MyStyleViewModel model = new MyStyleViewModel();
// -- (Load relevant style settings here) --
Response.ContentType = "text/css";
return View(model);
}
And then in the Index view, write out css as normal:
#model MyStyleViewModel
#{ Layout = null; }
body
{
color:#333;
#if (Model.Font == "Lucida")
{
#:font-family:"Lucida Grande", sans-serif;
}
else
{
#:font-family:Georgia, Serif;
}
}
I haven't run that exact view code, so adjust as needed for your situation.
You could simply use LESS. It is supported in Visual Studio 2012 (and 2010) and MVC 4, so it is easy enough to use, and will do exactly what you want. It is perfect for your scenario.
Setting up LESS requires more work than I can put into an answer here, so as much as I hate to do this, here are two links:
http://geekswithblogs.net/ToStringTheory/archive/2012/11/30/who-could-ask-for-more-with-less-css-part-2.aspx
http://www.hanselman.com/blog/VisualStudio2012RCIsReleasedTheBigWebRollup.aspx
http://richardneililagan.com/2012/08/automatic-dotless-compile-less-css/
Once set up you can either compile on the server side with Dot LESS, as mentioned in the last link above, or send it to be processed on client side with javascript.
It should be
#WebExtensionHelper.CustomCSS();
not
#{
WebExtensionHelper.CustomCSS();
}
Sorry for those who tried to help me earlier, I was unable to copy and paste my code at the time, and noticed in my question that I answered my problem.
So I'm trying to use C# to grab stored HTML in a database and then display it between a set HTML header and footer (I have a couple of these for different pages, so a masterpage would make life more complicated rather than less. I also come from a PHP background where this is sort of the way things work).
<!--#include virtual="header.html" -->
<% #Page Language="C#" Debug="true" %>
<% #Import Namespace="System.Data.Odbc" %>
<% #Import Namespace="System.Web.Configuration" %>
<script language="C#" runat="server">
void Page_Load(object sender,EventArgs e) {
//Gets the HTML Successfully
//Response.Write(fetched_html);
}
</script>
<!--#include virtual="footer.html" -->
Unfortunately with the current workflow the code generates content before the header or footer are put on the page, putting all the stored HTML at the top of the page before the header. I've tried a couple different Page_Events and none of them seem to work, so I need to know what to do.
Is there an equally simple way to reference and insert a simple html header file that would render before any of the Page_Events? I've tried Page_PreLoad and others to no success. Either the code is not fetched at all or I run into the same issue.
Use a MasterPage with a ContentPlaceholder. Then, on the content page, use a Literal and put the HTML in there.
See "The difference between literal and label".
Try this:
Assuming you have data holding some where in memory like datatable or dataset or collection.
To display a html text on the page we generally use <asp:Literal/>. So place a asp literal control on the page. It works in between <body> </body> tag.
Now render the text to the control using its Text property. e.g.
ltl.text = dt.rows[0]["htmlcol"].tostring();
To dynamically add text inside <head> </head>, u need HtmlMeta,Page etc class.
I added this in the head section of my page as told in the article..added the following two additional lines to get rid of the background image(RADEditor on my page is inheriting master page's bg image)
.reContentCell
{
background-image:none;
background-color:White;
}
.reDropDown{color:Aqua;}
Why are the changes not taking place?
[EDIT]
added !important to both the properties above...still can't see no change
[EDIT]
I am using RADEditor in like MANY pages soo was wondering if I can do some coding in the Master Pages ..like in Master Page I can detect if there's some radEditor in any of the ContentPlaceholders..then I can add the CSS file to be used for that Editor so it doesn't inherit master page's CSS properties...so how do i go about it ?? How do I search for radEditor in Content pages and then add CSS to it ???
[EDIT]
I have already tried the following :-
ie adding CustomSkin's CSS classes to Editor
<telerik:RadEditor ID="Editor1" EnableEmbeddedBaseStylesheet="true" runat="server">
<CssFiles>
<telerik:EditorCssFile value="Skins/CustomSkin/Editor.CustomSkin.css"/>
<telerik:EditorCssFile value="Skins/CustomSkin/Editor.CustomSkin.css"/>
<telerik:EditorCssFile value="Skins/CustomSkin/Editor.CustomSkin.css"/>
</CssFiles>
</telerik:RadEditor>
In the page's head section :-
I gave reference of CSS files...now its working fine..Editor is not getting screwed up or anything coz of Master page's CSS ...BUT what I want is some way to do this in the master page's code itself like I said above..plz help..thnx
[EDIT]
Master page's code behind :-
if(ContentPlaceHolders.Contains("what to type here??")){}
Intellisense is not showing Telerik RadEditor option in the drop down list
Is there some other way to add Editor's CSS files programmaticaly in master page's code behind??
use
.reContentCell, .reContentCell iframe
{
background-color:#FFFFFF !important;
}
because the original css file is adding a background colour to both the cell and the iframe.
Style sheet in master page is not working for one web page of asp.net application but it works for another web page.
If you are referencing a css file from a master page you should ensure it has an absolute path, that way it will work everywhere. For example:
<head runat="server">
<link type="text/css" rel="stylesheet" href="~/_styles/mystylesheet.css" />
</head>
The important thing to note here is that the head tag has the runar="server" attribute and that i am specifying the full virtual path using a tilde ("~").
Are none of its style elements being included? Is it being over ridden( they are Cascading Style Sheets)? Does it have the correct CSS include statement?
Are your pages in different levels of folders ?
For example,
..\main.css
..\folder1\MasterPage.master
..\folder1\css_working.aspx
..\folder1\folder2\css_not_working.aspx
in this scenario you should define your css in masterpage as :
<link rel="stylesheet" type="text/css" href="../main.css" />
And take your pages to same level, like that :
..\main.css
..\folder1\MasterPage.master
..\folder1\css_working.aspx
..\folder2\css_not_working.aspx
If you are using update panels there are some cases where the styling may be lost for AJAX toolkit controls. To fix this you need to put hte full name of hte class items into the stylesheet instead of letting hte toolkit handle this.
Also be sure to use a relative url where possible so that if a file moves it won't loose it's mapping.
Use Firebug or Debug Bar, these tools will show you all the styles being employed on each element, so you can see what stylesheets it is using and which ones it is not.
Also, when you build check for any warnings about stylesheets that it can't reference etc.
it could be a permission issue on the folder... if you have deny users="?" in your web config.. make sure you have an allow users on the folder where you have your style sheets
I have run in to a bit of a problem and I have done a bit of digging, but struggling to come up with a conclusive answer/fix.
Basically, I have some javascript (created by a 3rd party) that does some whizzbang stuff to page elements to make them look pretty. The code works great on single pages (i.e. no master), however, when I try and apply the effects to a content page within a master, it does not work.
In short I have a master page which contains the main script reference. All pages will use the script, but the parameters passed to it will differ for the content pages.
Master Page Script Reference
<script src="scripts.js" language="javascript" type="text/javascript" />
Single Page
<script>
MakePretty("elementID");
</script>
As you can see, I need the reference in each page (hence it being in the master) but the actual elements I want to "MakePretty" will change dependant on content.
Content Pages
Now, due to the content page not having a <head> element, I have been using the following code to add it to the master pages <head> element:
HtmlGenericControl ctl = new HtmlGenericControl("script");
ctl.Attributes.Add("language", "javascript");
ctl.InnerHtml = #"MakePretty(""elementID"")";
Master.Page.Header.Controls.Add(ctl);
Now, this fails to work. However, if I replace with something simple like alert("HI!"), all works fine. So the code is being added OK, it just doesn't seem to always execute depending on what it is doing..
Now, having done some digging, I have learned that th content page's Load event is raised before the master pages, which may be having an effect, however, I thought the javascript on the page was all loaded/run at once?
Forgive me if this is a stupid question, but I am still relatively new to using javascript, especially in the master pages scenario.
How can I get content pages to call javascript code which is referenced in the Master page?
Thanks for any/all help on this guys, you will really be helping me out with this work problem.
NOTES:
RegisterStartupScript and the like does not seem to work at any level..
The control ID's are being set fine, even in the MasterPage environment and are rendering as expected.
Apologies if any of this is unclear, I am real tired so if need be please comment if a re-word/clarification is required.
Put a ContentPlaceHolder in the head section of the master page, then add a asp:Content control on the content page referring to the placeholder and put your script in that control. You can customize it for each page this way.
Also, the reference by ID may not be working because when you use Master Pages, the control IDs on the page are automatically created based on the container structure. So instead of "elementID" as expected, it may be outputting "ctl00_MainContentPlaceHolder_elementID" View your source or use firebug to inspect your form elements to see what the IDs outputted are.
Isn't it possible to do with clean javascript ?-)
-- just add something similar to this inside the body-tag:
<script type="text/javascript">
window.onload = function(){
MakePretty("elementID");
}
</script>
By the way the script-tag has to have an end-tag:
<script type="text/javascript" src="myScript.js"></script>
Why not use jQuery to find all the controls? Something like this:
$(document).ready(function(){
$("input[type='text'], input[type='radio'], input[type='checkbox'], select, textarea").each(function(){
MakePretty(this);
});
});
This way you'll get all elements on the page, you can wait until the page is ready (so you don't modify the DOM illigally). The jQuery selector can get the elements in a bit more of a specific format if you need (ie, add a root element, like the ID of the body div).
It'd also be best to modify the MakePretty method so it takes the element not the ID as the parameter to reduce processing overhead.
Once you use Master Pages, the ids of controls on the client side aren't what you think they are. You should use Control.ClientID when you generate the script.
When using master pages, you need to be careful with the html attribute ID, since .NET will modify this value as it needs to keep ids unique.
I would assume your javascript is applying css styles via ID, and when you are using master pages the ID is different than what is in your aspx. If you verify your javascript is always being added, your answer needs to take into account the following:
ALWAYS set your master page id in page load (this.ID = "myPrefix";)
Any HTML element in your master page will be prefixed by the master page id (i.e.: on the rendered page will be "myPrefix_myDiv")
Any HTML element in your content place holder id will be prefixed with an additional prefix (i.e. myPrefix_ContentPlaceHolderId1_myDiv)
Please let me know if I can clarify anything. Hope this helps!