Account Suspended
Account Suspended
This Account has been suspended.
Contact your hosting provider for more information.
 All Data Structures Functions Variables Pages
DynamicSearchView.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  abstract class DynamicSearchView extends SearchView
41  {
42  const ADVANCED_SEARCH_TYPE_STATIC = 'Static';
43 
44  const ADVANCED_SEARCH_TYPE_DYNAMIC = 'Dynamic';
45 
46  public static function getDesignerRulesType()
47  {
48  return 'DynamicSearchView';
49  }
50 
55  public function __construct($model, $listModelClassName, $gridIdSuffix = null, $hideAllSearchPanelsToStart = false)
56  {
57  assert('$model instanceof DynamicSearchForm');
58  parent::__construct($model, $listModelClassName, $gridIdSuffix, $hideAllSearchPanelsToStart);
59  }
60 
61  protected function getClientOptions()
62  {
63  return array(
64  'validateOnSubmit' => true,
65  'validateOnChange' => false,
66  'beforeValidate' => 'js:$(this).beforeValidateAction',
67  'afterValidate' => 'js:afterDynamicSearchValidateAjaxAction',
68  'afterValidateAjax' => $this->renderConfigSaveAjax($this->getSearchFormId()),
69  );
70  }
71 
72  protected function getEnableAjaxValidationValue()
73  {
74  return true;
75  }
76 
77  protected function getExtraRenderForClearSearchLinkScript()
78  {
79  return parent::getExtraRenderForClearSearchLinkScript() .
80  "$(this).closest('form').find('.search-view-1').find('.dynamic-search-row').each(function()
81  {
82  $(this).remove();
83  });
84  $('#" . $this->getRowCounterInputId() . "').val(0);
85  $('#" . $this->getStructureInputId() . "').val('');
86  $(this).closest('form').find('.search-view-1').hide();
87  $('.select-list-attributes-view').hide();
88  resolveClearLinkPrefixLabelAndVisibility('" . $this->getSearchFormId() . "');
89  rebuildDynamicSearchRowNumbersAndStructureInput('" . $this->getSearchFormId() . "');
90  ";
91  }
92 
93  protected function getFormActionUrl()
94  {
95  return Yii::app()->createUrl('zurmo/default/validateDynamicSearch',
96  array('viewClassName' => get_class($this),
97  'modelClassName' => get_class($this->model->getModel()),
98  'formModelClassName' => get_class($this->model)));
99  }
100 
101  protected function getRowCounterInputId()
102  {
103  return 'rowCounter-' . $this->getSearchFormId();
104  }
105 
106  protected function getStructureInputId()
107  {
108  return get_class($this->model) . '_' . DynamicSearchForm::DYNAMIC_STRUCTURE_NAME;
109  }
110 
111  protected function getStructureInputName()
112  {
113  return get_class($this->model) . '[' . DynamicSearchForm::DYNAMIC_STRUCTURE_NAME . ']';
114  }
115 
116  protected function renderConfigSaveAjax($formName)
117  {
118  return "$(this).closest('form').find('.search-view-1').hide();
119  $('.select-list-attributes-view').hide();
120  $('#" . $formName . "').find('.attachLoading:first').removeClass('loading');
121  $('#" . $formName . "').find('.attachLoading:first').removeClass('loading-ajax-submit');
122  $('#" . $this->gridId . $this->gridIdSuffix . "-selectedIds').val(null);
123  $.fn.yiiGridView.update('" . $this->gridId . $this->gridIdSuffix . "',
124  {
125  data: '" . $this->listModelClassName . "_page=&" . // Not Coding Standard
126  $this->listModelClassName . "_sort=" .
127  $this->getExtraQueryPartForSearchFormScriptSubmitFunction() ."' // Not Coding Standard
128  }
129  );
130  $('#" . $this->getClearingSearchInputId() . "').val('');
131  ";
132  }
133 
134  protected function getExtraRenderFormBottomPanelScriptPart()
135  {
136  return parent::getExtraRenderFormBottomPanelScriptPart() .
137  "$('#" . $this->getSearchFormId(). "').find('.anyMixedAttributes-input').unbind('input.clear propertychange.clear keyup.clear');
138  $('#" . $this->getSearchFormId(). "').find('.anyMixedAttributes-input').bind('input.clear propertychange.clear keyup.clear', function(event)
139  {
140  resolveClearLinkPrefixLabelAndVisibility('" . $this->getSearchFormId() . "');
141  });";
142  }
143 
149  protected function renderAdvancedSearchScripts()
150  {
151  }
152 
153  protected function renderAdvancedSearchForFormLayout($panel, $maxCellsPerRow, $form = null)
154  {
155  if (isset($panel['advancedSearchType']) &&
156  $panel['advancedSearchType'] == self::ADVANCED_SEARCH_TYPE_DYNAMIC)
157  {
158  return $this->renderDynamicAdvancedSearchRows($panel, $maxCellsPerRow, $form);
159  }
160  else
161  {
162  return $this->renderStaticSearchRows($panel, $maxCellsPerRow, $form);
163  }
164  }
165 
166  protected function renderDynamicAdvancedSearchRows($panel, $maxCellsPerRow, $form)
167  {
168  assert('$form != null');
169  $content = $form->errorSummary($this->model);
170  $content .= $this->renderDynamicClausesValidationHelperContent($form);
171  $rowCount = 0;
172  $suffix = $this->getSearchFormId();
173  $viewClassName = get_class($this);
174  $modelClassName = get_class($this->model->getModel());
175  $formModelClassName = get_class($this->model);
176  if ($this->model->dynamicClauses!= null)
177  {
178  foreach ($this->model->dynamicClauses as $dynamicClause)
179  {
180  $attributeIndexOrDerivedType = ArrayUtil::getArrayValue($dynamicClause, 'attributeIndexOrDerivedType');
181  if ($attributeIndexOrDerivedType != null)
182  {
183  $searchAttributes = self::resolveSearchAttributeValuesForDynamicRow($dynamicClause,
184  $attributeIndexOrDerivedType);
185  $inputContent = DynamicSearchUtil::renderDynamicSearchAttributeInput($viewClassName,
186  $modelClassName,
187  $formModelClassName,
188  (int)$rowCount,
189  $attributeIndexOrDerivedType,
190  $searchAttributes,
191  $suffix);
192  $content .= DynamicSearchUtil::renderDynamicSearchRowContent( $viewClassName,
193  $modelClassName,
194  $formModelClassName,
195  $rowCount,
196  $attributeIndexOrDerivedType,
197  $inputContent,
198  $suffix);
199  $rowCount++;
200  }
201  }
202  }
203  $content .= $this->renderAddExtraRowContent($rowCount);
204  $content .= $this->renderAfterAddExtraRowContent($form);
205  $content .= $this->renderDynamicSearchStructureContent($form);
206  return $content;
207  }
208 
209  protected static function resolveSearchAttributeValuesForDynamicRow($dynamicClause, $attributeIndexOrDerivedType)
210  {
211  $dynamicClauseOnlyWithAttributes = $dynamicClause;
212  if (isset($dynamicClause['structurePosition']))
213  {
214  unset($dynamicClauseOnlyWithAttributes['structurePosition']);
215  }
216  if (isset($dynamicClause['attributeIndexOrDerivedType']))
217  {
218  unset($dynamicClauseOnlyWithAttributes['attributeIndexOrDerivedType']);
219  }
220  return $dynamicClauseOnlyWithAttributes;
221  }
222 
227  protected function renderAddExtraRowContent($rowCount)
228  {
229  assert('is_int($rowCount)');
230  $idInputHtmlOptions = array('id' => $this->getRowCounterInputId());
231  $hiddenInputName = 'rowCounter';
232  $ajaxOnChangeUrl = Yii::app()->createUrl("zurmo/default/dynamicSearchAddExtraRow",
233  array('viewClassName' => get_class($this),
234  'modelClassName' => get_class($this->model->getModel()),
235  'formModelClassName' => get_class($this->model),
236  'suffix' => $this->getSearchFormId()));
237  $content = ZurmoHtml::hiddenField($hiddenInputName, $rowCount, $idInputHtmlOptions);
238  // Begin Not Coding Standard
239  $addFieldLabelContent = $this->getAddFieldLabelContent();
240  $aContent = ZurmoHtml::wrapLink($addFieldLabelContent);
241  $content .= ZurmoHtml::ajaxLink($aContent, $ajaxOnChangeUrl,
242  array('type' => 'GET',
243  'data' => 'js:\'rowNumber=\' + $(\'#rowCounter-' . $this->getSearchFormId(). '\').val()',
244  'beforeSend' => 'js:function(){
245  $(this).makeOrRemoveLoadingSpinner(true, "#' . $this->getSearchFormId() . '", "dark");
246  }',
247  'success' => 'js:function(data){
248  $(\'#' . $this->getRowCounterInputId(). '\').val(parseInt($(\'#' . $this->getRowCounterInputId() . '\').val()) + 1)
249  $(\'#addExtraAdvancedSearchRowButton-' . $this->getSearchFormId() . '\').parent().before(data);
250  rebuildDynamicSearchRowNumbersAndStructureInput("' . $this->getSearchFormId() . '");
251  resolveClearLinkPrefixLabelAndVisibility("' . $this->getSearchFormId() . '");
252  $(this).makeOrRemoveLoadingSpinner(false, "#' . $this->getSearchFormId() . '");
253  }'),
254  array('id' => 'addExtraAdvancedSearchRowButton-' . $this->getSearchFormId(), 'namespace' => 'add'));
255  // End Not Coding Standard
256  return ZurmoHtml::tag('div', array('class' => 'add-fields-container'), $content);
257  }
258 
259  protected function renderAfterAddExtraRowContent($form)
260  {
261  }
262 
263  protected function getAddFieldLabelContent()
264  {
265  return Zurmo::t('ZurmoModule', 'Add criteria');
266  }
267 
268  protected function renderAfterFormLayout($form)
269  {
270  parent::renderAfterFormLayout($form);
271  Yii::app()->clientScript->registerScriptFile(
272  Yii::app()->getAssetManager()->publish(
273  Yii::getPathOfAlias('application.core.views.assets')) . '/dynamicSearchViewUtils.js');
274  Yii::app()->clientScript->registerScript('showStructurePanels' . $this->getSearchFormId(), "
275  $('#show-dynamic-search-structure-div-link-" . $this->getSearchFormId() . "').click( function()
276  {
277  $('#show-dynamic-search-structure-div-" . $this->getSearchFormId() . "').show();
278  $('#show-dynamic-search-structure-div-link-" . $this->getSearchFormId() . "').hide();
279  return false;
280  }
281  );");
282  }
283 
287  protected function renderDynamicClausesValidationHelperContent($form)
288  {
289  $htmlOptionsForInput = array('id' => get_class($this->model) . '_dynamicClausesNotUsed',
290  'name' => 'dynamicClausesValidationHelper',
291  'value' => 'notUsed');
292  $htmlOptionsForError = array('id' => get_class($this->model) . '_dynamicClauses');
293  $content = '<div style="display:none;">';
294  $content .= $form->hiddenField($this->model, 'dynamicClauses', $htmlOptionsForInput);
295  $content .= $form->error($this->model, 'dynamicClauses', $htmlOptionsForError);
296  $content .= '</div>';
297  return $content;
298  }
299 
300  protected function renderDynamicSearchStructureContent($form)
301  {
302  if ($this->shouldHideDynamicSearchStructureByDefault())
303  {
304  $style1 = '';
305  $style2 = 'display:none;';
306  }
307  else
308  {
309  $style1 = 'display:none;';
310  $style2 = '';
311  }
312  if (count($this->model->dynamicClauses) > 0)
313  {
314  $style3 = '';
315  }
316  else
317  {
318  $style3 = 'display:none;';
319  }
320  $content = ZurmoHtml::link(Zurmo::t('ZurmoModule', 'Modify Structure'), '#',
321  array('id' => 'show-dynamic-search-structure-div-link-' . $this->getSearchFormId() . '',
322  'style' => $style1));
323  $content .= ZurmoHtml::tag('div',
324  array('id' => 'show-dynamic-search-structure-div-' . $this->getSearchFormId(),
325  'class' => 'has-lang-label',
326  'style' => $style2), $this->renderStructureInputContent($form));
327  $content = ZurmoHtml::tag('div', array('id' => 'show-dynamic-search-structure-wrapper-' . $this->getSearchFormId(),
328  'style' => $style3), $content);
329  return $content;
330  }
331 
332  protected function renderStructureInputContent($form)
333  {
334  $idInputHtmlOptions = array('id' => $this->getStructureInputId(),
335  'name' => $this->getStructureInputName(),
336  'class' => 'dynamic-search-structure-input');
337  $content = $form->textField($this->model, 'dynamicStructure', $idInputHtmlOptions);
338  $content .= ZurmoHtml::tag('span', array(), Zurmo::t('Core', 'Search Operator'));
339  $content .= $form->error($this->model, 'dynamicStructure');
340  return $content;
341  }
342 
343  protected function shouldHideDynamicSearchStructureByDefault()
344  {
345  return true;
346  }
347 
348  protected function getClearSearchLabelPrefixContent()
349  {
350  if (Yii::app()->userInterface->isMobile())
351  {
352  return parent::getClearSearchLabelPrefixContent();
353  }
354  $criteriaCount = count($this->model->dynamicClauses);
355  if ($this->model->anyMixedAttributes != null)
356  {
357  $criteriaCount++;
358  }
359  if ($criteriaCount == 0)
360  {
361  $criteriaCountContent = '';
362  }
363  else
364  {
365  $criteriaCountContent = $criteriaCount . ' ';
366  }
367  return ZurmoHtml::tag('span',
368  array('class' => 'clear-search-link-criteria-selected-count'),
369  $criteriaCountContent);
370  }
371 
372  protected function getClearSearchLabelContent()
373  {
374  if (Yii::app()->userInterface->isMobile())
375  {
376  return parent::getClearSearchLabelContent();
377  }
378  return Zurmo::t('ZurmoModule', 'Criteria Selected <span class="icon-clear">Z</span>');
379  }
380 
381  protected function getClearSearchLinkStartingStyle()
382  {
383  if ($this->model->anyMixedAttributes == null && count($this->model->dynamicClauses) == 0)
384  {
385  return "display:none;";
386  }
387  }
388 
394  public static function resolveAttributeIndexOrDerivedTypeAndLabelsForDynamicSearchRow(
395  & $attributeIndexOrDerivedTypeAndLabels)
396  {
397  }
398  }
399 ?>
static ajaxLink($text, $url, $ajaxOptions=array(), $htmlOptions=array())
Definition: ZurmoHtml.php:328
Definition: Z.php:37
getExtraQueryPartForSearchFormScriptSubmitFunction()
Definition: SearchView.php:291
static getArrayValue($array, $element, $defaultValue=null)
Definition: ArrayUtil.php:45
renderDynamicClausesValidationHelperContent($form)
renderAddExtraRowContent($rowCount)
__construct($model, $listModelClassName, $gridIdSuffix=null, $hideAllSearchPanelsToStart=false)
static wrapLink($label)
Definition: ZurmoHtml.php:666
Generated on Fri Jul 10 2020 07:10:37
Account Suspended
Account Suspended
This Account has been suspended.
Contact your hosting provider for more information.