Asp.net - Postback loses Dropdownlist index - asp.net

I have a simple Dropdownlist control that JS handles,
once the index changes, a div is opened/closed.
html code for initializing the Dropdownlist-
<select id="selectmethod" onchange="run()">
<option value="1" selected="selected">option1</option>
<option value="2" >option2</option>
</select>
JavaScript code to handle OnChange event-
function run() {
var e = document.getElementById("selectmethod");
var value = e.options[e.selectedIndex].value;
if (value == 1) {
$('#changecourseitems').slideUp();
$('#addnewcourseitems').slideDown();
}
if (value == 2) {
$('#addnewcourseitems').slideUp();
$('#changecourseitems').slideDown();
}
Now when the user clicks on an <ASP:LinkButton ... />
a Postback event starts and the Dropdownlist index resets (so as the hidden div).
How can I maintain the Dropdownlist index after the Postback ?
Thanks!

To maintain the contents of the dropdownlist you either have to re-populate it on the server every time or use viewstate. For example you can populate the data once like this
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
DropDownList1.Items.Add(new ListItem() { Text = "option1", Value = "1", Selected = true });
DropDownList1.Items.Add(new ListItem() { Text = "option2", Value = "2" });
}
}
and in the page you can use an ASP control and enable view state:
<asp:DropDownList ID="DropDownList1" runat="server" EnableViewState="true">
</asp:DropDownList>
Now the data will be posted back and forth and will be maintained on the client side

To maintain the value, there are multiple approaches.
1. Change the select to server control.
2. Add a hidden value and save your select tag value to this hidden value in your run(). And then set the select value
in document.ready().
<asp:HiddenField ID="yourHiddenValue" runat="server" />
Your run method.
function run() {
var e = document.getElementById("selectmethod");
var value = e.options[e.selectedIndex].value;
if (value == 1) {
$('#changecourseitems').slideUp();
$('#addnewcourseitems').slideDown();
}
if (value == 2) {
$('#addnewcourseitems').slideUp();
$('#changecourseitems').slideDown();
}
$('#<%=yourHiddenValue.ClientID%>').val(value); // <--- added
}
This is document ready function.
$(function() {
var hiddenValue = $('#<%=yourHiddenValue.ClientID%>').val();
$('#selectmethod').val(hiddenValue);
}

If you want to persist the control's state in ASP.Net Web Form, you want to use DropDownList Server Control which uses ViewState under the hood.
<asp:DropDownList runat="server" ID="DropDownList1">
<asp:ListItem Text="Add New Course" Value="1" />
<asp:ListItem Text="Change Course" Value="2" />
</asp:DropDownList>
<div id="changecourseitems">Change course</div>
<div id="addnewcourseitems">Add new course</div>
<asp:LinkButton ID="LinkButton1" runat="Server" OnClick="LinkButton1_Click"
Text="Submit" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
var selectMethod = function(){
if ($('#<%= DropDownList1.ClientID %>').val() === '1') {
$('#changecourseitems').hide();
$('#addnewcourseitems').slideDown();
} else {
$('#addnewcourseitems').hide();
$('#changecourseitems').slideDown();
}
}
$('#<%= DropDownList1.ClientID %>').change(selectMethod);
selectMethod();
});
</script>

<asp:DropDownList ID="selectmethod" ClientIDMode="Static" runat="server" EnableViewState="true">
</asp:DropDownList>
With the ClientIDMode=static you maintain the id as it is specify on the control
your js file should be:
$('#selectmethod').change(function () {
var value = $(this).val();
if (value == 1) {
$('#changecourseitems').slideUp();
$('#addnewcourseitems').slideDown();
}
if (value == 2) {
$('#addnewcourseitems').slideUp();
$('#changecourseitems').slideDown();
}
});

Related

RadioButtonList toggle button with databind

