Advanced Search: Links n:n

SVN:b1162[5446]
This commit is contained in:
Eric Espié
2018-03-16 10:59:33 +00:00
parent d734cdaf48
commit bf02e04ae5
5 changed files with 64 additions and 32 deletions

View File

@@ -402,11 +402,10 @@ EOF
{
$oFilter->AddCondition('id', $aAlreadyLinkedIds, 'NOTIN');
}
//$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
$oBlock = new DisplayBlock($oFilter, 'search', false);
$sHtml .= $oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
array(
'menu' => false,
'open' => $bOpen,
'table_id' => "SearchResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}",
'table_id2' => 'add_'.$this->m_sAttCode,
@@ -415,14 +414,14 @@ EOF
'json' => $sJson,
'cssCount' => '#count_'.$this->m_sAttCode.$this->m_sNameSuffix
));
$sHtml .= "<div id=\"ObjectsAddForm_{$this->m_sAttCode}{$this->m_sNameSuffix}\">\n";
$sHtml .= "<form id=\"ObjectsAddForm_{$this->m_sAttCode}{$this->m_sNameSuffix}\">\n";
$sHtml .= "<div id=\"SearchResultsToAdd_{$this->m_sAttCode}{$this->m_sNameSuffix}\" style=\"vertical-align:top;background: #fff;height:100%;overflow:auto;padding:0;border:0;\">\n";
$sHtml .= "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>".Dict::S('UI:Message:EmptyList:UseSearchForm')."</p></div>\n";
$sHtml .= "</div>\n";
$sHtml .= "<input type=\"hidden\" id=\"count_{$this->m_sAttCode}{$this->m_sNameSuffix}\" value=\"0\"/>";
$sHtml .= "<input type=\"button\" value=\"".Dict::S('UI:Button:Cancel')."\" onClick=\"$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog('close');\">&nbsp;&nbsp;<input id=\"btn_ok_{$this->m_sAttCode}{$this->m_sNameSuffix}\" disabled=\"disabled\" type=\"button\" onclick=\"return oWidget{$this->m_iInputId}.DoAddObjects(this.id);\" value=\"".Dict::S('UI:Button:Add')."\">";
$sHtml .= "</div>\n";
$sHtml .= "</div>\n";
$sHtml .= "</form>\n";
$oPage->add($sHtml);
$oPage->add_ready_script("$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog({ width: $(window).width()*0.8, height: $(window).height()*0.8, autoOpen: false, modal: true, resizeStop: oWidget{$this->m_iInputId}.UpdateSizes });");
$oPage->add_ready_script("$('#dlg_{$this->m_sAttCode}{$this->m_sNameSuffix}').dialog('option', {title:'".addslashes(Dict::Format('UI:AddObjectsOf_Class_LinkedWith_Class', MetaModel::GetName($this->m_sLinkedClass), MetaModel::GetName($this->m_sClass)))."'});");
@@ -436,7 +435,7 @@ EOF
* @param string $sRemoteClass Name of the "remote" class to perform the search on, must be a derived class of m_sRemoteClass
* @param Array $aAlreadyLinkedIds List of IDs of objects of "remote" class already linked, to be filtered out of the search
*/
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinkedIds = array())
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinkedIds = array(), $oCurrentObj = null)
{
if ($sRemoteClass != '')
{
@@ -452,6 +451,7 @@ EOF
{
$oFilter->AddCondition('id', $aAlreadyLinkedIds, 'NOTIN');
}
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
$oBlock = new DisplayBlock($oFilter, 'list', false);
$oBlock->Display($oP, "ResultsToAdd_{$this->m_sAttCode}", array('menu' => false, 'cssCount'=> '#count_'.$this->m_sAttCode.$this->m_sNameSuffix , 'selection_mode' => true, 'table_id' => 'add_'.$this->m_sAttCode)); // Don't display the 'Actions' menu on the results
}

View File

@@ -101,17 +101,28 @@ function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates, oWizH
operation: 'addObjects',
json: me.oWizardHelper.ToJSON()
};
$.post( GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', theMap,
function(data)
{
$('#dlg_'+me.id).html(data);
$('#dlg_'+me.id).dialog('open');
me.UpdateSizes(null, null);
me.SearchObjectsToAdd();
$('#'+me.id+'_indicatorAdd').html('');
},
'html'
);
// Gather the already linked target objects
theMap.aAlreadyLinked = [];
$('#linkedset_'+me.id+' .selection:input').each(function (i) {
var iRemote = $(this).attr('data-remote-id');
theMap.aAlreadyLinked.push(iRemote);
});
$.ajax({
"url": GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
"method": "POST",
"data": theMap,
"dataType": "html"
})
.done(function (data) {
$('#dlg_'+me.id).html(data);
$('#dlg_'+me.id).dialog('open');
me.UpdateSizes(null, null);
me.SearchObjectsToAdd();
$('#'+me.id+'_indicatorAdd').html('');
})
;
};
this.SearchObjectsToAdd = function()

