Restore default select2 search behavior

The select2 data format requires that all option objects include both an
 `id` and `text`. See https://select2.org/data-sources/formats

 By restoring these duplicate properties, we avoid having to write and
 maintain a custom matcher method, and we're protecting ourselves
 against any other unexpected behavior in the future resulting from
 these options not having the required `text` property.

[MAILPOET-3958]
This commit is contained in:
John Oleksowicz
2021-12-16 16:06:42 -06:00
committed by Veljko V
parent f193957096
commit 22e3686810
3 changed files with 20 additions and 36 deletions

View File

@@ -5,42 +5,6 @@ export default () => {
const select2Config = {
data: window.mailpoetColumnsSelect2,
width: '15em',
templateResult(item) {
return item.name;
},
templateSelection(item) {
return item.name;
},
// A custom matcher is required because we are using optgroups instead of single values.
// See https://select2.org/searching
matcher: (params, data) => {
if (data.children === undefined) {
return null;
}
const searchTerm = (params.term ?? '').trim().toLowerCase();
if (searchTerm === '') {
return data;
}
// "children" are objects representing the individual options within an optgroup
// `name` is the label displayed to users
const matchedChildren = data.children.filter((child) => {
const label = child.name.toLowerCase();
const words = label.split(' ');
return words.some((word) => word.startsWith(searchTerm));
});
if (matchedChildren.length === 0) {
// Returning null prevent the entire optgroup from being displayed
return null;
}
// We can't change the original `data` object because select2 continues use it as the
// basis for future searches. In other words, if we simply modified `data`, it could
// prevent options that were previously filtered out from reappearing if the search term
// changes or gets cleared out.
const modifiedData = jQuery.extend(true, {}, data);
modifiedData.children = matchedChildren;
return modifiedData;
},
};
jQuery('select.mailpoet_subscribers_column_data_match')
.select2(select2Config)
@@ -69,6 +33,7 @@ export default () => {
const newColumnData = {
id: response.data.id,
name: response.data.name,
text: response.data.name, // Required for select2 default functionality
type: response.data.type,
params: response.data.params,
custom: true,

View File

@@ -72,6 +72,7 @@ class ImportExportFactory {
return [
'id' => $fieldId,
'name' => $fieldName,
'text' => $fieldName, // Required for select2 default functionality
'type' => ($fieldId === 'confirmed_at' || $fieldId === 'created_at') ? 'date' : null,
'custom' => false,
];
@@ -87,6 +88,7 @@ class ImportExportFactory {
return [
'id' => $field['id'],
'name' => $field['name'],
'text' => $field['name'], // Required for select2 default functionality
'type' => $field['type'],
'params' => unserialize($field['params']),
'custom' => true,
@@ -103,35 +105,42 @@ class ImportExportFactory {
[
'id' => 'ignore',
'name' => __('Ignore field...', 'mailpoet'),
'text' => __('Ignore field...', 'mailpoet'), // Required for select2 default functionality
],
[
'id' => 'create',
'name' => __('Create new field...', 'mailpoet'),
'text' => __('Create new field...', 'mailpoet'), // Required for select2 default functionality
],
] :
[
[
'id' => 'select',
'name' => __('Select all...', 'mailpoet'),
'text' => __('Select all...', 'mailpoet'), // Required for select2 default functionality
],
[
'id' => 'deselect',
'name' => __('Deselect all...', 'mailpoet'),
'text' => __('Deselect all...', 'mailpoet'), // Required for select2 default functionality
],
];
$select2Fields = [
[
'name' => __('Actions', 'mailpoet'),
'text' => __('Actions', 'mailpoet'), // Required for select2 default functionality
'children' => $actions,
],
[
'name' => __('System fields', 'mailpoet'),
'text' => __('System fields', 'mailpoet'), // Required for select2 default functionality
'children' => $this->formatSubscriberFields($subscriberFields),
],
];
if ($subscriberCustomFields) {
array_push($select2Fields, [
'name' => __('User fields', 'mailpoet'),
'text' => __('User fields', 'mailpoet'), // Required for select2 default functionality
'children' => $this->formatSubscriberCustomFields(
$subscriberCustomFields
),

View File

@@ -178,19 +178,23 @@ class ImportExportFactoryTest extends \MailPoetTest {
$select2FieldsWithoutCustomFields = [
[
'name' => 'Actions',
'text' => 'Actions',
'children' => [
[
'id' => 'ignore',
'name' => 'Ignore field...',
'text' => 'Ignore field...',
],
[
'id' => 'create',
'name' => 'Create new field...',
'text' => 'Create new field...',
],
],
],
[
'name' => 'System fields',
'text' => 'System fields',
'children' => $importExportFactory->formatSubscriberFields(
$importExportFactory->getSubscriberFields()
),
@@ -201,6 +205,7 @@ class ImportExportFactoryTest extends \MailPoetTest {
[
[
'name' => 'User fields',
'text' => 'User fields',
'children' => $importExportFactory->formatSubscriberCustomFields(
$importExportFactory->getSubscriberCustomFields()
),
@@ -223,19 +228,23 @@ class ImportExportFactoryTest extends \MailPoetTest {
$select2FieldsWithoutCustomFields = [
[
'name' => 'Actions',
'text' => 'Actions',
'children' => [
[
'id' => 'select',
'name' => 'Select all...',
'text' => 'Select all...',
],
[
'id' => 'deselect',
'name' => 'Deselect all...',
'text' => 'Deselect all...',
],
],
],
[
'name' => 'System fields',
'text' => 'System fields',
'children' => $importExportFactory->formatSubscriberFields(
$importExportFactory->getSubscriberFields()
),
@@ -246,6 +255,7 @@ class ImportExportFactoryTest extends \MailPoetTest {
[
[
'name' => 'User fields',
'text' => 'User fields',
'children' => $importExportFactory->formatSubscriberCustomFields(
$importExportFactory->getSubscriberCustomFields()
),