ASP.net - Dynamically displaying controls - asp.net

I am developing Quiz project. In DetailsView I want to display the Question and answers.
The number of answers vary for question to question.Say example
1 ) C# Support
(i) Generics
(ii) LINQ
(iii)EntLib
2 ) Find the odd one
(i) DB2
(ii) Oracle
(iii)MS-Access
(iv) Sql Server
(v) Javascript
so i can not fix the number of radio buttons.Some questions may have multiple answers.so i need to display checkboxes instead of radio buttons.
My Question is how to generate Radio Buttons or Checkboxed Dynamically ?

Create a RadioButtonList or CheckBoxList for each question and use its Items collection to add the answers.
Very simple example in C#:
class Question
{
public string QuestionText;
public List<string> Answers;
}
protected void AddQuestionsToContainer(Control container, List<Question> questions)
{
foreach (Question q in questions)
{
var qt = new Label();
qt.Text = q.QuestionText;
container.Controls.Add(qt);
var rbl = new RadioButtonList();
foreach (string answer in q.Answers)
{
rbl.Items.Add(new ListItem(answer));
}
container.Controls.Add(rbl);
}
}

I think your question more specifically is how to decide which quiz question has multiple answers.
If I'm correct than you need to have an extra column like isMultipleAnswers BIT in the table in DB (or whatever the source is you need to have a flag for each question), and handle a event for the DetailView like DataBinding, check the value for this field, based on that either add RadioButtonList or CheckBoxList.
Hope this helps!
BTW, why aren't you using Repeater??

Related

asp.net dynamic controls values

I am trying to create a poll system that will ask the users for the number of options they would like to add from a dropdownlist.
Then when the user choose a number i would like to add text-boxes for those numbers and finally use asp.net to iterate through the text-boxes and add their values in the database.
Example:
User chooses to add 5 options.
I use Jquery to to append 5 inputs to the form.
User adds their values.
I iterate through the text-boxes and execute a void based on these
values.
i am able to do the first 3 steps but i am stuck on the 4th step. To solve it i tried to use a loop:
foreach (TextBox tb in form1.Controls)
{
Response.Write(tb.Text);
}
but that throws an error:
Unable to cast object of type 'System.Web.UI.LiteralControl' to type 'System.Web.UI.WebControls.TextBox'.
how can i iterate throw the text-boxes?
thanks
Any static content is represented by a LiteralControl, which is why you experience that. A real easy way is to use LINQ:
var ctls = form1.Controls.OfType<TextBox>();
foreach (var ctl in ctls) { .. )
Or check the type as you loop through the controls to make sure it's a textbox first:
foreach (Control tb in form1.Controls)
{
if (tb is TextBox)
Response.Write(((TextBox)tb).Text);
}
Brian's answer seems a solid one. Another option that comes to mind at first sight is:
Declare a function...
Declare a simple array or even a string in js
Iterate from client side your inputs
And for each iteration you should be saving the value in that array or concatenating the value.
The array then can be saved as a string in some asp hiddenfield in order to do your server-side stuff.
Best regards.

ASP Multiselect listbox separator

