Conditional editing II.

A collection of tutorials and posts that show additional functionality of MATE

Moderator: KarelB

Conditional editing II.

Postby KarelB » Mon Jul 26, 2010 9:31 am

In the previous topic Conditinal editing I we saw how we could make the edit icon behave differently depending on the condition that the employee should belong to the Sales departement.

But to simplify the example I left out the V permission. Because if you add the V permission again it is possible to go into edit mode from the view screen, surpassing the restrictions we had set in the table view. To fix this we have to redefine the edit button on the view screen. This is a little bit harder to do, but with a little effort we can make this work too.

First we have to figure out that we are in the view screen. In the constructor add the following code after $this->Editor->main($data->action,$data->info); .

Code: Select all
if($data->action == 'view_row')
{
   $this->Editor->retArr[] = array('where' => 'javascript', 'value' => 'redefineEditButton(\''.$data->info.'\');');
}


The last code finds if we are in view mode and calls a new javascript function redefineEditButton. Put the new javascript function somewhere in your html page (eg inside the displayHtml function)
Code: Select all
<script type="text/javascript">
function redefineButtons(id)
{
   $$('#viewRowButtons button').each(function(btn)
   {
     if(btn.innerHTML == 'Edit')
     {
       $(btn).remove();
     }
   });
}
</script>


This will remove the edit button from the edit screen and your code is consistent again.

But this is the easy way out. If we go one step further we can also redefine the button and check on the department the row belongs to. Instead of removing the button we can change the onclick event of the button to call a useraction.
Code: Select all

<script type="text/javascript">
function redefineButtons(id)
{
   $$('#viewRowButtons button').each(function(btn)
   {
     if(btn.innerHTML == 'Edit')
     {
       $(btn).onclick=function(){toAjaxTableEditor("cond_edit",id);};
     }
   });
}
</script>


Now all we have left to do is the create the useraction cond_edit and the php function that checks the department setting.
In the iniateEditor function add the user action:
Code: Select all
$userActions = array('cond_edit' => array(&$this,'conditionalEdit'));
$this->Editor->setConfig('userActions',$userActions);


And as the last step we add the callback function conditionalEdit. Since we only have the id of the record we have to re-query the databse for the department.:
Code: Select all
   function conditionalEdit($id)
    {
       $sql = "SELECT department FROM employees WHERE id='".$id."'";
       $res = mysql_query($sql) or die(mysql_error());
       $info = mysql_fetch_assoc($res);
      
       if(! strcmp($info['department'],'Sales'))
       {
          $this->Editor->retArr[] = array('where' => 'javascript', 'value' =>'toAjaxTableEditor(\'edit_row\',\''.$id.'\');');
       }  else {
          $this->Editor->retArr[] = array('where' => 'javascript', 'value' => 'alert("Only employees from the Sales department can be edited")');
       }
    }


And here is the complete code for the script
Code: Select all
<?php
/*
 * Mysql Ajax Table Editor
 *
 * Copyright (c) 2008 Chris Kitchen <info@mysqlajaxtableeditor.com>
 * All rights reserved.
 *
 * See COPYING file for license information.
 *
 * Download the latest version from
 * http://www.mysqlajaxtableeditor.com
 */
require_once('Common.php');
require_once('php/lang/LangVars-en.php');
require_once('php/AjaxTableEditor.php');
class SpecialEdit2 extends Common
{
   var $Editor;
   
