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.
Related
I am displaying Grid using Grid.Mvc, sorting & paging are working but filters are not shown on the grid though I added ".Filterable(true).WithMultipleFilters()" to Grid. Below is my code. GridMvc.css is in place, Did I missing something? Thanks in advance!
#Html.Grid(Model.List).Columns(c =>
{
c.Add(o => o.key, true);
c.Add(o => o.listitem1).Titled("listitem1");
c.Add(o => o.listitem2).Titled("listitem2");
c.Add(o => o.listitem3).Titled("listitem3");
c.Add(o => o.listitem4).Titled("listitem4");
}).WithPaging(10).Sortable(true).Filterable(true).WithMultipleFilters()
I too had the same problem, few days back ,when i implemented mvc.grid in our project.
I have resolved the problem by adding the following code in the master page.
Code:
<html>
<head>
<link href="~/Content/MvcGrid/mvc-grid.css" rel="stylesheet">
</head>
<body>
#RenderBody()
<script src="~/Scripts/JQuery/jquery.js"></script>
<script src="~/Scripts/MvcGrid/mvc-grid.js"></script>
<script>
$('.mvc-grid').mvcgrid();
</script>
</body>
</html>
And Apart from this , kindly make sure the path of files(mvc-grid.css,jquery.js,mvc-grid.js) are correct because that can create the Huge problem
One important thing here is , this line of code
<script>
$('.mvc-grid').mvcgrid();
</script>
Should be place inside the body tag, I have tried to place that in head tag it is not working, if you place inside the body tag then only it will work.
If the information doesnt help you, no worries, they have given official installation documentation here:
http://mvc6-grid.azurewebsites.net/Home/Installation
Kindly follow that you will surely get it. All the best
Please let me know your thought or feedbacks.
Thanks
Karthik
You need to reference Gridmvc.css in your view.
I had this same problem, the gridmvc.js and gridmvc.css files were not loading and the problem with that is because I had them inside a #section{} function within a partial view. You can not use #section{} inside a partial view. Move it up in the tree and you will should be fine.
I was struggling with the exact same issue, and this topic almost helped. Even there was something missing...
That thing was the path to the gridmvc file, you must adapt it to "your" project.
For instance, mines are located in different folders, different than the ones showed in the validated answer;
and the names are slightly different.
But once I corrected both lines, in my _layout.cshtml file the grid was perfectly working!
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. :)
So I'm trying to create a custom editor so that for a DataType of "Duration" a textbox appears with a masked format of HH:MM:SS.
I've created a very simple piece of code so far
#Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { #class = "text-box single-line", type = "duration" })
<script>
$(document).ready(function () {
$("##Html.NameFor(c => c)").mask("00:00:00");
});
</script>
This is in my ~/Views/Shared/EditorTemplates/Duration.cshtml file. However it requires an additional javascript to be loaded (maskedInput.js).
Is there any razor includes I can use here so that I can include the maskedInput.js file once and only once in a page load. I realise I could add it to the parent page the editor will be on (but that would require knowing every page where this editor is used). I could add it to the master layout view but this would mean overhead for the pages that don't use this editor.
So I suppose in summary all I'm asking is :- "Is there a way to include a javascript file once and only once from a EditorTemplate".
I wrote a nuget package exactly for this purpose and wrote the blog post that YD1m has referred to.
To use the package, first thing you need to do is add a call to Html.RenderScripts() somewhere in your layout so that all of the script file references and blocks added using the helpers during the rendering of a Razor view are outputted in the response. The typical place to put this call is after the core scripts in your top level layout. Here's an example layout:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>#ViewBag.Title</title>
<meta name="viewport" content="width=device-width">
</head>
<body>
#RenderBody()
<script src="~/Scripts/jquery-2.0.2.js"></script>
#* Call just after the core scripts in the top level layout *#
#Html.RenderScripts()
</body>
</html>
If you're using the Microsoft ASP.NET Web Optimization framework, you can use the overload of Html.RenderScripts() to use the Scripts.Render() method as the function for generating scripts:
#Html.RenderScripts(Scripts.Render)
With that done, now all you need to do in your editor template is use the helpers in the nuget package to add a reference to the script and add your code block
#Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { #class = "text-box single-line", type = "duration" })
#using (Html.BeginScriptContext())
{
Html.AddScriptFile("~/Scripts/maskedInput.js");
Html.AddScriptBlock(
#<script>
$(document).ready(function () {
$("##Html.NameFor(c => c)").mask("00:00:00");
});
</script>);
}
The referenced script file will only be added once to the page and all of the script blocks will be written out at the end of Html.RenderScripts() call.
Using the helpers, you can add script files and script blocks in Views, Partial Views and Editor/Display Templates. Note that the current version (1.1.0.0) will not render out scripts using the helpers when called via AJAX but this is something that I'm looking to add in the next version.
Well, you can do following:
Add #RenderSection("MaskedInput", false) to your master layout. That'l render
#section MaskedInput{}
on each page that has that section;
On a page you need to add maskedInput.js you put:
#section MaskedInput
{
#*Include scripts, styles or whatever you need here*#
}
You can create singleton class with Dictionary property whic will store scripts from your custom helpers/templates.
In your templates you can call method, that put script in singleton dictionary property with some string key. In that method you can prevent adding scripts with same keys.
Finally you should to write a render action for rendering scripts from dictionary and call this action from your master layout.
Here you can find solution similar to mine:
Managing Scripts for Razor Partial Views and Templates in ASP.NET MVC
I am using MVC/Razor/.Net/C# and i would like to allow users to change the theme of the site just like you can change the theme in microsoft windows.
Does anyone know how to, or, can point me in the direction of some good tutorials/examples.
Cheers
This is a very, very broad question with any number of correct approaches.
You could create a base controller that loads the user's selected CSS theme name from a database during each request. Then you can put that value into the ViewBag (or ViewData) and reference it in your view:
<head>
#{
var themeName = ViewBag.ThemeName;
}
#if (String.IsNullOrWhiteSpace(themeName)) {
themeName = "default";
}
<link href="#Url.Content(String.Format("~/themes/{0}.css", themeName))" type="text/stylesheet" />
</head>
Usually this functionality is achieved with multiple CSS files and has little (or nothing to do with .NET).
You should design your HTML in a semantic way so that by changing the CSS files the entire output is different with each CSS applied.
This link gives a more explanatory intro into the subject -> http://www.thesitewizard.com/css/switch-alternate-css-styles.shtml
After you do that, what you need to do in your application is to store the user preference (of what skin) in a session or something like that and change the CSS file accordingly.
Asp.Net WebForms use to have the Skin/Theme feature, but I think that it was deprecated (it is not very good) and I also saw an implementation where instead of HTML the developer used XML and XSLT files to render the views (which is also too complicated for my taste).
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is there a CSS parser for C#?
I'd like to access some CSS properties of my website defined in an external .css file at runtime. I've found that there is a way to programmatically set css properties in the codebehind, but I haven't come across any way to read the ones that are already defined. (I'm using C#)
You can read them "at run time" only using client side script.
With jQuery it's really simple, plus you can then send the value to the server using AJAX then handle it or store it for later use.
If it's valid option let me know and I can post basic example of what I mean.
Basic example
First, the HTML used:
<div class="mydiv" id="testDiv">I'm red</div>
<button type="button" id="testButton">Test</button>
CSS:
<style type="text/css">
.mydiv { background-color: red; }
</style>
Now you have to include jQuery:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
And finally have this JS code:
<script type="text/javascript">
$(document).ready(function() {
$("#testButton").click(function() {
var oDiv = $("#testDiv");
var sColor = oDiv.css("background-color");
$.get("TestZone.aspx?cssvalue=" + sColor);
alert("value has been sent");
});
});
</script>
This will send the runtime background color of the test div to the server when the button is clicked, and in the code behind of TestZone.aspx you can handle the value. The example send it over the querystring you can same way send it as POST data if you prefer.
This is the way to get the display value for aWebControl in the code behind:
aWebControl.Style["display"]
ASP.NET only deals with the markup of the page itself.
You can programmatically get or set inline styles (CSS declared inline with an element using the style attribute) using the WebControl.Style property. This gives you a collection of name/value pairs that represents the inline style for that element.
control.Style["font-family"] = "Verdana";
Inline styles are considered pretty unpleasant, so don't use them unless you have a really good reason.
Anything outside of the page, you cannot access with ASP.NET natively. Essentially, the external stylesheets are only loaded by the browser rendering the page and aren't handled by the ASP.NET runtime, so you don't get a chance to inspect them.
If you want to interpret those files, you will need to load them manually and parse them with a CSS parser. Have a look at this question for possible solutions:
Is there a CSS parser for C#?