Skip to content

Commit

Permalink
Merge pull request #5088 from 3liz/backport-5045-to-release_3_9
Browse files Browse the repository at this point in the history
[Backport release_3_9] Form filter: filter autocomplete list based on previous applied filters
  • Loading branch information
nboisteault authored Dec 5, 2024
2 parents 2d0249d + d2a95a4 commit 2c1f580
Show file tree
Hide file tree
Showing 7 changed files with 719 additions and 439 deletions.
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

0 comments on commit 2c1f580

Please sign in to comment.