1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14: class Horde_Form_Renderer {
15:
16: var $_name;
17: var $_requiredLegend = false;
18: var $_requiredMarker = '*';
19: var $_helpMarker = '?';
20: var = true;
21: var $_cols = 2;
22: var $_varRenderer = null;
23: var $_firstField = null;
24: var $_stripedRows = true;
25:
26: 27: 28: 29: 30: 31: 32:
33: var $_encodeTitle = true;
34:
35: 36: 37: 38: 39: 40:
41: var $_attrColumnWidth = '15%';
42:
43: 44: 45: 46: 47: 48: 49: 50: 51:
52: function Horde_Form_Renderer($params = array())
53: {
54: global $registry;
55: if (isset($registry) && is_a($registry, 'Registry')) {
56:
57: $this->_requiredMarker = Horde::img('required.png', '*');
58: } else {
59:
60: $this->_requiredMarker = '*';
61: }
62:
63: if (isset($params['encode_title'])) {
64: $this->encodeTitle($params['encode_title']);
65: }
66:
67: $driver = 'html';
68: if (isset($params['varrenderer_driver'])) {
69: $driver = $params['varrenderer_driver'];
70: }
71: $this->_varRenderer = Horde_Core_Ui_VarRenderer::factory($driver, $params);
72: }
73:
74: function ($bool)
75: {
76: $this->_showHeader = $bool;
77: }
78:
79: 80: 81: 82: 83: 84: 85: 86: 87: 88:
89: function encodeTitle($encode = null)
90: {
91: if (!is_null($encode)) {
92: $this->_encodeTitle = $encode;
93: }
94: return $this->_encodeTitle = $encode;
95: }
96:
97: 98: 99:
100: function setAttrColumnWidth($width)
101: {
102: }
103:
104: function open($action, $method, $name, $enctype = null)
105: {
106: $this->_name = $name;
107: $name = htmlspecialchars($name);
108: $action = htmlspecialchars($action);
109: $method = htmlspecialchars($method);
110: echo "<form action=\"$action\" method=\"$method\"" . (empty($name) ? '' : " name=\"$name\" id=\"$name\"") . (is_null($enctype) ? '' : " enctype=\"$enctype\"") . ">\n";
111: Horde_Util::pformInput();
112: }
113:
114: function beginActive($name, $extra = null)
115: {
116: $this->_renderBeginActive($name, $extra);
117: }
118:
119: function beginInactive($name, $extra = null)
120: {
121: $this->_renderBeginInactive($name, $extra);
122: }
123:
124: function _renderSectionTabs(&$form)
125: {
126:
127: if (!$GLOBALS['browser']->hasFeature('javascript')) {
128: return;
129: }
130:
131: $open_section = $form->getOpenSection();
132:
133:
134: Horde::addScriptFile('form_sections.js', 'horde');
135: echo '<script type="text/javascript">' . "\n";
136: printf('var sections_%1$s = new Horde_Form_Sections(\'%1$s\', \'%2$s\');',
137: $form->getName(),
138: $open_section);
139: echo "\n" . '</script>';
140:
141:
142: echo "<div class=\"tabset\"><ul>\n";
143: foreach ($form->_sections as $section => $val) {
144: $class = ($section == $open_section) ? ' class="activeTab"' : '';
145: $js = sprintf('onclick="sections_%s.toggle(\'%s\'); return false;"',
146: $form->getName(),
147: $section);
148: printf('<li%s id="%s"><a href="#" %s>%s%s</a> </li>' . "\n",
149: $class, htmlspecialchars($form->getName() . '_tab_' . $section), $js,
150: $form->getSectionImage($section),
151: $form->getSectionDesc($section));
152: }
153: echo "</ul></div><br class=\"clear\" />\n";
154: }
155:
156: function _renderSectionBegin(&$form, $section)
157: {
158:
159: if ($this->_stripedRows && class_exists('Horde')) {
160: Horde::addScriptFile('stripe.js', 'horde');
161: $class = ' class="striped"';
162: } else {
163: $class = '';
164: }
165:
166: $open_section = $form->getOpenSection();
167: if (is_null($open_section)) {
168: $open_section = '__base';
169: }
170: printf('<div id="%s" style="display:%s;"><table%s cellspacing="0">',
171: htmlspecialchars($form->getName() . '_section_' . $section),
172: ($open_section == $section ? 'block' : 'none'),
173: $class);
174: }
175:
176: function _renderSectionEnd()
177: {
178: echo '</table></div>';
179: }
180:
181: function end()
182: {
183: $this->_renderEnd();
184: }
185:
186: function close($focus = true)
187: {
188: echo "</form>\n";
189: if ($focus && !empty($this->_firstField)) {
190: echo '<script type="text/javascript">
191: <!--
192: try {
193: document.getElementById("' . $this->_firstField . '").focus();
194: } catch(e) {}
195: //-->
196: </script>
197: ';
198: }
199: }
200:
201: function listFormVars(&$form)
202: {
203: $variables = &$form->getVariables(true, true);
204: $vars = array();
205: if ($variables) {
206: foreach ($variables as $var) {
207: if (is_object($var)) {
208: if (!$var->isReadonly()) {
209: $vars[$var->getVarName()] = 1;
210: }
211: } else {
212: $vars[$var] = 1;
213: }
214: }
215: }
216: echo '<input type="hidden" name="_formvars" value="' . htmlspecialchars(serialize($vars)) . '" />';
217: }
218:
219: function renderFormActive(&$form, &$vars)
220: {
221: $this->_renderForm($form, $vars, true);
222: }
223:
224: function renderFormInactive(&$form, &$vars)
225: {
226: $this->_renderForm($form, $vars, false);
227: }
228:
229: function _renderForm(&$form, &$vars, $active)
230: {
231:
232: $this->_cols = $form->hasHelp() ? 3 : 2;
233:
234: $variables = &$form->getVariables(false);
235:
236:
237: if (($tokenError = $form->getError('_formToken')) !== null) {
238: echo '<p class="form-error">' . htmlspecialchars($tokenError) . '</p>';
239: }
240:
241:
242: if (($secretError = $form->getError('_formSecret')) !== null) {
243: echo '<p class="form-error">' . htmlspecialchars($secretError) . '</p>';
244: }
245:
246: if (count($form->_sections)) {
247: $this->_renderSectionTabs($form);
248: }
249:
250: $error_section = null;
251: foreach ($variables as $section_id => $section) {
252: $this->_renderSectionBegin($form, $section_id);
253: foreach ($section as $var) {
254: $type = $var->getTypeName();
255:
256: switch ($type) {
257: case 'header':
258: $this->_renderHeader($var->getHumanName(), $form->getError($var->getVarName()));
259: break;
260:
261: case 'description':
262: $this->_renderDescription($var->getHumanName());
263: break;
264:
265: case 'spacer':
266: $this->_renderSpacer();
267: break;
268:
269: default:
270: $isInput = ($active && !$var->isReadonly());
271: $format = $isInput ? 'Input' : 'Display';
272: $begin = "_renderVar${format}Begin";
273: $end = "_renderVar${format}End";
274:
275: $this->$begin($form, $var, $vars);
276: echo $this->_varRenderer->render($form, $var, $vars, $isInput);
277:
278:
279: if ($var->hasAction()) {
280: $var->_action->printJavaScript();
281: }
282:
283: $this->$end($form, $var, $vars);
284:
285:
286: if ($active && empty($this->_firstField) && !$var->isReadonly() && !$var->isHidden()) {
287: $this->_firstField = $var->getVarName();
288: }
289:
290:
291: if (is_null($error_section) && $form->getError($var)) {
292: $error_section = $section_id;
293: }
294: }
295: }
296:
297: $this->_renderSectionEnd();
298: }
299:
300: if (!is_null($error_section) && $form->_sections) {
301: echo '<script type="text/javascript">' .
302: "\n" . sprintf('sections_%s.toggle(\'%s\');',
303: $form->getName(),
304: $error_section) .
305: "\n</script>";
306: }
307: }
308:
309: function submit($submit = null, $reset = false)
310: {
311: if (is_null($submit) || empty($submit)) {
312: $submit = Horde_Form_Translation::t("Submit");
313: }
314: if ($reset === true) {
315: $reset = Horde_Form_Translation::t("Reset");
316: }
317: $this->_renderSubmit($submit, $reset);
318: }
319:
320: 321: 322:
323: function _renderBeginActive($name, $extra)
324: {
325: echo '<div class="form" id="' . htmlspecialchars($this->_name) . '_active">';
326: if ($this->_showHeader) {
327: $this->_sectionHeader($name, $extra);
328: }
329: if ($this->_requiredLegend) {
330: echo '<span class="form-error">' . $this->_requiredMarker . '</span> = ' . Horde_Form_Translation::t("Required Field");
331: }
332: }
333:
334: 335: 336:
337: function _renderBeginInactive($name, $extra)
338: {
339: echo '<div class="form" id="' . htmlspecialchars($this->_name) . '_inactive">';
340: if ($this->_showHeader) {
341: $this->_sectionHeader($name, $extra);
342: }
343: }
344:
345: 346: 347:
348: function _renderEnd()
349: {
350: echo '</div>' . $this->_varRenderer->renderEnd();
351: }
352:
353: function ($header, $error = '')
354: {
355: ?><tr><td class="control" width="100%" colspan="<?php echo $this->_cols ?>" valign="bottom"><strong><?php echo $header ?></strong><?php
356: if (!empty($error)) {
357: ?><br /><span class="form-error"><?php echo $error ?></span><?php
358: }
359: ?></td></tr>
360: <?php
361: }
362:
363: function _renderDescription($text)
364: {
365: ?><tr><td width="100%" colspan="<?php echo $this->_cols ?>"><p style="padding:8px"><?php echo $text ?></p></td></tr>
366: <?php
367: }
368:
369: function _renderSpacer()
370: {
371: ?><tr><td colspan="<?php echo $this->_cols ?>"> </td></tr>
372: <?php
373: }
374:
375: function _renderSubmit($submit, $reset)
376: {
377: ?><div class="control">
378: <?php if (!is_array($submit)) $submit = array($submit); foreach ($submit as $submitbutton): ?>
379: <input class="button" name="submitbutton" type="submit" value="<?php echo $submitbutton ?>" />
380: <?php endforeach; ?>
381: <?php if (!empty($reset)): ?>
382: <input class="button" name="resetbutton" type="reset" value="<?php echo $reset ?>" />
383: <?php endif; ?>
384: </div>
385: <?php
386: }
387:
388:
389: function _renderVarInputBegin(&$form, &$var, &$vars)
390: {
391: $message = $form->getError($var);
392: $isvalid = empty($message);
393: echo "<tr valign=\"top\">\n";
394: printf(' <td%s align="right">%s%s%s%s</td>' . "\n",
395: empty($this->_attrColumnWidth) ? '' : ' width="' . $this->_attrColumnWidth . '"',
396: $isvalid ? '' : '<span class="form-error">',
397: $var->isRequired() ? '<span class="form-error">' . $this->_requiredMarker . '</span> ' : '',
398: $var->getHumanName(),
399: $isvalid ? '' : '<br />' . $message . '</span>');
400: printf(' <td%s%s>',
401: ((!$var->hasHelp() && $form->hasHelp()) ? ' colspan="2"' : ''),
402: ($var->isDisabled() ? ' class="form-disabled"' : ''));
403: }
404:
405: function _renderVarInputEnd(&$form, &$var, &$vars)
406: {
407:
408: if ($var->hasDescription()) {
409: echo '<br />' . $var->getDescription();
410: }
411:
412:
413: if ($var->hasHelp()) {
414: global $registry;
415: if (isset($registry) && $registry instanceof Horde_Registry) {
416: $link = Horde_Help::link($GLOBALS['registry']->getApp(), $var->getHelp());
417: } else {
418: $link = '<a href="#" onclick="alert(\'' . addslashes(@htmlspecialchars($var->getHelp())) . '\');return false;">' . $this->_helpMarker . '</a>';
419: }
420: echo "</td>\n <td style=\"text-align:right\">$link ";
421: }
422:
423: echo "</td>\n</tr>\n";
424: }
425:
426:
427: function _renderVarDisplayBegin(&$form, &$var, &$vars)
428: {
429: $message = $form->getError($var);
430: $isvalid = empty($message);
431: echo "<tr valign=\"top\">\n";
432: printf(' <td%s align="right">%s<strong>%s</strong>%s</td>' . "\n",
433: empty($this->_attrColumnWidth) ? '' : ' width="' . $this->_attrColumnWidth . '"',
434: $isvalid ? '' : '<span class="form-error">',
435: $var->getHumanName(),
436: $isvalid ? '' : '<br />' . $message . '</span>');
437: echo ' <td>';
438: }
439:
440: function _renderVarDisplayEnd(&$form, &$var, &$vars)
441: {
442: if ($var->hasHelp()) {
443: echo '</td><td> ';
444: }
445: echo "</td>\n</tr>\n";
446: }
447:
448: function ($title, $extra = '')
449: {
450: if (strlen($title)) {
451: echo '<div class="header">';
452: if (!empty($extra)) {
453: echo '<span class="rightFloat">' . $extra . '</span>';
454: }
455: echo $this->_encodeTitle ? htmlspecialchars($title) : $title;
456: echo '</div>';
457: }
458: }
459:
460: 461: 462: 463: 464: 465: 466: 467: 468: 469: 470: 471: 472: 473: 474:
475: function factory($renderer = '', $params = null)
476: {
477: if (is_array($renderer)) {
478: $app = $renderer[0];
479: $renderer = $renderer[1];
480: }
481:
482: 483:
484: $renderer = basename($renderer);
485: if (!empty($renderer) && $renderer != 'none') {
486: $class = 'Horde_Form_Renderer_' . $renderer;
487: } else {
488: $class = 'Horde_Form_Renderer';
489: }
490:
491: if (!class_exists($class)) {
492: if (!empty($app)) {
493: include $GLOBALS['registry']->get('fileroot', $app) . '/lib/Form/Renderer/' . $renderer . '.php';
494: } else {
495: include 'Horde/Form/Renderer/' . $renderer . '.php';
496: }
497: }
498:
499: if (class_exists($class)) {
500: return new $class($params);
501: } else {
502: return PEAR::raiseError('Class definition of ' . $class . ' not found.');
503: }
504: }
505:
506: 507: 508: 509: 510: 511: 512: 513: 514: 515: 516: 517: 518: 519: 520: 521: 522: 523: 524: 525: 526:
527: function &singleton($renderer, $params = null)
528: {
529: static $instances = array();
530:
531: $signature = serialize(array($renderer, $params));
532: if (!isset($instances[$signature])) {
533: $instances[$signature] = Horde_Form_Renderer::factory($renderer, $params);
534: }
535:
536: return $instances[$signature];
537: }
538:
539: }
540: