ListView -Dynamic Controls and DataPager events - asp.net

I have a listView control which is bound to an object datasource. In the ListView1_ItemDataBound event, I am generating some dynamic controls. I do this because depending on a particular column value, i might need to generate textbox, radio button, check box etc.
Some code here:
ListViewDataItem item = (ListViewDataItem)e.Item;
typez = Convert.ToInt32(DataBinder.Eval(item.DataItem,"Type").ToString());
if (typez == 1) //1 means generate radibutton
{
string[] options = DataBinder.Eval(item.DataItem, "QuestionDetail").ToString().Split(new string[] { delimiter }, StringSplitOptions.None);
questionID = Convert.ToInt32(DataBinder.Eval(item.DataItem, "Question_ID").ToString());
int optionCount = 1;
RadioButtonList rbl = new RadioButtonList();
//set ID for the radiobtnList to the questionid no.
rbl.ID = "mcq_" + questionID;
foreach (string s in options)
{
//adds the MCQ options to list item
ListItem li = new ListItem(Util.GetAlphabet(optionCount).ToUpper() + ". " + s, Util.GetAlphabet(optionCount).ToUpper(), true);
rbl.Items.Add(li);
optionCount++;
}
//PlaceHolder PlaceHolder1 = (PlaceHolder)e.Item.FindControl("PlaceHolder1");
PlaceHolder1.Controls.Add(rbl);
I have DataPager also. When I go to the next page I want to somehow capture the user response in the previous page. Otherwise, all the user response is lost. I tried using ListView1_PagePropertiesChanging event. But here I somehow do not seem to get the dynamic controls in the page.
I need to get the radio button selected value so that I can save it or put in some session variable so that when user comes back to this page he can see his previuos values.
Could someone please suggest some insight on what I am doing wrong.

Problem is that you have to create controls in OnInit, then ViewState persister can do it's job. If you do it after OnInit, in ItemDataBound, when Postback is triggered, controls doesn't exists and their's viewstate isn't deserialized.
To access values of radio buttons and get selected one, you have to look at Request.Form dictionary and find it.

Related

Dynamic controls(Textbox) in asp.net

I want to create dynamic text boxes during run time.
Suppose im gettng a text from a database as "# is the capital of India" now i want to replace that "#" by text box while it is rendered to user as below
<asp:TextBox runat="server" id = "someid"></asp:TextBox> is the capital of India
Im able to get the textbox and text as combination. However I cannot access the textboxes with the given id and when any event occurs on the page the textboxes are lost as they logically does not exist untill their state is stored.
I also went through the concepts of place holder and Viewstate to store the dynamically created controls and make their id's available for the methods, but as far as I tried I could not meet the textbox and text combination requirement.
Im looping over the entire text recieved from database and checking if there is any"#". Is yes then i want to replace it with a textbox on which i can call methods to take back the value entered in the text box to database and store it.
eg: text is "#" is the capital of India
for (int i = 0; i < que.Length; j++) //que holds the text
{
if (que[i] == '#')
{
//Textbox should be created
}
else
{
//the texts should be appended before or after the textbox/textboxes as text demands
}
}
On button click I'm passing request to database, which will send me necessary details i.e. question text, options and also saves the current checked value etc.
protected void BtnLast_Click(object sender, EventArgs e)
{
CheckBox1.Checked = false;
CheckBox2.Checked = false;
CheckBox3.Checked = false;
CheckBox4.Checked = false;
QuestionSet q = new QuestionSet();
StudentB b = new StudentB();
q = b.GetQuestion(1, 1, qid, 'L', 0, Checked, date);
qid = Convert.ToInt32(q.Question_Id);
Checked = q.Checked;
if (q.Question_Type == 11) //indicates its objective Question
{
//ill bind data to checkboxes
}
else if (q.Question_Type == 12) // indicate its fill in the blanks question
{
for (int j = 0; j < que.Length; j++)
{
if (que[j] == '#')
{
count++;
string res = "<input type = 'text' runat = 'server' id ='TxtBoxFillUp" + count + "'/>";
htm = htm.Append(res);
}
else
{
htm = htm.Append(que[j]);
}
}
}
}
Any help will be greatly appreciated, thanks in advance.
Adding control in the way you do it won't create control as asp.net creates it. You do have to create controls as usual .net object.
TextBox myNewTextBox = new TextBox() {};
// Set all initial values to it
And add this cotrol to placeholder or panel, whatever you use. Keep in mind that asp.net page events fire even if you use update panel, so in order to maintain state and events of newly created controls you have take care of creating such controls long before page's Load event fires. Here is my answer to another simialiar question.
Seeing the requirements you have:
1.) You need to use JavaScript. Since the ASP.NET will not recreate controls which are dynamically added. Dynamically added controls need to be recreated after every postback. This is the reason why your TextBoxes are Lost after every postback.
2.) You can write JavaScript code to Hide and show the textboxes for blank texts since at every button click you can call Client side functions using: OnClientClick() property of buttons.
3.) Also to Get the TextBoxes using ID property, add them in Markup( .aspx ) portion itself.