I have a radio button list connect to a local sqldb. The table has 2 cols - cata and catab, the radiobuttonlist is binded with cata and it works properly. I can enter records and view records. Next I applied bootstrap toggle button css , when I click buttons it works like toggle button, but I don't see any change when I change from record to record.
<asp:RadioButtonList ID="RadioButtonList1" runat="server" RepeatLayout="Flow"
RepeatDirection="Horizontal" CssClass="btn-group" data-toggle="buttons"
SelectedValue='<%# Bind("cata") %>'>
<asp:ListItem class="btn btn-primary" Value="1"></asp:ListItem>
<asp:ListItem class="btn btn-primary" Value="2"></asp:ListItem>
<asp:ListItem class="btn btn-primary" Value="3"></asp:ListItem>
<asp:ListItem class="btn btn-primary active" Value="4" Selected="True"></asp:ListItem>
</asp:RadioButtonList>
![screen shot][1]
Try below javascript to make toggling between your radio buttons.
<script>
$(document).ready(function () {
$('.btn-primary').click(function () {
$(this).addClass('active');
var allspan = $('#<%= RadioButtonList1.ClientID %>').find('span');
for (var i = 0; i < allspan.length; i++) {
if (allspan[i] == this) {
$(this).find('input[type="radio"]').prop('checked', true);
alert($(this).find('input[type="radio"]').val());
}
else {
$(allspan[i]).removeClass('active');
}
}
});
});
</script>
Select radio button value on Page_Load event:
Javascript Function:
function selectRadioValue(value)
{
var allspan = $('#<%= RadioButtonList1.ClientID %>').find('span');
for (var i = 0; i < allspan.length; i++) {
var objInnerRdo = $(allspan[i]).find('input[type="radio"]');
alert(objInnerRdo.val());
if (objInnerRdo.val() == value)
{
$(allspan[i]).addClass('active');
$(allspan[i]).find('input[type="radio"]').prop('checked', true);
}
else {
$(allspan[i]).removeClass('active');
}
}
}
Call this function using RegisterStartupScript where you passing database value. For Ex. I'm passing value "2" on page load.
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "Show Windows" + new Random().Next().ToString(), "selectRadioValue('2');", true);
}

Get selected value(s) RadComboBox client side

I have rad Combo box
<telerik:RadComboBox runat="server" ID="rcb" Height="150px" OnItemsRequested="rcb_ItemsRequested" AutoCompleteSeparator="," >
</telerik:RadComboBox>
I need to get Selected value from client side
i tried this
function getvalue()
{
var combobox = $find("<%= rcb.ClientID %>");
var value = combobox.get_selectedItem().get_value();
}
but get_selected Item get only last selected item .
I need to get all selected Item.
try the get_text() method http://www.telerik.com/help/aspnet-ajax/combobox-client-side-radcombobox.html to get the entire input
here is a basic sample that seems to do the trick
<telerik:RadComboBox runat="server" ID="rcb" Height="150px" OnItemsRequested="rcb_ItemsRequested" AutoCompleteSeparator=",">
</telerik:RadComboBox>
<asp:Button ID="Button1" Text="text" OnClientClick="getSel(); return false;" runat="server" />
<script>
function getSel() {
alert($find("rcb").get_text());
}
</script>
and
protected void rcb_ItemsRequested(object sender, RadComboBoxItemsRequestedEventArgs e)
{
for (int i = 0; i < 5; i++)
{
rcb.Items.Add(new RadComboBoxItem(i.ToString()));
}
}

Postback in asp.net: hiding or showing a control based on session variable?

In my markup for the page I have the following div:
<div id="utteranceFilterSection" runat="server" enableviewstate="true">
<asp:Label ID="lblShowFilterPrompt" runat="server" Text="Show: "></asp:Label>
<asp:DropDownList ID="ddlDetailsFilter"
AutoPostBack="true"
runat="server"
OnSelectedIndexChanged="ddlDetailsFilter_SelectedIndexChanged">
<asp:ListItem Value="All">All</asp:ListItem>
<asp:ListItem Value="Pass">Passed</asp:ListItem>
<asp:ListItem Value="Fail">Failed</asp:ListItem>
<asp:ListItem Value="Blocked">Blocked</asp:ListItem>
</asp:DropDownList>
</div>
I'd like to show or hide this div based on the contents of my session state. In Page_Load I have:
if (Page.IsPostBack)
{
//if (this.Session["ShowFilterControl"] != null)
//{
// this.utteranceFilterSection.Visible = true;
// this.Session.Remove("ShowFilterControl");
//}
this.utteranceFilterSection.Visible = true;
}
else
{
this.utteranceFilterSection.Visible = false;
}
Setting visible works fine if I use the uncommented postback code, however, if I try to do it using the commented out code, I see the code step through in the debugger but the div does not become visible. What am I doing wrong?
why don't you try to set a bool and evaluate that in the if statement along with the postback condition? like this:
bool showFilter = (bool)this.Session["ShowFilterControl"];
if (Page.IsPostBack && showFilter)
{
this.Session["ShowFilterControl"] = false;
this.utteranceFilterSection.Visible = true;
}
else
{
this.utteranceFilterSection.Visible = false;
}

How to validate a user chose at least one checkbox in a CheckBoxList?

