Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport release_3_9] Form filter: filter autocomplete list based on previous applied filters #5088

Merged
merged 8 commits into from
Dec 5, 2024
75 changes: 42 additions & 33 deletions assets/src/legacy/filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,48 +390,57 @@ var lizLayerFilterTool = function () {
* @param field_item
*/
function textFormInput(field_item) {
// Ajout des données d'autocompletion
var field = field_item['field'];
var sdata = {
request: 'getUniqueValues',
layerId: field_item.layerId,
fieldname: field,
filter: ''
};
$.get(globalThis['filterConfigData'].url, sdata, function (result) {
if (!checkResult(result)) {
return false;
}

var autocompleteData = [];
for (var a in result) {
var feat = result[a];
if (feat['v'] === null || !feat['v'] || (typeof feat['v'] === 'string' && feat['v'].trim() === ''))
continue;
autocompleteData.push(feat['v']);
}

var html = '';
html += getFormFieldHeader(field_item);
html += '<div style="width: 100%;">'
html += '<input id="liz-filter-field-text' + lizMap.cleanName(field_item.title) + '" class="liz-filter-field-text" value="" title="' + lizDict['filter.input.text.title'] + '" placeholder="' + lizDict['filter.input.text.placeholder'] + '">';
html += '</div>'
html += getFormFieldFooter(field_item);

$("#filter-field-order" + String(field_item.order)).append(html);
addFieldEvents(field_item);

$("#liz-filter-field-text" + lizMap.cleanName(field_item.title)).autocomplete({
source: autocompleteData,
autoFocus: false, // do not autofocus, because this prevents from searching with LIKE
delay: 200,
minLength: 2,
select: function (event, ui) {
$(this).val(ui.item.value);
$(this).change();
var html = '';
html += getFormFieldHeader(field_item);
html += '<div style="width: 100%;">'
html += '<input id="liz-filter-field-text' + lizMap.cleanName(field_item.title) + '" class="liz-filter-field-text" value="" title="' + lizDict['filter.input.text.title'] + '" placeholder="' + lizDict['filter.input.text.placeholder'] + '">';
html += '</div>'
html += getFormFieldFooter(field_item);

$("#filter-field-order" + String(field_item.order)).append(html);
addFieldEvents(field_item);

$("#liz-filter-field-text" + lizMap.cleanName(field_item.title)).autocomplete({
source: function (request, response) {
const autocompleteFilter = `"${field}" ILIKE '%${request.term}%' `;
if (!globalThis['filterConfigData'].filter) {
sdata.filter = autocompleteFilter;
} else {
sdata.filter = ' ( ' + globalThis['filterConfigData'].filter + ' ) AND ' + autocompleteFilter;
}
});
}, 'json');
fetch(globalThis['filterConfigData'].url, {
method: "POST",
body: new URLSearchParams(sdata)
}).then(response => {
return response.json();
}).then(result => {
var autocompleteData = [];
for (var a in result) {
var feat = result[a];
if (feat['v'] === null || !feat['v'] || (typeof feat['v'] === 'string' && feat['v'].trim() === '')) {
continue;
}
autocompleteData.push(feat['v']);
}
response(autocompleteData);
});
},
autoFocus: false, // do not autofocus, because this prevents from searching with LIKE
delay: 500,
minLength: 3,
select: function (event, ui) {
$(this).val(ui.item.value);
$(this).blur();
}
});
}

// Get the HTML form element for the uniqueValues field type
Expand Down
70 changes: 0 additions & 70 deletions tests/end2end/cypress/integration/form-filter-ghaction.js

This file was deleted.

106 changes: 106 additions & 0 deletions tests/end2end/playwright/form-filter.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// @ts-check
import { test, expect } from '@playwright/test';
import { gotoMap } from './globals';

test.describe('Form filter', () => {
test.beforeEach(async ({ page }) => {
const url = '/index.php/view/map/?repository=testsrepository&project=form_filter';
await gotoMap(url, page);
await page.locator('#button-filter').click();
});

test('Form filter with combobox', async ({ page }) => {
let getMapPromise = page.waitForRequest(/GetMap/);

const combo = '#liz-filter-field-test_filter';
const countFeature = '#liz-filter-item-layer-total-count';

// Default
await expect(page.locator('#liz-filter-item-layer-total-count')).toHaveText('4');
await expect(page.locator(combo + ' > option:nth-child(1)')).toHaveText(' --- ');

// Open the attribute tables for the 2 layers
await page.locator('#button-attributeLayers').click();
await page.locator('button[value="form_filter__a_"].btn-open-attribute-layer').click({ force: true });
await page.locator('#nav-tab-attribute-summary').click();
await page.locator('button[value="form_filter_child_bus_stops"].btn-open-attribute-layer').click({ force: true });

// Select the first one
await page.locator(combo).selectOption('_uvres_d_art_et_monuments_de_l_espace_urbain');
await expect(page.locator(countFeature)).toHaveText('1');

let getMapRequest = await getMapPromise;
// Re-send the request with additionnal echo param to retrieve the WMS Request
let echoGetMap = await page.request.get(getMapRequest.url() + '&__echo__');
let originalUrl = decodeURIComponent(await echoGetMap.text());
let urlObj = new URLSearchParams((new URL(originalUrl).search));

expect(urlObj.get('filter')).toBe('form_filter_layer:"id" IN ( 2 ) ');

// Check the attribute table shows only one line
await page.locator('#nav-tab-attribute-layer-form_filter__a_').click({ force: true });
await expect(page.locator('#attribute-layer-table-form_filter__a_ tbody tr')).toHaveCount(1);

// Check the child features are filtered too (3 children)
await page.locator('#nav-tab-attribute-layer-form_filter_child_bus_stops').click({ force: true });
await expect(page.locator('#attribute-layer-table-form_filter_child_bus_stops tbody tr')).toHaveCount(3);

// Reset
getMapPromise = page.waitForRequest(/GetMap/);
page.locator('#liz-filter-unfilter').click();
await expect(page.locator(countFeature)).toHaveText('4');

getMapRequest = await getMapPromise;

// Re-send the request with additionnal echo param to retrieve the WMS Request
echoGetMap = await page.request.get(getMapRequest.url() + '&__echo__');
originalUrl = decodeURIComponent(await echoGetMap.text());
urlObj = new URLSearchParams((new URL(originalUrl).search));

expect(urlObj.get('filter')).toBeNull();

// Select the second one
await page.locator(combo).selectOption('simple_label');
await expect(page.locator(countFeature)).toHaveText('1');

// Check the attribute table shows only one line
await getMapPromise;
await page.locator('#nav-tab-attribute-layer-form_filter__a_').click({ force: true });
await expect(page.locator('#attribute-layer-table-form_filter__a_ tbody tr')).toHaveCount(1);

// Check the child features are filtered too (2 children)
await page.locator('#nav-tab-attribute-layer-form_filter_child_bus_stops').click({ force: true });
await expect(page.locator('#attribute-layer-table-form_filter_child_bus_stops tbody tr')).toHaveCount(2);

// Disable combobox
await page.locator('div#liz-filter-box-test_filter button.btn-primary:nth-child(2)').click();
await expect(page.locator(countFeature)).toHaveText('4');
});

test('Form filter with autocomplete', async ({ page }) => {
await page.locator('#liz-filter-field-textautocomplete').fill('mon');

// Assert autocomplete list has 3 values
await expect(page.locator('#ui-id-2 .ui-menu-item')).toHaveCount(3);

await page.locator('#liz-filter-field-textautocomplete').fill('');

// Filter by ID then assert autocomplete list has now 2 values
// when filling 'mon' in the autocomplete field
await page.locator('#liz-filter-field-max-numericIDs').fill('3');
await page.locator('#liz-filter-field-textautocomplete').fill('mon');
await expect(page.locator('#ui-id-2 .ui-menu-item')).toHaveCount(2);

// Reset
await page.locator('#liz-filter-field-textautocomplete').fill('');
await page.locator('#liz-filter-unfilter').click();

// Filter by combobox then assert autocomplete list has now 1 value
// when filling 'mon' in the autocomplete field
await page.locator('#liz-filter-field-test_filter').selectOption('monuments');
await page.locator('#liz-filter-field-textautocomplete').fill('mon');
await expect(page.locator('#ui-id-2 .ui-menu-item')).toHaveCount(1);
await expect(page.locator('#ui-id-2 .ui-menu-item div')).toHaveText('monuments');
});
});

12 changes: 0 additions & 12 deletions tests/qgis-projects/tests/form_filter.md

This file was deleted.

Loading
Loading