my scenerio is like this,
i have to make a admin page ( header section ) in which i have to select single or multiple User Control from my dropdownlist ....
which will be added in the page dynamically ....
how should i do it ?
currently my idea is like this
when a some one selects and add a usercontrol from the dropdownlist list , i will add usercontrols tags in a textarea and save it in db ...
and when index pages of website is called then header section will be rendered from database and displayed ..
but how should i manage control tag which should be place on the top of the page in index.aspx while rendering it ??
please i know at some point it would be difficult to understand but i will try my best to reply if you have any query related to my question
take care
If i get your question correctly there is no need to store tags or anything in databse. Just the name and path of control (remember User Controls can only be loaded from same project) that you wana load.
Here is the code sample to load a user control dynamically.
<asp:DropDownList ID="userControlSelection" runat="server" AutoPostBack="true"
onselectedindexchanged="userControlSelection_SelectedIndexChanged">
<asp:ListItem Value="1">User Control One</asp:ListItem>
<asp:ListItem Value="2">User Control Two</asp:ListItem>
</asp:DropDownList>
<asp:Panel ID="controlHolder" runat="server" ></asp:Panel>
And in the code behing the important part is "this.LoadControl("~/WebUserControl2.ascx");" Look at this article for more info and loading user controls Dynamically creating User Controls
protected void userControlSelection_SelectedIndexChanged(object sender, EventArgs e)
{
Control c = null;
if (userControlSelection.SelectedValue == "1")
{
c = this.LoadControl("~/WebUserControl1.ascx");
}
else if (userControlSelection.SelectedValue == "2")
{
c = this.LoadControl("~/WebUserControl2.ascx");
}
if (c != null)
{
controlHolder.Controls.Clear();
controlHolder.Controls.Add(c);
}
else
{
//Throw some error
}
}
Hope this helps, Thanks
Related
NOTE: THIS IS A RE-PURPOSED QUESTION, WHICH AIMS TO MORE CLEARLY STATE THE ISSUE AND INFORMATION.
Ok... I am working on a project for a site of mine that has a form, and uses the RadioButtonList control for item categories. On one particular category, my radio list control has 4 vaules like so:
<td>
<asp:RadioButtonList ID="radCPUType" RepeatDirection="Horizontal" runat="server">
<asp:ListItem Value="AMD">AMD</asp:ListItem>
<asp:ListItem Value="Intel">Intel</asp:ListItem>
<asp:ListItem Value="AMD Dual (Server)">AMD Dual (Server)</asp:ListItem>
<asp:ListItem Value="Intel Dual (Server)">Intel Dual (Server)</asp:ListItem>
</asp:RadioButtonList>
</td>
<td>
<asp:Image ID="Image6" runat="server" ImageUrl="~/Images/Icon_CPU.jpg" />
</td>
And next to the list control, I have a default image control named Image6. I'm having a great deal of difficulty getting this image to change when I select a radio button list option. The code doesn't blow up, but nothing happens and the image remains unchanged on a radio option selection. I've tried various methods from similar examples, and none of them have been helpful.
I've tried JQuery for my script, and plain old JavaScript, all to no avail. I know I need to make the script reference the images I have in the Images directory of the solution, but I can't figure it out. The default image is Icon_CPU.jpg and for each choice, say... the 1st two, it will change to the following:
AMD selection = AMD_CPU_1.jpg
Intel selection = Intel_CPU_2.jpg
... and so on. The images will align properly if hard coded - I just can't get the code to work on selection. Can some help me with the script to actually make this work? Also, can you tell me if I need to rename my controls, or add anything in the PageLoad of the server-side control? Currently, I have nothing in it as below will show.
public partial class Controls_CPUBuilderForm : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnResetBuild_Click(object sender, EventArgs e)
{
// Clear radio button selections on the form
radFormSelect.ClearSelection();
radDriveType.ClearSelection();
radDriveSpace.ClearSelection();
radPSUSelect.ClearSelection();
radRAMSelect.ClearSelection();
radCPUType.ClearSelection();
radOpticalCount.ClearSelection();
radScreenCount.ClearSelection();
// Reset drop down lists to original selection
ddlDriveCount.SelectedIndex = -1;
ddlScreenOrient.SelectedIndex = -1;
}
}
Thank you all for your patience & knowledge in helping me gain better understanding for future purposes!
To solve your problem with C#, create an event handler for SelectedIndexChanged in your codebehind.
protected void radCPUType_SelectedIndexChanged(object sender, EventArgs e)
{
// Set the ImageUrl however you like
Image6.ImageUrl = "~/Images/Icon_CPU.jpg";
}
Next, refine your radio button list to set AutoPostBack="True" and OnSelectedIndexChanged="radCPUType_SelectedIndexChanged"
<asp:RadioButtonList ID="radCPUType" RepeatDirection="Horizontal" runat="server" AutoPostBack="True" OnSelectedIndexChanged="radCPUType_SelectedIndexChanged">
<asp:ListItem Value="AMD">AMD</asp:ListItem>
<asp:ListItem Value="Intel">Intel</asp:ListItem>
<asp:ListItem Value="AMD Dual (Server)">AMD Dual (Server)</asp:ListItem>
<asp:ListItem Value="Intel Dual (Server)">Intel Dual (Server)</asp:ListItem>
</asp:RadioButtonList>
Thanks to all for your suggestions. A BIG THANKS TO "KENT ANDERSON" -- whom provided the framework upon which I was able to expand on to get the functionality I was looking for.
That said, the answer was to create an Event Handler w/in the control's CodeBehind like thus:
protected void radCPUType_SelectedIndexChanged(object sender, EventArgs e)
{
// This was Kent's suggestion, and also to setup the ImageUrl as needed.
Image6.ImageUrl = "~/Images/MyDefault.jpg";
}
I setup the ImageUrl to initially hold the default image before selecting the option on the control. Next, I needed a way to populate the images on selection. As many suggestions had differing and maybe more complex ways of achieving this, I found that I could do this by passing the control as a parameter w/ an assigned value, through an if-else structure w/in the event handler:
protected void radCPUType_SelectedIndexChanged(object sender, EventArgs e)
{
// Setup the ImageUrl.
Image6.ImageUrl = "~/Images/MyDefault.jpg";
// Setup the if-else structure to assign images w/ the selections.
if (radCPUType.SelectedValue == "A selected option value")
{
Image6.ImageUrl = "~/Images/Associated Image.jpg";
}
else if (radCPUType.Selectedvalue == "Another selected option value")
{
Image6.ImageUrl = "~/Images/Another Associated Image.jpg")
}
else
{
Image6.ImageUrl = "~/Images/The Default Image.jpg";
}
}
Because the RadioButtonList control uses a value-based index, SelectedValue class was needed so the control could hold the option selection, as assigned in the HTML of radio list.
The control in the if portion equals the option chosen on the radio button list; the next statement then assigns the image associated with option selection to the ImageUrl, and I used else if of course to go through the remaining radio list options, ending with the default image in the closing else portion of the structure. It is a success! So again, as I'm sure there other ways to achieve a solution, this works best for me.
Thanks again for all your inputs, and another shot out to Kent Anderson, who's advice provided a foundation to build upon.
First lets attach the JS event in codebehind
radCPUType.Attributes.Add("onclick", "changeImage();");
Then we need to create the JS function.
<script type="text/javascript">
function changeImage() {
var img = $('#<%=radCPUType.ClientID %>');
switch ($('#<%=radCPUType.ClientID %> input[type=radio]:checked').val())
{
case 'AMD':
img.src = 'newimage.png';
break;
}
}
</script>
I haven't tested this but let me know if something isn't working.
Answer lifted straight from the previous question:
aspx
<td>
<asp:RadioButtonList ID="radCPUType" RepeatDirection="Horizontal" runat="server">
<asp:ListItem Value="AMD">AMD</asp:ListItem>
<asp:ListItem Value="Intel">Intel</asp:ListItem>
<asp:ListItem Value="AMD Dual (Server)">AMD Dual (Server)</asp:ListItem>
<asp:ListItem Value="Intel Dual (Server)">Intel Dual (Server)</asp:ListItem>
</asp:RadioButtonList>
</td>
<td>
<asp:Image ID="Image6" runat="server" ImageUrl="~/Images/Icon_CPU.jpg" />
</td>
javascript
$(document).ready(function () {
$("#<%= yourID.ClientID %> input").click(function () {
var value = $(this).val();
var image_name;
var image_path = "/Images/";
//If the images directory isn't at the website root you could use asp.nets
//resolveURL method instead
switch (value)
{
case "AMD":
image_name = '"AMD_CPU_1.jpg";
break;
case "Intel";
image_name = "Intel_CPU_2.jpg"
break;
case "AMD Dual (Server)";
image name = "" // Insert your image here
break;
case "Intel Dual (Server)";
image name = "" // Insert your image here
break;
}
/*************************************
*Old Ineeficient code
if (value == 'AMD') {
image_name = "AMD_CPU_1.jpg";
} else {
if (value == 'Intel') {
image_name = "Intel_CPU_2.jpg";
} else {
image_name = "Icon_CPU.jpg";
}
}
*************************************************/
//console.log(image_name);
$("#<%= Image6.ClientID %>").attr('src', image_path + image_name);
});
});
The <% %> is a server code block and should be used sparingly in aspx pages. <%= %> is short hand for <% Response.Write() %>. If you view the source HTML code of the page in a browser, you will see the ASP.net client ID of the Radio Button List & image controls in the jQuery selectors.
You should also use a tool like FireBug for Firefox or Chrome developer tools to check the paths for the image once you click the check boxes if you are getting unexpected results. Also note the line //console.log(image_name);. Removing comments form this line will dump the value of image_name to the console, which is useful for debugging. See more info here: http://blogs.msdn.com/b/cdndevs/archive/2011/05/26/console-log-say-goodbye-to-javascript-alerts-for-debugging.aspx
Side Note
I can see no need for an image control here. A plain old html image tag would work. If you use an image tag you won't get the asp.net name mangling you did in the original question and can reference it simply with $("#Image6")
More info on the switch statement if you're not familiar with it: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch
I have a master page and all of my pages are inheriting it.
For formatting, I thought to place the content that differs from one page to another in a ContentPlaceHolder.
Now, how can I insert everything into that? Since I am planning to populate the ContentPlaceHolder with stuff from a database I suppose I will have to do it programmatically.
How can I add controls to ContentPlace Holder?
I checked other answers, but I cannot access it by its ID.
Should I use multiple ContentPlaceHolders from the beginning? Let's say I want to put movies. Should there be only one with all the images and descriptions and ratings, ore one ContentPlaceHolder for each thing?
I am opened to other solutions, as I have no experience with ASP.
Old question... but I just ran into this issue and this was the #1 post that kept coming up on Google, so figure I'd add my answer since the others didn't work in my case.
Here is how I did it when a regular <asp:Content wouldn't work (though in normal use, the answer #JayC is how you do it):
MasterPage has this ContentPlaceHolder:
<asp:ContentPlaceHolder ID="ScriptsPlace" runat="server"></asp:ContentPlaceHolder>
Had to dynamically add some JavaScript from a User Control. Trying to use the ContentPlaceHolder directly gives this error:
Parser Error Message: Content controls have to be top-level controls
in a content page or a nested master page that references a master
page.
So I wanted to add the script from the code-behind. Here is the Page Load for the .ascx file:
protected void Page_Load(object sender, EventArgs e)
{
ContentPlaceHolder c = Page.Master.FindControl("ScriptsPlace") as ContentPlaceHolder;
if (c != null)
{
LiteralControl l = new LiteralControl();
l.Text="<script type=\"text/javascript\">$(document).ready(function () {js stuff;});</script>";
c.Controls.Add(l);
}
}
UPDATE: So it turns out I had to use this in more places than I expected, and ended up using a way that was much more flexible / readable. In the user control itself, I just wrapped the javascript and anything else that needed to be moved with a regular div.
<div id="_jsDiv" runat="server">
$(document).ready(function() {
//js stuff
});
Other server controls or HTML junk
</div>
And then the code behind will find that div, and then move it into the ContentPlaceHolder.
protected void Page_Load(object sender, EventArgs e)
{
ContentPlaceHolder c = Page.Master.FindControl("ScriptsPlace") as ContentPlaceHolder;
HtmlGenericCOntrol jsDiv = this.FindControl("_jsDiv") as HtmlGenericControl;
if (c != null && jsDiv != null)
{
c.Controls.Add(jsDiv);
}
}
I actually put this code in a custom user control, and I just have my regular user controls inherit from the custom user control, so once I wrap the javascript/etc with a <div id="_jsDiv" runat="server">, the custom user control takes care of the rest and I don't have to do anything in the code behind of the user control.
What normally happens is
you set up your master pages with the proper html and ContentPlaceHolders
you create pages based off that master page. If you use Visual Studio, and tell it to create a new page based upon a existing Master page, it will add the Content areas for you.
you add things to the Content areas in the newly created page.
If you want to dynamically add controls to the master (or any) page, you could add controls to any existing control. If it shouldn't be wrapped in any way, just add a Placeholder (it is an asp.net control).
I did like this
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
<asp:Literal ID="jsstuff" runat="server"></asp:Literal>
</asp:Content>
And this went into code behind:
string stuff = #"<script type=""text/javascript"">
var searchBox = 0;
var currentCountry = '';
</script>";
jsstuff.Text = stuff;
If the namespace for content Page and Master page is not same then the content page control not accessible in Codebehind in content page.
Also, check your designer files. if the control not listed in designer file then delete the file and recreate (project->convert to web application)
I have a Webpart that contains a couple of dropdowns on an update panel. There is a submit button that has the PostBackUrl set to a sharepoint Application Page
<asp:DropDownList ID="ClassSelector" runat="server" Enabled="False"
AutoPostBack="True" onselectedindexchanged="ClassSelector_SelectedIndexChanged">
<asp:ListItem Selected="True" Value="-null-">Select Class...</asp:ListItem>
<asp:ListItem Value="1">Class 1</asp:ListItem>
</asp:DropDownList>
<asp:Button ID="btnSubmit" runat="server" Text="Show Page" Enabled="False"
PostBackUrl="~/_layouts/MyWebParts/MyAppPage.aspx" />
This works in redirecting the browser to the Application Page I have created, but I am having trouble accessing the form data.
On the Page_Load function of the Application Page I have the following debugging code.
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = "";
foreach (String s in Page.Request.Form.AllKeys)
{
Label1.Text += s + ": " + Page.Request.Form[s] + "<br />";
}
}
This shows that the data I need has in fact been posted to the page.
ctl00$m$g_24a73cf8_8190_4ddb_b38b_bf523b12dbd3$ctl00$SemesterSelector: 28
ctl00$m$g_24a73cf8_8190_4ddb_b38b_bf523b12dbd3$ctl00$ClassSelector: 11-0021-A
But when I try to access this as:
Page.Request.Form["ClassSelector"]
Nothing is returned. I know I must be missing something simple here, but I am not sure what.
Any help is greatly appreciated.
Ah, the ASP.NET master page prefix problem! One of my favorites.
The master page for your application page puts a prefix in front of your server-side controls so that they will be unique. If you end up access your control via the Form collection, you have to access it using not only the control ID, but also the ContentPlaceholder prefix. That's why you see such a large ID dumped out of your debugging logic.
If you want to programmatically get to the ID of the control, you can use FindControl, but you'll have to target the apppropriate content placeholder scope for this. Here's a good tutorial/explanation here (which really emphasizes how complex this can get!).
Of course, the other option you can use is just hard-coding the control id based on what you're seeing from your debugging code...but that won't be reliable if you change content placeholders or more your control to a different container.
I guess the answer depends on how static your controls will be.
Hope this helps. Good luck!!
Well to access it that way you would have to use
Page.Request.Form["ctl00$m$g_24a73cf8_8190_4ddb_b38b_bf523b12dbd3$ctl00$ClassSelector"]
As you can actually see from your code where you set the label text to s plus Request.Form[s]
I have the following C# code on one of my pages:
protected override void Render(HtmlTextWriter writer)
{
//an array named fieldNames is delcared here
writer.Write("<form id=\"Form1\" runat=\"server\" action=\"\">");
writer.Write("<asp:checkboxlist id=\"checkBoxes\" runat=\"server\">");
for (int count = 0; count < fieldNames.GetLength(0); count++)
{ //iterates over the array of field names
writer.Write("<asp:listitem text=" + fieldNames[count] + " value=" + fieldNames[count] + "/>");
}
writer.Write("</asp:checkboxlist>");
writer.Write("</form>");
}
The intent is to create a list of checkboxes which have had their attributes set dynamically.
When run this does not throw any errors but no controls appear on the page.
When I view the source of the page I get the following html:
<form id="Form1" runat="server" action="">
<asp:checkboxlist id="checkBoxes" runat="server">
<asp:listitem text='Spares Part No' value='Spares Part No'/>
<asp:listitem text='Description' value='Description'/>
<asp:listitem text='Site' value='Site'/>
<asp:listitem text='Rack/Bin Number' value='Rack/Bin Number'/>
</asp:checkboxlist>
</form>
Out of interest I posted this in another application and it runs fine with all the controls being displayed.
Is this a problem with the order in which events are called? I am at a bit of a loss as to what to try next so any advice would be great.
Thanks,
Oliver
Basically you can't do this.
The Render event comes very late in the page life cycle. You can't just output ASPX markup because the events that parse the markup, instantiate controls etc have already run.
What you should do is add a PlaceHolder control to your page in the markup, and then in an earlier event (e.g. Init or Load) add the controls you want to that placeholder. Again you can't just write out the ASPX markup however, you need to instantiate the controls, along the lines of:
var checkbox = new CheckboxList { Id = "checkBoxes" };
uxPlaceHolder.Controls.Add(checkbox);
checkbox.Items.Add(new ListItem { Text = "...", Value = "..." });
One way you could achieve what you want would be to use a VirtualPathProvider to generate the markup for .aspx requests as they are requested by the framework. Or you could look at what HTML output you actually want to generate (i.e. a list of input elements with some associated javascript) and render these directly. Both of these should probably be classified as nasty hacks however.
You're rendering server-side code - which the browser doesn't understand.
You have to add the CheckBoxList and its ListItems to the form before the page renders.
The server-side control renders the html for the browser - it is created, normally, by Asp.Net parsing the server-side markup.
You are directly writing html content to browser, so you should use only html tags.
What I'm trying to do is basicly what this photo shows.
When I select something from the treeview it passes a parameter to a linq command that selects some data from the database. For every item in the selection I want to make a Icon and a text that represents if the item is a folder or a file.
When I push the Icon or the Link i want it to do the same as i would push the treeview, pass a parameter to a linq command that selects again from the database and populates the placeholder.
The way I'm doing this now is to make at runtima a Panel that holds the ImageButton and LinkButton. Then i add the Panel to the ContentPlaceHolder.
The problem with this that it does it every time i select something new and also i cant get it to work if the push the icon or the linkbutton, only the from the treeview.
Could i use some controller and css to get this look for the Icons ?
Is there another better way ?
This is basicly the same system as the Explorer uses in Windows, Treeview shows only the folder but the window shows the folders and files. When i click a folder that folder opens up and the main window is populated with items that are inside that folder. If i click a file a editor opens up with the contents of the file.
Not sure I understand you question 100% but I think I got the gist.
I'm assuming that you want the folders first, then the files. I would create two repeaters in this area, one to hold the Folder Image and link buttons, and the other for the file image and link buttons.
Break your linq command into two queries, one to get the folders and one for files. Then just bind the repeaters to the corresponding repeaters.
Here's a bit of code to get you started:
<asp:Repeater ID="rptFolders" runat="server" OnItemCommand="rptFolders_ItemDataBound">
<ItemTemplate>
<div>
<asp:ImageButton ID="btnImage" runat="server" />
<asp:LinkButton ID="btnLink" runat="server" />
</div>
</ItemTemplate>
</asp:Repeater>
And the code behind after calling DataBind():
protected void rptFolders_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Book book = (Book)e.Item.DataItem; //Or whatever your passing
ImageButton btnImage = e.Item.FindControl("btnImage");
LinkButton btnLink = e.Item.FindControl("btnLink");
btnLink.Text = book.Name;
btnLink.Click += new EventHandler(FolderClicked);
btnImage.Click += new ImageClickEventHandler(FolderClicked);
}
}
You can obviously do whatever you want with Click Events, just added those in for good measure.
I would probably create a Folder and File Control and use those instead of the imagebutton / linkbutton combo, this way I could store more information about the Folder / File to access them later without having to do another query to get the ID or what not. But there are a million approaches to this, pick the one you think is best.
Let me know if you need more guidance w/ this solution, or if I didn't understand your question.
Happy Coding...
Sorry had to add as another Answer. Here's a quick sample of the folder user control.
Create your Control... Format however you want.
<%# Control Language="C#" AutoEventWireup="true" CodeFile="FolderButton.ascx.cs" Inherits="FolderButton" %>
<div>
<asp:ImageButton ID="btnImage" runat="server" ImageUrl="yourfolder.jpg" />
<asp:LinkButton ID="btnTitle" runat="server" />
</div>
Add Properties and Click Event to the Code Behind (don't forget to fire the click event when your image and link buttons are clicked):
public partial class FolderButton : System.Web.UI.UserControl
{
public int DatabaseId { get; set; }
public string Name { get; set;} // you can even set your linkbutton text here.
public event EventHandler Click;
}
Create your Repeater of the FolderButton Controls:
<asp:Repeater ID="rptFolders" runat="server" OnItemDataBound="rptFolders_ItemDataBound">
<ItemTemplate>
<uc1:FolderButton ID="FolderButton1" runat="server" />
</ItemTemplate>
</asp:Repeater>
Set Folder Id on DataBinding:
protected void rptFolders_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Book book = (Book)e.Item.DataItem; //Or whatever your passing
FolderButton btnFolder = e.Item.FindControls("FolderButton1");
btnFolder.Name=book.Name;
btnFolder.DatabaseId=book.Id;
btnFolder.Click += new EventHandler(FolderClicked);
}
}
Lastly you can then do whever you want on the event Click:
void FolderClicked(object sender, EventArgs e)
{
int id = ((FolderButton)sender).DatabaseId;
/// Do something with your Id
}
Let me know if anything is unclear. This is just a quick freehand sample, so forgive any typos or bad practices... code is just for demostration purposes only.