Prompt service: Difference between revisions

From MozillaZine Knowledge Base
Jump to navigationJump to search
m (bug fix in confirmEx() code)
No edit summary
Line 1: Line 1:
=Prompt Tutorial=
<code>nsIPromptService</code> is an [[XPCOM]] interface available to C++ and chrome JavaScript code (not to web pages' JS), that provides methods for displaying a few simple types of dialogs. To learn how to create advanced dialogs, see [[Creating dialogs]]. For file/folder picker dialogs, see [[Dev : nsIFilePicker | nsIFilePicker article]].


==Adding message boxes to extensions - 14/3-2005==
<code>nsIPromptService</code> has 9 functions and a few constants that are important to understand. This article contains explanations for some of these functions, and example code for all of them.
You may think this is a stupid idea to write about since there are three simple functions that will let you post messages, prompt and confirm in javascript. The problem is that from Firefox 1.0.1 these functions are depreciated and won't work in later versions. Well, alert() will work but prompt and confirm will return an error. And they are also very simple functions that can't be customized enough.


==nsIPromptService==
==Getting nsIPromptService==
nsIPromptService is an XPCOM Interface which means that you can only use it in javascript handled by mozilla. It will let you use special functions especially for mozilla software and there are lots of useful interfaces that you can use in extensions. nsIPromptService has 9 functions and a few constants that are important to understand. I will explain some of these functions but you wil get code snippets for all of them. You can find more about the prompt functions here.
First of all, you need to obtain the prompt service which you can use to show messages. You can do this using the following code:
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);


==Using nsIPromptService==
==nsIPromptService methods==
//netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
===alert()===
  prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
<code>alert()</code> is the simplest function, which simply displays a message box with specified title and message. For example:
This will create a prompt object which you can use to show messages. As you can see I have commmented out a function. If you put this in your code you will be allowed to call components and use their special functions outside of mozilla. That is, if your javascript is not part of an extension or the mozilla (firefox, thunderbird or suite) source code, you will have to include it. Don't include it for extensions.
  var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);
prompts.alert(window, "Window title", "Hello world!");


prompts is the instance we will use to call the functions.
As in many other methods of <code>nsIPromptService</code>, first parameter is the ''parent window'' in the sense of <code>[http://xulplanet.com/references/xpcomref/ifaces/nsIWindowWatcher.html#method_openWindow nsIWindowWatcher.openWindow]</code>. You can pass <code>null</code>, in which case the parent window will be <code>nsIWindowWatcher.activeWindow</code>.


==alert()==
===alertCheck()===
  prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
<code>alertCheck()</code> will popup a message box with specified title, text and a checkbox. The checkbox can be a "Do not show this message again" option or something similar.
  prompts.alert(window, 'title','Text');
  var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
This is the simplest function and it will simply show a message box with a title and a message.
              getService(Components.interfaces.nsIPromptService);
check = {value: false}; // default value
  prompts.alertCheck(window, "Window title", "You have been warned",
                    "Don't ask again", check);
// do something with check.value;


==alertCheck()==
Notice how we get the state of the checkbox. The function changes the <code>value</code> member of the <code>check</code> object, so to get the result we use <code>check.value</code>. It's the standart way of getting so-called "out" parameters from an XPCOM component.
  prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
 
  check = {value:false};
===confirm() and confirmCheck()===
  prompts.alertCheck(window, 'title', 'Text', 'Check?', check);
<code>confirm()</code> is also simple. It displays a dialog with specified title, text and two buttons - OK and Cancel.
  return check.value;
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
This function will popup a message box with a checkbox. The checkbox can be a 'Do not show this message again' option or something simelar. Notice how we get the result of the checkbox. The function will change the value of the check object, so to get the result we return check.value.
              getService(Components.interfaces.nsIPromptService);
var result = prompts.confirm(window, "Title", "Do you want to quit?");
 
Below is an example for displaying a confirmation message with a checkbox. It is a hybrid of <code>confirm()</code> and <code>alertCheck()</code>, so it should be easy to understand without additional comments.
  var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);
  var check = {value: false};
  var result = prompts.confirmCheck(window, "Title", "Do you want to quit?",  
                                  "Do not ask me again", check);
  // do something check.value / result
 
===prompt()===
<code>prompt()</code> can be very important and useful in lots of cases, as it accepts user input. Instead of making an XUL dialog or adding more textboxes you can simply call a prompt function. As you can see the first few arguments are the same as the others but it has an extra object. This object is the default value before the function is called and the new value after the function has been called.  


==confirm()==
  var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
  prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
              getService(Components.interfaces.nsIPromptService);
  okorcancel = prompts.confirm(window, 'title', 'Text');
  var input = {value: "default value"};