I have encountered a problem and I didn't manage to find any soultions yet. Let me simplify things a bit.
I have 2 forms, the first contains an ASP ListBox with multi select mode enabled. I submit the form and in the other form I use just for testing purposes this snippet of code:
protected void Page_Load(object sender, EventArgs e)
{
foreach (string formKey in Request.Form.AllKeys)
{
if (formKey != null)
{
if (formKey.Equals("ctl00$MainContent$ListBox1"))
Label1.Text = Request.Form[formKey];
}
}
}
The problems is that the values that come from the listbox (the values that i selected in the previous form) are separated by "," for ex. "test1,test2,test3". How can i change this separator to "$" for example? I need to change it because the actual values may contain "," and i don't manualy feed them to the listbox.
I can't use any other mode of transfering this values between the form because the entire application uses this model. The values that i get are then sent to a workflow where there will be manipulated and in the workflow i need to know where each listbox item starts and ends so it must be an unique separator.
Any help is apreciated! Thank you very much
Thank you MatteKarla but unfortunately this does not solve my problem. Yes, this is a good way of transfering the values from one form to another.
However i must use the method I described above with Request form keys because the listbox is one of many others "parameters" that are generated at runtime and have their values sent to a workflow method that takes this values. And i can't afford to change that in my application.
My problem is that coma (",") separator is used by default with a multiselect listbox.
I thought that there maybe is a method to change that separator from coma to another char because the coma can also be included in the value itself and this will create confusion.
As i said if i select three values test1, test2 and test3, the result with my method will be a string looking like "test1,test2,test3". However a "test1$test2$test3" would be much better.
But I'm affraid that changing this default separator is not possbile. I must think at a method to overcome this problem like replacing before feeding the listbox all the intended coma from the values with some other char not to create confusion. But this is not a great way of doing it.
On your first page/form (First.aspx.cs) create a public property with the listbox:
public ListBox PostedListBox { get { return ListBox1; } }
Set the postback-url for the button to Second.aspx
Second page in the aspx-file after the #Page-directive add:
<%# PreviousPageType VirtualPath="~/First.aspx" %>
Then in Form_Load on Second.aspx.cs you can extract the values:
if (PreviousPage != null)
{
ListBox postedListbox = PreviousPage.PostedListBox;
foreach (var index in postedListbox.GetSelectedIndices())
{
var itemText = postedListbox.Items[index].Text;
}
}
Or you could just try to locate the control by using:
if (PreviousPage != null)
{
var control = PreviousPage.FindControl("ListBox1") as ListBox;
}
Third Edit:
You could use GetValues:
Request.Form.GetValues("ctl00$MainContent$ListBox1");
returns a string array containing each of the selected items.

comparing the old values vs new value and update

NOTE: i havent implement the above solution but closing this question and accepting this as answer even thou i havent implement.
what is the best way of doing? and i know that i can store the repeater in a different var and compare but i just wanted to know the elegant way of doing.
here is my for loop code that i want to compare and update the values that have changed and ignore the values that have not changed
GridViewRow row = gv.SelectedRow;
Repeater _rpt = gv.Rows[e.RowIndex].Cells[8].FindControl("rptReg") as Repeater;
Repeater _rpt1 = gv.Rows[e.RowIndex].Cells[9].FindControl("rptVisitor") as Repeater;
for (int i = 0; i < _rpt.Items.Count; i++) {
TextBox _txt = _rpt.Items[i].FindControl("txtId") as TextBox;
TextBox _txt1 = _rpt.Items[i].FindControl("txtName") as TextBox;
if (_rpt1.Items.Count > i)
TextBox _txt3 = _rpt1.Items[i].FindControl("txtVisitor") as TextBox;
//update db
}
}
It's a total hack and I'm sure there is a more elegant way to handle it but you could throw a hidden field in there and set up your form elements with an onchange script to update the value of the hidden field. Then just check for the value of the hidden field.
Hopefully someone has a better way to do it than that but if all else fails.
If you add a class to the hidden field of "hiddenIndicator" and to your form elements of "causesChanged" then the following Jquery should do what you want:
$(document).ready(function() {
$('input.causesChanged').change(function() {
$(this)
.closest('tr') // get the parent row
.find("input.hiddenIndicator") // find children that match the selector
.val('1'); //the value that indicates a change occured
});
})
I haven't tested that code but I used something similar in a project once.

How do I programmatically associate a RadioButton with a RadioButtonGroup in ActionScript3?

