grid view validation problem - asp.net

in a grid view how can i apply a validator to check if any of grid view rows with check box are checked or not.
i did it using the custom validator like this but giving the error
"Control 'GridView1' referenced by the ControlToValidate property of 'gridCheck' cannot be validated. "
following is my code
what should i do please suggest me the alternate
protected void gridCheck_ServerValidate(object source, ServerValidateEventArgs args)
{
foreach (GridView row in GridView1.Rows)
{
CheckBox cb = (CheckBox)row.FindControl("Chek");
if (cb != null && cb.Checked)
{
args.IsValid = true;
return;
}
else args.IsValid = false;
}
}

You'd have to add a template field column. Set the gridview to edit templates mode. (in your designer). You can drag and drop controls as usual and set their ids etc. Add your validator control, and set the id.

Related

How do I keep an edit button hidden in a formview after using a filterexpression?

I'm trying to have a user/admin scenario for editing a formview. What I have is the Edit buttons in the formview be visible=true by default. Then I use a statement which says if the role is not equal to admin, then set the visibility to false for the edit button. It works like it should, when I click around, do postbacks, etc. the items stay hidden if the user is and admin...except when I use a dropdown list for filtering, which uses a statement like dataSource1.FilterExpression = ("ID=" + ddl1.SelectedValue).
Whether I set the default visibility to true or false for the formview edit linkbutton, when using the FilterExpression, it changes the visibility of what I don't want it to be. It is because the FilterExpression sets the visibility of the control to whatever the default visibility property of the control is set to.
Below is some code as an example of what I mean. Please help!
protected void Page_PreRender(object sender, EventArgs e)
{
string role;
role = "client";
LinkButton editGeneralOverview = (LinkButton)formViewGeneralOverview.FindControl("EditButton");
if (role != "admin"))
{
editGeneralOverview.Visible = false;
}
if (ddlIDFilter.SelectedValue != "-- ALL --")
{
dataSourceGeneralOverview.FilterExpression = ("ID=" + ddlIDFilter.SelectedValue);
}
You could hide it in the FormViews DataBound event:
protected void formViewGeneralOverview_DataBound(Object sender, EventArgs e)
{
LinkButton editGeneralOverview = (LinkButton)formViewGeneralOverview.FindControl("EditButton");
if (role != "admin"))
{
editGeneralOverview.Visible = false;
}
}
This way your visibility setting gets (re)applied after the FilterExpression has already taken effect.
Note: in case you do not know, you can attach this event to the FormView in the markup by setting the OnDataBound property. Like this:
<asp:FormView ID="formViewGeneralOverview"
OnDataBound="formViewGeneralOverview_DataBound"
...whatever other propeties you have >
...templates and junk...
</asp:FormView>

ASP.NET: How to access a dynamically created control

I'm creating a bunch of Checkboxes dynamically:
CheckBox chkRead = new CheckBox();
chkRead.ID = "chk1";
chkRead.AutoPostBack = true;
chkRead.CheckedChanged += new EventHandler(CheckBox_CheckedChanged);
CheckBox chkPost = new CheckBox();
chkRead.ID = "chk2";
chkPost.AutoPostBack = true;
chkPost.CheckedChanged += new EventHandler(CheckBox_CheckedChanged);
protected void CheckBox_CheckedChanged(object sender, EventArgs e)
{
CheckBox chk = (CheckBox)sender;
}
What I want to do is the following:
When I check the chkPost CheckBox I want the chkRead CheckBox to be checked as well
In the CheckBox_CheckedChanged event I only have access to the CheckBox that was clicked
but I don't know how to check the other checkbox from that event.
This is from memory, but you could do something like this:
protected void CheckBox_CheckedChanged(object sender, EventArgs e)
{
CheckBox chk = (CheckBox)sender;
CheckBox chkPost = (CheckBox) chk.NamingContainer.FindControl("chk2");
CheckBox chkRead = (CheckBox) chk.NamingContainer.FindControl("chk1");
if(chk == chkPost && chk.Checked)
{
chkRead.Checked = true;
}
}
This is assuming you want to do all this in code-behind, after postback. If you want to do it in javascript, that's a different question.
This also assumes that chk1 and chk2 are in the same naming container. If they aren't, things will get complicated.
Since it is your code that creates the checkboxes, you can store their references in a list or dictionary and retrieve them by id when needed.
If you want to do it dynamically you can add an attribute to the checkboxess you are interested in-- you can then loop over the Page.Controls collection and test that the control you are looping over has that attribute and then you can check, or uncheck it.
some pseudo code:
foreach(var control in Page.Controls)
if(typeof(Control) is CheckBox and ((CheckBox)control).Attributes["myAttr"] != null)
//check or uncheck it
In reading your comment about nested controls-- this might be a bit of a hassle-- I tend to agree with Igor, that you should put the id's in a collection as they are being added dynamically.
Could you paste code where you are creating these checkboxes? Is it "OnInit" or somewhere else? Are you putting these checkboxes in container, do you store these controls as global variables or create them in method?

With the ASP.NET GridView control, how can I disable controls or individual cells in a GridViewRow after PageIndexChanged?

