[TIP] Show a webclient compatible dialog!

Share business templates, ideas, experiences, etc with fellow Servoy developers here

[TIP] Show a webclient compatible dialog!

Postby Karel Broer » Fri Mar 26, 2010 3:52 pm

Thanks to Servoy's powerfull solutionModel, I was able to create a global method that displays a dialog and returns the pressed button,
working in the webclient too! :D

You need 2 things for this stuff to work:
1. A global var named 'core_gDialogResult'
2. This global method:
Code: Select all
function core_DIALOG_show() {
        //empty result global
   globals.core_gDialogResult = null;
       
       //get title
   var vTitle = arguments[0];

       //get message
   var vMessage = arguments[1];

       //get buttons in array
   var vButtons = arguments[2];

       //get dialog width
   var vWidth = arguments[3];
   if(!vWidth){
      vWidth = 300; //set width to 300 as default
   }

        //get dialog height
   var vHeight = arguments[4];
   if(!vHeight){
      vHeight = 120; //set height to 120 as default
   }

        //get form stylesheet
   var vStyleSheet = arguments[5]
   if(!vStyleSheet){
      vStyleSheet = 'myDefaultCSS'; //set default stylesheet (not nessecary, but kinda nice to have)
   }

        //get message styleclass
   var vStyleClass = arguments[6]
   if(!vStyleClass){
      vStyleClass = 'myDefaultStyleClass'; //set default message styleclass (not nessecary, but kinda nice to have)
   }          
   var vDialogFormName = 'form_dlg';

        //Check if dialogform exists in session, if so, remove the dialog form
   if(history.removeForm(vDialogFormName)){
      solutionModel.removeForm(vDialogFormName);
   }

       //Create dialogform   
   var vDialogForm = solutionModel.newForm(vDialogFormName, null, null, vStyleSheet, false, vWidth, vHeight);
   vDialogForm.navigator = SM_DEFAULTS.NONE;
   vDialogForm.scrollbars = SM_SCROLLBAR.HORIZONTAL_SCROLLBAR_NEVER | SM_SCROLLBAR.VERTICAL_SCROLLBAR_NEVER;
   vDialogForm.borderType = 'EmptyBorder,0,0,0,0';
   vDialogForm.RECORD_VIEW;

       //Create form message label and insert the message
   var vMessageLabel =  vDialogForm.newLabel(vMessage, 20, 20, vWidth-20, vHeight-40);
   vMessageLabel.transparent = true;
   vMessageLabel.anchors = SM_ANCHOR.ALL;
   vMessageLabel.styleClass = vStyleClass
   vMessageLabel.verticalAlignment = SM_ALIGNMENT.TOP

       //Create button method
   var jButtonMethod = vDialogForm.newFormMethod('function BTN_click(event){ \
      globals.core_gDialogResult = event.getElementName() ; \
      application.closeFormDialog(); }  ');

   var vButton, vButtonName;
   var vX = 20;

       //Check if buttons are available in the arguments
   if(vButtons.length > 0){
      vX = vWidth - (110 * parseInt(vButtons.length)) - 15 ;

                //Put the button(s) on the form
      for(var i in vButtons){
         vButtonName = vButtons[i];
         vButton = vDialogForm.newButton(vButtonName, vX, vHeight-52, 100, 22,jButtonMethod);
         vButton.name = vButtonName;
         vButton.anchors = SM_ANCHOR.SOUTH | SM_ANCHOR.EAST
         vX = vX+110;
      }
   }

       //Show the formInDialog!
   application.showFormInDialog(vDialogFormName,-1,-1,vWidth,vHeight,vTitle,false,false,vDialogFormName)
}


This is how to use the method and show the dialog:
(dialogwidth,dialogheight,'stylesheet','message styleclass' are optional arguments, btw)

Code: Select all
globals.core_DIALOG_show('title','message',[button1,button2,ect],dialogwidth,dialogheight,'stylesheet','message styleclass')
if(globals.core_gDialogResult){
//do something
}


Offcourse you can modify the global method and add all kinds of stuff in the dialog, and use specific dialogs for specific purposes,
but this could be a nice way to start.

Enjoy!
Karel Broer
ServoyCamp - http://www.servoycamp.com
User avatar
Karel Broer
 
Posts: 779
Joined: Mon May 03, 2004 12:49 am
Location: Doetinchem

