Framework  3.9
tab_bar.inc
Go to the documentation of this file.
1 <?php
2 /**************************************************************
3 
4  Copyright (c) 2007-2010 Sonjara, Inc
5 
6  Permission is hereby granted, free of charge, to any person
7  obtaining a copy of this software and associated documentation
8  files (the "Software"), to deal in the Software without
9  restriction, including without limitation the rights to use,
10  copy, modify, merge, publish, distribute, sublicense, and/or sell
11  copies of the Software, and to permit persons to whom the
12  Software is furnished to do so, subject to the following
13  conditions:
14 
15  The above copyright notice and this permission notice shall be
16  included in all copies or substantial portions of the Software.
17 
18  Except as contained in this notice, the name(s) of the above
19  copyright holders shall not be used in advertising or otherwise
20  to promote the sale, use or other dealings in this Software
21  without prior written authorization.
22 
23  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
25  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
28  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30  OTHER DEALINGS IN THE SOFTWARE.
31 
32 *****************************************************************/
33 
34 
39 class TabBar
40 {
41  var $id;
42  var $tabs = array();
43  var $queryString = null;
44  var $useQueryString = true;
45  var $page = "";
47  var $states = array();
48  var $flags = array();
49  var $anchor = "";
50  var $cssClass = "";
52  var $showStates = true;
53 
54  var $dynamic = false;
55  var $container = "";
56  var $dynamicLoadHandler = null;
57  var $dynamicLoadFirstTab = true;
58 
59  var $disabled = false;
60 
71  function TabBar($id, $tabs, $queryString = "", $useQueryString = true, $showNumber = false)
72  {
73  global $config;
74  global $isAdmin;
75 
76  $this->id = $id;
77  $this->tabs = $tabs;
78  $this->page = ($config['prettyURLs'] === false) ? basename($_SERVER["PHP_SELF"]) : $_REQUEST['identifier'];
79  if ($isAdmin) $this->page = "/admin/{$this->page}";
80  $this->queryString = $queryString;
81  $this->useQueryString = $useQueryString;
82  $this->showNumber = $showNumber;
83  trace("PAGE: **** {$this->page}", 4);
84  }
85 
90  {
91  $qs = getCleanQueryString();
92  if ($qs)
93  {
94  $this->queryString = $qs;
95  $this->useQueryString = true;
96  }
97  else
98  {
99  $this->queryString = null;
100  $this->useQueryString = false;
101  }
102  }
103 
105  {
106  $this->container = $container;
107  $this->dynamic = true;
108  }
109 
110  function writeScript()
111  {
112  $script = "";
113  if (!$this->dynamic) return $script;
114 
115  $script .= <<<ENDSCRIPT
116  <script type="text/javascript">
117  window.addEvent('domready', function()
118  {
119  document.id('{$this->id}').getElements("a").each(function(a)
120  {
121  a.loadTab = function(override)
122 ENDSCRIPT;
123  if ($this->dynamicLoadHandler)
124  {
125  $script .= <<<ENDSCRIPT
126  {
127  var url = override ? override : this.href;
128  {$this->dynamicLoadHandler}(url);
129  };
130 ENDSCRIPT;
131  }
132  else
133  {
134  $script .= <<<ENDSCRIPT
135  {
136  var request = new Request.HTML(
137  {
138  evalScripts: false,
139  evalResponse: false,
140  method: 'get',
141  url: override ? override : this.href,
142  onSuccess: function(tree, elements, html, script)
143  {
144  var container = document.id('{$this->container}');
145  container.set('text', '');
146  container.adopt(tree);
147 
148  Browser.exec(script);
149 
150  }.bind(this)
151  });
152 
153  request.send();
154  };
155 ENDSCRIPT;
156  }
157 
158  $script .= <<<ENDSCRIPT
159 
160  a.addEvent('click', function(e)
161  {
162  new DOMEvent(e).stop();
163  var url = a.href;
164  var parent = a.getParent();
165  document.id('{$this->id}').getElements("li").each(function(l) { l.removeClass("current"); });
166  parent.addClass('current');
167 
168  a.loadTab();
169  });
170  });
171 ENDSCRIPT;
172 
173  if ($this->dynamicLoadFirstTab)
174  {
175  $script .= <<<ENDSCRIPT
176  document.id('{$this->id}').getElements("li.current a").each(function(a)
177  {
178  a.loadTab();
179  });
180 ENDSCRIPT;
181  }
182 
183  $script .= <<<ENDSCRIPT
184  });
185  </script>
186 ENDSCRIPT;
187  return $script;
188  }
192  function writeHTML()
193  {
194  foreach($this->tabs as $text => $entry)
195  {
196  if (is_object($entry) && get_class($entry) == "TabBar")
197  {
198  $entry->page = $this->page;
199  $entry->queryString = $this->queryString;
200  }
201  }
202 
203  $first = true;
204  $future = false;
205 
206  if ($this->anchor) echo "<a name='<?echo $this->anchor?>'></a>";
207 
208  echo "<div id='{$this->id}'";
209 
210  if ($this->cssClass) echo " class='{$this->cssClass}'";
211 
212  echo "><ul>";
213 
214  foreach ($this->tabs as $text => $entry)
215  {
216  ++$count;
217  $active = "";
218  $style = "";
219 
220  //AJG - make it easier to have conditional tabs.
221  if ($entry === null) continue;
222 
223  if (is_string($entry))
224  {
225  $url = $entry;
226  }
227  else if (is_object($entry) && get_class($entry) == "TabBar")
228  {
229  if ($entry->findPage($this->page))
230  {
231  $url = $this->page;
232  }
233  else
234  {
235  $url = $entry->getPage(0, false);
236  }
237  }
238 
239  if (!$first)
240  {
241  echo $this->spacer;
242  }
243  else
244  {
245  $first = false;
246  }
247 
248  $isMatch = $this->comparePaths($url, $this->page);
249  // JDG 12/01/09, get the basename of the url, in case we need a
250  // longer path in the tab include file, as with digital movies
251  if ($isMatch)
252  {
253  $style = " class='current'";
254  }
255 
256  if (($this->disabled || ($this->queryString == "" && $this->useQueryString)) && $count > 1)
257  {
258  $active = " class='disabled'";
259  }
260 
261  if ($this->showNumber) $text = "$count.&nbsp;$text";
262 
263  if ($this->useQueryString)
264  {
265  $dest = ($this->queryString!="") ? $this->appendQueryString($url, $this->queryString) :"#";
266  }
267  else
268  {
269  $dest = ($isMatch && !$this->dynamic) ? "#" : $url;
270  }
271 
272  if ($this->anchor)
273  {
274  $dest = ($dest != "#") ? "$dest#{$this->anchor}" : "#{$this->anchor}";
275  }
276 
277  if ($this->showStates)
278  {
279  if (array_key_exists($url, $this->flags))
280  {
281  $text = "<img src='{$this->states[$this->flags[$url]]}' style='border: none; display: inline-block;vertical-align: middle'/>&nbsp;$text";
282  }
283  else if ($this->defaultStateImage)
284  {
285  $text = "<img src='{$this->defaultStateImage}' style='border: none; display: inline-block;vertical-align: middle'/>&nbsp;$text";
286  }
287  }
288  echo "<li$style><a href=\"$dest\"$active>$text</a></li>";
289  }
290 
291  echo "</ul></div>\n";
292 
293  foreach($this->tabs as $text => $entry)
294  {
295  if (is_object($entry) && get_class($entry) == "TabBar" &&
296  $entry->findPage($this->page))
297  {
298  $entry->useQueryString = $this->useQueryString;
299  $entry->writeHTML();
300  }
301  }
302  }
303 
311  function appendQueryString($url, $qs)
312  {
313  if ($url[0] == "&")
314  {
315  $url = $qs.$url;
316  }
317  else
318  {
319  $url .= (strstr($url, "?") !== false) ? "&$qs" : "?$qs";
320  }
321  return $url;
322  }
323 
329  function getNextPage()
330  {
331  $found = false;
332 
333  foreach($this->tabs as $text => $url)
334  {
335  trace("getNextPage::text is $text and url is $url; this page is {$this->page}", 3);
336  if ($found)
337  {
338  $dest = ($this->queryString!="") ? $this->appendQueryString($url, $this->queryString) : $url;
339  trace("getNextPage::found; dest is$dest", 3);
340  return $dest;
341  }
342  else if ($this->comparePaths($url, $this->page))
343  {
344  $found = true;
345  trace("getNextPage::url is this page", 3);
346  }
347  }
348 
349  return ($found) ? "" : false;
350  }
351 
357  function getPage($idx, $appendQueryString = true)
358  {
359  $i = 0;
360 
361  foreach($this->tabs as $text => $entry)
362  {
363  if (is_object($entry) && get_class($entry) == "TabBar")
364  {
365  $num = count($entry->tabs);
366 
367  if ($num >= $idx - $i)
368  {
369  $entry->queryString = $this->queryString;
370  return $entry->getPage($idx - $i);
371  }
372  else
373  {
374  $i += $num;
375  continue;
376  }
377  }
378  else
379  {
380  $url = $entry;
381  }
382 
383  if ($i == $idx) break;
384  $i++;
385  }
386 
387  $dest = ($appendQueryString && $this->queryString!="") ? $this->appendQueryString($url, $this->queryString) : $url;
388  return $dest;
389  }
390 
391  private function comparePaths($url, $page)
392  {
393  trace("COMPARE PATHS: $url, $page", 2);
394 
395  if (strpos($url, "/") === false)
396  {
397  trace("COMPARING PATHS: $url, ".basename($page)." == " . (basename($page) == $url), 2);
398  return basename($page) == $url;
399  }
400  else
401  {
402  return $page == $url;
403  }
404  }
405 
411  function findPage($page)
412  {
413  foreach($this->tabs as $text => $url)
414  {
415  if ($this->comparePaths($url, $page))
416  {
417  return $text;
418  }
419  }
420 
421  return false;
422  }
423 
428  function next()
429  {
430  $next = $this->getNextPage();
431  if (!$next)
432  {
433  $next = $this->getPage(0);
434  }
435 
436  /*
437  * JDG 6/15/2010, insert "/" before identifier but not if
438  * the page is *.php
439  */
440  //if(!preg_match("/.php/i", $next))
441  // $next = "/". $next;
442  trace("tabbar::next:: next is $next",3);
443  redirect($next);
444  }
445 
446  function drawCheckList()
447  {
448  ?>
449  <table class="checklist">
450  <?
451  foreach($this->tabs as $title => $form)
452  {
453  $this->drawCheckListEntry($title, $form);
454  }
455  ?>
456  </table>
457  <?
458  }
459 
460  function drawCheckListEntry($title, $form)
461  {
462  if (get_class($form) == "TabBar")
463  {
464 ?>
465  <tr>
466  <td colspan="2" class="title"><b><?echo $title?></b></td>
467  </tr>
468 <?
469  foreach($form->tabs as $t => $f)
470  {
471  $this->drawCheckListEntry($t, $f);
472  }
473  }
474  else
475  {
476  $status = $this->flags[$form];
477 
478  if ($status && $this->states[$status])
479  {
480  $img = "<img src='{$this->states[$status]}' alt='$status'/>";
481  }
482  else if ($this->defaultStateImage)
483  {
484  $img = "<img src='{$this->defaultStateImage}' alt=''/>";
485  }
486  ?>
487  <tr>
488  <td class="status"><?echo $img ?></td>
489  <td class="link"><a href="<?echo $form ?>?<?echo $this->queryString?>"><?echo $title ?></a></td>
490  </tr>
491  <?
492 
493  }
494  }
495 
496  function setDefaultStateImage($img)
497  {
498  foreach($this->tabs as $text => $entry)
499  {
500  if (is_object($entry) && get_class($entry) == "TabBar")
501  {
502  $entry->defaultStateImage = $img;
503  }
504  }
505 
506  $this->defaultStateImage = $img;
507  }
508 
509 
510 }
511 
512 
513 
547 class TwoLevelTabBar extends TabBar
548 {
549  function TwoLevelTabBar($tabs, $qs)
550  {
551  foreach($tabs as $text => $entry)
552  {
553  if (is_array($entry))
554  {
555  $tabs[$text] = new TabBar("subtabs", $entry, $qs);
556  }
557  }
558 
559  $this->TabBar("tabs", $tabs, $qs);
560  $this->showStates = false;
561  }
562 
563  function setFlags($flags)
564  {
565  foreach($this->tabs as $text => $entry)
566  {
567  if (get_class($entry) == "TabBar")
568  {
569  $entry->flags = $flags;
570  }
571  }
572 
573  $this->flags = $flags;
574  }
575 
576  function setStates($states)
577  {
578  foreach($this->tabs as $text => $entry)
579  {
580  if (get_class($entry) == "TabBar")
581  {
582  $entry->states = $states;
583  }
584  }
585 
586  $this->states = $states;
587  }
588 
589 
590  function getNextPage()
591  {
592  $jump = false;
593 
594  foreach($this->tabs as $text => $entry)
595  {
596  if (get_class($entry) == "TabBar")
597  {
598  $entry->queryString = $this->queryString;
599 
600  if ($jump) return $entry->getPage(0);
601 
602  $next = $entry->getNextPage();
603 
604  if ($next === false) continue;
605  if ($next === "")
606  {
607  $jump = true;
608  continue;
609  }
610 
611  return $next;
612  }
613  }
614 
615  }
616 
622  function findPage($page)
623  {
624  // remove query string if given;
625  $page = preg_replace('/\?.*/', '', $page);
626 
627  foreach($this->tabs as $text => $entry)
628  {
629  if (get_class($entry) == "TabBar")
630  {
631  $found = $entry->findPage($page);
632  if($found)
633  {
634  return $found;
635  }
636  }
637  }
638 
639  return false;
640  }
641 
642 
644  {
645 ?>
646  <table class="checklist">
647  <tr>
648 <?
649  foreach($this->tabs as $title => $steps)
650  {
651 ?>
652  <td colspan="2" class="title"><b><?echo $title?></b></td>
653 <?
654  }
655 ?>
656  </tr>
657 <?
658  $idx = 0;
659 
660  do
661  {
662  $found = false;
663  $row = "";
664 
665  foreach($this->tabs as $title => $tabBar)
666  {
667  $steps = $tabBar->tabs;
668  $keys = array_keys($steps);
669  $title = $keys[$idx];
670  if (isset($steps[$title]))
671  {
672  $form = $steps[$title];
673  $found = true;
674  $status = $tabBar->flags[$form];
675 
676  if ($status && $this->states[$status])
677  {
678  $img = "<img src='{$this->states[$status]}' alt='$status'/>";
679  }
680  else if ($this->defaultStateImage)
681  {
682  $img = "<img src='{$this->defaultStateImage}' alt=''/>";
683  }
684 
685  $row .= "<td class=\"status\">$img</td>";
686  $row .= "<td class=\"link\"><a href=\"$form?{$this->queryString}\">$title</a></td>";
687  }
688  else
689  {
690  $row .= "<td class=\"status\"></td>";
691  $row .= "<td class=\"link\"></td>";
692 
693  }
694  }
695 
696  if ($found)
697  {
698 ?>
699  <tr>
700  <?echo $row?>
701  </tr>
702 <?
703  }
704 
705  $idx++;
706  }
707  while($found);
708 ?>
709  </table>
710 <?
711  }
712 
713  function setColor($color)
714  {
715  foreach($this->tabs as $text => $entry)
716  {
717  if (get_class($entry) == "TabBar")
718  {
719  $entry->cssClass = "{$color}_subtabs";
720  }
721  }
722 
723  $this->cssClass = "{$color}_tabs";
724  }
725 }
726 
727 
728 ?>
The TabBar class is a user-interface control that manages a line of tabs for multi-page dialogs.
Definition: tab_bar.inc:40
$showNumber
True to display the step number, false if not.
Definition: tab_bar.inc:46
drawCheckListEntry($title, $form)
Definition: tab_bar.inc:460
$queryString
The query string parameters to append to the navigation links.
Definition: tab_bar.inc:43
$dynamicLoadHandler
Javascript function to call to handle dynamic content load (optional)
Definition: tab_bar.inc:56
writeScript()
Definition: tab_bar.inc:110
dynamicLoad($container)
Definition: tab_bar.inc:104
$disabled
Set to true to generate disabled tab navigation.
Definition: tab_bar.inc:59
$flags
Array of flags to apply, indexed by tab.
Definition: tab_bar.inc:48
$useQueryString
Whether a query string is being used as the navigation key.
Definition: tab_bar.inc:44
appendQueryString($url, $qs)
Appends a query string to the supplied URL.
Definition: tab_bar.inc:311
findPage($page)
Finds the tab containing the specified URL.
Definition: tab_bar.inc:411
writeHTML()
Writes the HTML for this control to standard output.
Definition: tab_bar.inc:192
getPage($idx, $appendQueryString=true)
Return the URL for the page at the specified tab index.
Definition: tab_bar.inc:357
next()
Move to the next page in the tab list.
Definition: tab_bar.inc:428
setDefaultStateImage($img)
Definition: tab_bar.inc:496
$tabs
The tab records in this tab bar.
Definition: tab_bar.inc:42
drawCheckList()
Definition: tab_bar.inc:446
$dynamicLoadFirstTab
By default, dynamically loaded tab bars will do a request for the content of the first tab on page lo...
Definition: tab_bar.inc:57
$page
The current page (for display purposes). This can be set explicitly to force the correct tab display ...
Definition: tab_bar.inc:45
$states
Array of display states to apply, indexed by tab.
Definition: tab_bar.inc:47
$cssClass
CSS class to apply to the top level container for the tabs.
Definition: tab_bar.inc:50
preserveQueryString()
Preserve the current query string in tab links.
Definition: tab_bar.inc:89
$id
The DOM ID of the TabBar container element.
Definition: tab_bar.inc:41
$container
The DOM ID of the container that will contain dynamically loaded content.
Definition: tab_bar.inc:55
$defaultStateImage
Image to show in the default tab state.
Definition: tab_bar.inc:51
$dynamic
true to indicate dynamic (AJAX-based) loading
Definition: tab_bar.inc:54
TabBar($id, $tabs, $queryString="", $useQueryString=true, $showNumber=false)
Construct a new TabBar control.
Definition: tab_bar.inc:71
getNextPage()
Get the next page in the tab list after the current page.
Definition: tab_bar.inc:329
$anchor
Anchor name to generate (leave empty for no anchor tag)
Definition: tab_bar.inc:49
$showStates
true to show tab states, false to ignore them
Definition: tab_bar.inc:52
The TabBar class is a user-interface control that manages 2 lines of tabs for multi-page dialogs.
Definition: tab_bar.inc:548
drawHorizontalCheckList()
Definition: tab_bar.inc:643
setFlags($flags)
Definition: tab_bar.inc:563
TwoLevelTabBar($tabs, $qs)
Definition: tab_bar.inc:549
findPage($page)
Finds the tab containing the specified URL.
Definition: tab_bar.inc:622
setStates($states)
Definition: tab_bar.inc:576
getNextPage()
Get the next page in the tab list after the current page.
Definition: tab_bar.inc:590
setColor($color)
Definition: tab_bar.inc:713
trace($msg, $lvl=3, $callStack=null)
Send output to the trace log.
Definition: functions.inc:1010
getCleanQueryString()
Returns the query string for the current page, cleaned of any Fakoli-related navigation parameters.
Definition: functions.inc:986
redirect($page)
Simplified redirect.
Definition: functions.inc:930