I have a set of stylesheets with different colour options. I have created a user control with a list of the stylesheet options which are setup as linkbuttons. On click I set a session variable with the path of the stylesheet I want to use, then on the master page I check this session and set the stylesheet accordingly.
The problem is that the stylesheet changes don't take effect until I refresh the page again. How can I force the stylesheet to reload instantly?
Here is my usercontrol:
<ul id="swatch">
<li>
<div class="green"></div>
<asp:LinkButton ID="lbGreen" runat="server" Text="Green" ClientIDMode="Static"
onclick="lbGreen_Click"></asp:LinkButton>
</li>
<li>
<div class="maroon"></div>
<asp:LinkButton ID="lbMaroon" runat="server" Text="Maroon" ClientIDMode="Static"
onclick="lbMaroon_Click"></asp:LinkButton>
</li>
<li>
<div class="silver"></div>
<asp:LinkButton ID="lbSilver" runat="server" Text="Silver" ClientIDMode="Static"
onclick="lbSilver_Click"></asp:LinkButton>
</li>
<li>
<div class="black"></div>
<asp:LinkButton ID="lbBlack" runat="server" Text="Black" ClientIDMode="Static"
onclick="lbBlack_Click"></asp:LinkButton>
</li>
</ul>
Here is the code behind for this control:
public partial class StylesheetPicker : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void lbGreen_Click(object sender, EventArgs e)
{
SetStylesheet("green");
}
protected void lbMaroon_Click(object sender, EventArgs e)
{
SetStylesheet("maroon");
}
protected void lbSilver_Click(object sender, EventArgs e)
{
SetStylesheet("silver");
}
protected void lbBlack_Click(object sender, EventArgs e)
{
SetStylesheet("black");
}
private void SetStylesheet(string selectedStyle)
{
switch (selectedStyle)
{
case "green":
Session["style"] = "/css/green.css";
break;
case "maroon":
Session["style"] = "/css/maroon.css";
break;
case "silver":
Session["style"] = "/css/silver.css";
break;
case "black":
Session["style"] = "/css/black.css";
break;
default:
Session["style"] = "/css/green.css";
break;
}
}
}
and then here is the code snippet I have on my master page:
if(Session["style"] != null)
{
var stylesheet = Session["style"];
<link rel="stylesheet" type="text/css" href="#stylesheet" />
}
else
{
<link rel="stylesheet" type="text/css" href="/css/green.css" />
}
It seems I have to click the linkbuttons twice to get the stylesheet to change. How can I do it so when the button is clicked it changes instantly?
Thanks
Give your stylesheet link element an id, then you should be able to change the href on it to something else. This code works in chrome, not sure about other browsers:
<link id="userStylesheet" rel="stylesheet" type="text/css" href="/css/green.css" />
Javascript to change it:
var linkTag = document.getElementById('userStylesheet');
linkTag.href = "css/maroon.css";
For the server side problem you could problem just redirect after they postback a change to it to get it to take effect on the next page load.
create a placeholder for your stylesheet in the master page, then you can set the stylesheet on the Page_Load/postback and not have to refresh the page?
in fact Adding StyleSheets Programmatically in Asp.Net seems to be what you are after.
If I remember correctly what ends up happening is that the session variable is getting set after the masterpage has already evaluated the if. The second click is just serving to reload the page one more time after the session variable is set in the first click (but to late to evaluate from the master.
These days there are better ways of doing this, but if you really want to make this approach work you are going to have to do something like force a page reload after the variable is set, or evaluate the post data earlier than the master page's render manually.
Related
So there's a ListView element on my ASP.NET page that I need to be able to update from the code behind. To my understanding, Microsoft has prepared UpdatePanels and DataBindung for exactly such purpose, allowing me to "bind" the ListView's content to a property member in the code behind and promising to take care of updating the browser's view automatically (?) when the property changes.
However, only the initial load of items via GetStuff() works; I can see in the debug console that my timer keeps adding new elements to the List, but those never arrive in the browser's view. What am I missing?
In Default.aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="myLittleProject.Default" %>
<%# Register Src="~/StuffListItemControl.ascx" TagPrefix="stf" TagName="StuffListItem" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<!-- some irrelevant stuff -->
</head>
<bod>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager" runat="server"></asp:ScriptManager>
<!-- some irrelevant stuff -->
<asp:UpdatePanel runat="server" ID="StuffUpdatePanel" UpdateMode="Always">
<ContentTemplate>
<ul>
<asp:ListView ID="StuffBoundContent" runat="server">
<ItemTemplate>
<stf:StuffListItem runat="server" ID="StuffListItemControl" />
</ItemTemplate>
</asp:ListView>
</ul>
</ContentTemplate>
</asp:UpdatePanel>
<!-- some more irrelevant stuff -->
</form>
</body>
</html>
And in Default.aspx.cs:
using System.Collections.Generic;
namespace myLittleProject
{
public partial class Default : System.Web.UI.Page
{
public static List<Stuff> StuffContent;
protected void Page_Load(object sender, EventArgs e)
{
StuffContent = Stuff.GetStuff(); // returns a list of three elements from the database
System.Timers.Timer t = new System.Timers.Timer();
t.Interval = 3000;
t.Elapsed += T_Tick;
t.Enabled = true;
}
protected void Page_PreRender(object sender, EventArgs e)
{
StuffBoundContent.DataSource = StuffContent;
StuffBoundContent.DataBind();
}
private void T_Tick(object sender, EventArgs e)
{
StuffContent.Add(new Stuff(StuffContent.Count + 1, DateTime.Now.ToShortDateString(), new string[] { "what", "ever" }));
System.Diagnostics.Debug.WriteLine("[TIMER EVENT] StuffContent.Count = " + StuffContent.Count.ToString());
}
}
}
System.Timers.Timer does not work with a webpage. The reason that t is disposed after the page is sent to the client. Use a Timer control if you really want to use one.
<asp:Timer ID="Timer1" runat="server" OnTick="Timer1_Tick"></asp:Timer>
And then you can update the ListView in Timer1_Tick.
protected void Timer1_Tick(object sender, EventArgs e)
{
//update the ListView
}
Place the Timer Control inside the UPdatePanel if you do not want a full postback when the timer is triggered.
Another thing to remember is that although you use an UpdatePanel, a complete page life cycle is triggered. So all other code you use in Page Load (and PrerRender) is executed even when only the ListView update is visible to the user. This could put a huge load on the server when an updatepanel is triggered every few seconds. Maybe better use Ajax.
PS you don't need to use Page_PreRender to bind data.
I have to hide column 4 when specific users log in to a website. This is my current code for asp and c#:
protected void Page_Load(object sender, EventArgs e)
{
((LoggedIn)Page.Master).CurrentPage = LoggedIn.LoggedInMenuPages.1;
if (CurrentCustomer.AdminRole==false)
{
******NEED TO HIDE ITEM 4
}
}
Put runat="server" to the elements and also specific ID, after that go in Page_Load write the ControlID.Visible=false
ASPX
<li id="AdminElement" runat="server">
//other tags
</li>
Page_Load
AdminElement.Visible = CurrentCustomer.AdminRole;
//remove the class attribute from the aspx
AdminElement.Attributes["class"] = GetCurrentPageStyle("4");
I am trying to create Div dynamically on the press of button click.
For that i refered this link>> http://forums.asp.net/t/1349244.aspx
and made code on server side(.cs page) as follows>>
public static int i = 0;
protected void Button1_Click(object sender, EventArgs e)
{
i++;
HtmlGenericControl newControl = new HtmlGenericControl("div");
newControl.ID = "NEWControl"+i;
newControl.InnerHtml = "This is a dynamically created HTML server control.";
PlaceHolder1.Controls.Add(newControl);
}
This code was giving me just one div each time when i press the button., I wanted to have addition of divs.
On client side using javascript also i tried>>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" OnClientClick="addDiv();" />
</div>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</form>
</body>
</html>
<script type="text/javascript">
function addDiv() {
alert("Control comming in function");
var r = document.createElement('Div');
r.style.height = "20px";
r.style.width = "25px";
r.appendChild("div");
alert("Control going out of function");
}
</script>
Both of these didnt work.
What mistake am i making?
Is there any thing wrong?
Use this
public int Index
{
get
{
if(ViewState["Index"]==null)
{
ViewState["Index"]=0;
}
else
{
ViewState["Index"]=int.Parse(ViewState["Index"].ToString())+1;
}
return int.Parse(ViewState["Index"].ToString());
}
}
protected void Button1_Click(object sender, EventArgs e)
{
HtmlGenericControl newControl = new HtmlGenericControl("div");
newControl.ID = "NEWControl"+Index;
newControl.InnerHtml = "This is a dynamically created HTML server control.";
PlaceHolder1.Controls.Add(newControl);
}
It is giving you one div, cause you are adding one div.
Remember that asp.net needs you to create all dynamically added controls on very PostBack after that.
If you want two controls you have to add two to the PlaceHolder.
Just use one parent div with some ID(predefined lets say id="dvDynamic") and runat="server"
and then use it the dvDynamic.innerHTML = "<div> /* dynamic div contents */ </div>"
Its the simplest way, as if you are using html element in ASP.net use dom controls for better generation. Dynamic creation of control will require handled, interface and many things to co-ordinate with that control. As its not predefined by system. you have to create it.
SO choose the DOM element option. that is faster and better :)
I hope this will help :)
i am trying to use javascript events in asp.net webforms. but events for input controls like textfield, such as onClick, onFocus,onBlur, dont appear. do i need to change my directive:
<%# Page Title="" Language="C#" MasterPageFile="~/YourGuruMaster.master" AutoEventWireup="true" CodeFile="AskQuestion.aspx.cs" Inherits="AskQuestion" %>
i want to be able to do this:
//code page
protected void Page_Load(object sender, EventArgs e)
{
QuestionTextBox1.Attributes["onfocus"] = "ClearSearchText()";
//Markup page
function ClearSearchText() {
var searchUserName = document.getElementById('<%=QuestionTextBox1.ClientID%>');
if (searchUserName.value = searchUserName.defaultValue) {
searchUserName.value = "";
}
return false;
}
<p dir="rtl" style="">
<asp:TextBox ID="QuestionTextBox1" runat="server" Width="702px"
Text="פרטים עד 5000 תווים"></asp:TextBox>
Add onfocus and onblur into the markup as follows:
<asp:TextBox ID="TextBox1" runat="server" onfocus="TextBox1_focus(this, event)" onblur="TextBox1_blur(this, event)" Text="Search..."></asp:TextBox>
<script type="text/javascript">
var searchText = 'Search...';
function TextBox1_focus(sender, e) {
if (sender.value == searchText)
sender.value = '';
}
function TextBox1_blur(sender, e) {
if (sender.value == '')
sender.value = searchText;
}
</script>
Well, not sure which ASP.NET version you use. I think last versions allow this (rendering attributes that the server controls don't understand to the browser still). Try using "onfocus" instead (lower case).
However, if this is not working for you, then you have to do it from code behind...
protected void Page_Load(object sender, EventArgs e)
{
QuestionTextBox1. Attributes["onfocus"]="someJavaScriptMethod";
}
Alternatively, if you have jQuery in the page you can go something like ...
<script type="text/javascript">
$(function() {
$('#<%= QuestionTextBox1.ClientID %>').focus(someJavaScriptMethod);
});
</script>
If you do that, inside someJavaScriptMethod(), you can use the word this to point at the focused control, and you can create a jQuery object from it easily like $(this).
.
Please leave me a comment if none of the above solves your problem.
Willing to admit I'm a complete .NET newbie, but I have extensive experience in classic ASP, which is making this quite tricky as the whole structure of .net is completely different.
I know I'm meant to use code behind, but for now I'm happy embedding it into the pages because:
Each page is going to be simple, so
there wont be too much mixing up
It's probably too much of a step to
do everything the 'right' way, I'd
rather step up to that slowly as I
get to grips with .net
So excusing my lack of code behind, on this page I am trying to get the ID returned by the querystring "mid" (Menu ID), and then display a different CSS class for the menu button we are currently on. Two menu classes, navButton and navButtonO (over).
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="admin.aspx.cs" Inherits="AlphaPack._Default"
title="Administration"
%>
<script language="C#" runat="server" >
protected int menuID;
protected void Page_Load(object sender, EventArgs e)
{
string menuIDdata = Page.Request.QueryString["mid"];
menuID = 0;
// Check the user is allowed here
if (!Roles.IsUserInRole("Admin"))
{
Response.Redirect("../default.aspx");
}
// Get the menu ID
if (int.TryParse(menuIDdata, out menuID))
{
menuID = int.Parse(menuIDdata);
}else{
menuID = 0;
}
}
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML
1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="mainHead" runat="server" >
<title>Administration</title>
<link rel="Stylesheet" href="../style/admin.css" />
</head>
<body>
<div class="topMenu">
<div class="navButton<%if(menuID == 0){ response.write("O") }%>">
Admin Home
</div>
<div class="navButton<%if(menuID == 1){ response.write("O") }%>">
User Manager
</div>
<div class="navButton<%if(menuID == 2){ response.write("O") }%>">
Products
</div>
</div>
<br /><br />
<div class="subMenu">
Products Categories
</div>
<br /><br />
Welcome to the Admin
</body>
</html>
Thanks for any help, don't pull any punches.
You should really put your code in the code behind page, there is no value to keeping it in the markup page even if it is simple. Second you are still thinking classic asp and using Response.Write. There is almost no reason to ever use Response.Write, if you are using it in a markup page then you are almost always doing it wrong. Turn your divs into Panel controls which will render out as divs. Then use a simple switch statement to set the CssClass property in the code behind page. You are using int.Parse you should only use this if you are guaranteed to get an int back from parsing the text. If it does not parse it will throw an exception, use int.TryParse instead.
Promote midID to a class variable.
protected int menuID;
protected void Page_Load(object sender, EventArgs e)
{
menuID = 0;
// Check the user is allowed here
if (!Roles.IsUserInRole("Admin"))
{
Response.Redirect("../default.aspx");
}
// Get the menu ID
menuID = int.Parse(Page.Request.QueryString["mid"]);
}
int menuId = 0;
Should be:
public int MenuId{get;set;}