All Data Structures Functions Variables Pages
ZurmoHtml.php
1 <?php
2  /*********************************************************************************
3  * Zurmo is a customer relationship management program developed by
4  * Zurmo, Inc. Copyright (C) 2017 Zurmo Inc.
5  *
6  * Zurmo is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  *
13  * Zurmo is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  *
23  * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive
24  * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.
25  *
26  * The interactive user interfaces in original and modified versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  *
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the Zurmo
32  * logo and Zurmo copyright notice. If the display of the logo is not reasonably
33  * feasible for technical reasons, the Appropriate Legal Notices must display the words
34  * "Copyright Zurmo Inc. 2017. All rights reserved".
35  ********************************************************************************/
36 
40  class ZurmoHtml extends CHtml
41  {
47  public static function encode($text)
48  {
49  return htmlspecialchars($text, ENT_QUOTES, Yii::app()->charset, false);
50  }
51 
57  public static function errorSummary($model, $header = null, $footer = null, $htmlOptions = array())
58  {
59  $content = '';
60  if (!is_array($model))
61  {
62  $model = array($model);
63  }
64  if (isset($htmlOptions['firstError']))
65  {
66  $firstError = $htmlOptions['firstError'];
67  unset($htmlOptions['firstError']);
68  }
69  else
70  {
71  $firstError = false;
72  }
73  foreach ($model as $m)
74  {
75  foreach ($m->getErrors() as $errors)
76  {
77  foreach ($errors as $errorOrRelatedError)
78  {
79  if (is_array($errorOrRelatedError))
80  {
81  foreach ($errorOrRelatedError as $relatedError)
82  {
83  if ($relatedError != '' && !is_array($relatedError))
84  {
85  $content .= "<li>$relatedError</li>\n";
86  }
87  elseif ($relatedError != '' && is_array($relatedError))
88  {
89  //For now do nothing, as this is too nested to matter.
90  //This can be refactored if needed
91  }
92  }
93  }
94  elseif ($errorOrRelatedError != '')
95  {
96  $content .= "<li>$errorOrRelatedError</li>\n";
97  }
98  if ($firstError)
99  {
100  break;
101  }
102  }
103  }
104  }
105  if ($content !== '')
106  {
107  if ($header === null)
108  {
109  $header = '<p>' . Zurmo::t('yii', 'Please fix the following input errors:') . '</p>';
110  }
111  if (!isset($htmlOptions['class']))
112  {
113  $htmlOptions['class'] = parent::$errorSummaryCss;
114  }
115  return parent::tag('div', $htmlOptions, $header."\n<ul>\n$content</ul>" . $footer);
116  }
117  else
118  {
119  return '';
120  }
121  }
122 
126  public static function activeRadioButtonList($model, $attribute, $data, $htmlOptions = array(),
127  $dataSelectOptions = array(), $dataHtmlOptions = array())
128  {
129  self::resolveNameID($model, $attribute, $htmlOptions);
130  $selection = self::resolveValue($model, $attribute);
131  if ($model->hasErrors($attribute))
132  {
133  self::addErrorCss($htmlOptions);
134  }
135  $name = $htmlOptions['name'];
136  unset($htmlOptions['name']);
137  if (array_key_exists('uncheckValue', $htmlOptions))
138  {
139  $uncheck = $htmlOptions['uncheckValue'];
140  unset($htmlOptions['uncheckValue']);
141  }
142  else
143  {
144  $uncheck = '';
145  }
146 
147  if (isset($htmlOptions['id']))
148  {
149  if (isset($htmlOptions['ignoreIdPrefix']) && $htmlOptions['ignoreIdPrefix'])
150  {
151  $hiddenOptions = array('id' => $htmlOptions['id']);
152  }
153  else
154  {
155  $hiddenOptions = array('id' => self::ID_PREFIX . $htmlOptions['id']);
156  }
157  }
158  else
159  {
160  $hiddenOptions = array('id' => false);
161  }
162  $hidden = $uncheck !== null ? self::hiddenField($name, $uncheck, $hiddenOptions) : '';
163  return $hidden . self::radioButtonList($name, $selection, $data, $htmlOptions, $dataSelectOptions, $dataHtmlOptions);
164  }
165 
170  public static function radioButtonList($name, $select, $data, $htmlOptions = array(),
171  $dataSelectOptions = array(), $dataHtmlOptions = array())
172  {
173  $template = isset($htmlOptions['template'])?$htmlOptions['template']:'{input} {label}';
174  $separator = isset($htmlOptions['separator'])?$htmlOptions['separator']:"<br/>\n";
175  unset($htmlOptions['template'], $htmlOptions['separator']);
176 
177  $labelOptions = isset($htmlOptions['labelOptions'])?$htmlOptions['labelOptions']:array();
178  unset($htmlOptions['labelOptions']);
179 
180  $items = array();
181  $baseID = self::getIdByName($name);
182  if (isset($htmlOptions['dataInputPrefix']))
183  {
184  $baseID = $htmlOptions['dataInputPrefix'] . $baseID;
185  unset($htmlOptions['dataInputPrefix']);
186  }
187  $id = 0;
188  foreach ($data as $value => $label)
189  {
190  $checked = !strcmp($value, $select);
191  $htmlOptions['value'] = $value;
192  $htmlOptions['id'] = $baseID . '_' . $id++;
193  if (isset($dataHtmlOptions[$value]) && isset($dataHtmlOptions[$value]['disabled']))
194  {
195  $htmlOptions['disabled'] = $dataHtmlOptions[$value]['disabled'];
196  }
197  $option = self::radioButton($name, $checked, $htmlOptions);
198  $label = self::label($label, $htmlOptions['id'], $labelOptions);
199  $selectOption = "";
200  if (isset($dataSelectOptions[$value]))
201  {
202  $selectOption = str_replace("{bindId}", $htmlOptions['id'], $dataSelectOptions[$value]);
203  }
204  if (isset($dataHtmlOptions[$value]) && isset($dataHtmlOptions[$value]['class']))
205  {
206  $class = $dataHtmlOptions[$value]['class'];
207  }
208  else
209  {
210  $class = null;
211  }
212  $items[] = strtr($template, array('{input}' => $option,
213  '{label}' => $label . $selectOption,
214  '{value}' => $value,
215  '{class}' => $class));
216  }
217  return implode($separator, $items);
218  }
219 
220  public static function activeCheckBox($model, $attribute, $htmlOptions = array())
221  {
222  self::resolveNameID($model, $attribute, $htmlOptions);
223  if (isset($htmlOptions['disabled']))
224  {
225  $disabledClass = ' disabled';
226  }
227  else
228  {
229  $disabledClass = '';
230  }
231  if (!isset($htmlOptions['value']))
232  {
233  $htmlOptions['value'] = 1;
234  }
235  if (!isset($htmlOptions['checked']) && self::resolveValue($model, $attribute) == $htmlOptions['value'])
236  {
237  $htmlOptions['checked'] = 'checked';
238  }
239  self::clientChange('click', $htmlOptions);
240  if (array_key_exists('uncheckValue', $htmlOptions))
241  {
242  $uncheck = $htmlOptions['uncheckValue'];
243  unset($htmlOptions['uncheckValue']);
244  }
245  else
246  {
247  $uncheck = '0';
248  }
249  if ($model->{$attribute} == 1)
250  {
251  $labelClass = ' c_on';
252  }
253  else
254  {
255  $labelClass = null;
256  }
257  $hiddenOptions = isset($htmlOptions['id']) ? array('id' => self::ID_PREFIX . $htmlOptions['id']) : array('id' => false);
258  $hidden = $uncheck !== null ? self::hiddenField($htmlOptions['name'], $uncheck, $hiddenOptions) : '';
259  return $hidden . parent::tag("label", array("class" => "hasCheckBox" . $labelClass . $disabledClass),
260  self::activeInputField('checkbox', $model, $attribute, $htmlOptions));
261  }
262 
267  public static function checkBox($name, $checked = false, $htmlOptions = array())
268  {
269  if ($checked)
270  {
271  $htmlOptions['checked'] = 'checked';
272  }
273  else
274  {
275  unset($htmlOptions['checked']);
276  }
277  $value = isset($htmlOptions['value']) ? $htmlOptions['value'] : 1;
278  self::clientChange('click', $htmlOptions);
279 
280  if (array_key_exists('uncheckValue', $htmlOptions))
281  {
282  $uncheck = $htmlOptions['uncheckValue'];
283  unset($htmlOptions['uncheckValue']);
284  }
285  else
286  {
287  $uncheck = null;
288  }
289 
290  if ($uncheck !== null)
291  {
292  // add a hidden field so that if the radio button is not selected, it still submits a value
293  if (isset($htmlOptions['id']) && $htmlOptions['id'] !== false)
294  {
295  $uncheckOptions = array('id' => self::ID_PREFIX . $htmlOptions['id']);
296  }
297  else
298  {
299  $uncheckOptions = array('id' => false);
300  }
301  $hidden = self::hiddenField($name, $uncheck, $uncheckOptions);
302  }
303  else
304  {
305  $hidden = '';
306  }
307 
308  // add a hidden field so that if the checkbox is not selected, it still submits a value
309  if ($checked)
310  {
311  $labelClass = ' c_on';
312  }
313  else
314  {
315  $labelClass = null;
316  }
317  if (isset($htmlOptions['labelClass']))
318  {
319  $labelClass .= ' ' . $htmlOptions['labelClass'];
320  }
321  return $hidden . parent::tag("label", array("class" => "hasCheckBox" . $labelClass), self::inputField('checkbox', $name, $value, $htmlOptions));
322  }
323 
328  public static function ajaxLink($text, $url, $ajaxOptions = array(), $htmlOptions = array())
329  {
330  if (!isset($htmlOptions['href']))
331  {
332  $htmlOptions['href'] = '#';
333  }
334  $ajaxOptions['url'] = $url;
335  $htmlOptions['ajax'] = $ajaxOptions;
336  self::clientChange('click', $htmlOptions);
337  if (isset($htmlOptions['namespace']))
338  {
339  unset($htmlOptions['namespace']);
340  }
341  return self::tag('a', $htmlOptions, $text);
342  }
343 
351  protected static function clientChange($event, &$htmlOptions)
352  {
353  if (!isset($htmlOptions['submit']) && !isset($htmlOptions['confirm']) && !isset($htmlOptions['ajax']))
354  {
355  return;
356  }
357  if (isset($htmlOptions['namespace']))
358  {
359  $namespace = true;
360  $event = $event . '.' . $htmlOptions['namespace'];
361  unset($htmlOptions['namespace']);
362  }
363  else
364  {
365  $namespace = false;
366  }
367  if (isset($htmlOptions['live']))
368  {
369  $live = $htmlOptions['live'];
370  unset($htmlOptions['live']);
371  }
372  else
373  {
374  $live = self::$liveEvents;
375  }
376  if (isset($htmlOptions['return']) && $htmlOptions['return'])
377  {
378  $return = 'return true';
379  }
380  else
381  {
382  $return = 'return false';
383  }
384  if (isset($htmlOptions['on' . $event]))
385  {
386  $handler = trim($htmlOptions['on' . $event], ';') . ';';
387  unset($htmlOptions['on' . $event]);
388  }
389  else
390  {
391  $handler = '';
392  }
393 
394  if (isset($htmlOptions['id']))
395  {
396  $id = $htmlOptions['id'];
397  }
398  else
399  {
400  $id = $htmlOptions['id'] = isset($htmlOptions['name']) ? $htmlOptions['name']: self::ID_PREFIX.self::$count++;
401  }
402  $cs = Yii::app()->getClientScript();
403  $cs->registerCoreScript('jquery');
404 
405  if (isset($htmlOptions['submit']))
406  {
407  $cs->registerCoreScript('yii');
408  $request = Yii::app()->getRequest();
409  if ($request->enableCsrfValidation && isset($htmlOptions['csrf']) && $htmlOptions['csrf'])
410  {
411  $htmlOptions['params'][$request->csrfTokenName] = $request->getCsrfToken();
412  }
413  if (isset($htmlOptions['params']))
414  {
415  $params = CJavaScript::encode($htmlOptions['params']);
416  }
417  else
418  {
419  $params = '{}';
420  }
421  if ($htmlOptions['submit'] !== '')
422  {
423  $url = CJavaScript::quote(self::normalizeUrl($htmlOptions['submit']));
424  }
425  else
426  {
427  $url = '';
428  }
429  $handler .= "jQuery.yii.submitForm(this, '$url', $params);{$return};";
430  }
431 
432  if (isset($htmlOptions['ajax']))
433  {
434  $handler .= self::ajax($htmlOptions['ajax'])."{$return};";
435  }
436  if (isset($htmlOptions['confirm']))
437  {
438  $confirm = 'confirm(\''.CJavaScript::quote($htmlOptions['confirm']).'\')';
439  if ($handler !== '')
440  {
441  $handler = "if ($confirm) {" . $handler . "} else return false;";
442  }
443  else
444  {
445  $handler = "return $confirm;";
446  }
447  }
448 
449  if (isset($htmlOptions['selector']))
450  {
451  $selector = $htmlOptions['selector'];
452  unset($htmlOptions['selector']);
453  }
454  else
455  {
456  $selector = '#' . $id;
457  }
458 
459  if ($live)
460  {
461  if ($namespace)
462  {
463  $cs->registerScript('Yii.CHtml.' . $selector, "$('body').off('$event', '$selector'); $('body').on('$event', '$selector', function(){{$handler}});");
464  }
465  else
466  {
467  $cs->registerScript('Yii.CHtml.' . $selector, "$('body').on('$event', '$selector', function(){{$handler}});");
468  }
469  }
470  else
471  {
472  if ($namespace)
473  {
474  $cs->registerScript('Yii.CHtml.' . $selector, "$('$selector').off('$event'); $('$selector').on('$event', function(){{$handler}});");
475  }
476  else
477  {
478  $cs->registerScript('Yii.CHtml.' . $selector, "$('$selector').on('$event', function(){{$handler}});");
479  }
480  }
481  unset($htmlOptions['params'],
482  $htmlOptions['submit'],
483  $htmlOptions['ajax'],
484  $htmlOptions['confirm'],
485  $htmlOptions['return'],
486  $htmlOptions['csrf']);
487  }
488 
493  public static function activeCheckBoxList($model, $attribute, $data, $htmlOptions = array())
494  {
495  self::resolveNameID($model, $attribute, $htmlOptions);
496  $selection = self::resolveValue($model, $attribute);
497  if ($model->hasErrors($attribute))
498  {
499  self::addErrorCss($htmlOptions);
500  }
501  $name = $htmlOptions['name'];
502  unset($htmlOptions['name']);
503  if (array_key_exists('uncheckValue', $htmlOptions))
504  {
505  $uncheck = $htmlOptions['uncheckValue'];
506  unset($htmlOptions['uncheckValue']);
507  }
508  else
509  {
510  $uncheck = '';
511  }
512  $hiddenOptions = isset($htmlOptions['id']) ? array('id' => self::ID_PREFIX . $htmlOptions['id']) : array('id' => false);
513  $hidden = $uncheck !== null ? self::hiddenField($name, $uncheck, $hiddenOptions) : '';
514  return $hidden . self::checkBoxList($name, $selection, $data, $htmlOptions);
515  }
516 
520  public static function checkBoxList($name, $select, $data, $htmlOptions = array())
521  {
522  $template = isset($htmlOptions['template'])?$htmlOptions['template']:'{input} {label}';
523  $separator = isset($htmlOptions['separator'])?$htmlOptions['separator']:"<br/>\n";
524  unset($htmlOptions['template'], $htmlOptions['separator']);
525  if (substr($name, -2) !== '[]')
526  {
527  $name .= '[]';
528  }
529  if (isset($htmlOptions['checkAll']))
530  {
531  $checkAllLabel = $htmlOptions['checkAll'];
532  $checkAllLast = isset($htmlOptions['checkAllLast']) && $htmlOptions['checkAllLast'];
533  }
534  unset($htmlOptions['checkAll'], $htmlOptions['checkAllLast']);
535 
536  $labelOptions = isset($htmlOptions['labelOptions']) ? $htmlOptions['labelOptions']:array();
537  unset($htmlOptions['labelOptions']);
538  $items = array();
539  $baseID = self::getIdByName($name);
540  $id = 0;
541  $checkAll = true;
542  foreach ($data as $value => $label)
543  {
544  $checked = !is_array($select) && !strcmp($value, $select) || is_array($select) && in_array($value, $select);
545  $checkAll = $checkAll && $checked;
546  $htmlOptions['value'] = $value;
547  $htmlOptions['id'] = $baseID . '_' . $id++;
548  $option = self::checkBox($name, $checked, $htmlOptions);
549  if (!isset($labelOptions['class']))
550  {
551  $labelOptions['class'] = null;
552  }
553  if ($checked)
554  {
555  $labelOptions['class'] . ' c_on';
556  }
557  $label = self::label($label, $htmlOptions['id'], $labelOptions);
558  $items[] = strtr($template, array('{input}' => $option, '{label}' => $label));
559  }
560  if (isset($checkAllLabel))
561  {
562  $htmlOptions['value'] = 1;
563  $htmlOptions['id'] = $id = $baseID . '_all';
564  $option = self::checkBox($id, $checkAll, $htmlOptions);
565  $label = self::label($checkAllLabel, $id, $labelOptions);
566  $item = strtr($template, array('{input}' => $option, '{label}' => $label));
567  if ($checkAllLast)
568  {
569  $items[] = $item;
570  }
571  else
572  {
573  array_unshift($items, $item);
574  }
575  $name = strtr($name, array('['=>'\\[',']'=>'\\]')); // Not Coding Standard
576  $js = <<<EOD
577  $('#$id').click(function()
578  {
579  $("input[name='$name']").prop('checked', this.checked);
580  });
581  $("input[name='$name']").click(function()
582  {
583  $('#$id').prop('checked', !$("input[name='$name']:not(:checked)").length);
584  });
585  $('#$id').prop('checked', !$("input[name='$name']:not(:checked)").length);
586 EOD;
587  $cs = Yii::app()->getClientScript();
588  $cs->registerCoreScript('jquery');
589  $cs->registerScript($id, $js);
590  }
591  return self::tag('span', array('id' => $baseID), implode($separator, $items));
592  }
593 
598  public static function activeDropDownList($model, $attribute, $data, $htmlOptions = array())
599  {
600  static::resolveNameID($model, $attribute, $htmlOptions);
601  $selection = static::resolveValue($model, $attribute);
602  $options = "\n" . static::listOptions($selection, $data, $htmlOptions);
603  static::clientChange('change', $htmlOptions);
604  if ($model->hasErrors($attribute))
605  {
606  static::addErrorCss($htmlOptions);
607  }
608  $multiSelectClass = null;
609  if (isset($htmlOptions['multiple']))
610  {
611  $multiSelectClass .= ' isMultiSelect';
612  if (substr($htmlOptions['name'], -2) !== '[]')
613  {
614  $htmlOptions['name'] .= '[]';
615  }
616  }
617  $content = static::tag('span', array('class' => 'select-arrow'), '');
618  $content .= static::tag('select', $htmlOptions, $options);
619  return static::tag('div', array('class' => 'hasDropDown' . $multiSelectClass), $content);
620  }
621 
627  public static function dropDownList($name, $select, $data, $htmlOptions = array())
628  {
629  $htmlOptions['name'] = $name;
630  if (!isset($htmlOptions['id']))
631  {
632  $htmlOptions['id'] = static::getIdByName($name);
633  }
634  elseif ($htmlOptions['id'] === false)
635  {
636  unset($htmlOptions['id']);
637  }
638  $multiSelectClass = null;
639  if (isset($htmlOptions['multiple']))
640  {
641  $multiSelectClass .= ' isMultiSelect';
642  }
643  static::clientChange('change', $htmlOptions);
644  $options = "\n" . static::listOptions($select, $data, $htmlOptions);
645  $content = static::tag('span', array('class' => 'select-arrow'), '');
646  $content .= static::tag('select', $htmlOptions, $options);
647  return static::tag('div', array('class' => 'hasDropDown' . $multiSelectClass), $content);
648  }
649 
656  public static function wrapLabel($label, $class = 'z-label')
657  {
658  return static::tag('span', array('class' => $class), $label);
659  }
660 
666  public static function wrapLink($label)
667  {
668  return static::span('z-spinner') . static::span('z-icon') . static::wrapLabel($label);
669  }
670 
676  public static function span($class)
677  {
678  return static::tag('span', array('class' => $class), null);
679  }
680 
686  public static function resolveDivWrapperForContent($innerContent, & $content, $class = null)
687  {
688  if ($class != null)
689  {
690  $htmlOptions = array('class' => $class);
691  }
692  else
693  {
694  $htmlOptions = array();
695  }
696  if ($innerContent != null)
697  {
698  $content .= ZurmoHtml::tag('div', $htmlOptions, $innerContent);
699  }
700  }
701 
702  public static function wrapAndRenderContinuumButtonContent($content)
703  {
704  $clearFixContent = ZurmoHtml::tag('div', array('class' => 'clearfix'), $content);
705  return ZurmoHtml::tag('div', array('class' => 'continuum'), $clearFixContent);
706  }
707 
708  public static function icon($class)
709  {
710  $icon = ZurmoHtml::tag('i', array('class' => $class), '');
711  return ZurmoHtml::tag('span', array(), $icon);
712  }
713  }
714 ?>
static checkBox($name, $checked=false, $htmlOptions=array())
Definition: ZurmoHtml.php:267
static ajaxLink($text, $url, $ajaxOptions=array(), $htmlOptions=array())
Definition: ZurmoHtml.php:328
static encode($text)
Definition: ZurmoHtml.php:47
static radioButtonList($name, $select, $data, $htmlOptions=array(), $dataSelectOptions=array(), $dataHtmlOptions=array())
Definition: ZurmoHtml.php:170
static errorSummary($model, $header=null, $footer=null, $htmlOptions=array())
Definition: ZurmoHtml.php:57
static clientChange($event, &$htmlOptions)
Definition: ZurmoHtml.php:351
static activeRadioButtonList($model, $attribute, $data, $htmlOptions=array(), $dataSelectOptions=array(), $dataHtmlOptions=array())
Definition: ZurmoHtml.php:126
Generated on Wed Apr 8 2020 07:10:38