Re: [TIP] Show a webclient compatible dialog!

Postby Harjo » Fri Mar 26, 2010 4:52 pm

I dont understand how this could work in webclient!

because, this: application.showFormInDialog(vDialogFormName,-1,-1,vWidth,vHeight,vTitle,false,false,vDialogFormName)
is always the last thing to use in webclient.

So I believe this:

if(globals.core_gDialogResult){
//do something
}

is never fired, or fired directly after the showFormInDialog, right?
Harjo Kompagnie
ServoyCamp
Servoy Certified Developer
Servoy Valued Professional
SAN Developer
Harjo
 
Posts: 4321
Joined: Fri Apr 25, 2003 11:42 pm
Location: DEN HAM OV, The Netherlands

Re: [TIP] Show a webclient compatible dialog!

Postby Karel Broer » Fri Mar 26, 2010 5:04 pm

Argh.. you're f.... right, Harjo. Dang.. I hoped this method would act the same way as in the rich client.
Well.. then this post also contains a featue request :x :
Can the webclient act the same way in a method as the rich client, pleeease??
Karel Broer
ServoyCamp - http://www.servoycamp.com
User avatar
Karel Broer
 
Posts: 779
Joined: Mon May 03, 2004 12:49 am
Location: Doetinchem

Re: [TIP] Show a webclient compatible dialog!

Postby patrick » Fri Mar 26, 2010 5:47 pm

... or you simply split your code. You could also pass a method for each button to execute. You original method has then to be split into two parts: one, that shows the dialog and the other processes the result.
Patrick Ruhsert
Servoy DACH
patrick
 
Posts: 3703
Joined: Wed Jun 11, 2003 10:33 am
Location: Munich, Germany

Re: [TIP] Show a webclient compatible dialog!

Postby Harjo » Fri Mar 26, 2010 5:52 pm

exactly!
Harjo Kompagnie
ServoyCamp
Servoy Certified Developer
Servoy Valued Professional
SAN Developer
Harjo
 
Posts: 4321
Joined: Fri Apr 25, 2003 11:42 pm
Location: DEN HAM OV, The Netherlands

Re: [TIP] Show a webclient compatible dialog!

Postby Karel Broer » Wed Mar 31, 2010 3:07 pm

Allright.. After some modifications to the former code, I'll hope to wrap up to this post by sharing this code, which makes it possible to show a webclient compatible dialog and fire any -global- method from it. :P

In this example we'll show a dialog that asks if the user wants to delete a record.
A formname is given as argument in order for the method to know what record it should delete.
(You can do this more safely, by giving the JRecordObject as argument and have a method delete that record, but I like you to figure that out yourself. :wink: )

1. Call the dialog and set arguments
Code: Select all
//Show delete record dialog
function core_DIALOG_deleteRecord(event, targetForm)
{

//set form to delete record from
vArguments = 'myTableForm'
//Call dialog method and set arguments,  like methodname, title, message, buttons, etc.
//Possible arguments are: event,'globalMethodName','arguments','title','message',[button1,button2,ect],dialogwidth,dialogheight,'stylesheet','message styleclass'
globals.core_DIALOG_show(event,'core_CALLBACK_deleteRecord',vArguments,'Attention', 'Are you sure you want to delete this record?', ['OK', 'Cancel'])
      return;
}


