Override the class and use JQuery

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

Moderator: KarelB

Override the class and use JQuery

Postby KarelB » Thu May 26, 2011 4:17 pm

In MATE when defining a column the display_text option is used for both the columnheader as well as for the label on the add and edit screens. Occasionally i would like to have some more info to give my users some guidance on what the input format is or the purpose of the inputfield. I therefore created a tooltip system like this:

Image

This involves a couple of lines of jQuery code from the qTip plugin and overridding the class. As this is going to be a bit of a complicated example I am not going to explain everything in detail, but all the documentation of jquery/qtip can be found on their website. As an example we wil take Example1.php from the free version.
At the end of the tutorial you will find complete copies of the class file and the new Example1.php

jQuery
Although MATE uses the prototype javascript library you can use the jQuery library and its plugins as well if you include the jQuery files before the prototype file and if you set the noConflict option.
You can grep a copy of the latest jQuery code from http://jquery.com/ and the qtip plugin from http://craigsworks.com/projects/qtip/

Put the following three lines (with correct names and paths) in the Common.php before the protoype.js line:
Code: Select all
         <script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
         <script type="text/javascript" src="js/jquery.qtip-1.0.0-rc3.min.js"></script>
         <script type="text/javascript">  $jq = jQuery.noConflict();</script>

You are now ready to use jQuery code in your pages.

Put the following little javascript function in the script section of the displayHtml function in Example1.php:
Code: Select all
            function createTips()
            {
               $jq("#tableLayer a[tooltip]").each(function()
               {
                  $jq(this).qtip({
                     content: $jq(this).attr("tooltip"), // Use the tooltip attribute of the element for the content
                     style: "blue" // Give it a crea mstyle to make it stand out
                  });
               });
            }

This will automatically create a tooltip of any element inside a <a> tag with the attribute "tooltip"
Eg. <a href="#" tooltip="My Message" ><img src="images/tooltip16x16.gif" border="0"></a> wil show a tooltip with the text "My Message" when hovering over the image.

Overriding the class
So all we have left to do is to put the image with the <a< tags inside the edit or add tablescreen and display a message. In this example I only will do the edit screen, but it is similar for the add screen.
You could edit the original AjaxTableEditor.php file, but it is better to override the class.
Create the new class extension TT_AjaxTableEditor.php in the same directory as Example2.php
Code: Select all
require_once('php/AjaxTableEditor.php');
class TT_AjaxTableEditor extends AjaxTableEditor
{

}

The function editRow( and addRow) from AjaxTableEditor.php are the ones that create the html for the tables.
Put copy of the editRow in your TT_AjaxTableEditor extension and replace the following code
Code: Select all
$html .= '<tr><td id="'.$col.'_label_cell" class="labelCell"><label for="'.$this->inputIdPrefix.$col.'">'.$info['display_text']:</label></td><td id="'.$col.'_input_cell" class="inputCell">'.$inputHtml.'</td></tr>';

with:
Code: Select all
if (isset($info['tooltip']) && $info['tooltip']){
   $tt='&nbsp;&nbsp;<a href="#" tooltip="'.$info['tooltip'].'"><span style="vertical-align:middle;"><img src="images/tooltip16x16.gif" border="0"></span></a>&nbsp;&nbsp;';
} else {
   $tt ='';
}      
$html .= '<tr><td id="'.$col.'_label_cell" class="labelCell"><label for="'.$this->inputIdPrefix.$col.'">'.$info['display_text'].$tt.':</label></td><td id="'.$col.'_input_cell" class="inputCell">'.$inputHtml.'</td></tr>';

We also need to call the javscript createTips so add the following line
Code: Select all
$this->retArr[] = array('where' => 'javascript', 'value' => 'createTips();');

after the
Code: Select all
$this->retArr[] = array('layer_id' => 'tableLayer', 'where' => 'innerHTML', 'value' => $html);