return okorcancel;
  var check = {value: false};
Confirm is also simple. You can put it straight into an if sentence if you are not saving the answer for later. Below is a confirm message with a checkbox. It is just as straight forward as the confirm and alertCheck so it shouldn't be a problem.
  result = prompts.prompt(window, "Title", "What's your name?", input, "Do not ask again", check);
prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
  // input.value is the string user entered
  check = {value:false};
// check.value indicates whether or not the checkbox is checked
  okorcancel = prompts.confirmCheck(window, 'title', 'Text', 'Check?', check);
  // result - whether user clicked OK (true) or Cancel
  return check.value;
  return okorcancel;


==prompt()==
===promptPassword() and promptUsernameAndPassword()===
prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
Below are other versions of prompt, promptPassword() with a password textbox and promptUsernameAndPassword which has a username and password field.
input = {value:"default"};
check = {value:false};
okorcancel = prompts.prompt(window, 'title', 'Text', input, 'Check?', check);
return input.value;
return check.value;
return okorcancel;
Prompt can be very important and useful in lots of cases, at it accepts user input. Instead of making an xul dialog or adding more textboxes you can simply call a prompt function. As you can see the first few arguments are the same as the others but it has an extra object. This object is the default value before the function is called and the new value after the function has been called. Below are other versions of prompt, promptPassword() with a password textbox and promptUsernameAndPassword which has a username and password field.


  //promptPassword
  //promptPassword
  prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
  var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);
  input = {value:"password"};
  input = {value:"password"};
  check = {value:false};
  check = {value:false};
Line 57: Line 68:
   
   
  //promptUsernameAndPassword
  //promptUsernameAndPassword
  prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
  var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);
  username = {value:"ihoss"};
  username = {value:"ihoss"};
  password = {value:"password"};
  password = {value:"password"};
Line 67: Line 79:
  return okorcancel;
  return okorcancel;


==confirmEx()==
===confirmEx()===
  prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
  var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
  check = {value:false};
              getService(Components.interfaces.nsIPromptService);
  flag = 0;
  var check = {value: false};
  button = prompts.confirmEx(window, 'title', 'Text', flag, 'Button_0', 'Button_1', 'Button_2', 'Check?', check);
  var flag = 0;
  return check.value;
  var button = prompts.confirmEx(window, "Window title", "Message text", flag,  
  return button;
              "Button 0", "Button 1", "Button 2", "Checkbox label", check);
ConfirmEx is designed to be customizable so you can make your own messages. You can have upto 3 buttons with a variety of special values (that depend on the system language) and string values and a checkbox if you want to. If you don't want the checkbox put null in the eighth (second to last) parameter. Flag is an integer that is the sum of some constants. Below is a table that explains how it is done:
  // |check.value| indicates whether or not the checkbox is checked
{| border=1 cellspacing=0
  // |button| indicates which button was clicked
!  
<code>confirmEx()</code> is designed to be customizable so you can make your own messages. It can display a dialog with up to 3 buttons with a variety of predefined (localized if necessary) labels or specified by your code labels, and a checkbox if you want. If you don't want the checkbox to be displayed, just put <code>null</code> in the eighth (checkbox label) parameter.
! BUTTON_POS_0
 
1  
<code>flag</code> is an integer that is the sum of some constants. Below is a table that explains how it is done:
! BUTTON_POS_1
{| border=1 cellspacing=0 cellpadding=3
256
! !! BUTTON_POS_0<br/>1 !! BUTTON_POS_1<br/>256 !! BUTTON_POS_2<br/>65536
! BUTTON_POS_2
65536
|-
|-
! BUTTON_TITLE_OK
! BUTTON_TITLE_OK<br/>1
1
| 1*1 || 256*1 || 65536*1
| 1*1||256*1||65536*1
|-
|-
! BUTTON_TITLE_CANCEL
! BUTTON_TITLE_CANCEL<br/>2
2
| 1*2 || 256*2 || 65536*2
| 1*2||256*2||65536*2
|-
|-
! BUTTON_TITLE_YES
! BUTTON_TITLE_YES<br/>3
3
| 1*3 || 256*1 || 65536*3
| 1*3||256*1||65536*3
|-
|-
! BUTTON_TITLE_NO
! BUTTON_TITLE_NO<br/>4
4
| 1*4 || 256*4 || 65536*4
| 1*4||256*4||65536*4
|-
|-
! BUTTON_TITLE_SAVE
! BUTTON_TITLE_SAVE<br/>5
5
| 1*5 || 256*5 || 65536*5
| 1*5||256*5||65536*5
|-
|-
! BUTTON_TITLE_DONT_SAVE
! BUTTON_TITLE_DONT_SAVE<br/>6
6
| 1*6 || 256*6 || 65536*6
| 1*6||256*6||65536*6
|-
|-
! BUTTON_TITLE_REVERT
! BUTTON_TITLE_REVERT<br/>7
7
| 1*7 || 256*7 || 65536*7
| 1*7||256*7||65536*7
|-
|-
! BUTTON_TITLE_IS_STRING
! BUTTON_TITLE_IS_STRING<br/>127
127
| 1*127 || 256*127 || 65536*127
| 1*127||256*127||65536*127
|-
|-
! STD_OK_CANCEL_BUTTONS
! STD_OK_CANCEL_BUTTONS<br/>513
513
| 1*513 || 256*513 || 65536*513
| 1*513||256*513||65536*513
|}
|}
This simply means that if you want Button_1 to be YES then you take 256*3. If you want Button_0 to be SAVE, Button_1 to be DONT SAVE and Button_2 to have a string value then you set flag to be 1*5+256*6+65536*127. The third button will now get the string value of Button_2 in the function.
This simply means that if you want Button 1 to be "Yes" then you take <code>256*3</code>. If you want Button 0 to be "Save", Button 1 to be "Don't save" and Button 2 to have a string value then you set flag to be <code>1*5 + 256*6 + 65536*127</code>. The third button will now get the string value of <code>"Button 2"</code>, as specified in the snippet above.
 
