Creating Custom Postback Handlers
If you want to create a custom Postback Handler, you need to do three things:
Create a postback handler definition - a C# class declaring which parameters the postback handler accepts.
Write the javascript implementation of the postback handler logic.
Register the postback handler to be used from the markup.
Step 1: Creating the Postback Handler Definition
First, you need to create a class that inherits from the PostBackHandler
class.
public class ConfirmPostBackHandler : PostBackHandler
{
protected internal override string ClientHandlerName => "confirm";
protected internal override Dictionary<string, string> GetHandlerOptionClientExpressions()
{
return new Dictionary<string, string>()
{
["message"] = TranslateValueOrBinding(MessageProperty)
};
}
public string Message
{
get { return (string)GetValue(MessageProperty); }
set { SetValue(MessageProperty, value); }
}
public static readonly DotvvmProperty MessageProperty
= DotvvmProperty.Register<string, ConfirmPostBackHandler>(c => c.Message, null);
}
This class contains several things:
The
ClientHandlerName
property specifies the name of the postback handler in the javascript. You'll need the value later in Step 2 to register the handler.The
GetHandlerOptionClientExpressions
returns a key-value collection of postback handler parameters. This collection will be serialized and placed in the HTML page. Thanks to this, you can read the values of the postback handler parameters on the client side. TheTranslateValueOrBinding
generates an expression either with the static value, or with the{value: Something}
binding. If you evaluate this expression on the client side, it'll provide the value of the property.The
Message
property is a postback handler parameter which you can use in the DOTHTML markup to pass a value to the handler.
Step 2: Implementing the Postback Handler Logic in Javascript
A postback handler on the client side is just a function which returns an object with one function execute(callback, sender)
.
The callback
is a function without parameters which you can call to make the postback.
The sender
is a DOM element which represents the control making the postback.
You can register a postback handler to be used on the client side using this code snippet:
dotvvm.events.init.subscribe(function () {
dotvvm.postBackHandlers["confirm"] = function ConfirmPostBackHandler(options) {
var message = options.message; // you'll get the parameters passed to the handler in the options object
return {
execute: function(callback) {
// do whathever you need and if you need to do the postback, invoke the 'callback()' function
if (confirm(message)) {
callback();
}
}
};
};
});
If you need to display a div instead of the default Javascript confirmation, you can do something like this:
dotvvm.events.init.subscribe(function () {
dotvvm.postBackHandlers["customConfirm"] = function ConfirmPostBackHandler(options) {
this.execute = function(callback) {
// set the message to the confirmation dialog
$("#confirm-dialog p.message").text(options.message);
// display the confirmation dialog
$("#confirm-dialog").show();
// do the postback when the OK button is clicked
// (unbind first because a previous callback could be attached to the event)
$("#confirm-dialog button.ok-button").unbind("click").on("click", callback);
};
};
});
Step 3: Register the PostBack Handler
The postback handler is registered in the same way as any other user control. You can find more information about the custom control registration in the Code-only Controls tutorial.
Other Usages
Using the postback handler mechanism you can implement many useful things, not only the confirmations.
In some cases you may want to delay the postback for a little while. This may be useful when the user types into the TextBox
and you need to
show him the search suggestions. It won't make a good user experience to do the postback immediately on each keystroke.
Instead, you can wait e.g. 500 milliseconds before you issue the postback. It might help the performance of the application as the server won't get many requests. It can look like this:
dotvvm.events.init.subscribe(function () {
dotvvm.postBackHandlers["delay"] = function ConfirmPostBackHandler(options) {
this.execute = function(callback, sender) {
// increment the counter and remember the state
sender.counter = (sender.counter | 0) + 1;
var currentCounterState = sender.counter;
// wait
window.setTimeout(function () {
// if the counter hasn't changed, do the postback
if (sender.counter === currentCounterState) {
callback();
}
}, options.delay);
};
};
});
When the execute
method is called, we increment the counter on the sender
DOM element and remember its state.
Then we call window.setTimeout
which executes the function passed as the first argument after the specified delay.
In the function we have to check whether the counter state has changed. If it has, it means that another event was triggered and we shouldn't make the postback because we might not have the current data.
If the counter state is the same as it was before the waiting procedure, we just invoke the callback
and that's it.