Ticket T171941
Visible to All Users
Duplicate

How do I provide keyboard shortcuts for certain XAF Actions in Web UI?

created 10 years ago

Hi,
Please find the screenshot i have attached with the Question.
In xaf WinApplication we have many shortcuts for different action controller.
Do we have anything like that InXAF webapplication for save , new and cancel buttons.

Regards,
Nitz

Comments (3)
Dennis Garavsky (DevExpress) 10 years ago

    Can I make this ticket public?

      Yes you can . in the solution 1st part of code is in VB.net but you mentioned it C#, please rectify that.

      Dennis Garavsky (DevExpress) 10 years ago

        Thanks. Yes, it was VB.NET code under the C# title. I have corrected this.

        Answers approved by DevExpress Support

        created 10 years ago (modified 10 years ago)

        Hello Nitz,

        There are currently no built-in shortcuts in XAF Web UI, but it is not that difficult to implement them using the standard HTML and JavaScript approaches linked to the corresponding XAF's API.
        I have made a quick example based on my previous article on how to add some client-side functionality to the XAF's form (KA18958):

        Visual Basic
        Imports Microsoft.VisualBasic Imports System Imports DevExpress.ExpressApp Imports DevExpress.ExpressApp.SystemModule Imports DevExpress.ExpressApp.Web Imports DevExpress.ExpressApp.Web.Templates Imports DevExpress.ExpressApp.Actions Namespace MainDemo.Module.Web.Controllers Public Class WebShortcutsWindowController Inherits WindowController Implements IXafCallbackHandler Public Sub New() TargetWindowType = WindowType.Main End Sub Protected Overrides Sub OnActivated() MyBase.OnActivated() AddHandler Frame.ViewChanged, AddressOf Frame_ViewChanged AddHandler CType(Window, WebWindow).PagePreRender, AddressOf CurrentRequestWindow_PagePreRender End Sub Protected Overrides Sub OnDeactivated() RemoveHandler CType(Window, WebWindow).PagePreRender, AddressOf CurrentRequestWindow_PagePreRender RemoveHandler Frame.ViewChanged, AddressOf Frame_ViewChanged MyBase.OnDeactivated() End Sub Private Sub Frame_ViewChanged(ByVal sender As Object, ByVal e As ViewChangedEventArgs) If (e.SourceFrame IsNot Nothing) AndAlso (e.SourceFrame.View IsNot Nothing) Then AddHandler e.SourceFrame.View.ControlsCreated, AddressOf View_ControlsCreated End If End Sub Private Sub View_ControlsCreated(ByVal sender As Object, ByVal e As EventArgs) RegisterXafCallackHandler() End Sub Private Sub RegisterXafCallackHandler() If XafCallbackManager IsNot Nothing Then XafCallbackManager.RegisterHandler("T171941", Me) End If End Sub Protected ReadOnly Property XafCallbackManager() As XafCallbackManager Get Return If(WebWindow.CurrentRequestPage IsNot Nothing, DirectCast(WebWindow.CurrentRequestPage, ICallbackManagerHolder).CallbackManager, Nothing) End Get End Property Private Sub CurrentRequestWindow_PagePreRender(ByVal sender As Object, ByVal e As EventArgs) Dim window As WebWindow = DirectCast(sender, WebWindow) Dim script As String = If(IsSuitableView(), "window.onkeydown = function(e) {" & ControlChars.CrLf & _ " var key = e.keyCode ? e.keyCode : e.which;" & ControlChars.CrLf & _ " if (key == 13 && e.ctrlKey) { //Control+Enter" & ControlChars.CrLf & _ " RaiseXafCallback(globalCallbackControl, 'T171941', 'SaveAction', '', false);" & ControlChars.CrLf & _ " }" & ControlChars.CrLf & _ " };", "window.onkeydown=undefined;") window.RegisterStartupScript(Me.GetType().FullName, script) End Sub Public Sub ProcessAction(ByVal parameter As String) If IsSuitableView() AndAlso (Frame IsNot Nothing) Then Dim saveAction As SimpleAction = Frame.GetController(Of ModificationsController)().SaveAction If parameter = "SaveAction" AndAlso saveAction.Enabled AndAlso saveAction.Active Then saveAction.DoExecute() End If End If End Sub Protected Overridable Function IsSuitableView() As Boolean Return Frame.View IsNot Nothing AndAlso Frame.View.IsRoot AndAlso Not(TypeOf Frame.View Is ListView) AndAlso Not(TypeOf Frame Is NestedFrame) AndAlso Not(TypeOf Frame Is PopupWindow) End Function End Class End Namespace
        C#
        using System; using DevExpress.ExpressApp; using DevExpress.ExpressApp.SystemModule; using DevExpress.ExpressApp.Web; using DevExpress.ExpressApp.Web.Templates; using DevExpress.ExpressApp.Actions; namespace MainDemo.Module.Web.Controllers { public class WebShortcutsWindowController : WindowController, IXafCallbackHandler { public WebShortcutsWindowController() { TargetWindowType = WindowType.Main; } protected override void OnActivated() { base.OnActivated(); Frame.ViewChanged += Frame_ViewChanged; ((WebWindow)Window).PagePreRender += CurrentRequestWindow_PagePreRender; } protected override void OnDeactivated() { ((WebWindow)Window).PagePreRender -= CurrentRequestWindow_PagePreRender; Frame.ViewChanged -= Frame_ViewChanged; base.OnDeactivated(); } void Frame_ViewChanged(object sender, ViewChangedEventArgs e) { if((e.SourceFrame != null) && (e.SourceFrame.View != null)) { e.SourceFrame.View.ControlsCreated += View_ControlsCreated; } } void View_ControlsCreated(object sender, EventArgs e) { RegisterXafCallackHandler(); } private void RegisterXafCallackHandler() { if(XafCallbackManager != null) { XafCallbackManager.RegisterHandler("T171941", this); } } protected XafCallbackManager XafCallbackManager { get { return WebWindow.CurrentRequestPage != null ? ((ICallbackManagerHolder)WebWindow.CurrentRequestPage).CallbackManager : null; } } void CurrentRequestWindow_PagePreRender(object sender, EventArgs e) { WebWindow window = (WebWindow)sender; string script = IsSuitableView() ? @"window.onkeydown = function(e) { var key = e.keyCode ? e.keyCode : e.which; if (key == 13 && e.ctrlKey) { //Control+Enter RaiseXafCallback(globalCallbackControl, 'T171941', 'SaveAction', '', false); } };" : "window.onkeydown=undefined;"; window.RegisterStartupScript(GetType().FullName, script); } public void ProcessAction(string parameter) { if(IsSuitableView() && (Frame != null)) { SimpleAction saveAction = Frame.GetController<ModificationsController>().SaveAction; if(parameter == "SaveAction" && saveAction.Enabled && saveAction.Active) { saveAction.DoExecute(); } } } protected virtual bool IsSuitableView() { return Frame.View != null && Frame.View.IsRoot && !(Frame.View is ListView) && !(Frame is NestedFrame) && !(Frame is PopupWindow); } } }

        This is not a complete solution, and you need to modify and test it further according to your business needs. See also the eXpressApp Framework > Concepts > Extend Functionality > Built-in Controllers and Actions and How to execute Actions in code articles for more information on how to access other XAF Controllers and execute their Actions in code.

          Show previous comments (1)
          Anatol (DevExpress) 8 years ago

            Hello Emir,

            I've created a separate ticket on your behalf (T476522: How to use keyboard shortcuts for actions from a popup window in ASP.NET). It has been placed in our processing queue and will be answered shortly.

            HC HC
            Hadiuddin Chishti 8 years ago

              Hi Anatol,

              We are trying to use the above controller, please let us know how can we use the below code in  custom control action.

              public void ProcessAction(string parameter) { if(IsSuitableView() && (Frame != null)) { SimpleAction saveAction = Frame.GetController<ModificationsController>().SaveAction; if(parameter == "SaveAction" && saveAction.Enabled && saveAction.Active) { saveAction.DoExecute(); } }

              Regrards
              Hadiuddin Chishti

              Anatol (DevExpress) 8 years ago

                Hello Hadiuddin,

                Let's discuss this task in a separate ticket: T518942: How to execute the ProcessAction method in a custom control action.

                Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

                Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.