   function displayHtml()
   {
      ?>
         <br />
   
         <div align="left" style="position: relative;"><div id="ajaxLoader1"><img src="images/ajax_loader.gif" alt="Loading..." /></div></div>
         
         <br />
         
         <div id="historyButtonsLayer" align="left">
         </div>
   
         <div id="historyContainer">
            <div id="information">
            </div>
      
            <div id="titleLayer" style="padding: 2px; font-weight: bold; font-size: 18px; text-align: center;">
            </div>
      
            <div id="tableLayer" align="center">
            </div>
            
            <div id="recordLayer" align="center">
            </div>      
            
            <div id="searchButtonsLayer" align="center">
            </div>
         </div>
         
         <script type="text/javascript">
            trackHistory = false;
            var ajaxUrl = '<?php echo $_SERVER['PHP_SELF']; ?>';
            toAjaxTableEditor('update_html','');
         </script>
            <script type="text/javascript">
         function redefineEditButton(id)
         {
            $$('#viewRowButtons button').each(function(btn)
            {
              if(btn.innerHTML == 'Edit')
              {
                $(btn).onclick=function(){toAjaxTableEditor("cond_edit",id);};
              }
            });
         }
         </script>

      <?php
   }

   function initiateEditor()
   {
      $tableColumns['id'] = array('display_text' => 'ID', 'perms' => 'TVQSXO');
      $tableColumns['first_name'] = array('display_text' => 'First Name', 'perms' => 'EVCTAXQSHO');
      $tableColumns['last_name'] = array('display_text' => 'Last Name', 'perms' => 'EVCTAXQSHO');
      $tableColumns['email'] = array('display_text' => 'Email', 'perms' => 'EVCTAXQSHO');
      $tableColumns['department'] = array('display_text' => 'Department', 'perms' => 'EVCTAXQSHO', 'select_array' => array('Accounting' => 'Accounting', 'Marketing' => 'Marketing', 'Sales' => 'Sales', 'Production' => 'Production'));
      $tableColumns['hire_date'] = array('display_text' => 'Hire Date', 'perms' => 'EVCTAXQSHO', 'display_mask' => 'date_format(hire_date,"%d %M %Y")', 'calendar' => '%d %B %Y','col_header_info' => 'style="width: 250px;"');
      
      $tableName = 'employees';
      $primaryCol = 'id';
      $errorFun = array(&$this,'logError');
      $permissions = 'VEAIDQCSXHO';
      
      $this->Editor = new AjaxTableEditor($tableName,$primaryCol,$errorFun,$permissions,$tableColumns);
      $this->Editor->setConfig('tableInfo','cellpadding="1" width="1000" class="mateTable"');
      $this->Editor->setConfig('orderByColumn','first_name');
      $this->Editor->setConfig('addRowTitle','Add Employee');
      $this->Editor->setConfig('editRowTitle','Edit Employee');
      
      $this->Editor->setConfig('removeIcons','E');
      $userIcons[] = array('format_fun' => array(&$this,'getEditIcon'));
        $this->Editor->setConfig('userIcons',$userIcons);
      
      $userActions = array('cond_edit' => array(&$this,'conditionalEdit'));
        $this->Editor->setConfig('userActions',$userActions);
      
   }
   
   function conditionalEdit($id)
    {
       $sql = "SELECT department FROM employees WHERE id='".$id."'";
       $res = mysql_query($sql) or die(mysql_error());
       $info = mysql_fetch_assoc($res);
      
       if(! strcmp($info['department'],'Sales'))
       {
          $this->Editor->retArr[] = array('where' => 'javascript', 'value' =>'toAjaxTableEditor(\'edit_row\',\''.$id.'\');');
       }  else {
          $this->Editor->retArr[] = array('where' => 'javascript', 'value' => 'alert("Only employees from the Sales department can be edited")');
       }
    }
   
   
   function getEditIcon($info)
   {
      $iconHtml = '';
      $numIcons = 0;
      if(! strcmp($info['department'],'Sales'))
      {
         // Return edit icon with normal edit function
         $iconHtml .= '<li class="edit"><a href="javascript: toAjaxTableEditor(\'edit_row\',\''.$info['id'].'\');" title="Edit"></a></li>';
   
      } else {
         // Return edit icon with with an alert message and do nothing.
         $iconHtml .= '<li class="edit"><a href="#" onclick=\'alert("Only employees from the Sales department can be edited");\' title="Edit"></a></li>';
      }
      $numIcons++;
      return array('icon_html' => $iconHtml, 'num_icons' => $numIcons);
   }
   