I have a UI component that, for various reasons, I have to construct programatically. The component is a table of radio buttons grouped by column.
Right now, I'm constructing the column groups like so:
private function createGroupsForItemList(items: XMLList): void {
for each (var item: XML in items) {
var rbGroup: RadioButtonGroup = new RadioButtonGroup();
groups[item.#level.toString()] = rbGroup;
}
}
I'm trying to associate the RadioButton instances with the column groups like so:
private function createValueControl(item: XML): UIComponent {
var control: RadioButton = new RadioButton();
control.label = "";
control.group = groups[item.#level.toString()];
control.addEventListener(Event.SELECT, updateSelection);
return control;
}
I can see in the debugger that the control has an association to the group:
control.group == groups[item.#level.toString()]
However, I can see equally that the group does not know anything about the control:
group.radioButtons.length == 0
I imagine that this is because the setter for group in RadioButton is a dumb setter; all it does is copy to the variable, which doesn't do the magic that groupName does. However, I can't seem to find the value I should use to set the RadioButton.groupName property correctly.
So, in short, I'm stumped on how to get these bits to talk to each other. How do I do this?
-- EDIT --
It turns out that I can have the groups created and associated simply by setting the groupName property, but I can't get at the group to set up a selection listener; the group is NULL immediately after the setting process, which means that the second line below throws the Flex equivalent of an NPE:
control.groupName = groupNameForLevel(item);
control.group.addEventListener(Event.SELECT, updateSelection);
First instinct is that this issue has to do with invalidateDisplayList and when and how that is called. Of course, since issues related to that function are behind a number of Flex's quirks, I may just be scapegoating.
This is not the answer to your question per se, but it seems like it might actually work as an alternate solution.
RadioButtonGroups will initialize based on a IFlexDisplayObject. This means that you can do something like:
var c:HBox = new HBox();
var rbg:RadioButtonGroup = new RadioButtonGroup( c );
// do stuff with rbg.
c.addChild( new RadioButton() );
The problem is that it may not be the most practical answer, but it has the decided benefit of being a workable solution.
Setting groupName should work.
All I can suggest is to step through the group() getter of the RadioButton component and see where exactly it is failing. Are you programmatically creating the group too? If that's the case, maybe it isn't initialized fully yet.

ASP.NET paging control [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
I'm looking for a decent paging control in ASP.NET, much like the Stackoverflow pager. Can anyone recommend one?
I'd prefer one that didn't use Postback either, just a customisable querystring.
It's quite easy to roll your own. I created a simple user control based on the stack overflow pager with two properties...
Total number of pages available according to the underlying data
Number of links to show
The selected page is determined by reading the query string. The biggest challenge was altering the URL with the new page number. This method uses a query string parameter 'p' to specify which page to display...
string getLink(int toPage)
{
NameValueCollection query = HttpUtility.ParseQueryString(Request.Url.Query);
query["p"] = toPage.ToString();
string url = Request.Path;
for(int i = 0; i < query.Count; i++)
{
url += string.Format("{0}{1}={2}",
i == 0 ? "?" : "&",
query.Keys[i],
string.Join(",", query.GetValues(i)));
}
return url;
}
A simple formula to determine the range of page numbers to show...
int min = Math.Min(Math.Max(0, Selected - (PageLinksToShow / 2)), Math.Max(0, PageCount - PageLinksToShow + 1));
int max = Math.Min(PageCount, min + PageLinksToShow);
Each link then gets generated using something like (where min and max specify the range of page links to create)...
for (int i = min; i <= max; i++)
{
HyperLink btn = new HyperLink();
btn.Text = (i + 1).ToString();
btn.NavigateUrl = getLink(i);
btn.CssClass = "pageNumbers" + (Selected == i ? " current" : string.Empty);
this.Controls.Add(btn);
}
One can also create 'Previous' (and 'Next') buttons...
HyperLink previous = new HyperLink();
previous.Text = "Previous";
previous.NavigateUrl = getLink(Selected - 1);
The first and last buttons are straight forward...
HyperLink previous = new HyperLink();
previous.Text = "1";
first.NavigateUrl = getLink(0);
In determining when to show the "...", show a literal control when the link range is not next to the first or last pages...
if (min > 0)
{
Literal spacer = new Literal();
spacer.Text = "…";
this.Controls.Add(spacer);
}
Do the same for above for "max < PageCount".
All of this code is put in an override method of CreateChildControls.
I was expecting more answers but it looks like a lot of people just make their own. I've found a decent one that is maintained quite often on codeproject.com
It's not quite the same as the stackoverflow.com one. It'd be nice if there was a decent open source control that had a variety of different output options.
I've worked with the DevExpress and Telerik page controls and prefer the DevExpress pager. I'm not sure if the DevExpress pager can work directly with a querystring but I would be surprised if it didn't as it is very flexible. As far as paging between existing pages after download, everything can reside on the client or, if a trip to the server is necessary, the control is fully AJAX equipped. I suggest you start your search at www.devexpress.com and then check out www.Telerik.com as well (which is also AJAX equipped).
Not a control, but this is the way to implement paging at the DB level: SQL Server 2005 Paging
I have written a pager control named: Flexy Pager
Read more: http://www.codeproject.com/Articles/748270/Flexy-Pager-for-ASP-NET-WebForm-MVC
You can try NPager. Uses query string for page indexes, no postbacks. Needs Bootstrap for styling, however you can have your own custom css classes for the control using 'pagination' CSS class.Here is a working DEMO

Resources