==select()==
prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
list = new Array("ihoss","internet","firefox","xul","stupid entry","out of ideas");
selected = {value:2};
okorcancel = prompts.select(window, 'title', 'Text', 6, list, selected);
return selected.value;
return okorcancel;
 
select will give you a listbox with options and you can select one of the values. Selected will get the index of the item you selected and you can get its calue with list[selected.value]; The 4th parameter is the number of entries you want. This integer has to be less than or equal to the length of the array. If it is less then only the items up to that index will be in the listbox.


==Not working?==
===select()===
Ok, so you have added everything and it still does not work?
<code>select()</code> displays a dialog with a listbox and OK/Cancel buttons. The listbox contains specified options, and user can select exactly one of them. <code>selected.value</code> will get the index of the item user selected and you can get its value with <code>list[selected.value]</code> The 4th parameter is the number of entries you want to be displayed, it must be less than or equal to the length of the <code>list</code> array. If it is less then only the items up to that index will be shown in the listbox.
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);
var list = ["ihoss", "internet", "firefox", "xul", "stupid entry", "out of ideas"]
var selected = {};
var ok = prompts.select(window, "Window title", "Prompt text",
                        list.length, list, selected);
// selected.value contains the index
// |ok| indicates whether OK or Cancel button was pressed


* It can not be used on a web page, only as a local file or in an extension
* Make sure you have everything as the right data type.


==Finaly==
That's it. Add the code where it is needed and test your extension. You can download this tutorial and a javascript file [http://ihoss.not-a-blog.com/download/prompt.zip here]. If you have any questions or ideas send me a [mailto:ihoss.com@gmail.com mail] and I will gladly help you.


[[User:Ihoss|Ihoss]] - March/2005
==Original version==
The original version of this tutorial is by [[User:Ihoss|Ihoss]] and can be found [http://ihoss.not-a-blog.com/prompt.php here].


This tutorial is originaly on my extension and tutorial page: [http://ihoss.not-a-blog.com/prompt.php nsIPrompt tutorial]
[[Category:Example code]]

Revision as of 18:00, 25 April 2005

nsIPromptService is an XPCOM interface available to C++ and chrome JavaScript code (not to web pages' JS), that provides methods for displaying a few simple types of dialogs. To learn how to create advanced dialogs, see Creating dialogs. For file/folder picker dialogs, see nsIFilePicker article.

nsIPromptService has 9 functions and a few constants that are important to understand. This article contains explanations for some of these functions, and example code for all of them.

Getting nsIPromptService

First of all, you need to obtain the prompt service which you can use to show messages. You can do this using the following code:

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);

nsIPromptService methods

alert()

alert() is the simplest function, which simply displays a message box with specified title and message. For example:

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);
prompts.alert(window, "Window title", "Hello world!");

As in many other methods of nsIPromptService, first parameter is the parent window in the sense of nsIWindowWatcher.openWindow. You can pass null, in which case the parent window will be nsIWindowWatcher.activeWindow.

alertCheck()

alertCheck() will popup a message box with specified title, text and a checkbox. The checkbox can be a "Do not show this message again" option or something similar.

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);
check = {value: false}; // default value
prompts.alertCheck(window, "Window title", "You have been warned", 
                   "Don't ask again", check);
