Setting Visibility of Button Control in GridView Header - asp.net

I have a gridview that displays entries from a data table. I am giving users the ability to select a subset of the data in the table by having a textbox and search button in the grid view header. The search button fires the gridview row command, and changes the underlying sqlDataSource's select command, and adds the text value from the text box as a parameter.
This works smoothly.
Also, I have a "Show All" button in the header, that clears out the select parameters, so all entries in the table are shown. Again, this works perfectly.
What is NOT working is controlling the visibility of the "Show All" button control. Below is the html markup for the data grid header template:
<HeaderTemplate>
<asp:Button ID="btnShowAll" runat="server" CausesValidation="False" CommandName="ShowAll" Text="Show All" />
<asp:Button ID="btnSearch" runat="server" CausesValidation="True" CommandName="Search" Text="Search" ValidationGroup="vldSearch" /><br />
<asp:TextBox ID="txtSearchName" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="vldSearchName" runat="server" ErrorMessage="You have to provide an attorney name to search for." Text="*" ControlToValidate="txtSearchName" ValidationGroup="vldSearch" ForeColor="White"></asp:RequiredFieldValidator>
</HeaderTemplate>
In the Row Command event handler, here is how I am setting the visibility of the button:
If Not Me.dgAttorneys.HeaderRow Is Nothing Then
Dim btnShowAll As Button = Me.dgAttorneys.HeaderRow.FindControl("btnShowAll")
btnShowAll.Visible = Me.sqlAttorneys.SelectParameters.Count > 0
Trace.Write("Show all status is " & btnShowAll.Visible.ToString)
End If
The trace statement is showing the correct visible status - if the "show all" button is clicked, I do a SelectParameters.Clear() on the sqlAttorneys sqlDataSource.
Is my problem due to a misunderstanding of how the "FindControl" method works - I had assumed my new btnShowAll that I define is actually a reference to the "physical" control on the aspx page, so any changes I make to my local object is reflected in the control on the page.
If this is not the case, what is the best way to get a reference to the button control in the header row of the grid view?

I managed to get the button behavior to work - it was all to do with where in the overall process I was setting the button visibility. I moved that code block (setting the button visibility based on the presence of a search parameter) to the DataBound event for the data grid, and the button's visibility was set as it should be.
I suspect this is because during the overall data binding process, based on the state of the overall grid view and each grid row, the appropriate template object is used to render each row. Thus, any changes made to the button's visible property were being overridden during the data binding process. By shifting my code to set the visibility until after the data binding was complete, then it took effect.

Related

Wait cursor on click of auto select button on GridView

I have an asp:GridView control where the first column is where the user selects the row (so it displays an underlined "Select" on each row). The AutoGenerateSelectButton is set to "True". When the row is selected, the query behind it may take some time to return the data on the page, so I'd like to set the cursor to 'wait'. The problem is, on the client side, I'm not sure how I can trap which row was selected before the postback. With an autogenerate Select on a grid, the actual HTML on the page is an anchor tag with a javascript:postback assigned.
I can easily set a wait cursor for a control like an asp:Button by simply doing a
btnButton.Attributes.Add("onclick", "document.body.style.cursor = 'wait';")
in the C# code behind, but I'm not sure how to do something similar with a asp"GridView control when someone not just clicks on the grid but clicks the Select hyperlink.
Thanks!
Set AutoGenerateSelectButton=false and use a button instead. This shall replace the select link column on your gridview, which should allow for your desired cursor functionality.
<asp:GridView ID="GridView1" runat="server" OnSelectedIndexChanged="GridView1_SelectedIndexChanged">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton Text="Select" runat="server" CommandName="Select" OnClientClick="$('body').addClass('waiting');"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I placed the jquery directly into client side click, but it could also be used in a function. I found the javascript/css resources from another question on SO.
Changing cursor to waiting in javascript/jquery
CSS:
<style>
body.waiting * {
cursor: progress;
}
</style>

Why ASP.NET Controls defined in mark up already created on Page_PreInit life cycle event

I read Microsoft's article on ASP.Net Page Life Cycle events. It confused on one thing. When Page_PreInit gets called, all the controls' Init method is not yet called. When I setup a test project, I observed a different behavior. In the mark up, I created asp label and button controls and set certain properties such as Text. I put a break point at the beginning of Page_PreInit. When break point got hit, I checked if the controls got created or not by referring to them by their Ids in the Watch window. They all existed and none returned null. Then I checked the Text property and it was what I set in the mark up. So doesn't this contradict what Microsoft says? If this is the case what do Controls' Init method do if they are already initialized? Is there something I miss?
I created asp label and button controls and set certain properties
such as Text. ... Then I checked the Text property and it was what I set
in the mark up.
If you set property value at Design Time, they are in control tree so properties are available in all events.
However, if you add a TextBox and a user clicks on submit, TextBox Text Property only start available at Page_Load event.
The reason is that Page_Load is the place where properties are loaded with information recovered from view state and control state.
Look at this example
<asp:Label runat="server" ID="Label1" Text="Name" />
<asp:TextBox runat="server" ID="TextBox1" />
<asp:PlaceHolder runat="server" ID="PlaceHolder1" />
<asp:Button runat="server" ID="SubmitButton"
Text="Submit" OnClick="SubmitButton_Click" />
After Postback,
Notice that you can only retrieve TextBox value at Page_Load event.

