I have a column in a GridView which has a Dropdownlist in the EditTemplate
The data for this dropdownlist is added dynamically (items.add()) after the user enters the edit mode for that row.
foreach (var bgElement in userCropList.FirstOrDefault(c => c.Crop == cropToBeUpdated).BGs)
{
ddl.Items.Add(bgElement.BG);
}
ddl.SelectedIndex = userCropList.FirstOrDefault(c => c.Crop == cropToBeUpdated).BGs.FindIndex(d => d.Default == true);
When the user clicks the update button to save his changes, the page does a postback and as such lose the items aswell as the selectedindex which i need for the following bit in the RowUpdating event.
DropDownList ddl = (DropDownList)GVCrops.Rows[e.RowIndex].FindControl("ddlAvailableBGs");
updatedCrop.BGs.FirstOrDefault(c => c.BG == ddl.SelectedValue).Default = true;
What came to my mind was to put the value the user selects in a viewstate variable and read from it in the RowUpdating event.
I am asking if there is an easier (not that it is hard) or already available thing that I am missing which could that for me?
Edit:
Ok, turns out my method ..
RowEditing():
ViewState.Add("SelectedBGIndex", ddl.SelectedValue);
RowUpdating():
if (ViewState["SelectedBGIndex"] != null)
{
updatedCrop.BGs.FirstOrDefault(c => c.BG == ViewState["SelectedBGIndex"].ToString()).Default = true;
}
..is not going to work for the same reason apparently.
When the user clicks the update button for the row it will post back and the drop down list is reset with no selection and no items inside.
Seems like the solution would be a JavaScript function.
Any thoughts how to approach it?
Related
I have a asp.net page that has two controls on it, A placeholder and a submit button. During the Page_Load I create a checklist of tasks dynamically. Each row consists of a description, link to a tutorial, and a checkbox. All of the information in the row is kept in a database. If the database says the task has been checked, the code sets the checked property to true. The problem I'm having is that when the submit button is clicked I cannot find what the value is of the checked property for all of the checkboxes on the page(about 23 total).
Here is the code to create the checkboxes...
checkbox = new CheckBox();
phChecklist.Controls.Add(checkbox);
if (item.Attributes.Contains("ree_completed"))
checkbox.Checked = (bool)item.Attributes["ree_completed"];
checkbox.EnableViewState = true;
checkbox.ClientIDMode = System.Web.UI.ClientIDMode.Static;
checkboxId = "checkbox" + (string)item.Attributes["ree_sectionnumber"].ToString() + (string)item.Attributes["ree_sequencenumber"].ToString();
checkbox.ID = checkboxId;
Here is the code to try and find the value of the checkbox...
foreach (Entity item in checklistCollection.Entities)
{
checkboxId = "checkbox" + (string)item.Attributes["ree_sectionnumber"].ToString() + (string)item.Attributes["ree_sequencenumber"].ToString();
itemChecked = (bool)ViewState[checkboxId];
if (itemChecked == "true")
** update database **
//CheckBox checkbox = (CheckBox)phchecklist.FindControl(checkboxId);
}
I think I've read every post on this subject and have tried most of them. I have also read about the ViewState but the suggestions that I have read about have not worked. As you can see I also tried finding the checkbox in the controls collection by the id and that also did not work.
I do not recreate the checkboxes when posting back to the page. Some posts mention that you have to recreate the controls but when I tried to do that I received an error message saying it was a duplicate id. The other reason I would prefer not to have to recreate the page is the performance hit. The database is in a Microsoft Dynamic CRM database that is remote.
How do I retain the value of checked property across a post back?
UPDATE: I changed my logic around and fixed the duplicate id error. The page will now recreate all of the controls during the post back. I still cannot find the value of any of the checkbox controls when the submit button is clicked.
Gary
You need to provide an ID for the checkbox control when you create it. Since you are creating multiple checkboxes; one for each row in the database ... you need to add the unique row identifier to the ID. So you need to build the checkbox ID from the row ID (usually the IDENTITY). Example: ">
Then on postback while you are post-processing each row in the table, you can query the request for that specific key value pair. Something similar to this:
foreach (DataRow dr in dataTable.Rows)
Response["chk_" + dr("ID")];
Use Page Init as opossed to page_Load event. As per https://msdn.microsoft.com/en-us/library/ms178472.aspx "Use this event to read or initialize control properties"
In case for that to work you need to add an event handler to dynamically added controls
in your case
checkbox = new CheckBox();
phChecklist.Controls.Add(checkbox);
checkbox.CheckedChanged += checkBox_CheckedChanged;
and then what you need to do in the method
private void CheckBox_CheckedChanged(object sender, System.EventArgs e)
{
...
}
As I commented, you certainly need to create your controls during the Init event, Load is too late. Check out the asp.Net page life's cycle for details.
On a side note, you might want to let ASP.NET handle the controls's ID. You say you need to keep some value in order to get back to the database, you can wrap your checkboxes in a table. You will then be able to iterate through your controls without having to guess their names.
For instance, if your row has a HiddenField followed by your actual CheckBox:
//Please call me during Init
protected void createTheControls() {
TableRow tr;
TableCell td;
CheckBox cb;
HiddenField section, sequence;
foreach (Object item in someList)
{
section = new HiddenField();
section.Value = item.Attributes["ree_sectionnumber"].ToString();
sequence = new HiddenField;
sequence.Value = item.Attributes["ree_sequencenumber"].ToString();
cb = new CheckBox();
cb.ID = String.Concat("checkbox", (String)sequence.Value);
if (item.Attributes.Contains("ree_completed"))
cb.Checked = (bool)item.Attributes["ree_completed"];
td = new TableCell();
td.Controls.Add(section);
td.Controls.Add(sequence);
td.Controls.Add(cb);
tr = new TableRow();
tr.Cells.Add(td);
}
}
protected void readTheControls()
{
foreach (TableRow tr in myTable.Rows)
{
HiddenField section = (HiddenField)tr.Cells[0].Controls[0];
HiddenField sequence = (HiddenField)tr.Cells[0].Controls[1];
CheckBox cb = (CheckBox)tr.Cells[0].Controls[2];
}
}
I notice you try to use the ViewState explicitly, which I believe is not going to be of any help here. The solution above may look cumbersome, but it will ensure you dont need to mess with ID's when fetching the controls.
Here's a thorough explanation from MSDN, and here are a few short and sweet SO answers explaining ViewState's purpose.
It is a very weird problem
when I change the value of the drop down list, a new drop down list is show. I am so confused,
To know what I am talking about, please check these images.
edit
code for bind
CallerId = Request["CallerID"];
if (String.IsNullOrWhiteSpace(CallerId)) return;
var results = ZumaDa.GetCustomerInformation(CallerId);
rowCount = results.Rows.Count;
CallerId = rowCount > 0 ? results.Rows[0][4].ToString() : CallerId;
if (rowCount > 1)
{
ListView1.Enabled = false;
GridView1.DataSource = results;
GridView1.DataBind();
}
else
{
GridView1.Enabled = false;
ListView1.DataSource = results;
ListView1.DataBind();
}
That code is in page load and NOT on !ispostback
Since you updated your question with the ListView markup, and your Page_Load code, it appears the problem of the duplicated DropDownList goes away after you wrap your databinding code in an if (!Page.IsPostBack) block.
One problem in your code is that, in your SelectedIndexChanged event, you're searching the ListView for your DropDownList and TextBox. You need to search the ListViewItem control where the SelectedIndexChanged event occurred.
To do that, you can first get the DropDownList from the "sender" parameter. Then you should find the "NamingContainer" control of the DropDownList, and search that. Like this:
var dropDown = (DropDownList)sender;
var visitID = (TextBox)dropDown.NamingContainer.FindControl("visitID");
That second line of code might need to have an additional ".NamingContainer" depending on your markup.
I think you need to bind listview in !IsPostback check means when do postback it pageload event fired and it bind dropdown with second time or if its not please share binding code
I have a ListView with DataPager control. I'm trying to display a series of questions.Each question along with it's choices belongs to an item in the listview and I am displaying one question per page. The choices are radio buttons with autopostback enabled.
Now, based on the user's response to the first question I want to filter the rest of the questions in the listview to display only the ones relevant to the user's choice. Also, I don't want to completely remove the other questions from the listview because if the user navigates to the first question and changes his response, I want the list to change accordingly. Is there a way to dynamically hide the pages that contain the irrelevant questions?
Thanks.
Note: The list items are populated by a custom sql query:
SELECT questionNumber,questionText,OptionA,OptionB,OptionC,OptionD,OptionE,OptionF,OptionG,OptionH,OptionI,OptionJ,OptionK,OptionL,Other,questionTag,subType from Questionairre
In this query the value present in the field "subType" should be compared with the choice made in the first question.. The subtype field for the first question will not be checked. The following code is what I have so far. The variable "firstChoice" is the static variable that stores the value postedback from the first question.
protected void ListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
ListViewDataItem di = (ListViewDataItem)e.Item;
Label q=new Label();
foreach(Control control in di.Controls)
{
if (control.GetType() == typeof(Label))
{
q = (Label)control;
if (q.ID == "subType" && q.Text != firstChoice)
{
di.Visible = false;
}
}
}
}
On the page load there will be gridview with a default row....there is a button with a + sign at the bottom...on the button click i want to create a new rows in the grid..before that i need to make sure that all fields have values.But I am getting null values..
My code is:
TextBox name_value = ((TextBox)Gridview1.Rows[0].FindControl("TextBox1"));
TextBox age_value = ((TextBox)Gridview1.Rows[0].FindControl("TextBox2"));
DropDownList sex_value = ((DropDownList)Gridview1.Rows[0].FindControl("DropDownList1"));
DropDownList berth_value = ((DropDownList)Gridview1.Rows[0].FindControl("DropDownList2"));
Any help will be appreciated.
Please write this code at end of the code
Gridview1.EditIndex-1 not sure EditIndex or Edititemindex please try it may be help you.
Try using a condition
if(name_value.Text!="" && age_value.Text && sex_value.Text && berth_value.Text)
{
//action
}
I would like some help with the following problem. I have a dropdownlist implemented in my masterpage. It has an sql data source from which it loads the values of companies. Depending on which value(company) selected, it shows that value in a label on a different page.
The ddl which is in the masterpage is ofc still visible and should display the selected value which it does at the 1st time a value is selected. But when i select another value in the ddl it shows the value which was 1st selected and so on. So it doesn't update or something.
My code:
This is the onselectedIndexChanged event handler:
protected void DropDownListType_SelectedIndexChanged(object sender, EventArgs e)
{
String input1 = DropDownListType.Text;
String input2 = DropDownListType.SelectedValue;
String url = "~/test.aspx?pcompany="+input1;
DropDownListType.SelectedValue = input2;
Session["Company"] = input2;
Response.Redirect(url);
}
and this is the code i'm using in my Page_load method from the masterpage:
if (Session["Company"] != null)
{
DropDownListType.SelectedValue = (String)Session["Company"];
}
If I remove this last piece of code from my page_load method it updates the label with value on the redirected page but it resets my ddl to default value instead of keeping it at 4 when value 4 selected.
I hope this is a bit clear to you all. Any help is appreciated. Ty in advance.
try setting the label value in the PreRender() method. The problem you're having is with the page life cycle. I would change your OnLoad method to use
if(!IsPostBack) {
if (Session["Company"] != null)
{
DropDownListType.SelectedValue = (String)Session["Company"];
}
}
This way you're only setting it once when the page loads and from then on the page will set the selected value automatically using viewstate.
The Load event is fired before the SelectedIndexChanged event, that's why you don't have it set in Session yet.
See ASP.NET Page Life Cycle
just set the AutoPostback property of the DropDownList to true and then it will work.
This is because otherwise the onselectedIndexChanged will be called only on PostBack from a button or any other field.
And also, as the above answer says, use this code:
if(!IsPostBack) {
if (Session["Company"] != null)
{
DropDownListType.SelectedValue = (String)Session["Company"];
}
}