   function SpecialEdit2()
   {
      if(isset($_POST['json']))
      {
         session_start();
         // Initiating lang vars here is only necessary for the logError, and mysqlConnect functions in Common.php.
         // If you are not using Common.php or you are using your own functions you can remove the following line of code.
         $this->langVars = new LangVars();
         $this->mysqlConnect();
         if(ini_get('magic_quotes_gpc'))
         {
            $_POST['json'] = stripslashes($_POST['json']);
         }
         if(function_exists('json_decode'))
         {
            $data = json_decode($_POST['json']);
         }
         else
         {
            require_once('php/JSON.php');
            $js = new Services_JSON();
            $data = $js->decode($_POST['json']);
         }
         if(empty($data->info) && strlen(trim($data->info)) == 0)
         {
            $data->info = '';
         }
         $this->initiateEditor();
         $this->Editor->main($data->action,$data->info);
         if($data->action == 'view_row')
         {
            $this->Editor->retArr[] = array('where' => 'javascript', 'value' => 'redefineEditButton(\''.$data->info.'\');');
         }

         if(function_exists('json_encode'))
         {
            echo json_encode($this->Editor->retArr);
         }
         else
         {
            echo $js->encode($this->Editor->retArr);
         }
      }
      else if(isset($_GET['export']))
      {
            session_start();
            ob_start();
            $this->mysqlConnect();
            $this->initiateEditor();
            echo $this->Editor->exportInfo();
            header("Cache-Control: no-cache, must-revalidate");
            header("Pragma: no-cache");
            header("Content-type: application/x-msexcel");
            header('Content-Type: text/csv');
            header('Content-Disposition: attachment; filename="'.$this->Editor->tableName.'.csv"');
            exit();
        }
      else
      {
         $this->displayHeaderHtml();
         $this->displayHtml();
         $this->displayFooterHtml();
      }
   }
}
$lte = new SpecialEdit2();
?>


Have fun!
Karel
KarelB
 
Posts: 429
Joined: Mon Dec 01, 2008 11:49 pm
Location: The Netherlands

Re: Conditional editing II. might have session problem

Postby Sir_Toby » Sat Oct 29, 2011 11:46 pm

Hello KarelB,

fresh downloaded free version mate2-2 installed, database "osm2c" installed with user "root", filled with your mate.sql datas and DB access configured accordingly in the Common.php. Cookies in browser enabled and old ones cleared.
=> Works perfect with your example1.php and example2.php.