2. Global method that creates the dialog
Code: Select all
function core_DIALOG_show()
{
   //get event
   var vEvent = arguments[0]
   
   //get methodname
   var vMethod = arguments[1];
   
   //get method arguments
   var vMethodArguments = arguments[2]
   
   //get title
   var vTitle = arguments[3];
   
   //get message
   var vMessage = arguments[4];
   
   //get buttons
   var vButtons = arguments[5];
   
   //get (optional) dialog width
   var vWidth = arguments[6];
   if(!vWidth)
   {
      vWidth = 300;
   }

   //get (optional) dialog height   
   var vHeight = arguments[7];
   if(!vHeight)
   {
      vHeight = 120;
   }
   
   //get (optional) form stylesheet
   var vStyleSheet = arguments[8]
   if(!vStyleSheet)
   {
      vStyleSheet = 'myDefaultCSS'
   }

   //get (optional) message styleclass
   var vStyleClass = arguments[9]
   if(!vStyleClass)
   {
      vStyleClass = 'myDefaultStyleClass'
   }
   
   //set dialog formname
   var vDialogFormName = 'form_dlg';

   //Check if dialogform exists in session, if so, remove the dialog form
   if(history.removeForm(vDialogFormName))
   {
      solutionModel.removeForm(vDialogFormName);
   }

   //Create dialogform 
   var vDialogForm = solutionModel.newForm(vDialogFormName, null, null, vStyleSheet, false, vWidth, vHeight);
   vDialogForm.navigator = SM_DEFAULTS.NONE;
   vDialogForm.scrollbars = SM_SCROLLBAR.HORIZONTAL_SCROLLBAR_NEVER | SM_SCROLLBAR.VERTICAL_SCROLLBAR_NEVER;
   vDialogForm.borderType = 'EmptyBorder,0,0,0,0';
   vDialogForm.RECORD_VIEW;

   //Create form message label and insert the message
   var vMessageLabel = vDialogForm.newLabel(vMessage, 20, 20, vWidth - 20, vHeight - 40);
   vMessageLabel.transparent = true;
   vMessageLabel.anchors = SM_ANCHOR.ALL;
   vMessageLabel.styleClass = vStyleClass
   vMessageLabel.verticalAlignment = SM_ALIGNMENT.TOP

    //Create button method and set method with arguments
   var jButtonMethod = vDialogForm.newFormMethod('function BTN_click(event,vMethodArguments){ \
      var vArguments = new Array(); \
      vArguments.push(event); \
      vArguments.push("' + vMethodArguments + '");\
      application.closeFormDialog(); \
      globals.' + vMethod + '(vArguments) ; } ');
      

   var vButton, vButtonName;
   var vX = 20;

    //Check if buttons are available in the arguments   
   if(vButtons.length > 0)
   {
      vX = vWidth -(110 * parseInt(vButtons.length)) - 15;

      //Put the button(s) on the form
      for(var i in vButtons)
      {
         vButtonName = vButtons[i];
         vButton = vDialogForm.newButton(vButtonName, vX, vHeight - 52, 100, 22, jButtonMethod);
         vButton.name = vButtonName;
         vButton.anchors = SM_ANCHOR.SOUTH | SM_ANCHOR.EAST
         vX = vX + 110;
      }
   }
    //Show the formInDialog!
   application.showFormInDialog(vDialogFormName, -1, -1, vWidth, vHeight, vTitle, false, false, vDialogFormName)
}


3. Create a global callback method that executes after the user pressed a button in the dialog
Code: Select all
function core_CALLBACK_deleteRecord() {
   //All arguments are returned in 1 array
   var vResult = arguments[0]
                          
   //First node in the array contains the event
   var JSEvent = vResult[0]
    var vButtonPressed = JSEvent.getElementName()
   
    //Second node contains the arguments passed to the dialog method
    //In this case it is the formname from which to delete the record
    var vForm = vResult[1]
   application.output('Pressed button ' + vButtonPressed + ' on form ' + vForm)   
   
   if(!vForm || vButtonPressed != 'OK'){
       return false;
    }
    else {
       forms[vForm].controller.deleteRecord()
    }
}

Hope you like it !
Karel Broer
ServoyCamp - http://www.servoycamp.com
User avatar
Karel Broer
 
Posts: 779
Joined: Mon May 03, 2004 12:49 am
Location: Doetinchem

Re: [TIP] Show a webclient compatible dialog!

Postby bcusick » Tue Nov 30, 2010 9:35 pm

Hey Karel,

Nice stuff! I built something very similar. I've taken your code and updated it for the 5.x syntax - and add a couple of little touches:

1) The button size will grow based on the text you pass;
2) The first button is automatically focused when the dialog is shown;
3) Fixed a small bug with the button placement;
4) Turned the text into HTML if there is a return in it;
5) Tightened up the spacing, etc.