Why is my ASP.NET Button control not calling the appointed function?

I want to set up a search functionality on my web site. The user types some information into a text box and click a search button. Upon clicking the search button, a database is searched using the text in the text box, and the results are displayed in a table. If the text in the text box matches one result from the database perfectly, rather than displaying a list of results the page is populated with detailed information about the matching result.
In order to make it easier to match a result exactly, I want to add a button next to each result which "selects" that result, filling the text box with that result's text and therefore populating the page with the details. Here's what I have.
Upon clicking the search button, after the check to see if a result is matched exactly, I create a table which contains the results and the buttons:
for(int x=0; x < res_list.Length; x++)
{
TableRow newRow = new TableRow();
TableCell textCell = new TableCell();
TableCell buttonCell = new TableCell();
buttonCell.ID = "bc" + x;
Button cellButton = new Button();
cellButton.ID = "btn" + x;
textCell.Text = res_list[x];
textCell.Attributes.Add("Width","60%");
cellButton.Text = x.ToString();
// cellButton.OnClientClick = "NameClick"; This property refers to client-side scripts, which I am not using.
cellButton.Click += new EventHandler(NameClick);
buttonCell.Controls.Add(cellButton);
newRow.Cells.Add(firstCell);
newRow.Cells.Add(buttonCell);
myTable.Rows.Add(newRow);
}
I have tried both the OnClientClick method and the Click method seen above, both of which have yielded the same results.
My NameClick function is as follows:
void NameClick(object sender, EventArgs e)
{
Button sendButton = (Button)sender;
int index = Int32.Parse(sendButton.Text);
SearchTextBox.Text = myTable.Rows[index].Cells[0].Text;
return;
}
I set up a breakpoint at the beginning of the NameClick function, and when I click one of these buttons it is never reached. Why is this function not being called by my buttons?
EDIT: I want to accomplish this without using JavaScript, if possible.
You use cellButton.OnClientClick = "NameClick";, but do you actually have a NameClick function in your javascript? If not, clicking the button will cause a JS error which will probably block the postback.
Other than that, it is advisable to assign explicit ID's to controls which you create programatically. Otherwise the autogenerated ID's may change on postback, which will prevent control events from firing.
Something like the following should work (not tested):
myTable.ID = "someid";
for (int x=0; x < res_list.Length; x++)
{
TableRow newRow = new TableRow();
newRow.ID = "r" + x;
TableCell textCell = new TableCell();
TableCell buttonCell = new TableCell();
buttonCell.ID = "bc" + x;
Button cellButton = new Button();
cellButton.ID = "btn" + x;
textCell.Text = res_list[x];
textCell.Attributes.Add("Width","60%");
cellButton.Text = x.ToString();
//cellButton.OnClientClick = "NameClick"; // not needed unless you have actual JS for it
cellButton.Click += new EventHandler(NameClick);
buttonCell.Controls.Add(cellButton);
newRow.Cells.Add(firstCell);
newRow.Cells.Add(buttonCell);
myTable.Rows.Add(newRow);
}
cellButton.OnClientClick should point to a client-side function, i.e. JavaScript. Do you have a JS function somewhere?
If the answer is no, then we've found your problem. You should create one. It will be helpful to set your ClientIDMode property of your dynamically generated controls to Static or Predictable, so your JS function can easiliy access them.
Do you need assistance with the JS function?
when you click on the button, the page start the life cycle again and your control Does not exist in the page you need to create the control again or save it in the viewstate or use control state
when he call back in the life cycle
in the page life cycle event SaveControlState, loadControlState
if you want to create a javascript click event you need to make sure that the control doesnt call to server side event for this in the javascript function you need to return false
you have to add this event in your asp syntax for button.
<asp:Button runat="server " OnClick="ButtonClick"/>

ListBox switch items asp.net jquery

I've two ListBox (second one is empty on page load) and two buttons which switch items between those ListBox.However,im using Jquery two switch items,which means there are no Postbacks.Once,ive finished,i click another button to save the items from the second List,this time using PostBack.
When it runs on server,ASP.NET does not recognize any item on the list,showing listbox2.items.count = 0(zero),but im sure that list does have items.
I wonder if add items to the list without postbacks is the problem;
Any suggestions?
code trying to get list:
try
{
estabelecimentos = new List<int>();
int x = lstSelect.Items.Count;//always 0,but list isnt empty
estabelecimentos = lstSelect.Items.Cast<ListItem>().Select(v => int.Parse(v.Value)).ToList();
}
catch(Exception ex)
{
divErro.Visible = true;
lblErro.Text = ex.Message;
return;
}
You are correct, when you postback to the server the datasource of the second list is read out of the ViewState (which had no items in it). You could store the second list's data in a hidden input (client side) or you could do postbacks to update the second list.