This will insert the tooltip image code if a column has the option tooltip set like: 'tooltip' => 'My Message'
So set the tooltip option for example to the email column and call the new class TT_AjaxTableEditor.
Following is the complete Example1.php file:
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('TT_AjaxTableEditor.php');
class Example1 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','');
                        function createTips()
            {
               $jq("#tableLayer a[tooltip]").each(function()
               {
                  $jq(this).qtip({
                     content: $jq(this).attr("tooltip"), // Use the tooltip attribute of the element for the content
                     style: "blue" // Give it a crea mstyle to make it stand out
                  });
               });
            }
         </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', 'tooltip' => 'Only use your company email address and not your pivate email address');
      $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 = 'EAVIDQCSXHO';
      
      $this->Editor = new TT_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('iconTitle','Edit Employee');
   }
   
   
   function Example1()
   {
      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(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 Example1();
?>


and the complete code for the new class file TT_AjaxTableEditor.php
Code: Select all
<?php
require_once('php/AjaxTableEditor.php');
class TT_AjaxTableEditor extends AjaxTableEditor
{
   function editRow()
   {
      if(stristr($this->permissions,'E'))
      {
         $html = '';
         $calJs = array();
         $id = $this->escapeData($this->info);
         $jsUpdateFun = 'updateRow(\''.$id.'\',\''.$this->varPrefix.'\');';
         $query = "select * from $this->tableName where $this->primaryKeyCol = '$id'";
         $result = $this->doQuery($query);
         if($row = mysql_fetch_assoc($result))
         {
            $html .= '<form id="'.$this->varPrefix.'_edit_form" name="'.$this->varPrefix.'_edit_form"><table '.$this->editTableInfo.'>';
            foreach($this->tableColumns as $col => $info)
            {
               if(stristr($info['perms'],'E') && !isset($info['join']['real_column']))
               {
                  if(isset($row[$col]) && strlen($row[$col]) > 0)
                  {
                     // If it is a calendar and there is a default and no date use the default
                     if(isset($info['default']) && isset($info['calendar']) && $info['calendar'] && substr($row[$col],0,10) == '0000-00-00')
                     {
                        $defVal = $info['default'];
                     }
                     else
                     {
                        $defVal =  $row[$col];
                     }
                  }
                  else if(isset($info['default']))
                  {
                     $defVal = $info['default'];
                  }
                  else
                  {
                     $defVal = '';
                  }
                  $inputInfo = isset($info['input_info']) ? $info['input_info'] : '';
                  $inputHtml = '';
                  
                  if(isset($info['edit_fun']) && is_callable($info['edit_fun']))
                  {
                     $defVal = call_user_func($info['edit_fun'],$col,$defVal,$row);
                  }
                  if(isset($info['format_input_fun']) && is_callable($info['format_input_fun']))
                  {
                     $inputHtml .= call_user_func($info['format_input_fun'],$col,$defVal,$row,$inputInfo);
                  }
                  else if(isset($info['hidden_edit']) && $info['hidden_edit'])
                  {
                     $inputHtml .= '<input type="hidden" id="'.$this->inputIdPrefix.$col.'" value="'.htmlspecialchars($defVal).'" '.$inputInfo.' />';                  
                  }
                  else if(isset($info['select_query']))
                  {
                     $inputHtml .= $this->getSelect($info['select_query'],$this->inputIdPrefix.$col,$defVal,$inputInfo);         
                  }
                  else if(isset($info['select_array']) && is_array($info['select_array']))
                  {
                     $inputHtml .= $this->getSelectFromArray($info['select_array'],$this->inputIdPrefix.$col,$defVal,$inputInfo);               
                  }
                  else if(isset($info['textarea']))
                  {
                     $numRows = isset($info['textarea']['rows']) ? $info['textarea']['rows'] : 7;
                     $numCols = isset($info['textarea']['cols']) ? $info['textarea']['cols'] : 25;
                     $inputHtml .= '<textarea id="'.$this->inputIdPrefix.$col.'" rows="'.$numRows.'" cols="'.$numCols.'" value="'.htmlspecialchars($defVal).'" '.$inputInfo.' >'.htmlspecialchars($defVal).'</textarea>';
                  }
                  else if(isset($info['checkbox']))
                  {
                     $checkedValue = isset($info['checkbox']['checked_value']) ? $info['checkbox']['checked_value'] : '';
                     $unCheckedValue = isset($info['checkbox']['un_checked_value']) ? $info['checkbox']['un_checked_value'] : '';
                     $checked = $defVal == $checkedValue ? 'checked="checked"' : '';
                     $inputHtml .= '<input type="checkbox" id="'.$this->inputIdPrefix.$col.'" value="'.$defVal.'" onclick="updateCheckBoxValue(this,\''.$checkedValue.'\',\''.$unCheckedValue.'\');" '.$checked.' '.$inputInfo.' />';
                  }
                  else if(isset($info['join']) && is_array($info['join']))
                  {
                     $joinTable = !empty($info['join']['db']) ? $info['join']['db'].'.'.$info['join']['table'] : $info['join']['table'];
                     $info['join']['display_mask'] = isset($info['join']['display_mask']) ? $info['join']['display_mask'] : $joinTable.'.'.$info['join']['column'];
                     $selectQuery = 'select distinct('.$info['join']['column'].'), '.$info['join']['display_mask'].' from '.$joinTable.' order by '.$info['join']['display_mask'].' asc';
                     $inputHtml .= $this->getSelect($selectQuery,$this->inputIdPrefix.$col,$defVal,$inputInfo);
                  }
                  else if(isset($info['calendar']))
                  {
                     $inputHtml .= '<span><input type="hidden" id="'.$this->inputIdPrefix.$col.'" value="'.htmlspecialchars($defVal).'" /></span>';                  
                  }
                  else
                  {
                     $maxLength = isset($info['maxlen']) ? 'maxlength="'.$info['maxlen'].'"' : '';
                     $inputHtml .= '<input type="text" id="'.$this->inputIdPrefix.$col.'" value="'.htmlspecialchars($defVal).'" '.$maxLength.' onKeyPress="if(enterPressed(event)){'.$jsUpdateFun.' return false;}" '.$inputInfo.' />';
                  }
                  if(isset($info['hidden_edit']) && $info['hidden_edit'])
                  {
                     $html .= $inputHtml;
                  }
                  else
                  {   
                     if(isset($info['req']) && $info['req'])
                     {
                        $inputHtml .= $this->reqMarker;
                     }
                     if (isset($info['tooltip']) && $info['tooltip']){
                        $tt_seen = true;
                        $tt='&nbsp;&nbsp;<a href="#" tooltip="'.$info['tooltip'].'"><span style="vertical-align:middle;"><img src="images/tooltip16x16.gif" border="0"></span></a>&nbsp;&nbsp;';
                     } else {
                        $tt ='';
                     }      
                     $html .= '<tr><td id="'.$col.'_label_cell" class="labelCell"><label for="'.$this->inputIdPrefix.$col.'">'.$info['display_text'].$tt.':</label></td><td id="'.$col.'_input_cell" class="inputCell">'.$inputHtml.'</td></tr>';
                  }
                  if(isset($info['calendar']))
                  {
                     $calJs[] = $this->getCalJs($info['calendar'],$col);
                  }
               }
            }
            $html .= '</table></form><div id="editRowButtons"><button class="ajaxButton" onclick="'.$jsUpdateFun.'">'.$this->langVars->btnUpdate.'</button><button class="ajaxButton" onclick="toAjaxTableEditor(\'update_html\',\'\');">'.$this->langVars->btnCancel.'</button></div>';
         }
         $this->retArr[] = array('layer_id' => 'titleLayer', 'where' => 'innerHTML', 'value' => $this->editRowTitle);
         $this->retArr[] = array('layer_id' => 'recordLayer', 'where' => 'innerHTML', 'value' => '');      
         $this->retArr[] = array('layer_id' => 'searchButtonsLayer', 'where' => 'innerHTML', 'value' => '');      
         $this->retArr[] = array('layer_id' => 'tableLayer', 'where' => 'innerHTML', 'value' => $html);
         
         $this->retArr[] = array('where' => 'javascript', 'value' => 'createTips();');
         
         if(count($calJs) > 0)
         {
            $this->retArr[] = array('where' => 'javascript', 'value' => implode("\n",$calJs));
         }
         //$this->retArr[] = array('where' => 'javascript', 'value' => "resetScrollTop();");
         
         if(is_callable($this->editScreenFun))
         {
            call_user_func($this->editScreenFun);
         }
      }      
   }
}
?>

and the little questionmark image that should go into the image directory:
Image

That's it.
KarelB
 
Posts: 458
Joined: Mon Dec 01, 2008 11:49 pm
Location: The Netherlands

Re: Override the class and use JQuery

Postby ducc » Sun Jun 19, 2011 8:34 pm

WOW.

I was combining several projects into one super project, and it all broke.

And 36 hours later I found this:
Code: Select all
 <script type="text/javascript">  $jq = jQuery.noConflict();</script>


And now my life is good again. Thank you very much.


ducc
ducc
 
Posts: 5
Joined: Thu Mar 31, 2011 3:33 pm

Re: Override the class and use JQuery

Postby hexxamillion » Fri Dec 09, 2011 9:31 pm

This is awesome! Exactly what i needed. Two How-To's in one..can't get better than that. 8-)
hexxamillion
 
Posts: 100
Joined: Fri Jul 08, 2011 11:36 pm

Re: Override the class and use JQuery

Postby mukeshdak » Wed Feb 27, 2013 6:13 pm

Can anybody post link to online demo, so that we can see, how this looks
mukeshdak
 
Posts: 30
Joined: Fri May 11, 2012 3:18 pm

Re: Override the class and use JQuery

Postby garcianc » Sat May 04, 2013 3:49 am

I was having the toughest time getting this excellent How-To to work using the latest versions of qtip and jquery. They would just not play nice together. Aparently, as of this writing, qtip2 version 2.1 will solve the issue but I did not want to wait - plus the whole experience had me worried that the solution would be too fragile.

So I followed the example above with the exception that I am not using jquery. If anyone arrived here more interested in a tooltip solution than a jquery solution, this is what I did for a quick and dirty tooltip capability.

Everything works the same, except that you do not change anything in Common.php and you do not need the createTips() function in the script section of the displayHtml function. In other words, all you need to do is override the class.

in the TT_AjaxTableEditor.php file you need to make one minor tweak to a line from the above example.

In the line
Code: Select all
   $tt='&nbsp;&nbsp;<a href="#" tooltip="'.$info['tooltip'].'"><span style="vertical-align:middle;"><img src="images/help-icon.png" border="0"></span></a>&nbsp;&nbsp;';


Change the word "tooltip" with the word "title", like this:
Code: Select all
   $tt='&nbsp;&nbsp;<a href="#" title="'.$info['tooltip'].'"><span style="vertical-align:middle;"><img src="images/help-icon.png" border="0"></span></a>&nbsp;&nbsp;';


You also need to leave out the following line, since you will not need it:
Code: Select all
$this->retArr[] = array('where' => 'javascript', 'value' => 'createTips();');

It won't be as pretty as qtip, but it should work.
garcianc
 
Posts: 15
Joined: Sat Dec 01, 2012 8:25 pm


Return to How To

Who is online

Users browsing this forum: No registered users and 1 guest

cron