Skip to end of metadata
Go to start of metadata

This relates to the KRAD - Configurable Rich Lightbox content - modal dialog & data framework Requirements.

Existing KNS Question Framework

Design summary

KNS Provided Promts:
  • Are you sure you want to cancel?
  • Are you sure you want to delete?
  • Are you sure you want to disapprove this document?
  • Would you like to save this document before you close it?
  • Potential sensitive data was found on the document. Do you wish to continue?

Limitations

  • Was limited to a single True or False question / answer.
  • Had an optional text area.  No additional HTML elements available.
  • Implemented using old struts technology
  • Customization required programming

Proposed design for new KRAD dialog Framework

Overview:

  • DialogGroup: Create a new type of Uif-Group that defines the lightbox content (Uif-DialogGroup ?)
  • More Complex questionairre responses are available to the controller in view form.
  • DialogManager: New class to manage the dialogs (building, status, responses, tracking issues)
    • Keeps track of which dialogs have been asked/answered
  • BaseController Modifications
    • askQuestion() or showDialog() methods. Called by controllers when question is asked.
      • If dialog has not yet been presented by the user: create content, return to the page and display the lightbox
      • For dialogs that have already been asked and answered, return answer back to the controller.
    • returnFromDialog()

Question by Claus:

Using the above model would mean we have a the hidden UIF-Group on the parent view. How about every lightbox content has its own view? We would have pre-made views such as lookup-view, inquiry-view, simple-dialog-view, etc. FancyBox could then use the ajax call to get the content.

Defining available Dialogs

  • Canned Dialogs
    • dialogGroup - assumes a format message, maybe an input field, footer buttons.
    • Derived from group, but does not use "items" property.
    • rather than have them build up the group items piece by piece, have properties for message text, button text
    • transform the promptGroup properties into a list of group items during one of the lifecycle methods (moves the properties into group "items")
  • Custom Dialogs - for more complex dialogs, user simply creates the group and set it as hidden.
    • the various responses in the dialog are then available in the form.
  • add dialog list in View - needed on server side to find by id.

Invoking Dialogs from Controller methods

ControllerBase: Add methods to ControllerBase to manage calling and return from dialogs

  • boolean : showDialog( dialogId, view )
  • String : showDialog( dialogId, view)
  • returnFromDialog()

have a property "dialogInProgress" that is set in showDialog(). Let's us determine when to clear out our visitedDialog history map in the DialogManager.
UIFControllerInterceptor is called after the controller is finished and before sending the response. The controller needs to know whether we are returning from the main view or a dialog. because we need to know when to clear out the map of visited dialogs in the DialogManager.

showDialog:

  • check the DialogManager to determine if question has already been asked.
  • if already asked and answered, return value to calling controller method
  • if not yet asked, build up group representing dialog and invoke

returnFromDialog:

  • determines the response value from dialog
  • updates the DialogManager map
  • clears the dialogInProgress property
  • then invokes original controller method.

DialogManager - keeps track of which dialogs have been called and answered .

Returning From Dialog

  • have all Dialogs return to returnFromDialog() method with a methodToCall parameter specifying the original controller method
  • DialogManager - tracks which dialogs have been visited and their response
    • contains a map of prompts/questions asked and the answers recieved.

Requirement Questions:  (be sure to move these to requirements page)

  • Are all dialogs invoked from within a controller? Or, Can a dialog be created by a browser event?
  • List the first set of canned Dialogs
    • OK, Cancel
      • Contains a question and two buttons
      • Configurable question text  (default= "")
      • Configurable button labels (defaults: "OK", "Cancel")
    • Yes, No - same as above but with different default text, and button labels.
    • CheckboxDialog
    • RadioButtonDialog

Task List / micro milestones

  • DialogGroup   (DialogGroup.java,  DialogGroup.jsp,  .xml definition)
    • create Initial Canned DialogGroup with question, and two buttons.
    • display in view (not in lightbox)  format and get it looking right
    • create other canned dialogs
      • checkboxes?
      • radio buttons?
    • create an example of a custom, more complex dialog group
  • DialogManager
    • create Initial DialogManager class
  • BaseController / UifControllerHandler hooks
    • implement askQuestion() method
      • implement tracking of dialogs asked
      • test show dialog case
      • test question already asked / answered case
    • implement returnFromDialog() method
      • implement common return method that performs housekeeping then forwards to intended controller method
    • determine user response
      • boolean
      • String
      • getting data from more complex dialog groups?
  • Javascript helper method to fire up lightbox on load
  • create a test page
  • testing
    • Create Test page(s)
    • Unit tests
    • selenium tests
  • Documentation

Milestone 3 Enhancements 

  1. Complete response back to client without returning to DispatcherServlet 
  2. Enhance ability to associate dialog to an action
    1. invokes dialog from client upon action
    2. content populated via ajax
    3. submit on yes, return without submit on no
  3. Formal testing
    1. Selenium Tests
    2. Unit Tests - DialogManager
  4. Documentation

