Get selected value(s) RadComboBox client side - asp.net

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()));
}
}

Related

ASP.NET Repeater control validation causing errors

I'm working on an ASP.NET form based application.
I have a repeater bound to database. It has any of the the following controls per row:
RadioButtonList
TextBox
DropDownList
CheckBoxList
There are one of the following validation controls per row:
RequiredFieldValidator
CustomValidator
I have a button outside the repeater. When I click on save button, the code will loop through each repeater item, read selected data and saves it in database.
The problem I'm facing is as soon as I click on save button, it gives me error:
The ControlToValidate property of 'reqValidator' cannot be blank.
I made sure that repeater is loaded for the first time only and not when the page is posted back.
Also, the code in save button does not seem to be executed. Here is my code:
<cms:CMSUpdatePanel runat="server" ID="updatePanelCampaignQuestions">
<ContentTemplate>
<asp:Repeater ID="repeaterQuestions" runat="server" OnItemDataBound="repeaterQuestions_ItemDataBound">
<ItemTemplate>
<div class="repeater-container">
<asp:Label ID="lbQuestion" runat="server" Text='<%# Eval("Question") %>' />
<asp:Label ID="lbQuestionType" runat="server" Text='<%# Eval("QuestionType") %>' Style="display: inline; visibility: hidden" />
<asp:Label ID="lbAnswers" runat="server" Text='<%# Eval("Answers") %>' Style="display: inline; visibility: hidden" />
<asp:Label ID="lbArticleCampaignQuestionID" runat="server" Text='<%# Eval("ArticleCampaignQuestionID") %>' Style="display: inline; visibility: hidden" />
<div class="row validation-container">
<div class="col-md-12 col-lg-12">
<asp:TextBox ID="txtAnswer" CssClass="form-control" runat="server" TextMode="MultiLine" Rows="2" ValidationGroup="Campaign"></asp:TextBox>
<asp:RadioButtonList ID="rdAnswer" runat="server"></asp:RadioButtonList>
<asp:DropDownList ID="ddnAnswer" runat="server"></asp:DropDownList>
<asp:CheckBoxList ID="chkAnswer" CssClass="chkAnswer" runat="server"></asp:CheckBoxList>
<asp:RequiredFieldValidator ID="reqValidator" runat="server" Display="Dynamic" Style="color: #f00" />
<asp:CustomValidator ID="customValidator" runat="server" ClientValidationFunction="checkAnswer" Display="Dynamic" Style="color: #f00" />
<hr />
</div>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
The code for repeater OnItemDataBound:
protected void repeaterQuestions_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
string questionType = (e.Item.FindControl("lbQuestionType") as Label).Text;
RequiredFieldValidator reqValidator = (RequiredFieldValidator)e.Item.FindControl("reqValidator");
CustomValidator customValidator = (CustomValidator)e.Item.FindControl("customValidator");
if (questionType.ToLower().Equals("text"))
{
e.Item.FindControl("txtAnswer").Visible = true;
e.Item.FindControl("rdAnswer").Visible = false;
e.Item.FindControl("chkAnswer").Visible = false;
e.Item.FindControl("ddnAnswer").Visible = false;
reqValidator.ControlToValidate = e.Item.FindControl("txtAnswer").ID;
reqValidator.ErrorMessage = "Please fill the answer";
e.Item.Controls.Remove(customValidator);
}
else if (questionType.ToLower().Equals("single selection"))
{
e.Item.FindControl("txtAnswer").Visible = false;
e.Item.FindControl("rdAnswer").Visible = true;
e.Item.FindControl("chkAnswer").Visible = false;
e.Item.FindControl("ddnAnswer").Visible = false;
string strAnswers = (e.Item.FindControl("lbAnswers") as Label).Text;
string[] answers = strAnswers.Split(new[] { "##" }, StringSplitOptions.None);
foreach(string answer in answers)
{
(e.Item.FindControl("rdAnswer") as RadioButtonList).Items.Add(answer);
}
reqValidator.ControlToValidate = e.Item.FindControl("rdAnswer").ID;
reqValidator.ErrorMessage = "Please select one";
e.Item.Controls.Remove(customValidator);
}
else if (questionType.ToLower().Equals("drop down"))
{
e.Item.FindControl("txtAnswer").Visible = false;
e.Item.FindControl("rdAnswer").Visible = false;
e.Item.FindControl("chkAnswer").Visible = false;
e.Item.FindControl("ddnAnswer").Visible = true;
string strAnswers = (e.Item.FindControl("lbAnswers") as Label).Text;
string[] answers = strAnswers.Split(new[] { "##" }, StringSplitOptions.None);
(e.Item.FindControl("ddnAnswer") as DropDownList).Items.Add(new ListItem("- Please Select -", "0"));
foreach (string answer in answers)
{
(e.Item.FindControl("ddnAnswer") as DropDownList).Items.Add(answer);
}
reqValidator.InitialValue = "0";
reqValidator.ControlToValidate = e.Item.FindControl("ddnAnswer").ID;
reqValidator.ErrorMessage = "Please select one";
e.Item.Controls.Remove(customValidator);
}
else if (questionType.ToLower().Equals("multiple selection"))
{
e.Item.FindControl("txtAnswer").Visible = false;
e.Item.FindControl("rdAnswer").Visible = false;
e.Item.FindControl("chkAnswer").Visible = true;
e.Item.FindControl("ddnAnswer").Visible = false;
string strAnswers = (e.Item.FindControl("lbAnswers") as Label).Text;
string[] answers = strAnswers.Split(new[] { "##" }, StringSplitOptions.None);
foreach (string answer in answers)
{
(e.Item.FindControl("chkAnswer") as CheckBoxList).Items.Add(answer);
}
e.Item.Controls.Remove(reqValidator);
customValidator.ErrorMessage = "Please select at least one";
}
}
}
The code for save button:
private void SaveAnswer()
{
int userID = GetUserID();
int campaignID = GetCampaignID();
foreach (RepeaterItem item in repeaterQuestions.Items)
{
string answer = "";
string questionType = (item.FindControl("lbQuestionType") as Label).Text;
int articleCampaignQuestionID = int.Parse((item.FindControl("lbArticleCampaignQuestionID") as Label).Text);
if (questionType.ToLower().Equals("text"))
{
answer = (item.FindControl("txtAnswer") as TextBox).Text;
}
else if (questionType.ToLower().Equals("single selection"))
{
answer = (item.FindControl("rdAnswer") as RadioButtonList).SelectedItem.Text;
}
else if (questionType.ToLower().Equals("drop down"))
{
answer = (item.FindControl("ddnAnswer") as DropDownList).SelectedItem.Text;
}
else if (questionType.ToLower().Equals("multiple selection"))
{
CheckBoxList answerList = (item.FindControl("chkAnswer") as CheckBoxList);
foreach (ListItem checkItem in answerList.Items)
{
if (checkItem.Selected)
{
answer += checkItem.Text + "##";
}
}
if (answer.EndsWith("##"))
answer = answer.Substring(0, answer.Length - 2);
}
// save value of answer to database
}
I'm stuck on this for a very long time now. There is no other exception on the page other than the one mentioned above.
Edit
What is the flow of page postback?
Click on btnSaveAnswer , code for button executes , repeater is reloaded
Or
Click on btnSaveAnswer, repeater is reloaded , code for button executes
If I put repeater binding with:
if(!Page.IsPostBack)
I get the required field validator error
and
if I don't use above if, then I cannot read values from controls in repeater
I figured out the problem in my code. Here is what I did:
Since my repeater is being built dynamically, I'm binding repeater every time and not using Page.IsPostBack
Instead of binding repeater in Page_Load, I'm binding in Page_Init
This fixed my issue

Asp.net - Postback loses Dropdownlist index

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();
}
});