How to get a handle to a dynamic imagebutton in an ajax panel postback

I write an imagebutton to a table cell in a new row when a user selects an item in a list:
ImageButton imgbtnRemove = new ImageButton();
imgbtnRemove.ID = "uxStandardLetterDeleteImage_" + items.letterName;
imgbtnRemove.CommandName = "uxStandardLetterDeleteImage_" + items.letterName;
imgbtnRemove.ImageUrl = items.remove;
imgStatus.AlternateText = "Remove";
tRow.Cells[3].Controls.Add(imgbtnRemove);
When the new imagebutton is clicked, I can't seem to get a handle to it. I see it in Page_PreRender event, where I also reload the table on each postback.
string returnData = Request.Form.ToString();
but iterating through the form controls images:
if (c is System.Web.UI.WebControls.Button ||
c is System.Web.UI.WebControls.ImageButton)
does not find it. I can find it if I manually put in a:
imgbtnRemove.Click += new System.Web.UI.ImageClickEventHandler(this.ButtonClick);
in the Page_Load and then grab it in the click event:
switch (((System.Web.UI.WebControls.ImageButton)sender).CommandName)
...
but because there are new rows being added and deleted, this gets rather ugly programmatically. I'm thinking there must be an elegant solution to dynamic imagebutton creation and retrieval on the fly from server side code. I've done a lot of digging but this one is stumping me.
Thanks in advance...
If you're creating dynamic controls during the event handling phase of the Page lifecycle (for example, in the item selected event), then the control will be gone on the next postback.
In order for dynamic controls to be registered with ViewState, they have to be created in the Init phase of the event lifecycle.
Also, you say you're iterating through the Form's controls... when you are adding the imagebutton to the table's cells. Are you recursively descending the control heirarchy to look for the imagebutton?

How do I count checked checkboxes across all pages of a gridview using jquery?

I want to instantly update a status line indicating the number of checked checkboxes across all pages of an asp.net gridview. Right now I am only ably to count the number of checkboxes that are checked on the current gridview page.
Here is my code:
$(document).ready(initAll);
function initAll(){
countChecked();
$(".activeBoxes").click(countChecked);
}
function countChecked() {
var n = $(".activeBoxes input:checked").length;
$("#checkboxStatus").text(n + (n == 1 ? " vehicle is" : " vehicles are") + " selected on this page. ");
if( n == 0){
$(".activateButton").hide();
$("#checkboxStatus").hide();
}else{
$("#checkboxStatus").show();
$(".activateButton").show();
}
}
Keep a hidden text field on your page and everytime you check a box, call a javascript method that will write the 'id' of the checkbox to the hidden field. Each time you postback your page, serialise the hidden field's value to the session in your desired objects structure (be it objects, hash table, array etc).
Upon rendering the page, each checkbox can check the session object structure (that you have created before) and determine if the state of the checkbox was last checked or not.
You could use JQuery to loop through all checkboxes on the page and increment a counter if the checkbox is checked.
You can track the total selection in viewstate (or something similar) on page change. I did something similar tracking the selected row ID's in an array. In my case I had to re-check the items when they returned to the page. Additionally if you allow sorting the selection may move across pages.
Edit: Sorry this doesn't actually your Jquery question, but maybe it will help...
What you're missing is removing the ID. When checking rows and tempid is not checked make sure it is not in saveids.
Do you know that Google is your friend?
Selecting CheckBoxes Inside GridView Using JQuery
The WML Video
And without JQuery but for more perfectionist behavior (like the image below), try this link
alt text http://www.gridviewguy.com/ArticleImages/GridViewCheckBoxTwistAni.gif
I am using a viewstate to keep track of all checked items across all pages and rechecking them upon returning to the page.
I will have to add my viewstate value to the page total and somehow subtract overlapping totals. Since my jquery does not include an id, this will be tricky.
protected ArrayList savedIds;
if (ViewState["SavedIds"] == null) savedIds = new ArrayList();
else savedIds = (ArrayList)ViewState["SavedIds"];
List<int> activateList = new List<int>();
foreach (GridViewRow tt in GridView2.Rows)
{
CheckBox cb = (CheckBox)tt.FindControl("ActivateItem");
HiddenField id = (HiddenField)tt.FindControl("IdField");
if (cb.Checked)
{
int tempId = 0;
string tempId2 = id.Value.ToString();
int.TryParse(tempId2, out tempId);
activateList.Add(tempId);
}
}
foreach (int activateId in activateList)
{
if (!savedIds.Contains(activateId.ToString())) savedIds.Add(activateId.ToString());
}
ViewState["SavedIds"] = savedIds;

Resources