View File

@@ -40,7 +40,7 @@ try
throw new SecurityException('You must be logged in');
}
$sParams = stripslashes(utils::ReadParam('params', '', false, 'raw_data'));
$sParams = utils::ReadParam('params', '', false, 'raw_data');
if (!$sParams)
{
throw new AjaxSearchException("Invalid query (empty filter)", 400);
@@ -54,7 +54,7 @@ try
$oFilter = CriterionParser::Parse($aParams['base_oql'], $aParams['criterion']);
$oDisplayBlock = new DisplayBlock($oFilter, 'list', false);
$sListParams = stripslashes(utils::ReadParam('list_params', '{}', false, 'raw_data'));
$sListParams = utils::ReadParam('list_params', '{}', false, 'raw_data');
$aListParams = (array) json_decode($sListParams, true);
foreach($aListParams as $key => $value)

View File

@@ -68,13 +68,30 @@ class CriterionToSearchForm extends CriterionConversionAbstract
}
}
// Regroup criterion by variable name
// Regroup criterion by variable name (no ref first)
usort($aAndCriterion, function ($a, $b) {
$iRefCmp = strcmp($a['ref'], $b['ref']);
if ($iRefCmp != 0) return $iRefCmp;
$iOpCmp = strcmp($a['operator'], $b['operator']);
if (array_key_exists('ref', $a) || array_key_exists('ref', $b))
{
if (array_key_exists('ref', $a) && array_key_exists('ref', $b))
{
$iRefCmp = strcmp($a['ref'], $b['ref']);
if ($iRefCmp != 0) return $iRefCmp;
return $iOpCmp;
return strcmp($a['operator'], $b['operator']);
}
if (array_key_exists('ref', $a))
{
return 1;
}
return -1;
}
if (array_key_exists('oql', $a) && array_key_exists('oql', $b))
{
return strcmp($a['oql'], $b['oql']);
}
return 0;
});
$aMergeFctByWidget = array(
@@ -88,16 +105,20 @@ class CriterionToSearchForm extends CriterionConversionAbstract
{
if (!is_null($aPrevCriterion))
{
if (strcmp($aPrevCriterion['ref'], $aCurrCriterion['ref']) == 0)
if (array_key_exists('ref', $aPrevCriterion))
{
// Same attribute, try to merge
if (array_key_exists('widget', $aCurrCriterion))
// If previous has ref, the current has ref as the array is sorted with all without ref first
if (strcmp($aPrevCriterion['ref'], $aCurrCriterion['ref']) == 0)
{
if (array_key_exists($aCurrCriterion['widget'], $aMergeFctByWidget))
// Same attribute, try to merge
if (array_key_exists('widget', $aCurrCriterion))
{
$sFct = $aMergeFctByWidget[$aCurrCriterion['widget']];
$aPrevCriterion = self::$sFct($aPrevCriterion, $aCurrCriterion, $aMergedCriterion);
continue;
if (array_key_exists($aCurrCriterion['widget'], $aMergeFctByWidget))
{
$sFct = $aMergeFctByWidget[$aCurrCriterion['widget']];
$aPrevCriterion = self::$sFct($aPrevCriterion, $aCurrCriterion, $aMergedCriterion);
continue;
}
}
}
}

View File

@@ -88,7 +88,7 @@ class SearchForm
$sRootClass = $sClassName;
}
$sJson = stripslashes(utils::ReadParam('json', '', false, 'raw_data'));
$sJson = utils::ReadParam('json', '', false, 'raw_data');
if (!empty($sJson))
{
$aListParams['json'] = json_decode($sJson, true);
@@ -119,7 +119,7 @@ class SearchForm
$sHtml .= "<form id=\"fs_{$sSearchFormId}\" action=\"{$sAction}\" class=\"{$sStyle}\">\n"; // Don't use $_SERVER['SCRIPT_NAME'] since the form may be called asynchronously (from ajax.php)
$sHtml .= "<h2 class=\"sf_title\"><span class=\"sft_picto fa fa-search\"></span>" . Dict::Format('UI:SearchFor_Class_Objects', $sClassesCombo) . "<a class=\"sft_toggler fa fa-caret-down pull-right\" href=\"#\" title=\"" . Dict::S('UI:Search:Toggle') . "\"></a><a class=\"sft_refresh fa fa-refresh pull-right\" href=\"#\" title=\"" . Dict::S('UI:Button:Refresh') . "\"></a></h2>\n";
$sHtml .= "<div id=\"fs_{$sSearchFormId}_criterion_outer\">\n";
$sHtml .= "</div>\n";
$sHtml .= "</div>\n</form>\n";
$aFields = $this->GetFields($oSet);
$oSearch = $oSet->GetFilter();