Issue with Required Field validation in a asp.net application having two pages workflow

I have a asp.net application with two pages. The first page is having a next button and second page is having a back and submit button. The second page contains text box control with required field validtor.
As per current design, required field validator on 2nd page should get fired on clicking on submit button.
The issue I am having is :- User Fills the first page and then go to second page. Now, user wants to comeback to first page and then go to second page, the required field validator on text box is getting fired and showing up the error message. I dont want this. This should be like - text box should be blank and no error message should be displayed. Error messages should be displayed on clicking on the Submit button on the second page.
I tried couple of options :- 1. putting InitialValue on required field etc.. but no luck.
Could you pls help me out??
The following Markup should solve your problem :
<asp:TextBox ID="tbData" runat="server" ValidationGroup="Submit"></asp:TextBox>
<asp:Button ID="btnSubmit" runat="server" Text="Button" ValidationGroup="Submit" />
<asp:Button ID="btnBack" runat="server" Text="Button" />
<asp:RequiredFieldValidator ID="reqFieldVal1" runat="server" ErrorMessage="Field must be filled in."
ControlToValidate="tbData" ValidationGroup="Submit"></asp:RequiredFieldValidator>
These fields use the ValidationGroup property to set which fields will cause the validation of which validator controls.
You will notice that there is no ValidationGroup property on the btnBack button as this should not cause validation.
For more information on this see the MSDN Article for Specifying Validation Groups

Asp.Net Toggle checked property of a Data Bound checkbox

I have a GridView control that has one column of checkboxes set up like this:
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="RowCheckBox" runat="server" Enabled="false" Checked='<%# (bool)DataBinder.Eval(Container.DataItem ,"Associated") %>'/>
</ItemTemplate>
</asp:TemplateField>
Then when the user clicks an Edit button I run a script that enables all the checkboxes (which works fine), and then when the user then clicks on a checkbox the tick is appearing or disappearing as it should.
The problem I'm having is that when I try to read the value of the checkbox from the codebehind:
CheckBox checkBox = (CheckBox) row.FindControl("RowCheckBox");
bool checked = checkBox.Checked;
If the value bound to it was true then checked is still true, no matter if it was toggled or not.
Has anyone got any ideas why this is?
In the end I couldn't find a solution so have done a work around:
Add a Hidden Field to the Template Field,
Update the value of the hidden field to True or False with Javascript (adding an onclick attribute to the checkbox),
In the code behind cast the hidden field value to a bool and use that instead of the checked property of the checkbox.
I think it might be something to do with View States, but I'm not sure what they are and haven't got the time to investigate unfortunately.
Clivest

Using Validation controls with a GridView

A typical situation:
In my GridView control, I have a Footer row which contains a Textbox and an "Add" Button. When the button is pushed, the Text entered in the TextBox is added to the grid. I also have a validation control to require that, when the button is pushed, that text has been entered in the TextBox. After a new row is added, the textbox is clear to allow for easy entry of the next item.
The user may also edit the text in previously entered rows by clicking the Edit LinkButton, which puts the row into edit mode. Clicking an Update LinkButton commits the change.
The problem:
When, I click the Update link to commit the changes, if text has not been entered in the Footer row's TextBox (the row used to add a new entry), the validation control returns a "Entry Required" error. It should only require an entry if the Add button is pushed, not if the Update LinkButton is pushed.
It seems that the server side Validation control's validating event fires before the GridView's RowCommand event or the btnAdd_Click event, so I am wondering how, from the server, I can determine what event fired the postback so I can determine whether what edits should be performed for the given situation.
I am using a mix of client side "required" validation edits as well as more complex server sides. Since I probably have to have some server sided validations, I would be happy with just knowing how to handle server sided validations, but really, know how to handle this situation for client validations would also be helpful.
Thanks.
Convert your CommandField into a TemplateField, and in the EditItemTemplate, change the Update LinkButton's CausesValidation property to false.
Update:
Converting to a TemplateField is simple and doesn't require any code changes (just markup):
Changing the CausesValidation property to false in the markup is also straightforward:
<asp:TemplateField ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="lnkUpdate" runat="server" CausesValidation="False"
CommandName="Update" Text="Update"></asp:LinkButton>
<%--
More controls
--%>
</EditItemTemplate>
<ItemTemplate>
<%--
Controls
--%>
</ItemTemplate>
</asp:TemplateField>
Now, if you want your footer and data rows to be validated separately, you need to use validation groups, which is explained in Microsoft's documentation. All the controls in the same validation group will have their ValidationGroup property set to the same value, like this:
<asp:LinkButton ID="lnkUpdate" runat="server" CausesValidation="True"
CommandName="Update" Text="Update" ValidationGroup="GridViewDataRowGroup">
</asp:LinkButton>

Resources