 |
 |
 |
 |

Datamanager Actions
Conventions used in this document:
- Any text that is in this font is considered code, a literal value, the name of a file, folder, MySQL table, MySQL field, or a value in a MySQL field.
- Any text that is surrounded by angle brackets like <this> means that you should substitute it for your own value.
Example: vconsole/modules/<module>/ means that you should substitute <module> for your own value like invoices for the Manage Invoices module.
- Any text that is surrounded by square brackets like [this] means that it is optional.
Example: check_email($email, $error[, $dnscheck]); means that [, $dnscheck] is optional
- When you see ... in the code font, this means that you can add 1 or more items at that point. Do not actually include ... in your code.
Datamanager Actions are actions that are performed on the data that is managed by a datamanager type module. (See The Datamanager for more information on datamanager type modules) Actions can be just about anything you want them to be, but they are designed to do something to your data like, add a new record or maybe to edit or delete an existing record. Since these 3 actions (add, edit, and delete) are the basic actions that most developers will use, we will go over these 3 types of actions in this section. Remember, you can make your action do just about anything, even if it has nothing to do with the data in the data manager. With that said, there are a few components that are required.
How To Create A Datamanager Action.
Follow this procedure to create a datamanager action:
- Define your action in the singleops or groupops section of the dms.php file. If you don't do this then the user will not be able to right click on items and click on the action in the drop down menu. Although this is not required, it is recommended. The reason that this is not required is because, if you create an entry in the vc_modules-actions table (see below), then the user can add the action to the toolbar using the "Customize Toolbar" button in the top navigation bar or the action button can be displayed by default. The reason that this is recommended is to allow your users better control of their data. Allowing them to right click on a record and choose what they want to do with that record (or records) is the way that most software applications work. If you have the VConsole Developer Toolkit extension for Dreamweaver installed, then you can simply open up your dms.php file, place your cursor in thesingleops or groupops section, and select "Insert Action" from the VConsole menu. If you are coding your dms.php file manually, then check here for instructions on how to add an action to your dms.php file.
- Create your action file. Your action file should be located in the vconsole/modules/<name_of_module>/actions/ folder and it should be named the same as your action parameter in your dms.php file. So if in your dms.php file, you named your action del, then your action file should be del.php. Your action file should perform the action that the user is expecting to be performed to the record or records that he / she selected. We will go over how to code your action file below. Your action file is executed after the main.php file and before the datamanager() function is called (assuming that your main.php file is coded correctly). Also, your action file should either be a wizardmanager or propertiesmanager formatted action file or it should return without printing any output to the browser. If you do print output to the browser, then you risk messing up the user interface. Remember, actions are called using AJAX using the updateDataTable() javascript function as documented here. If your action file outputs anything, then make sure that the updateDataTable() function understands it and make sure that you are doing it properly (See the Advanced Users Only section below). We recommend using a wizardmanager or propertiesmanager formatted action file because it takes care of outputting everything to the browser in the correct way. Only advanced web developers should attempt to output anything from their custom action files. If you output incorrect data to the browser, your users may get javascript errors, the interface may not work as expected, or both. If you want to provide feedback to your users about the result of the action, you should use the set_message() php function instead of printing something out to the browser. Any messages that are set using the set_message() php function are handled correctly by the datamanager.
- You should create an entry in the vc_modules-actions table. Although this is not required, it is recommended because it allows you to set permissions on your datamanager actions. In other words, you can say who has permission to execute the action and no additional coding is required. You simply go to the group manager and set the appropriate permissions through the GUI. Here are the fields for the vc_modules-actions table and what they mean.
- module - This should match your module as in the vc_modules.module field.
- action - This should match the name of your action as in the dms.php groupops or singleops section as well as the action file. If your action is del, then enter del here.
- button - Optional. If entered, this should be the name of a button image as required by the getimage() function. You can open up the vconsole/showimages.php file in a browser to show a list of all the available buttons. This is the button image that is shown in the top navigation bar when the user adds the action to the bar using the "Customize Toolbar" button. To add your own images, add them to the vconsole/skins/buttons/ folder.
- order - This should be a positive whole number or 0 or -1. If set to 0, then the action button is not shown in the top navigation bar by default. In other words, the user has to add it using the "Customize Toolbar" button. If set to 1 or higher, then the button is shown in the top navigation bar by default and the user can't get rid of it. Buttons with a 1 or higher setting here are shown in order from lowest to highest. If set to -1 then the button is not shown at all and the user cannot add it.
- name - This should be the human readable name for the action. Something like "Delete Invoices" is appropriate. This is also shown in the top navigation bar when the user has added the action button to it using the "Customize Toolbar" button. (No HTML Allowed)
- perm - This should be the human readable name for the permission to this action. This is shown in the Manage Groups module when managing permissions for groups. Something like: "Allow Deletion of Invoices" is appropriate. (No HTML Allowed)
- help - Optional. This should be set to a human readable message to show the user when they hover their mouse over the action button in the top navigation bar for a short period of time. HTML is ok.
- conf - Optional. If set, this should be set to a human readable message to show to the user when they click the top navigation button. This message is passed to the confirm() javascript function so no HTML is allowed. If set, then the user is shown this message and is given a chance to cancel their action. If not set, then the settings from the dms.php file under the groupops section for the action are used, and if not found there, then the settings from the singleops section are used.
- alwaysallow - This should be set to either 1 or 0. If set to 1, then the action is always allowed and no permission checking is done (unless you do the checking manually in your php action file, which is perfectly acceptable.). If set to 0, then the action permission is checked before the user gets to the main.php file
After doing all of this, your action should be fully recognized by VConsole.
Coding Your Action File.
There are 3 different possibilities for coding your action files.
- Format your action file in the wizardmanager format.
- Format your action file in the propertiesmanager format.
- Code your action file manually.
We will go over each of these possibilities in detail. in the next sections.
Formatting your action file in the wizardmanager format.
Do this if you want to collect information from your user and give them a step by step wizard with lots field choices, field validation, and step conditions. Usually, you would use this type of action for editing data records, creating new records, or performing actions to records that require input from the user.
In order to do this, simply copy the code from the file below and then modify your action file using the instructions found in The Wizardmanager section of this publication.
The code found in the file below is heavily commented so you should be able to follow the instructions contained in the file. Once you have saved your file, all you need to do is create your wizardmanager fields in the $wm data structure and then configure the section for when the input from the user has been collected. A wizardmanager action takes the user through a step by step wizard that collects information from them. Once all the input has been collected, the wizardmanager then returns control to you passing back fully validated input from the user. You can then do what ever you want with that information. Preferably, you will perform the action that the user is expecting to be performed. We have also posted a real world example at the bottom of this page if you are interested.
(Also, if you have the VConsole Developer Tools for Dreamweaver extension installed, there is no need to copy the code from the file below. All you need to do is choose "New Wizardmanager Action File" from the "VConsole" main menu and the file is created for you.)
Formatting your action file in the propertiesmanager format.
Do this if you want to collect information from your user and give them a series of property tabs featuring lots of field choices and field validation. Usually, you would use this type of action for editing data records or creating new records.
In order to do this, simply copy the code from the file below and then modify your action using the instructions found in The Propertiesmanager section of this publication. The code found in the file below is heavily commented so you should be able to follow the instructions contained in the file. Once you have saved your file, all you need to do is create your propertiesmanager fields in the $pm data structure and then configure the section for when the input from the user has been collected. A propertiesmanager action shows the user a series of properties tabs each with their own set of fields. Once the user clicks on the save button, the propertiesmanager then returns control to you passing back fully validated input from the user. You can then do what ever you want with that information. Preferably, you will perform the action that the user is expecting to be performed. We have also posted a real world example at the bottom of this page if you are interested. (Also, if you have the VConsole Developer Tools for Dreamweaver extension installed, there is no need to copy the code from the file below. All you need to do is choose "New Propertiesmanager Action File" from the "VConsole" main menu and the file is created for you.)
Coding your action file manually.
To code your action file manually, you simply need to figure out what records the user selected and then perform the action to the record or records. You can then set a confirmation or error message and then return without printing out anything to the browser. (As mentioned above, do not output anything to the browser unless you know the impact of doing so.)
- Figuring out what records the user selected. When an action is performed, it is usually because the user has right clicked on 1 or more records and then selected the action menu item that calls your action file. So in order to perform the action on the records that the user selected, you must first figure out what records were selected by the user. You do this using the PHP function datamanager_getselected(). This function returns an array of selected ids. The ids are taken from the MySQL table primary index (as defined in your dms.php file as the tableindex parameter). So if your MySQL table has a primary key field named id, then this function will return an array of id fields for each selected record. Let's go over an example:
- Performing the action. OK, now that you know what records have been selected by the user, you will want to perform the desired action to those records. How you do that is up to you.
- Setting a confirmation message. OK, so you have performed the requested action to all the selected records. Now you probably want to set a confirmation message. DO NOT OUTPUT ANYTHING TO THE BROWSER. You can set a confirmation message using the set_message() php function. This function takes 2 arguments. The type of message to display and the actual message. (Please see PHP functions for more information) Here is a quick example of how to do this.
set_message('success', 'Your records have been changed.');
- Indexing Your Records. OK, 1 more thing to do. If you have added or modified any records, you will want to index or re-index them so that the search works correctly when the user searches for records. If you do not do this, then the user may have to invoke the "Reindex All Records" option on the Searchbuilder drop down menu. You should index every record that is added and re-index every record that is modified. You do this using the searchindex() php function. The searchindex() function takes 2 required parameters which are the module name and the id of the record to re-index. Here is a quick example of how to re-index records (assuming that $selected contains an array of all the selected records)
foreach ($selected as $id) { searchindex($_SESSION['module'], $id); }
If you have deleted any records, then you will also want to delete the search indexes for those records. You do that using the delete_searchindex() php function. This function takes 2 required parameters which are the module name and the name of the MySQL table. Calling the function 1 time takes care of deleting all indexes for the table that don't exist, so there is no need to call it more than once. Here is an example of how to call the function.
delete_searchindex($_SESSION['module'], '<mysql_tablename>');
Make sure that you substitute <mysql_tablename> for the actual name of the MySQL table that you deleted records from.
- Return Control. Now, all you have to do is return. That's it. See below for some real world examples.
Real World Examples. Add, Modify, Delete.
Here, we provide you with some real world examples of how to perform add, modify and delete actions. In the first example, we take you though adding a new record. We do this using a wizardmanager formatted action file. The second example takes you through modifying a record using a propertiesmanager formatted action file. And the third example simply deletes all the selected records using a custom coded action file. OK, let's get started.
Example 1. Adding a record using a wizardmanager formatted action file. ( See documentation on wizardmanager parameters here)
With just this little bit of code, the user gets a feature rich wizard complete with field validation.
- <?php
- $wm = array(
- array(
- 'title' => 'New Record',
- 'image' => 'document_add',
- 'info' => 'You are adding a record',
- ),
-
- array(
- 'condition' => 1,
- 'instructions' => 'Fill out the form below',
- 'fields' => array(
-
- array(
- 'type' => 'text',
- 'name' => 'name',
- 'label' => 'Name',
- 'labelpos' => 'before',
- 'pack' => 'nextrow',
- 'help' => 'Enter a name',
- 'fielddata' => array(
- 'attributes' => array(
- 'size' => 50
- )
- ),
- 'validate' => array(
- 'required' => true,
- 'minlength' => 5,
- 'maxlength' => 50,
- 'type' => 'text'
- )
- ),
-
- array(
- 'type' => 'textarea',
- 'name' => 'desc',
- 'label' => 'Description',
- 'labelpos' => 'before',
- 'pack' => 'nextrow',
- 'help' => 'Enter a description',
- 'fielddata' => array(
- 'attributes' => array(
- 'cols' => 50,
- 'rows' => 5
- )
- ),
- 'validate' => array(
- 'required' => true,
- 'minlength' => 5,
- 'maxlength' => 255,
- 'type' => 'text'
- )
- )
- )
- ),
-
- array(
- 'condition' => 1,
- 'instructions' => 'Confirm your action',
- 'fields' => array(
-
- array(
- 'type' => 'checkbox',
- 'name' => 'confirm',
- 'label' => 'Check this box to confirm your action',
- 'labelpos' => 'after',
- 'pack' => 'nextrow',
- 'help' => 'You must check this box to continue.',
- 'fielddata' => array(
- 'value' => 1
- ),
- 'validate' => array(
- 'required' => true,
- 'failmsg' => 'You must check the box to continue.',
- )
- )
- )
- )
- );
- $data = wizardmanager($wm);
- if (is_array($data)) {
-
- $id = db_query("INSERT INTO `table1` SET
- `name` = " . db_quote($data[1]['name']) . ",
- `description` = " . db_quote($data[1]['desc']), $dbr);
-
-
- searchindex($_SESSION['module'], $id);
-
-
- set_message('success', 'The new record was created');
-
-
- print $OUT['messages'] . "<<>>updateDataTable();";
- exit;
-
- } else {
-
- print "<<>>wmdivClose()";
- exit;
- }
- ?>
This action file delivers a 2 step wizard to the user. The first step asks for a name and description for the record and the 2nd step makes them check the checkbox to confirm the addition of the record. Line 2 - 79 define the $wm data structure that is handed off to the wizardmanager function. Line 80 takes care of handing off the $wm data structure to the wizardmanager() function and storing the user's input in the $data array. If the user didn't hit the cancel button, then lines 82 through 96 are executed which takes care of adding the record to the database, indexing the record, setting a success message for the user, and then outputting the message to the user correctly. If the user pressed the cancel button, then line 100 closes out of the wizard. Notice that there is no need to validate the user's input. Field validation is taken care of in the wizardmanager() function. The name field is a required field so if the user does not enter it, they get a failure message. Also, the wizardmanager() function makes sure that it is between 5 and 50 characters and that it does not contain any special characters. All this is specified using the validate array in the $wm data structure. (See The Wizardmanager for more information on what all these parameters are)
Example 2. Editing a record using a propertiesmanager formatted action file. (See documentation on propertiesmanager parameters here)
With just this little bit of code, the user gets a series of properties tabs complete with field validation.
- <?php
- $selected = datamanager_getselected();
- if (count($selected) != 1) {
- set_message('error', 'You must select only 1 record to edit');
- return;
- }
- $id = $selected[0];
- db_query("SELECT * FROM `table1` WHERE `id` = " . db_quote($id), $dbr);
- $mod = mysql_fetch_assoc($dbr);
- if (!$mod['id']) {
- set_message('error', 'The specified record was not found');
- return;
- }
- $pm = array(
- array(
- 'title' => 'Edit Record',
- 'image' => 'document_config',
- 'info' => 'You are editing a record',
- ),
-
- array(
- 'tab' => 'Name',
- 'instructions' => 'Enter a name',
- 'fields' => array(
-
- array(
- 'type' => 'text',
- 'name' => 'name',
- 'label' => 'Name',
- 'labelpos' => 'before',
- 'pack' => 'nextrow',
- 'help' => 'Enter a name',
- 'fielddata' => array(
- 'default' => $mod['name'],
- 'attributes' => array(
- 'size' => 50
- )
- ),
- 'validate' => array(
- 'required' => true,
- 'minlength' => 5,
- 'maxlength' => 50,
- 'type' => 'text'
- )
- ),
- )
- ),
-
- array(
- 'tab' => 'Description',
- 'instructions' => 'Enter a description',
- 'fields' => array(
-
- array(
- 'type' => 'textarea',
- 'name' => 'desc',
- 'label' => 'Description',
- 'labelpos' => 'before',
- 'pack' => 'nextrow',
- 'help' => 'Enter a description',
- 'fielddata' => array(
- 'default' => $mod['description'],
- 'attributes' => array(
- 'cols' => 50,
- 'rows' => 5
- )
- ),
- 'validate' => array(
- 'required' => true,
- 'minlength' => 5,
- 'maxlength' => 255,
- 'type' => 'text'
- )
- )
- )
- )
- );
- $data = propertiesmanager($pm);
- if (is_array($data)) {
-
- db_query("UPDATE `table1` SET
- `name` = " . db_quote($data['name']) . ",
- `description` = " . db_quote($data['desc']) . "
- WHERE `id` = " . db_quote($id), $dbr);
-
-
- searchindex($_SESSION['module'], $id);
-
-
- set_message('success', 'The record was updated');
-
-
-
- print $OUT['messages'] . "<<>>updateDataTable();";
- exit;
-
- } else {
-
- print "<<>>wmdivClose()";
- exit;
- }
- ?>
This action file delivers an interface that has 2 properties tabs (Name and Description). Each tab has 1 field (although, in a real action file, you will probably have more fields per tab). Each field contains the current values of the record and the user can make changes to that data.
- Line 2 gets all the records that the user selected.
- Lines 3 - 6 makes sure that the user selected only 1 record, since a user can only edit 1 record at a time.
- Line 7 sets the variable $id to the id of the selected record.
- Lines 8 - 13 gets the current data for the record and stores it in the $mod associative array.
- Lines 15 - 78 define the data structure that is required by the propertiesmanager() function.
- Line 79 calls the propertiesmanager() function and passes the $wm data structure as an argument. The propertiesmanager() returns the input from the user in the $data array.
- Lines 80 - 96 take care of updating the record, indexing the changes, setting a message for the user, and outputting that message to the user.
- Lines 98 - 102 take care of handling the situation where the user clicks on the "Cancel" button.
Notice that there is no need to validate the user's input. That is taken care of in the propertiesmanager() function. The name field is a required field so if the user does not enter it, they get a failure message. Also, the propertiesmanager() function makes sure that it is between 5 and 50 characters and that it does not contain any special characters. All this is specified using the validate array in the $pm data structure. ( See The Propertiesmanager for more information on what all these parameters are)
Example 3. Deleting records using a custom coded action file.
Using the example below, a user can delete multiple records at once. Plus, this is done with very little code.
- <?php
- $selected = datamanager_getselected();
- if (!count($selected)) {
- set_message('error', 'You must select at least 1 record to delete');
- return;
- }
- $qry = '';
- foreach ($selected as $id) {
- $qry .= " OR `id` = " . db_quote($id);
- }
- db_query("DELETE FROM `table1` WHERE 0 $qry", $dbr);
- $deleted = mysql_affected_rows();
-
- delete_searchindex($_SESSION['module'], 'table1');
-
- set_message('success', "Deleted {$deleted) records.");
-
- return;
- ?>
OK, so let's go over this action file.
- Line 2 gets an array of all the selected items.
- Lines 3 - 6 return an error to the user if they did not select any records since we obviously need at least 1 record to delete.
- Lines 7 - 10 construct the end of the query that we use to delete records. We could delete records 1 by 1 by putting a delete query on line 9, but it is faster the way that we do it. Always remember that 1 long query is faster than multiple short queries. This is because each query has the overhead of issuing the query to the MySQL server to execute the query.
- Line 11 - OK, so we actually execute the query on line 11.
- Line 12 - Then line 12 gets the number of records that were deleted. We could just get a count using count($selected), but we want to make sure that the number is accurate and the mysql_affected_rows() function gives the real number of records that were deleted. 99.99% of the time, count($selected) and mysql_affected_rows() will be exactly the same, but if 2 people are deleting records at the same time, it is possible for count($selected) and mysql_affected_rows() to give different numbers.
- Line 15 - Moving on... Line 15 deletes all the search indexes that do not exist in the table. You want to call the delete_searchindex() function every time you delete a record from any datamanager managed table.
- Line 18 sets a message so that the user knows that the action succeeded.
- And line 20 simply returns control to the datamanager for output.
Notice that we do not output anything to the browser. If, in your custom coded action files, you want the user to see something, use the set_message() function and then return. That is the safest way to get your message across without messing up the user interface. If you MUST output something to the browser, see below.
Advanced Users Only. Making your action files output directly to the browser.
Above, we said NOT to have your action files output anything to the browser. This is because the javascript that calls the action file is expecting well formatted code and replaces only certain areas of the page. Remember, the interface uses AJAX and the entire interface is not re-drawn every time someone executes an action. Although we do not recommend outputting anything to the browser, we include this section for documentation purposes and so that you will have a better understanding of how the VConsole interface works. The AJAX function expects a series of parameters separated by double angle brackets like this <<>> . Each parameter replaces a certain area of the interface (or executes javascript). If you do not output anything for a parameter, then that area of the interface is not changed. Here is what the AJAX function expects.
CP_Area <<>>Menu_System <<>>Top_Menu <<>>Current_Records <<>>Load_More_Records <<>>Displays <<>>Modules <<>>Screen_Title <<>>Data <<>>Javascript <<>>WM_Header <<>>WM_Content
Let's go over each parameter and what each does.
- CP_Area - This is the container for the data manager. NEVER output anything for this parameter unless you want to mess up the user interface. This is because most of the other components are contained within this component. Replacing it would give javascript errors unless you ouput the correct html code.
- Menu_System - This parameter contains all the data for the menu system including right click menus and main cascading drop down menus. Unless you know what to output, you should not output anything here as well.
- Top_Menu - This parameter defines what is displayed in the main menu bar (The one with all the drop down lists.)
- Current_Records - This parameter should contain the the text that is displayed at the top and possibly bottom of the data records. It includes how many records there are total and how many records are currently displayed.
- Load_More_Records - This parameter should contain the Load More Records drop down list. This allows the user to load more records on the fly.
- Displays - This parameter should contain the Displays buttons in the main menu (List, Calendar, Icon, Map, Reporting)
- Modules - This parameter determines what is displayed in the Top Navigation Bar. (The one with all the graphic buttons)
- Screen_Title - This parameter determines what is displayed as the Module Title
- Data - This parameter determines what is displayed where the data records usually go.
- Javascript - Anything that is output here is evaluated as javascript code and executed.
- WM_Header - Replaces the Header area of the Wizard Manager Floating DIV (Not visible anyway unless you pass javascript that shows it.)
- WM_Content - Replaces the Content area of the Wizard Manager Floating DIV (Not visible anyway unless you pass javascript that shows it.)
If you don't want to replace a component in your user interface, don't specify it. So, If I just want to put something where the data records usually go, output this:
<<>><<>><<>><<>><<>><<>><<>><<>>My Output Goes Here
Also, one more thing. You notice in the code above, that in the Wizardmanager and Propertiesmanager formatted action files, the output is:
$OUT['messages'] . '<<>>updateDataTable();'
You would think that this replaces the CP_Area and the Menu_System, right? Wrong! The reason is that after the wizardmanager() or propertiesmanager() function is called, the output has already been sent to the calling javascript function and a new javascript function is called that expects 2 parameters. The 2 parameters that are expected after the wizardmanager() or propertiesmanager() functions are called is very simple. The first is human readable output that will be placed in the Wizardmanager floating div and the second is javascript to execute.
NEXT: The Wizard Manager
COMMENTS There are no comments at this time.
|
|
 |
 |
 |
|