Code: Select all
function core_DIALOG_show(event,callbackMethodName,callbackMethodArguments,title,msg,buttonArray,width,height,styleSheetName,styleClassName)
{
   if(!buttonArray) {
      buttonArray = ["OK"];
   }
   
   if(!width){
      width = 300;
   }

   if(!height){
      height = 120;
   }
   
   //get (optional) form stylesheet
   if(!styleSheetName){
      styleSheetName = 'DEFAULTSTYLENAME_HERE!';
   }

   //get (optional) message styleclass
   if(!styleClassName){
      styleClassName = 'DEFAULTSTYLECLASS_FOR_MESSAGE_HERE!';
   }
   
   //set dialog formname
   var dialogFormName = 'form_dlg';

   //Check if dialogform exists in session, if so, remove the dialog form
   if(history.removeForm(dialogFormName))
   {
      solutionModel.removeForm(dialogFormName);
   }

   //Create dialogform 
   
   
   var dialogForm = solutionModel.newForm(dialogFormName, null, null, styleSheetName, false, width, height);
   dialogForm.navigator = SM_DEFAULTS.NONE;
   dialogForm.scrollbars = SM_SCROLLBAR.HORIZONTAL_SCROLLBAR_NEVER | SM_SCROLLBAR.VERTICAL_SCROLLBAR_NEVER;
   dialogForm.borderType = 'EmptyBorder,0,0,0,0';
   dialogForm.RECORD_VIEW;
    var jFormMethod = dialogForm.newFormMethod('function onShow(firstShow,event){ \
      controller.focusFirstField(); } ');
   
   dialogForm.onShow = jFormMethod;

   if(utils.stringPatternCount(msg,'\n') > 0) { //there is a return - so turn it into HTML
      msg = "<html><head></head><body>" + utils.stringReplace(msg,"\n","<br>") + "</body></html>"
   }

   //Create form message label and insert the message
   var messageLabel = dialogForm.newLabel(msg, 10, 10, width - 10, height - 30);
   messageLabel.transparent = true;
   messageLabel.anchors = SM_ANCHOR.DEFAULT;
   messageLabel.styleClass = styleClassName;
   messageLabel.verticalAlignment = SM_ALIGNMENT.TOP;
   messageLabel.horizontalAlignment = SM_ALIGNMENT.LEFT;
   
   var jButtonMethod = dialogForm.newFormMethod('function BTN_click(event){ \
      application.closeFormDialog(); } ');
   
   //Create button method and set method with arguments
   if(callbackMethodName) {
      jButtonMethod = dialogForm.newFormMethod('function BTN_click(event,callbackMethodArguments){ \
      var args = new Array(); \
      args.push(event); \
      args.push("' + callbackMethodArguments + '");\
      application.closeFormDialog(); \
      globals.' + callbackMethodName + '(args) ; } ');
   } else {
      var jButtonMethod = dialogForm.newFormMethod('function BTN_click(event){ \
      application.closeFormDialog(); } ');
   }
     

   var dialogBtn, buttonName, btnWidth;
   var x = width;
   

    //Check if buttons are available in the arguments   
   if(buttonArray.length > 0)
   {

      //Put the button(s) on the form
      for(var i in buttonArray)
      {
         buttonName = buttonArray[i];
         if(buttonName.length > 6) {
            btnWidth = 75 + ((buttonName.length - 6) * 3) + (utils.stringWordCount(buttonName)*5);
         } else {
            btnWidth = 70
         }
         
         x = x - (btnWidth + 10);
         
         dialogBtn = dialogForm.newButton(buttonName, x, height - 52, btnWidth, 22, jButtonMethod);
         dialogBtn.name = buttonName;
         dialogBtn.anchors = SM_ANCHOR.SOUTH | SM_ANCHOR.EAST;
         dialogBtn.showFocus = false;
         dialogBtn.tabSeq = i+1;
      }
   }
    //Show the formInDialog!
   application.showFormInDialog(dialogFormName, -1, -1, width+10, height+10, title, false, false, dialogFormName)
}


Here are parameters (you can paste these in ABOVE the "@properties={typeid:24,uuid:"XXXXXXXXXXXXXXX"} (after you paste in the method and save):
Code: Select all
* @param {JSEvent} event the event that triggered the action
* @param {String} callback global method name
* @param {String} string of method arguments
* @param {String} OPTIONAL dialog title - default "Information"
* @param {Array} OPTIONAL array of button names - default "OK"
* @param {Integer} OPTIONAL int dialog width - default 300
* @param {Integer} OPTIONAL int dialog height - default 120
* @param {String} OPTIONAL - stylesheet name
* @param {String} OPTIONAL - styleclass name


Hope this helps!
Bob Cusick
bcusick
 
Posts: 1255
Joined: Wed Apr 23, 2003 11:27 pm
Location: Thousand Oaks, CA USA


Return to Sharing Central

Who is online

Users browsing this forum: No registered users and 2 guests

cron