I have a GridView inside an UpdatePanel. The GridView (GV) contains In-Row Buttons. If the GV list is very long and press the Buttons on the bottom rows, the page scrolls to the top and I cannot find which button I had clicked.
I have tried, MaintainScrollPositionOnPostback="true", but since I am using an UpdatePanel, this does not seem to be working.
I would like the screen to remain on the Row where I have clicked the Button.
set UpdatePanel UpdateMode="Always"
add this function:
public static string GetPostBackControlId(Page page)
{
Control control = null;
// first we will check the "__EVENTTARGET" because if post back made by the controls
// which used "_doPostBack" function also available in Request.Form collection.
string controlName = page.Request.Params["__EVENTTARGET"];
if (!String.IsNullOrEmpty(controlName))
{
control = page.FindControl(controlName);
}
else
{
// if __EVENTTARGET is null, the control is a button type and we need to
// iterate over the form collection to find it
// ReSharper disable TooWideLocalVariableScope
string controlId;
Control foundControl;
// ReSharper restore TooWideLocalVariableScope
foreach (string ctl in page.Request.Form)
{
// handle ImageButton they having an additional "quasi-property"
// in their Id which identifies mouse x and y coordinates
if (ctl.EndsWith(".x") || ctl.EndsWith(".y"))
{
controlId = ctl.Substring(0, ctl.Length - 2);
foundControl = page.FindControl(controlId);
}
else
{
foundControl = page.FindControl(ctl);
}
if (!(foundControl is Button || foundControl is ImageButton)) continue;
control = foundControl;
break;
}
}
return control == null ? String.Empty : control.ID;
}
use this in page_loadto get postback controlId:
if (IsPostBack)
{
string controlName = GetPostBackControlId(this);
}
Related
How to find control (i.e image button) inside repeater, that repeater is already in a datalist? because I have to perform delete operation on that image button.
Here is my code, here I'm getting repeater but not image button:
foreach (DataListItem item in Dlist_SearchResult.Controls)
{
rptrResult = (Repeater)item.FindControl("Rptr_result");
imgbtnDelete = (ImageButton)item.FindControl("imgbtnDelete");
}
You can use Recursion in your FindControl. FindControl by default is not recursive.
Try this:
private static Control FindControlRecursive(Control rootCtrl, string ID)
{
if (rootCtrl.ID == ID)
return rootCtrl;
foreach (Control ctr in rootCtrl.Controls)
{
Control foundCtl = FindControlRecursive(ctr, ID);
if (foundCtl != null)
return foundCtl;
}
return null;
}
you can call it
Button btn = FindControlRecursive((Control)Page,"imgbtnDelete");
Please refer the attached screenshot. I have an array of the checkbox and a button for the post back in ASP.Net page. I have written a function as follows to determine what all check boxes have been checked on the button click event: The following code is a part of the business component which is called from ASP.Net. Please let me know how can I return actionArray back to calling functon in ASP.Net page.
public void checkBoxValidation(Control parent, string strKey)
{
XmlDocument getCyleXML = new XmlDocument();
string strChkID="", strActionXPath = "",strAction="";
ArrayList actionArray = new ArrayList();
// Loop through all the controls on the page
foreach (Control c in parent.Controls)
{
// Check and see if it's a checkbox.
if ((c.GetType() == typeof(CheckBox)))
{
// Since its a checkbox, see if this is checked.
if (((CheckBox)(c)).Checked == true)
{
// Find the ID of the checkbox
strChkID = ((CheckBox)(c)).ID.ToString();
getCyleXML = CycleXML(strKey);
strActionXPath = "/Actions/Action[checkbox='" + strChkID + "']/*[self::Name]";
strAction = getCyleXML.SelectSingleNode(strActionXPath).ToString();
actionArray.Add(strAction);
}
}
// Now we need to call itself (recursion) because all items (Panel, GroupBox, etc) is a container so we need to check
// all containers for any checkboxes.
if (c.HasControls())
{
checkBoxValidation(c, strKey);
}
}
}
The code should be like this :
public ArrayList checkBoxValidation(Control parent, string strKey, ArrayList actionArray)
{
XmlDocument getCyleXML = new XmlDocument();
string strChkID="", strActionXPath = "",strAction="";
if(actionArray == null) { actionArray = new ArrayList(); }
// Loop through all the controls on the page
foreach (Control c in parent.Controls)
{
// Check and see if it's a checkbox.
if ((c.GetType() == typeof(CheckBox)))
{
// Since its a checkbox, see if this is checked.
if (((CheckBox)(c)).Checked == true)
{
// Find the ID of the checkbox
strChkID = ((CheckBox)(c)).ID.ToString();
getCyleXML = CycleXML(strKey);
strActionXPath = "/Actions/Action[checkbox='" + strChkID + "']/*self::Name]";
strAction = getCyleXML.SelectSingleNode(strActionXPath).ToString();
actionArray.Add(strAction);
}
}
// Now we need to call itself (recursion) because all items (Panel, GroupBox, etc) is a container so we need to check
// all containers for any checkboxes.
if (c.HasControls())
{
checkBoxValidation(c, strKey, actionArray);
}
}
return actionArray;
}
How do we pass the Click event of ImageButton inside a GridView to httpmodule
for linkbutton's i am doing this way:
if (request.Form.GetValues("__EVENTTARGET") != null)
{
//If it's a link button execute we can directley check for the params
if (request.Params.Get("__EVENTTARGET").Contains("xyz"))
{
//some Code
}
This is not working for ImageButton.
If you're trying to attach an event to a button within a gridview might I suggest in your base page on the prerender event parse through all gridviews on the page (use a recursive findcontrol algorithm) and look for any imagebuttons, if you find one you should then be able to attach an event to it.
EDIT:
I use something similar in the following:
public abstract class AmendmentPopUpWindow : BaseMasterPlanPage
{
// override this method if the correct save controls arent being hidden in the popups
public virtual IEnumerable<WebControl> SaveControls
{
get { return Controls.All().OfType<WebControl>().Where(c => c.ID.ToLower().Contains("save")); }
}
protected override void OnPreRender(EventArgs e)
{
if (WebConfiguration.Global_EnableAmendments && SystemVersion.HasValue)
{
foreach (var control in Controls.All())
{
if (control is RadioButton || control is TextBox || control is DropDownList || control is RadComboBox || control is CheckBox || control is CheckBoxList ||
control is RadEditor || control is RadTextBox || control is RadNumericTextBox)
{
var webControl = control as WebControl;
webControl.Enabled = false;
webControl.ForeColor = Color.Gray;
}
}
foreach (var saveControl in SaveControls)
saveControl.Visible = false;
}
base.OnPreRender(e);
}
EDIT: The .All() is an extension method defined as follows (stolen from here)
public static IEnumerable<Control> All(this ControlCollection controls)
{
foreach (Control control in controls)
{
foreach (Control grandChild in control.Controls.All())
yield return grandChild;
yield return control;
}
}
ImageButtons have an additional quasi-property in their names which identifies the mouse-coordinates (X and Y).
So to find the ImageButton's name your should iterate through posted parameters and found those which end with .x or .y:
foreach (string item in request.Form)
{
if (item.EndsWith(".x") || item.EndsWith(".y"))
{
var controlName = item.Substring(0, item.Length - 2);
// some code here
}
}
You could also cound this answer useful. It contains a more generic method to determine which control caused a postback.
HTML has an input button type to reset all fields in a form to their initial state in one step: <input type="reset" ... />.
Is there a similar simple way to reset all form fields of an aspx page from code-behind? Or is it necessary to reset all controls one by one with TextBox1.Text=string.Empty, TextBox2.Text=string.Empty, etc. ?
Thanks in advance!
Update:
Context is a simple Contact/"Send us a message" page with 8 asp:TextBoxes on the page (where the user enters the name, address, phone, email, message, etc.). Then he clicks on submit, the Onclick message handler in code-behind sends an email to some administrator, and all the form fields the user filled in should be emptied and he gets a notification in a label ("Message sent blabla..."). I want to have the form fields cleared to avoid that the user clicks again on submit and the same message is sent a second time.
You need only write a fork for each type of control unless one of the control has something special that needs to be done to reset it.
foreach( var control in this.Controls )
{
var textbox = control as TextBox;
if (textbox != null)
textbox.Text = string.Empty;
var dropDownList = control as DropDownList;
if (dropDownList != null)
dropDownList.SelectedIndex = 0;
...
}
ADDITION You asked how to clear controls even ones that are buried. To do that, you should create a recursive routine like so:
private void ClearControl( Control control )
{
var textbox = control as TextBox;
if (textbox != null)
textbox.Text = string.Empty;
var dropDownList = control as DropDownList;
if (dropDownList != null)
dropDownList.SelectedIndex = 0;
...
foreach( Control childControl in control.Controls )
{
ClearControl( childControl );
}
}
So, you would call this by passing the page:
ClearControls( this );
Refer this link for more information
http://www.freshcodehub.com/Article/3/clear-all-fields-like-textbox-dropdownlist-checkbox-radiobutton-label-after-form-submission-in-aspnet-c
public void ClearControls(Control parent)
{
foreach (Control c in parent.Controls)
{
if ((c.GetType() == typeof(TextBox))) //Clear TextBox
{
((TextBox)(c)).Text = "";
}
if ((c.GetType() == typeof(DropDownList))) //Clear DropDownList
{
((DropDownList)(c)).ClearSelection();
}
if ((c.GetType() == typeof(CheckBox))) //Clear CheckBox
{
((CheckBox)(c)).Checked = false;
}
if ((c.GetType() == typeof(CheckBoxList))) //Clear CheckBoxList
{
((CheckBoxList)(c)).ClearSelection();
}
if ((c.GetType() == typeof(RadioButton))) //Clear RadioButton
{
((RadioButton)(c)).Checked = false;
}
if ((c.GetType() == typeof(RadioButtonList))) //Clear RadioButtonList
{
((RadioButtonList)(c)).ClearSelection();
}
if ((c.GetType() == typeof(HiddenField))) //Clear HiddenField
{
((HiddenField)(c)).Value = "";
}
if ((c.GetType() == typeof(Label))) //Clear Label
{
((Label)(c)).Text = "";
}
if (c.HasControls())
{
ClearControls(c);
}
}
}
using the manual approach of String.Empty for each and every Textbox or any other field will be cumbersome, also by using Response.Redirect(); it will be difficult to show any confirmation message or same. So, on reading so many blogs i have found a reliable approach so far:
Public void reset(Control control)
{
foreach (Control x in control.Controls)
{
if (x is TextBox)
{
(x as TextBox).Text = String.Empty;
}
else if (x is DropDownList)
{
(x as DropDownList).SelectedIndex = 0;
}
.
.
reset(x);
}
}
use this code as reset(this); in your page wherever you want to reset or clear the values. At end of the if conditions do not forget to use the function recursively using the same
`Control` object x.
Using form.Controls.Clear() is not such a good approach because it will clear the entire form and you will even lose all the buttons on the form.
Instead if you just want to clear all the form fields like text fields and radio buttons I would recommend you try the following:
If you have a Reset button “Button1” then on click call a function reset();
In the reset function:
protected void resetButton_Click(object sender, EventArgs e)
{
TextBox1.Text=""; //set equal to empty string to all fields
}
Or redirect to same page by terminating the previous page
protected void resetButton_Click(object sender, EventArgs e)
{
Response.Redirect("~/Test2.aspx", true);
}
For your scenario the easiest way to clear the fields, in my opinion, is to turn off the ViewState (EnableViewState=false) of the controls you want to appear blank after the submit.
Or perhaps for the whole page unless there is some state you need.
I was wondering if anyone can post an example of how to get a selected radio button option from an asp.net radio button list control via jquery on the loading of a page.
Thanks
In your javascript function where you want to query the list, use this code..
var selected = jQuery('#<%= MyRadioButtonList.ClientID %> input:checked').val();
// or ...
var selected = $('#<%= MyRadioButtonList.ClientID %> input:checked').val();
to set a sample label with the results of your selected radiobuttonlist, you could do this...
$(document).ready(function(){
var selected = $('#<%= MyRadioButtonList.ClientID %> input:checked').val();
$("#<%= MySampleLabel.ClientID %>").text(selected);
}
Working example here.
The selector I used to get the radio buttons will grab all the radio buttons with the class ofinterest on the page.
$(function(){
var value = $('input.ofinterest:checked').val();
$('#result').text(value);
});
If you want to scope the selector further, and you don't mind writing your JS directly in your aspx/ascx, you can use Scott's solution above instead. But if you give the buttons you're interested in a known classname, you can put this JS in a .js file.
protected void radioButton_CheckedChanged(object sender, EventArgs e)
{
throw new ApplicationException("Radio Changed");
RadioButton rb = (RadioButton)sender;
TextBox tbexact = (TextBox)this.UpdatePanel1.FindControl("TextBoxExact");
TextBox tbpartial = (TextBox)this.UpdatePanel1.FindControl("TextBoxPartial");
DropDownList dropdown = (DropDownList)this.UpdatePanel1.FindControl("DropDownListCountries");
RadioButton rbc = (RadioButton)this.UpdatePanel1.FindControl("RadioButtonExact");
if (tbexact == null)
throw new ApplicationException("Could not find control");
else
throw new ApplicationException("Found it");
if (rbc != null && rb.Equals(rbc))
{
tbpartial.Enabled = false;
dropdown.Enabled = false;
mCriteria = SearchCriteria.Exact;
}
rbc = (RadioButton)this.UpdatePanel1.FindControl("RadioButtonPartial");
if (rbc != null && rb.Equals(rbc))
{
tbexact.Enabled = false;
dropdown.Enabled = false;
mCriteria = SearchCriteria.Partial;
}
rbc = (RadioButton)this.UpdatePanel1.FindControl("RadioButtonPerCountry");
if (rbc != null && rb.Equals(rbc))
{
tbexact.Enabled = false;
tbpartial.Enabled = false;
mCriteria = SearchCriteria.Country;
}
}