Then additional file conditional2.php created, filled with your complete code for the script "Conditional editing II". Below given is the result of error text for "Conditional editing II" from browser Seamonkey, which is similar to error text for your "Conditional editing I" example. I have deleted all empoyees in database -except one- to shorten the error message to minimum:

    There was a problem with the response text
    <b>Warning</b>: session_start() [<a href='function.session-start'>function.session-start</a>]: Cannot send session cache limiter - headers already sent (output started at E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\originaler\conditional2.php:1) in <b>E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\originaler\conditional2.php</b> on line <b>136</b>

    [{"layer_id":"tableLayer","where":"innerHTML","value":"<div><form id=\"id-employees_table_form\" style=\"margin: 0px;\"><table cellpadding=\"1\" width=\"1000\" class=\"mateTable\">\n\t\t\t<tr class=\"header\"><td ><a href=\"javascript: toAjaxTableEditor('order_by_changed', new Array('id','asc'));\">ID<\/a><\/td><td ><a href=\"javascript: toAjaxTableEditor('order_by_changed', new Array('first_name','desc'));\">First Name<\/a> &uarr;<\/td><td ><a href=\"javascript: toAjaxTableEditor('order_by_changed', new Array('last_name','asc'));\">Last Name<\/a><\/td><td ><a href=\"javascript: toAjaxTableEditor('order_by_changed', new Array('email','asc'));\">Email<\/a><\/td><td ><a href=\"javascript: toAjaxTableEditor('order_by_changed', new Array('department','asc'));\">Department<\/a><\/td><td style=\"width: 250px;\" ><a href=\"javascript: toAjaxTableEditor('order_by_changed', new Array('hire_date','asc'));\">Hire Date<\/a><\/td><td>&nbsp;<\/td><\/tr><tr id=\"row_1\" class=\"ajaxRow\" bgcolor=\"#FFFFFF\" ><td >2<\/td><td >Sally<\/td><td >Jones<\/td><td >sallyj@gmail.com<\/td><td >Marketing<\/td><td >26 October 2004<\/td><td nowrap=\"nowrap\"><ul class=\"actions\" style=\"width: 104px;\"><li class=\"info\"><a href=\"javascript: toAjaxTableEditor('view_row','2');\" title=\"Info\"><\/a><\/li><li class=\"copy\"><a href=\"javascript: toAjaxTableEditor('copy_row','2');\" title=\"Copy\"><\/a><\/li><li class=\"delete\"><a href=\"javascript: confirmDeleteRow('2')\" title=\"Delete\"><\/a><\/li><li class=\"edit\"><a href=\"#\" onclick='alert(\"Only employees from the Sales department can be edited\");' title=\"Edit\"><\/a><\/li><\/ul><\/td><\/tr><\/table><\/form><\/div>"},{"layer_id":"recordLayer","where":"innerHTML","value":"<div>Displaying 1 - 1 of 1 Records<\/div>"},{"layer_id":"searchButtonsLayer","where":"innerHTML","value":"<div style=\"padding-top: 5px; padding-bottom: 5px;\">Page #: <select id=\"page_number\" onchange=\"toAjaxTableEditor('page_num_changed',this.value);\"><option value=\"0\" selected=\"selected\" style=\"font-weight: bold\">1<\/option><\/select>&nbsp;<button onclick=\"toAjaxTableEditor('add_row','');\">Add<\/button>&nbsp;<button onclick=\"window.location='\/Ajaxed_MySQL_Table_Editor-2.2\/originaler\/conditional2.php?export=1'\">Export<\/button>&nbsp;<button onclick=\"toAjaxTableEditor('show_hide_columns','');\">Show\/Hide Columns<\/button>&nbsp;<button onclick=\"toAjaxTableEditor('order_columns_screen','');\">Order Columns<\/button>&nbsp;<button onclick=\"toAjaxTableEditor('show_advanced_search','');\">Advanced Search<\/button>&nbsp;<\/div>Search: <input type=\"text\" id=\"searchString\" value=\"\" size=\"25\" onKeyPress=\"if(enterPressed(event)){handleSearch(); return false;}\" \/>&nbsp;<button onclick=\"handleSearch();\">Search<\/button>&nbsp;<button onclick=\"clearSearch();\">Clear Search<\/button>"},{"layer_id":"titleLayer","where":"innerHTML","value":"Employees"}]


In other installation also the error messages:
    <b>Warning</b>: session_start() [<a href='function.session-start'>function.session-start</a>]: Cannot send session cache limiter - headers already sent (output started at E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\conditional2.php:1) in <b>E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\conditional2.php</b> on line <b>136</b>

    <b>Warning</b>: Cannot modify header information - headers already sent by (output started at E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\conditional2.php:1) in <b>E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\php\AjaxTableEditor.php</b> on line <b>543</b>
[/list]

What is your advice to get your conditional editing examples working in my installation?

Thanks for copy/paste-able description.
Sir_Toby
 
Posts: 5
Joined: Wed Dec 08, 2010 1:52 pm

Re: Conditional editing II.

Postby KarelB » Tue Nov 01, 2011 8:31 pm

