Let’s start with some background – a common need is for a button to execute some JavaScript code in order to create a more responsive page. With the standard ASP:Button the OnClientClick is used to specify this execution statement. Take the following simple example:
<script type=
"text/javascript"
>
function
ButtonClick(button) {
alert(
"The Button with ID "
+ button.id +
" was clicked."
);
}
</script>
<asp:Button ID=
"Button1"
Text=
"Regular Button"
OnClientClick=
"ButtonClick(this); return false;"
runat=
"server"
/>
What you can see here is a function called with parentheses, an argument provided to the function and the return false; statement that prevents the postback.
The case with Telerik’s ASP.NET AJAX Button is slightly different, however. It follows the convention all other Telerik ASP.NET AJAX controls use for their client-side event handlers – only the name of the JavaScript function must be provided.
Moreover, RadButton has two properties for setting a client-side click event handler – OnClientClicking and OnClientClicked. The former can be cancelled to prevent the postback with JavaScript while the latter cannot be. They work in conjunction with the AutoPostBack property of the control – when set to false it has the same effect the return false; has for the regular button.
Now, what happens when you try to migrate from the standard controls to the RadControls and employ the approach you have been using for the ASP button with RadButton – namely to put the function call in the OnClientClicked property. When the page loads, either this will throw a JavaScript error, or the function will be executed immediately because of the parentheses. Having a JavaScript error, the page will not function properly and the expected handler will not be called. To evade this just follow the RadButton conventions listed above.
Here is a simple example of using the OnClientClicked event properly:
<script type=
"text/javascript"
>
function
ButtonClick(sender, args) {
alert(
"The Button with ID "
+ sender.get_id() +
" was clicked."
);
}
</script>
<telerik:RadButton runat=
"server"
ID=
"RadButton1"
Text=
"RadButton"
OnClientClicked=
"ButtonClick"
AutoPostBack=
"false"
>
</telerik:RadButton>
Note the value of the OnClientClicked property is only the function’s name and that AutoPostBack is false.
Following is the same functionality, implemented in the OnClientClicking event so that the postback can be cancelled conditionally:
<script type=
"text/javascript"
>
function
ButtonClick(sender, args)
{
alert(
"The Button with ID "
+ sender.get_id() +
" was clicked."
);
var
shouldCancelPostback =
true
;
args.set_cancel(shouldCancelPostback);
}
</script>
<telerik:RadButton runat=
"server"
ID=
"RadButton1"
Text=
"RadButton"
OnClientClicking=
"ButtonClick"
>
</telerik:RadButton>
The AutoPostBack property is not necessary because the event propagation is cancelled with the set_cancel(true) method. It has the same effect as having return false; at the end of your function.
At this point you are probably wondering what the two arguments that I am using are and where they come from. The answer is simple – following the MS AJAX convention these are the control instance that fired the event (so you can use its full Client-side API) and an event arguments object that has contextually meaningful properties and methods, depending on the control and the particular event. They are automatically provided to the event handler by our code.
You can also call JavaScript code from RadButton by using an anonymous function, which is specified in the OnClientCkicked property. This approach is used when you want to define your own custom function that accepts custom arguments, which is not possible in the first case.
<script type=
"text/javascript"
>
function
ButtonClick(sender, args, username) {
alert(
"The Button with ID "
+ sender.get_id() +
" was clicked by "
+ username +
"."
);
}
</script>
<telerik:RadButton runat=
"server"
ID=
"RadButton1"
Text=
"RadButton"
OnClientClicked=
"function(sender, args){ButtonClick(sender, args, 'John');}"
AutoPostBack=
"false"
>
</telerik:RadButton>
Now that we’ve covered the basics, it is time for the more advanced stuff. We have to deliver more than expected, so our button has a rich client-side API. This allows you, for example, to easily add and remove handlers during runtime. There can even be multiple handlers for the same event to top it off. Copy this code in your VS and see how several functions can be executed:
<telerik:RadButton runat=
"server"
ID=
"rbAddHandlers"
AutoPostBack=
"false"
Text=
"Add handlers"
OnClientClicked=
"addHandlers"
>
</telerik:RadButton>
<telerik:RadButton runat=
"server"
ID=
"rbDynamicHandlers"
AutoPostBack=
"false"
Text=
"Click me to test!"
>
</telerik:RadButton>
<telerik:RadButton runat=
"server"
ID=
"rbRemoveHandler"
AutoPostBack=
"false"
Text=
"Remove one of the handlers"
OnClientClicked=
"removeOneHandler"
>
</telerik:RadButton>
<script type=
"text/javascript"
>
function
addHandlers(sender, args)
{
var
demoButton = $find(
"<%=rbDynamicHandlers.ClientID %>"
);
demoButton.add_clicked(firstHandler);
demoButton.add_clicked(secondHandler);
}
function
removeOneHandler(sender, args)
{
var
demoButton = $find(
"<%=rbDynamicHandlers.ClientID %>"
);
demoButton.remove_clicked(firstHandler);
}
function
firstHandler(sender, args)
{
alert(
"firstHandler from RadButton with text "
+ sender.get_text());
}
function
secondHandler(sender, args)
{
alert(
"secondHandler from RadButton with text "
+ sender.get_text());
}
</script>
As you can see, handlers can be added many times and removed just as many. The add_<event>(function) and remove_<event>(function) methods are what you need to make your pages more dynamic. They take a function as an argument and are available for the other events as well, e.g. add_clicking(clickingHandler).
The goodies do not end here – this approach is widely available in the entire suite, so it can be used for other RadControls as well and is not limited to RadButton.
Grab these simple snippets and paste them in your VS to click around and see RadButton’s power in action. You can extend them further with all the other customization options it offers – both in terms of functionality and appearance. Test it out, take a look at its online demos and I hope you will easily adopt this control in your projects.
Marin Bratanov was a Principal Technical Support Engineer in the Blazor division.