[TIP] Show a webclient compatible dialog!

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:
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)

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!

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?

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??

… 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.

exactly!

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

//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

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

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 !

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.
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","
") + "</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):

* @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!