Select Values from two combobox from a list of combobox?

I have six combobox placed on my form and at same time i want user can select values from maximum of two combobox.
for this i have take a counter variable which get incremented every time when selectedindex of a combobox get changed but didn't reach to solution.
Can you guys explain how can i do this ?
I created an example for you. I hope it can be usefull.
ASP.Net Page:
<form id="form1" runat="server">
<div>
<div>
<label>Combobox 1</label>
<asp:DropDownList runat="server" OnSelectedIndexChanged="Unnamed1_SelectedIndexChanged" AutoPostBack="True">
<asp:ListItem>Select</asp:ListItem>
<asp:ListItem>Combo-1-1</asp:ListItem>
<asp:ListItem>Combo-1-2</asp:ListItem>
</asp:DropDownList>
</div>
<div>
<label>Combobox 2</label>
<asp:DropDownList runat="server" OnSelectedIndexChanged="Unnamed1_SelectedIndexChanged" AutoPostBack="True">
<asp:ListItem>Select</asp:ListItem>
<asp:ListItem>Combo-2-1</asp:ListItem>
<asp:ListItem>Combo-2-2</asp:ListItem>
</asp:DropDownList>
</div>
<div>
<label>Combobox 3</label>
<asp:DropDownList runat="server" OnSelectedIndexChanged="Unnamed1_SelectedIndexChanged" AutoPostBack="True">
<asp:ListItem>Select</asp:ListItem>
<asp:ListItem>Combo-3-1</asp:ListItem>
<asp:ListItem>Combo-3-2</asp:ListItem>
</asp:DropDownList>
</div>
<div>
<label>Combobox 4</label>
<asp:DropDownList runat="server" OnSelectedIndexChanged="Unnamed1_SelectedIndexChanged" AutoPostBack="True">
<asp:ListItem>Select</asp:ListItem>
<asp:ListItem>Combo-4-1</asp:ListItem>
<asp:ListItem>Combo-4-2</asp:ListItem>
</asp:DropDownList>
</div>
<div>
<label>Combobox 5</label>
<asp:DropDownList runat="server" OnSelectedIndexChanged="Unnamed1_SelectedIndexChanged" AutoPostBack="True">
<asp:ListItem>Select</asp:ListItem>
<asp:ListItem>Combo-5-1</asp:ListItem>
<asp:ListItem>Combo-5-2</asp:ListItem>
</asp:DropDownList>
</div>
<div>
<label>Combobox 6</label>
<asp:DropDownList runat="server" OnSelectedIndexChanged="Unnamed1_SelectedIndexChanged" AutoPostBack="True" Height="19px">
<asp:ListItem>Select</asp:ListItem>
<asp:ListItem>Combo-6-1</asp:ListItem>
<asp:ListItem>Combo-6-2</asp:ListItem>
</asp:DropDownList>
</div>
<div>
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>
</div>
</div>
</form>
ASP.Net Code-Behind
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ViewState["DropdownSelectLimit"] = 0;
}
}
protected void Unnamed1_SelectedIndexChanged(object sender, EventArgs e)
{
if (ViewState["DropdownSelectLimit"] != null)
{
if ((int)ViewState["DropdownSelectLimit"] < 2)
{
int count = (int)ViewState["DropdownSelectLimit"];
count++;
ViewState["DropdownSelectLimit"] = count;
}
else
{
DropDownList dropDown = (DropDownList)sender;
dropDown.SelectedIndex = 0;
Label1.Text = "You can't select any option anymore";
}
}
}
If you have any question just ask me on comments :)
I created a setup for Winforms as it wasn't complete clear if you wanted it for Winforms or ASP.Net
I will not handle how you should fill a combobox, i'm sure you know how to do this, whether this is filled static or dynamic.
My solution (although quite rude) makes you link a simplified handler named HandleComboBoxSelectedIndexChanged to each combobox SelectionChanged event. This can be The SelectedItemChanged, SelectedValueChanged or SelectedIndexChanged.
Quite important: each combo needs a null value.
//will hold a list of your combobox names
private List<string> SelectedCombos;
//form load: Link the events to the correct handler
private void Form_Load()
{
foreach(var combo in Controls)
{
if(combo is ComboBox)
combo.SelectedValueChanged += HandleComboBoxSelectedIndexChanged;
}
}
//will handle the selectedIndexOrItemchanged event
private void HandleComboBoxSelectedIndexChanged(object sender, EventArgs e)
{
if(SelectedCombos = null)
SelectedCombos = new List<string>();
var combo = (ComboBox)sender;
if(combo.SelectedValue == null)
if(!SelectedCombos.Exist(combo.Name))
SelectedCombos.Remove(combo.Name);
else
if(!SelectedCombos.Exist(combo.Name) && SelectedCombos.Count < 2)
SelectedCombos.Add(combo.Name)
SetComboAvailability();
}
Another function which might be useful, whenever 2 combos are selected, make the enabled state false. This means that your user can only select from the 2 selected combos untill one of them is reset at it's null position. This way your user can only select what is possible.
//set the combos availability, less then 2 selections ok, own selection also ok else not ok
private void SetComboAvailability()
{
foreach(var combo in Controls)
{
if(combo is ComboBox)
combo.Enabled = SelectedCombos.Count < 2 || SelectedCombos.Contains(combo.Name);
}
}
Below a small example of how you could retrieve all your values from the combos based on their names.
//Something for handling all the values
private void RetrieveValues()
{
foreach(var v in SelectedCombos)
{
var combo = this.Controls.Find(v);
if(combo is ComboBox)
{
//do something with the selectedValue
var val = combo.SelectedValue; // or selecteditem
MessageBox.Show(string.Format("Control {0} has value {1}", combo.Name, val);
}
}
}
If you don't understand something feel free to ask.
Also:
the EventArgs property might change according to the selected event:
do: _comboBox1.SelectedValueChanged+= (TAB TWICE in VS) to see what the automatic code generation looks like. (always handy)
Example:
_comboBox1.SelectedValueChanged += _comboBox1_SelectedValueChanged;
private void _comboBox1_SelectedValueChanged(object sender, EventArgs e){}

Why do I have to click a button twice in an ASP.NET repeater to get the command to fire?

I have an ASP.NET page with the following 3 main areas:
1 - list of checkboxes on the left for fitlering results
2 - Repeater that displays the matching results in the middle (with a button for each item)
3 - Repeater that displays the selected items on the right
On initial page load the page will show the data bound checkboxes and will show all results (since nothing has been checked in the filters). As the user checks or unchecks the checkboxes, the page will reload and the matching results will change. So far this part works great.
In the Results Repeater, each item has a Button. When the user clicks the button for an item in the Results the idea is that the item will get added to the Selected Repeater on the right. What is happening is that after I check or uncheck filter checkboxes - the first time that I then try and click on the buttons in the Results repeater, nothing happens. The page just reloads. Then if I click the button a second time, the Repeater Command will fire and the item will get added to the Repeater on the right hand side. Then, as long as I don't change any of the checkboxes I can click on one of the command buttons and it will work right away. But if I check one of the checkboxes in the filters area (which causes the Results to get re-bound) then I have to click one of the buttons twice to get it to fire.
I have a sense that this has something to do with ViewState but I have no idea. Does anyone know why this would be happening?
Below is my code for both the ASPX page and the code behind.
ASPX Code:
<h3>Filters</h3>
<asp:Repeater ID="rptTechnologies" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Technology</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<asp:Repeater ID="rptVerticals" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Vertical</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<asp:Repeater ID="rptIndustries" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Industry</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<asp:Repeater ID="rptSolutions" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Solution</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<h3>Results</h3>
<asp:Repeater ID="rptMatchingSlides" runat="server" OnItemDataBound="rptMatchingSlides_ItemDataBound" OnItemCommand="rptMatchingSlides_Command">
<ItemTemplate>
<h4><asp:Literal ID="litName" runat="server"></asp:Literal></h4>
<asp:Button ID="btnSelect" runat="server" Text="Select" CommandName="Select" />
</ItemTemplate>
<SeparatorTemplate><hr /></SeparatorTemplate>
</asp:Repeater>
<h3>Selected</h3>
<asp:Repeater ID="rptSelectedSlides" runat="server" OnItemDataBound="rptSelectedSlides_ItemDataBound">
<ItemTemplate>
<h4><asp:Literal ID="litName" runat="server"></asp:Literal></h4>
</ItemTemplate>
<SeparatorTemplate><hr /></SeparatorTemplate>
</asp:Repeater>
Here is the code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
this.BindData();
}
}
public List<string> SelectedSlides
{
get
{
if (Session["SelectedIDs"] != null)
{
string[] _ids = Session["SelectedIDs"].ToString().Split(new char[] { '|' });
List<String> _retVal = new List<string>();
foreach (string _id in _ids)
{
_retVal.Add(_id);
}
return _retVal;
}
else
{
return new List<string>();
}
}
set
{
//Set the session value
string _val = "";
foreach (string _id in value)
{
if (_val == "")
{
_val = _id;
}
else
{
_val += "|" + _id;
}
}
Session["SelectedIDs"] = _val;
}
}
protected void BindData()
{
//Filters
rptTechnologies.DataSource = Repository.GetTaxonomyItems();
rptTechnologies.DataBind();
rptVerticals.DataSource = Repository.GetTaxonomyItems();
rptVerticals.DataBind();
rptIndustries.DataSource = Repository.GetTaxonomyItems();
rptIndustries.DataBind();
rptSolutions.DataSource = Repository.GetTaxonomyItems();
rptSolutions.DataBind();
this.BindMatchingSlides();
}
protected void BindMatchingSlides()
{
...build list of ids from checkboxes...
rptMatchingSlides.DataSource = Repository.GetMatchingSlides(_selectedIDs);
rptMatchingSlides.DataBind();
}
protected void BindSelectedSlides()
{
if (this.SelectedSlides.Count > 0)
{
rptSelectedSlides.DataSource = this.SelectedSlides;
rptSelectedSlides.DataBind();
}
else
{
divSelectedSlides.Visible = false;
}
}
protected void rptMatchingSlides_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Literal _litName = (Literal)e.Item.FindControl("litName");
Button _btnSelect = (Button)e.Item.FindControl("btnSelect");
_litName.Text = ...set name here...
_btnSelect.CommandArgument = ...use unique ID of item from database...
_btnSelect.ID = "btnSelect_" + e.Item.ItemIndex;
}
}
protected void rptMatchingSlides_Command(object sender, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Select")
{
Item _slide = ...get data from database based on Command Argument...
if (_slide != null)
{
List<string> _selectedSlides = this.SelectedSlides;
_selectedSlides.Add(_slide.ID.ToString());
this.SelectedSlides = _selectedSlides;
}
this.BindSelectedSlides();
}
}
Thanks to Jeremy - removing the line of code where I was setting the ID fixed it. Doh! Somewhere else I had read that you needed to set a unique value for the IDs of the buttons in a repeater. So that must have been the culprit. Thanks to Jeremy.

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