This normally means that you are echo-ing something before the actual output.
Are there any empty lines after the closing php tag "?>"
KarelB
 
Posts: 429
Joined: Mon Dec 01, 2008 11:49 pm
Location: The Netherlands

Re: Conditional editing II.

Postby Sir_Toby » Wed Nov 02, 2011 10:39 am

Yes, there were empty lines after the closing php tag "?>" in the common.php and in the conditional2.php, I also found empty line in php/lang/LangVars-en.php . I removed all of them, cleared the cookies. In browser Seamonkey configuration I also allowed all cookies with unlimited time. Then called conditional2.php again. The error result did not change, errors message upper part here again. Remarkable is that the same lines with line number 136 resp 539 are given twice.
There also was no change of error message when I used first time Internet Explorer for calling the conditional2.php instead of with Seamonkey.

-------
There was a problem with the response text
<b>Warning</b>: session_start() [<a href='function.session-start'>function.session-start</a>]: Cannot send session cookie - headers already sent by (output started at E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\originaler\conditional2.php:1) in <b>E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\originaler\conditional2.php</b> on line <b>136</b>

<b>Warning</b>: session_start() [<a href='function.session-start'>function.session-start</a>]: Cannot send session cache limiter - headers already sent (output started at E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\originaler\conditional2.php:1) in <b>E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\originaler\conditional2.php</b> on line <b>136</b>

<b>Warning</b>: Cannot modify header information - headers already sent by (output started at E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\originaler\conditional2.php:1) in <b>E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\originaler\php\AjaxTableEditor.php</b> on line <b>539</b>

<b>Warning</b>: Cannot modify header information - headers already sent by (output started at E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\originaler\conditional2.php:1) in <b>E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\originaler\php\AjaxTableEditor.php</b> on line <b>539</b>

[{"layer_id":"tableLayer","where":"innerHTML","value":"<div><form id=\"id-employees_table_form\" style=\"margin: 0
.....
(cutted)

-------
The conditional2.php indeed has in line 136 the code session_start();
But I probably had nothing broken as I simply copied your full code that you published in first section of this thread.


About the line 539 in php\AjaxTableeditor.php :
I (personally unexperienced status) did not find any remarkable code around this line, regarding the problem.
Wired calculation of the line numbers from conditional2.php with its 198 lines, subtracted from the error message line 539 from the AjaxTableEditor.php points nearby to code with sessions at line 259, where in original the code for function main has a by // deactivated $this->startSession(); at line 253.
Simply uncommended this line did not succeed, but delivered a shorter error message, which remarkably is only given once, not as double repetion like above given error message:
----
There was a problem with the response text
<b>Warning</b>: session_start() [<a href='function.session-start'>function.session-start</a>]: Cannot send session cache limiter - headers already sent (output started at E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\originaler\conditional2.php:1) in <b>E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\originaler\conditional2.php</b> on line <b>136</b>

<b>Fatal error</b>: Call to undefined method AjaxTableEditor::startSession() in <b>E:\XAMPP\xampp\htdocs\Ajaxed_MySQL_Table_Editor-2.2\originaler\php\AjaxTableEditor.php</b> on line <b>253</b>

--------
So the problem is not solved yet, and I would like to know if error is repeatable by someone, which can be tested easily using the basic mate2.2 installation and the full code conditional II of the first section of this thread.
Sir_Toby
 
Posts: 5
Joined: Wed Dec 08, 2010 1:52 pm

Re: Conditional editing II.

Postby KarelB » Tue Nov 08, 2011 6:33 am

There is no need to edit anything in php/AjaxTableeditor.php.
If you get an error the issue is in your configuration file. Try uncommenting the session_start line.
KarelB
 
Posts: 429
Joined: Mon Dec 01, 2008 11:49 pm
Location: The Netherlands


Return to How To

Who is online

Users browsing this forum: No registered users and 1 guest