I've got a CheckBoxList control that I want to require the user to check at least ONE box, it does not matter if they check every single one, or 3, or even just one.
In the spirit of asp.net's validation controls, what can I use to enforce this? I'm also using the Ajax validation extender, so it would be nice if it could look like other controls, and not some cheesy server validate method in the codebehind.
<asp:CheckBoxList RepeatDirection="Horizontal" RepeatLayout="Table" RepeatColumns="3" ID="ckBoxListReasons" runat="server">
<asp:ListItem Text="Preliminary Construction" Value="prelim_construction" />
<asp:ListItem Text="Final Construction" Value="final_construction" />
<asp:ListItem Text="Construction Alteration" Value="construction_alteration" />
<asp:ListItem Text="Remodel" Value="remodel" />
<asp:ListItem Text="Color" Value="color" />
<asp:ListItem Text="Brick" Value="brick" />
<asp:ListItem Text="Exterior Lighting" Value="exterior_lighting" />
<asp:ListItem Text="Deck/Patio/Flatwork" Value="deck_patio_flatwork" />
<asp:ListItem Text="Fence/Screening" Value="fence_screening" />
<asp:ListItem Text="Landscape - Front" Value="landscape_front" />
<asp:ListItem Text="Landscape - Side/Rear" Value="landscape_side_rear" />
<asp:ListItem Text="Other" Value="other" />
</asp:CheckBoxList>
It's easy to do this validation server side, but I am assuming you want to do it client side?
JQuery can do this very easily as long as you have something that all checkbox controls have in common to use as a selector such as class (CssClass on your .NET control). You can make a simple JQuery function and connect it to a ASP.NET custom validator. Remember if you do go the custom validator route to make sure you check it server side as well in case javascript is not working, you don't get a free server side check like the other .NET validators.
For more information on custom validators check out the following links: www.asp.net and
MSDN
You don't need to use JQuery, it just makes the javascript function to iterate and look at all your checkbox controls much easier but you can just use vanilla javascript if you like.
Here is an example I found at: Link to original
<asp:CheckBoxList ID="chkModuleList"runat="server" >
</asp:CheckBoxList>
<asp:CustomValidator runat="server" ID="cvmodulelist"
ClientValidationFunction="ValidateModuleList"
ErrorMessage="Please Select Atleast one Module" ></asp:CustomValidator>
// javascript to add to your aspx page
function ValidateModuleList(source, args)
{
var chkListModules= document.getElementById ('<%= chkModuleList.ClientID %>');
var chkListinputs = chkListModules.getElementsByTagName("input");
for (var i=0;i<chkListinputs .length;i++)
{
if (chkListinputs [i].checked)
{
args.IsValid = true;
return;
}
}
args.IsValid = false;
}
Side Note: JQuery is just a little js file include you need to add to your page. Once you have it included you can use all the JQuery you like. Nothing to install and it will be full supported in the next version of Visual Studio I think.
Here's a cleaner jQuery implementation that allows one ClientValidationFunction for any number of CheckBoxList controls on a page:
function ValidateCheckBoxList(sender, args) {
args.IsValid = false;
$("#" + sender.id).parent().find("table[id$="+sender.ControlId+"]").find(":checkbox").each(function () {
if ($(this).attr("checked")) {
args.IsValid = true;
return;
}
});
}
Here's the markup:
<asp:CheckBoxList runat="server"
Id="cblOptions"
DataTextField="Text"
DataValueField="Id" />
<xx:CustomValidator Display="Dynamic"
runat="server"
ID="cblOptionsValidator"
ControlId="cblOptions"
ClientValidationFunction="ValidateCheckBoxList"
ErrorMessage="One selection required." />
And finally, the custom validator that allows the client function to retrieve the target control by ID:
public class CustomValidator : System.Web.UI.WebControls.CustomValidator
{
public string ControlId { get; set; }
protected override void OnLoad(EventArgs e)
{
if (Enabled)
Page.ClientScript.RegisterExpandoAttribute(ClientID, "ControlId", ControlId);
base.OnLoad(e);
}
}
You can use a CustomValidator for that with a little bit of javascript.
<asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage="Select at least one"
ClientValidationFunction="checkCheckBoxList"></asp:CustomValidator>
<script type="text/javascript">
function checkCheckBoxList(oSrc, args) {
var isValid = false;
$("#<%= CheckBoxList1.ClientID %> input[type='checkbox']:checked").each(function (i, obj) {
isValid = true;
});
args.IsValid = isValid;
}
</script>
And for a RadioButtonList
<asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage="Select at least one" ClientValidationFunction="checkRadioButtonList"></asp:CustomValidator>
<script type="text/javascript">
function checkRadioButtonList(oSrc, args) {
if ($("input[name='<%= RadioButtonList1.UniqueID %>']:checked").val() == null) {
args.IsValid = false;
} else {
args.IsValid = true;
}
}
</script>
Here is another solution that may be considered via Dado.Validators on GitHub.
<asp:CheckBoxList ID="cblCheckBoxList" runat="server">
<asp:ListItem Text="Check Box (empty)" Value="" />
<asp:ListItem Text="Check Box 1" Value="1" />
<asp:ListItem Text="Check Box 2" Value="2" />
<asp:ListItem Text="Check Box 3" Value="3" />
</asp:CheckBoxList>
<Dado:RequiredFieldValidator runat="server" ControlToValidate="cblCheckBoxList" ValidationGroup="vlgSubmit" />
Example codebehind.aspx.cs
btnSubmit.Click += (a, b) =>
{
Page.Validate("vlgSubmit");
if (Page.IsValid) {
// Validation Successful
}
};
https://www.nuget.org/packages/Dado.Validators/
Ref: Check if a checkbox is checked in a group of checkboxes in clientside
We can achieve this by C# also
bool Item_selected = false;
foreach (ListItem item in checkbox.Items)
{
if (item.Selected == true)
{
Item_selected = true;
}
}
if (!Item_selected )
{
//your message to user
// message = "Please select atleast one checkbox";
}
Loop through each of the items in ckBoxListReasons. Each item will be of type 'ListItem'.
The ListItem will have a property called 'Selected' that is a boolean. It's true when that item is selected. Something like:
Dim bolSelectionMade As Boolean = False
For Each item As ListItem in ckBoxListReasons.Items
If item.Selected = True Then
bolSelectionMade = True
End If
Next
bolSelectionMade will be set to true if the user has made at least one selection. You can then use that to set the Valid state of any particular validator control you like.