I have a data bound GridView control, in which I am able to disable individual cells based on the User role. This only works on the first page.
private void LimitAccessToGridFields()
{
if (User.IsInRole("Processing")) return;
foreach (GridViewRow gridViewRow in gvScrubbed.Rows)
{
var checkBox = ((CheckBox) gridViewRow.FindControl("cbScrubbed"));
checkBox.Enabled = false;
// ButtonField does not have an ID to FindControl with
// Must use hard-coded Cell index
gridViewRow.Cells[1].Enabled = false;
}
}
I call this method on Page_Load, where it works. I've tried it in the PageIndexChaging and PageIndexChanged event handlers, where it doesn't work. While debugging, it appears to successfully set Enabled to false in both of the controls in the row. My goal is to disable these fields, depending on user role, after changing the page. How should this be accomplished?
You do not need to iterate through any controls to disable or hide/visible them.
Every cell in a GridView control is actually a HTML table reference, when rendered (look at the code in your page using FireFly or Inspector).
So why not iterate through all the cells, and any controls found within each cell, just disable them? Or you can simply loop through each row of your GridView and disable or hide it directly, which will affect everything inside the row.
Hiding using a Table Cell reference example:
foreach (GridViewRow gRow in myGridView.Rows)
{
if (gRow.RowType == DataControlRowType.DataRow)
{
TableCellCollection tbcCol = (TableCellCollection)gRow.Cells;
foreach (TableCell tblCell in tbcCol)
tblCell.Enabled = false;
}
}
So that will disable everything table cell by table cell.
OR.. why not just disable the entire row?
foreach (GridViewRow gRow in myGridView.Rows)
{
if (gRow.RowType == DataControlRowType.DataRow)
gRow.Enable = false;
}
If you need to pin-point or filter particular control types (CheckBox, TextBox, Label, etc) and only affect those controls then simply test for them!
foreach (GridViewRow gRow in myGridView.Rows)
{
if (gRow.RowType == DataControlRowType.DataRow)
{
TableCellCollection tbcCol = (TableCellCollection)gRow.Cells;
foreach (TableCell tblCell in tbcCol)
if (((TextBox)tblCell) != null)
((TextBox)tblCell).Enable = false;
}
}
I found that this must be done in the RowDataBound event handler.
if (e.Row.RowType == DataControlRowType.DataRow)
{
// details elided ...
// Limits the access to grid fields.
if (!User.IsInRole("PROCESSING"))
{
cbstuff.Enabled = false; // a checkbox
e.Row.Cells[1].Enabled = false; //a link button
}
}

dynamic data - all option in paging

I'm developing a dynamic data web app. On list.aspx page it has GridViewPager control for paging, it option in drop down list as 10,20,.. rows in a page like that, but it does not an option show all rows in a page.
How I can add "All" option in it?
I assume you are referring to a GridView and the automatic paging functionality included. If not please clarify. However, if this is the case then the default paging options do not include a show all. You can roll your own, I would start here: http://msdn.microsoft.com/en-us/library/5aw1xfh3.asp
In content folder Dynamic Data site lies the code for GridViewPager control.
What I have done is I added "All" option in dropdown list with values 0, and in the code behind file in function DropDownListPageSize_SelectedIndexChanged I check if selected value is 0 then set AllowPaging = false else true.
protected void DropDownListPageSize_SelectedIndexChanged(object sender, EventArgs e)
{
if (_gridView == null)
{
return;
}
DropDownList dropdownlistpagersize = (DropDownList)sender;
int sz=Convert.ToInt32(dropdownlistpagersize.SelectedValue);
//_gridView.PageSize = Convert.ToInt32(dropdownlistpagersize.SelectedValue);
if (sz<=0)
{
_gridView.AllowPaging = false;
//_gridView.DataBind();
//return;
}
else
{
_gridView.AllowPaging = true;
_gridView.PageSize = sz;
_gridView.AllowPaging = true;
}
int pageindex = _gridView.PageIndex;
_gridView.DataBind();
if (_gridView.PageIndex != pageindex)
{
//if page index changed it means the previous page was not valid and was adjusted. Rebind to fill control with adjusted page
_gridView.DataBind();
}
}
You will have to implement your own pager and attached it to the Gridview. Default pager will not give you this option. May be this link could help you. http://www.codeproject.com/KB/grid/GridView_pager.aspx

Set focus on textbox after postback

I have a search page with 3 TextBoxes that users can filter a search with.
I have put the focus on the TextBox that contains text. If more than one contains text just focus on last TextBox.
private void SetFocusOnTextBox(ControlCollection ctrlCollection)
{
foreach (Control ctrl in ctrlCollection)
{
if (ctrl.GetType() == typeof(TextBox))
{
if (((TextBox)ctrl).Text != string.Empty)
{
SetFocus(ctrl);
}
}
}
}
After the code runs and a user searches, the focus comes to the beginning of the TextBox, not the end where it would be presumed. How to put insert marked at the end of that TextBox?
I think the answer is here: Use JavaScript to place cursor at end of text in text input element.
Taken from the linked solution: You have to add onfocus="this.value = this.value" to the three controls in the markup file. This is not so easy in ASP.NET as it should be, but one solution is to add the attribute in the code behind file.
protected void Page_Init(object sender, EventArgs e)
{
// MoveCursorToEndOnFocus is called in Page_Init and not Page_Load to avoid
// filling the ViewState with unnecessary data.
// TODO: Call MoveCursorToEndOnFocus here.
}
private void MoveCursorToEndOnFocus(ControlCollection controlCollection)
{
foreach (TextBox textBox in controlCollection
.Where(control => control.GetType() == typeof(TextBox)))
{
textBox.Attributes.Add("onchange", "this.value = this.value");
}
}
Shouldn't it be
if (((TextBox)ctrl).Text == string.Empty)
to advance to the bottommost empty textbox? If it is if (((TextBox)ctrl).Text != string.Empty), it will set focus (eventually) to the bottommost nonempty textbox.
As for advancing your cursor to the last character, try this:
function cursorToEnd( elem )
{
elem.focus();
elem.value+='x';
elem.value=elem.value.replace(/x$/,"");
}

Resources