Test Cases

This section is a reminder of what tests to perform during development.  Add to this list any specific functionality or behavior that should be confirmed

Dialog tests

  • Basic default dialog.  question, two buttons
  • Basic dialog with alternate text for question and button labels
  • Test reversing the button order
  • Basic dialog with optional text area
  • Extending the basic dialog
  • Custom dialog

Functional Server side tests

  • Capability to do basic  form submit -> controller -> ask question -> return from dialog -> controller (get response) -> return to original page
  • Multiple Questions in a single controller method
  • Asking the same question more than once (for different purpose) in same controller method
  • Both AJAX and with full POST
  • Multiple browser windows working on same page
  •  

Lightbox tests

  • display canned content
  • display custom content
  • complex controls
    • various controls - datepicker, collections, tab groups
    • progressive disclosure
  • sizing tests ??
    • size to fit
    • size configured to specific size
    • large content, scrolling ???
  • No labels

5 Comments

  1. A few things to add/suggest:

    For the Dialog Group (and canned dialogs) I would purpose starting with this:

    Dialog Group properties:

      String promptText; // text that will display for the question

      Message promptMessage; // Message component for the text, styling and so on

      InputField explanationInputField; // input field used to collect a response

      boolean includeResponseInput; // indicates whether the response input field should be rendered

      List<KeyValue> availableResponses; // list of key value pairs that will make up the button choices

      InputField responseInputField; // used to render the available responses

    Then create a default bean that initialize the responseInputField to an Uif-InputField with TextAreaControl. Pointing to a generic form property on Uif-FormBase (dialogExplanationText or something like that).

      The availableResponses will be used to render a horizontal checkbox group control (reponseInputField). Then use the jQuery UI button plugin to style them like buttons. I think we want to go this route instead of the action buttons because we can control the form posting (in cases where the dialog is completely client side).

      Default responseInputField to an input field with horizontal checkbox group. 

      Use vertical box layout for the group.

      Next we will want to create some lists that have common response. Like 'Y':'Yes', 'N', 'No' and 'Y':'Ok','N':'Cancel' and so on. These lists can be referenced when setting the availableResponses property, or a custom list can be created.

  2. More ...

    Dialog Render:

    1) From Server

    2) Client Dom

    3) Client Ajax

    Add an option to DialogGroup named invocationMode that defaults to server. Can be changed to dom or ajax. 

    We will need to add something to the end of the view template that iterates through the dialogGroups and writes those that are marked as client dom or client ajax. For the dom option the group would then be hidden. For ajax just the wrapper is needed. Take a look at template.tag and how it handles progressiveDisclosure. We might be able to let the template.tag handle it for us and by setting the progress properties.

  3. Next ...

    JS Helper Methods:

    showDialogGroup(groupId); // used by custom app code to show a group through a dialog. This id is the group id for a dialog that has been setup with the client dom or client ajax invocation method.

    showContentsInDialog(contents); // used by custom app code to show contents in a dialog. This will handle the general lightbox support. The can add the contents to the page using a hidden group or however else they want to.

    handleActionConfirmation(groupId, clientInd); // this method will be used to display a dialog coming back from a server request, or from a dialog confirmation (see next note)

  4. I think it would be nice to give the ability to configure a dialog to appear client side for an action. Here is one possibility:

    Action Component:

    Add property 'confirmationDialogId'. This will point to the id of a setup dialog group.

    When a dialog group has an action pointing to it with the confirmationDialogId, we will want to set its invocationType to client dom.

    Add a data attribute to the action (button, image, or link) data-confirmation="id".

    When the button is clicked, get the id from the data attribute and call handleActionConfirmation(id, true);. This method will need to handle canceling the request if the No option was selected, otherwise the action will continue.

  5. Server dialog responses to Ajax requests versus browser requests:

    1) Ajax - When an ajax request is made and a dialog is needed, we will simply return the dialog group (as is done for component refresh) and attached the load script handleActionConfirmation(dialogId, false); to the dialog group. A special return handler will need to be indicated as well once that is supported in the framework.

    2) Browser - For browser posts, we will need to render a complete view. Since the contents will be covered up (just the dialog displaying in the lightbox), I think we could have an empty view that we render and attached handleActionConfirmation(dialogId, false) to the load event on the view. We would also need to write out the dialog group at the end of the view template. We could do this in the same place we are checking for client dom or ajax invocation. One possible way to handle this is to look at the render flag on the dialog group when iterating through at the end of the view template. If the render template is true, then we will write out (either as hidden or ajax wrapper). This will be true for any dialogs initially configured as client dom or ajax, and when there is a server request for a dialog we will explicitly set the render flag to true. For all others it will be set to false.