Get GridView selected row DataKey in Javascript

I have GridView which I can select a row. I then have a button above the grid called Edit which the user can click to popup a window and edit the selected row. So the button will have Javascript code behind it along the lines of
function editRecord()
{
var gridView = document.getElementById("<%= GridView.ClientID %>");
var id = // somehow get the id here ???
window.open("edit.aspx?id=" + id);
}
The question is how do I retrieve the selected records ID in javascript?
I worked it out based on JasonS response. What I did was create a hidden field in the Grid View like this:
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:HiddenField ID="hdID" runat="server" Value='<%# Eval("JobID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField Visible="False">
<ItemTemplate>
<asp:LinkButton ID="lnkSelect" runat="server" CommandName="select" Text="Select" />
</ItemTemplate>
</asp:TemplateField>
Then on the OnRowDataBind have code to set the selected row
protected virtual void Grid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Click to highlight row
Control lnkSelect = e.Row.FindControl("lnkSelect");
if (lnkSelect != null)
{
StringBuilder click = new StringBuilder();
click.AppendLine(m_View.Page.ClientScript.GetPostBackClientHyperlink(lnkSelect, String.Empty));
click.AppendLine(String.Format("onGridViewRowSelected('{0}')", e.Row.RowIndex));
e.Row.Attributes.Add("onclick", click.ToString());
}
}
}
And then in the Javascript I have code like this
<script type="text/javascript">
var selectedRowIndex = null;
function onGridViewRowSelected(rowIndex)
{
selectedRowIndex = rowIndex;
}
function editItem()
{
if (selectedRowIndex == null) return;
var gridView = document.getElementById('<%= GridView1.ClientID %>');
var cell = gridView.rows[parseInt(selectedRowIndex)+1].cells[0];
var hidID = cell.childNodes[0];
window.open('JobTypeEdit.aspx?id=' + hidID.value);
}
</script>
Works a treat :-)
1) change your javascript function to use a parameter
function editRecord(clientId)
{ ....
2) output the call in your editRecord button... if you want to avoid dealing with the .net generated ids, just use a simple
<input type="button" onclick="editRecord(your-rows-client-id-goes-here)" />
Based off of your comments to #DaveK's response, in javascript you can set the id of a hidden field to the clientId of the selected row when the user selects it. Then have your editRecord function use the value set on the hidden form field.
one could avoid javascript altogether, by setting anchor tags pre-populated with the query string for each row (although this will effect your table layout, it will need only one click rather than 2 from the user)
insert in the gridview template:
<asp:HyperLink runat="server" ID="editLink" Target="_blank"
NavigateURL='<%# Eval("JobID","edit.aspx?id={0}") %>'>
Edit..
</asp:HyperLink>

Resources