I was playing around with WebMethods when I came across this issue.
I wanted to create a simple calculator using WebMethod and javascript, but it will only work if the options of the DDL have the "selected" attribute in the source within the browser. If I remove the UpdatePanel this works fine; the page is refreshed and the html source code will display a "selected" attribute on whatever I chose within the DDL. With the UpdatePanel, only the first option is selected (by default). The issue is that I don't want whole page to refresh.
Here's my code:
<input id="TextA" type="text" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<triggers>
<asp:AsyncPostBackTrigger ControlID="DropDownList1" EventName="SelectedIndexChanged" />
</triggers>
<ContentTemplate>
<asp:DropDownList ID="DropDownList1" runat="server"
onselectedindexchanged="DropDownList1_SelectedIndexChanged" AutoPostBack="True">
<asp:ListItem Value="+">+</asp:ListItem>
<asp:ListItem Value="-">-</asp:ListItem>
<asp:ListItem Value="/">/</asp:ListItem>
<asp:ListItem Value="*">*</asp:ListItem>
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
<input id="TextB" type="text" />
The WebMethod:
[WebMethod]
public string Add(double a, double b)
{
double Calc = a + b;
//string StringCalc = Calc.ToString();
string Complete = "The answer is " + Calc;
return Complete;
}
[WebMethod]
public string Subtract(double a, double b)
{
double Calc = a - b;
string Complete = "The answer is " + Calc;
return Complete;
}
[WebMethod]
public string Divide(double a, double b)
{
double Calc = a / b;
string Complete = "The answer is " + Calc;
return Complete;
}
[WebMethod]
public string Multiply(double a, double b)
{
double Calc = a * b;
string Complete = "The answer is " + Calc;
return Complete;
}
The JS:
<script type="text/javascript">
function Add() {
var v1 = $get('TextA').value;
var v2 = $get('TextB').value;
CalculatorWebService.Add(v1, v2, ResultCallBack);
}
function Subtract() {
var v1 = $get('TextA').value;
var v2 = $get('TextB').value;
CalculatorWebService.Subtract(v1, v2, ResultCallBack);
}
function Divide() {
var v1 = $get('TextA').value;
var v2 = $get('TextB').value;
CalculatorWebService.Divide(v1, v2, ResultCallBack);
}
function Multiply() {
var v1 = $get('TextA').value;
var v2 = $get('TextB').value;
CalculatorWebService.Multiply(v1, v2, ResultCallBack);
}
var DropDownSelection = document.getElementById('DropDownList1');
switch (DropDownSelection.options[DropDownSelection.selectedIndex].value) {
case "+":
$addHandler($get('ButtonA'), 'click', Add);
break;
case "-":
$addHandler($get('ButtonA'), 'click', Subtract);
break;
case "/":
$addHandler($get('ButtonA'), 'click', Divide);
break;
case "*":
$addHandler($get('ButtonA'), 'click', Multiply);
break;
}
function ResultCallBack(result) {
$get('TextA').value = result;
}
</script>
To summarise, when I select an option within the DDL, the "selected" attribute is not applied to any option (other than the first default option) if I use an UpdatePanel, and so my code won't work. Have I misinterpreted how the UpdatePanel works?
Below is the section of my page source code where you can see that despite me selecting "/", it is not "selected".
<div id="UpdatePanel1">
<select name="DropDownList1" onchange="javascript:setTimeout('__doPostBack(\'DropDownList1\',\'\')', 0)" id="DropDownList1">
<option selected="selected" value="+">+</option>
<option value="-">-</option>
<option value="/">/</option>
<option value="*">*</option>
</select>
</div>
I don't see that you even need an UpdatePanel
.
The purpose of an update panel is to allow you to post information back to the server and change the appearance of the screen from the server side, without doing a full page refresh.
But if all your server functionality is through Web Methods
, you don't need to post back at all. You can react to the responses from the Web Methods
and change the screen as needed, all through javascript
.
To respond to another part of your question: you don't need to involve the server to change which list item has the selected
attribute in a DropDownList
or HTML select
. You can do that in javascript
.
But, if your user is selecting the items in the DropDownList
or select
, you don't even need to do that: the act of selecting an item causes the selected
attribute to be associated with the list item.
You won't see it, though, if you use the browser's View Source feature, because that only shows the code that came down from the server. It doesn't reflect how the markup may have been changed.
If you want to be certain that the list item has the selected
attribute, you need to use the browser's page inspection and debugging tools, which can be accessed with F12
in IE or Ctrl-Shift-I
in Chrome.
I hope this helps.