2
0
forked from Wavyzz/dolibarr

Enhance Custom Report Filter Editor (#32154)

* Enhance filter editor

* add trans keys

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
This commit is contained in:
Mohamed DAOUD
2024-12-01 23:32:32 +01:00
committed by GitHub
parent f6fe770695
commit b8089532ff
6 changed files with 102 additions and 7 deletions

View File

@@ -11313,6 +11313,13 @@ class Form
</script>
';
// Convert $arrayoffiltercriterias into a json object that can be used in jquery to build the search component dynamically
$arrayoffiltercriterias_json = json_encode($arrayoffiltercriterias);
$ret .= '<script>
var arrayoffiltercriterias = ' . $arrayoffiltercriterias_json . ';
</script>';
$arrayoffilterfieldslabel = array();
foreach ($arrayoffiltercriterias as $key => $val) {
$arrayoffilterfieldslabel[$key]['label'] = $val['label'];
@@ -11356,6 +11363,19 @@ class Form
$ret .= $form->selectDate(($dateOne ? $dateOne : -1), 'dateone', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '');
$ret .= '</span>';
// Value selector (will be populated dynamically) based on search_filter_field value if a selected value has an array of values
$ret .= '<select class="value-selector width150" id="value-selector" style="display:none">';
$ret .= '</select>';
$ret .= '<script>
$(document).ready(function() {
$("#value-selector").select2({
placeholder: "' . dol_escape_js($langs->trans('Value')) . '"
});
$("#value-selector").hide();
$("#value-selector").next(".select2-container").hide();
});
</script>';
$ret .= '</div>';
$ret .= '<div class="btn-div">';
@@ -11390,10 +11410,21 @@ class Form
$ret .= '<script>
$(document).ready(function() {
$(".search_filter_field").on("change", function() {
let maybenull = 0;
const selectedField = $(this).find(":selected");
const fieldType = selectedField.data("type");
let fieldType = selectedField.data("type");
const selectedFieldValue = selectedField.val();
const operators = getOperatorsForFieldType(fieldType);
// If the selected field has an array of values then ask toshow the value selector instead of the value input
if (arrayoffiltercriterias[selectedFieldValue]["arrayofkeyval"] !== undefined) {
fieldType = "select";
}
// If the selected field may be null then ask to append the "IsDefined" and "IsNotDefined" operators
if (arrayoffiltercriterias[selectedFieldValue]["maybenull"] !== undefined) {
maybenull = 1;
}
const operators = getOperatorsForFieldType(fieldType, maybenull);
const operatorSelector = $(".operator-selector");
// Clear existing options
@@ -11411,14 +11442,47 @@ class Form
$("#datemonth, #dateyear").val(null).trigger("change.select2");
$("#dateone").datepicker("setDate", null);
$(".date-one, .date-month, .date-year").hide();
$("#value-selector").val("").hide();
$("#value-selector").next(".select2-container").hide();
$("#value-selector").val(null).trigger("change.select2");
if (fieldType === "date" || fieldType === "datetime" || fieldType === "timestamp") {
$(".date-one").show();
} else if (arrayoffiltercriterias[selectedFieldValue]["arrayofkeyval"] !== undefined) {
var arrayofkeyval = arrayoffiltercriterias[selectedFieldValue]["arrayofkeyval"];
var valueSelector = $("#value-selector");
valueSelector.empty();
Object.entries(arrayofkeyval).forEach(function([key, val]) {
valueSelector.append("<option value=\'" + key + "\'>" + val + "</option>");
});
valueSelector.trigger("change.select2");
$("#value-selector").show();
$("#value-selector").next(".select2-container").show();
} else {
$(".value-input").show();
}
});
$("#operator-selector").on("change", function() {
const selectedOperator = $(this).find(":selected").val();
if (selectedOperator === "IsDefined" || selectedOperator === "IsNotDefined") {
// Disable all value input elements
$(".value-input, .dateone, .datemonth, .dateyear").val("").prop("disabled", true);
$("#datemonth, #dateyear").val(null).trigger("change.select2");
$("#dateone").datepicker("setDate", null).datepicker("option", "disabled", true);
$(".date-one, .date-month, .date-year").prop("disabled", true);
$("#value-selector").val("").prop("disabled", true);
$("#value-selector").val(null).trigger("change.select2");
} else {
// Enable all value input elements
$(".value-input, .dateone, .datemonth, .dateyear").prop("disabled", false);
$(".date-one, .date-month, .date-year").prop("disabled", false);
$("#dateone").datepicker("option", "disabled", false);
$("#value-selector").prop("disabled", false);
}
});
$(".add-filter-btn").on("click", function(event) {
event.preventDefault();
@@ -11436,6 +11500,17 @@ class Form
value = `${year}-${month}-${day}`;
}
}
// If the selected field has an array of values then take the selected value
if (arrayoffiltercriterias[field]["arrayofkeyval"] !== undefined) {
value = $("#value-selector").val();
}
// If the operator is "IsDefined" or "IsNotDefined" then set the value to 1 (it will not be used)
if (operator === "IsDefined" || operator === "IsNotDefined") {
value = "1";
}
const filterString = generateFilterString(field, operator, value, fieldType);
// Submit the form

View File

@@ -1105,7 +1105,7 @@ function getParameterByName(name, valueifnotfound)
/**
* Get the list of operators for a given field type
*/
function getOperatorsForFieldType(type) {
function getOperatorsForFieldType(type, maybenull = 0) {
// Define the list of operators for each general field category
const operatorList = {
selectlink: {
@@ -1147,8 +1147,8 @@ function getOperatorsForFieldType(type) {
console.log('Get list of operators for type='+type);
if (/^select$/i.test(type) || /^link$/i.test(type)) {
generalType = "selectlink";
if (/^select$/i.test(type) || /^link$/i.test(type)) {
generalType = "selectlink";
} else if (/^(varchar|char|text|blob|nchar|mediumtext|longtext)\(\d+\)$/i.test(type) || /^varchar$/i.test(type)) {
generalType = "text";
} else if (/^(int|integer|float|double|decimal|numeric)(\(\d+,\d+\))?$/i.test(type)) {
@@ -1165,6 +1165,12 @@ function getOperatorsForFieldType(type) {
return [];
}
// If maybenull is true, then append the "IsDefined" and "IsNotDefined" operators
if (maybenull === 1) {
operatorList[generalType]["IsDefined"] = '<?php print dol_escape_js($langs->trans('IsDefined')); ?>';
operatorList[generalType]["IsNotDefined"] = '<?php print dol_escape_js($langs->trans('IsNotDefined')); ?>';
}
// Return the operators for the general type, or an empty array if not found
return operatorList[generalType] || [];
}
@@ -1194,6 +1200,12 @@ function generateFilterString(column, operator, context, fieldType) {
case "EndsWith":
filter = column + " like \'%" + context + "\'";
break;
case "IsDefined":
filter = column + ":isnot:null";
break;
case "IsNotDefined":
filter = column + ":is:null";
break;
case "=":
filter = column + " = \'" + context + "\'";
break;

View File

@@ -572,6 +572,12 @@ function fillArrayOfFilterFields($object, $tablealias, $labelofobject, &$arrayof
'tablefromt' => $tablepath,
'type' => $val['type']
);
if (!empty($val['arrayofkeyval'])) {
$arrayoffields[$tablealias.'.'.$key]['arrayofkeyval'] = $val['arrayofkeyval'];
}
if ((!isset($val['isamesaure']) || $val['isamesaure'] != 1) && (!isset($val['notnull']) || $val['notnull'] != '1')) {
$arrayoffields[$tablealias.'.'.$key]['maybenull'] = 1;
}
}
}

View File

@@ -1339,3 +1339,5 @@ addToFilter=Add
FilterAssistance=Filter editor
Operator=Operator
AllFieldsRequired=All fields are required.
IsDefined=Is defined
IsNotDefined=Is not defined

View File

@@ -5381,7 +5381,7 @@ img.boxhandle, img.boxclose {
}
@media only screen and (max-width: 620px) {
.search-component-assistance .operand, .operator, .value {
display: block;
display: block !important;
}
.search-component-assistance .separator, .end-separator {
padding: 0px;

View File

@@ -5361,7 +5361,7 @@ img.boxhandle, img.boxclose {
}
@media only screen and (max-width: 620px) {
.search-component-assistance .operand, .operator, .value {
display: block;
display: block !important;
}
.search-component-assistance .separator, .end-separator {
padding: 0px;