// do something with check.value;

Notice how we get the state of the checkbox. The function changes the value member of the check object, so to get the result we use check.value. It's the standart way of getting so-called "out" parameters from an XPCOM component.

confirm() and confirmCheck()

confirm() is also simple. It displays a dialog with specified title, text and two buttons - OK and Cancel.

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);
var result = prompts.confirm(window, "Title", "Do you want to quit?");

Below is an example for displaying a confirmation message with a checkbox. It is a hybrid of confirm() and alertCheck(), so it should be easy to understand without additional comments.

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);
var check = {value: false};
var result = prompts.confirmCheck(window, "Title", "Do you want to quit?", 
                                  "Do not ask me again", check);
// do something check.value / result

prompt()

prompt() can be very important and useful in lots of cases, as it accepts user input. Instead of making an XUL dialog or adding more textboxes you can simply call a prompt function. As you can see the first few arguments are the same as the others but it has an extra object. This object is the default value before the function is called and the new value after the function has been called.

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);
var input = {value: "default value"};
var check = {value: false};
result = prompts.prompt(window, "Title", "What's your name?", input, "Do not ask again", check);
// input.value is the string user entered
// check.value indicates whether or not the checkbox is checked
// result - whether user clicked OK (true) or Cancel

promptPassword() and promptUsernameAndPassword()

Below are other versions of prompt, promptPassword() with a password textbox and promptUsernameAndPassword which has a username and password field.

//promptPassword
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);
input = {value:"password"};
check = {value:false};
okorcancel = prompts.promptPassword(window, 'title', 'Text', input, 'Check?', check);
return input.value;
return check.value;
return okorcancel;

//promptUsernameAndPassword
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);
username = {value:"ihoss"};
password = {value:"password"};
check = {value:false};
okorcancel = prompts.promptUsernameAndPassword(window, 'title', 'Text', username, password, 'Check?', check);
return username.value;
return password.value;
return check.value;
return okorcancel;

confirmEx()

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);
var check = {value: false};
var flag = 0;
var button = prompts.confirmEx(window, "Window title", "Message text", flag, 
             "Button 0", "Button 1", "Button 2", "Checkbox label", check);
// |check.value| indicates whether or not the checkbox is checked
// |button| indicates which button was clicked

confirmEx() is designed to be customizable so you can make your own messages. It can display a dialog with up to 3 buttons with a variety of predefined (localized if necessary) labels or specified by your code labels, and a checkbox if you want. If you don't want the checkbox to be displayed, just put null in the eighth (checkbox label) parameter.

flag is an integer that is the sum of some constants. Below is a table that explains how it is done:

BUTTON_POS_0
1
BUTTON_POS_1
256
BUTTON_POS_2
65536
BUTTON_TITLE_OK
1
1*1 256*1 65536*1
BUTTON_TITLE_CANCEL
2
1*2 256*2 65536*2
BUTTON_TITLE_YES
3
1*3 256*1 65536*3
BUTTON_TITLE_NO
4
1*4 256*4 65536*4
BUTTON_TITLE_SAVE
5
1*5 256*5 65536*5
BUTTON_TITLE_DONT_SAVE
6
1*6 256*6 65536*6
BUTTON_TITLE_REVERT
7
1*7 256*7 65536*7
BUTTON_TITLE_IS_STRING
127
1*127 256*127 65536*127
STD_OK_CANCEL_BUTTONS
513
1*513 256*513 65536*513

This simply means that if you want Button 1 to be "Yes" then you take 256*3. If you want Button 0 to be "Save", Button 1 to be "Don't save" and Button 2 to have a string value then you set flag to be 1*5 + 256*6 + 65536*127. The third button will now get the string value of "Button 2", as specified in the snippet above.

select()

select() displays a dialog with a listbox and OK/Cancel buttons. The listbox contains specified options, and user can select exactly one of them. selected.value will get the index of the item user selected and you can get its value with list[selected.value] The 4th parameter is the number of entries you want to be displayed, it must be less than or equal to the length of the list array. If it is less then only the items up to that index will be shown in the listbox.

var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
              getService(Components.interfaces.nsIPromptService);
var list = ["ihoss", "internet", "firefox", "xul", "stupid entry", "out of ideas"]
var selected = {};
var ok = prompts.select(window, "Window title", "Prompt text", 
                        list.length, list, selected);
// selected.value contains the index
// |ok| indicates whether OK or Cancel button was pressed


Original version

The original version of this tutorial is by Ihoss and can be found here.