Hi everyone,
I’m working on a requirement where, when a user clicks the Columns menu option, we need to provide them with both a Search option and a “Select All” feature.
Is it possible to implement these features using OutSystems Forge components? If so, could you offer any suggestions or insights on how to achieve this?
Any advice would be greatly appreciated!
Thank you!
Hi @Sathish Kumar
Take a look at this post that can give you a good starting point.
Cheers,GM
Hello @Sathish Kumar
To have the community help please share an oml with your use case and what you have already tried to make it more collaborative and efficient.Also, try to check on Wijmo's Flexgrid website if the use case is possible and share an example so it can be easier to adapt.
Hi @Gonçalo Martins I don't have any OML for this. A new requirement from the client is that they want both a "Select All" option and a "Search" function in the column picker. above image was mockup screenshot and found a related script for the Select All feature, but I’m having trouble implementing it. Could you help me with this?
Thanks,
Sathish R
Could someone please assist me?
Hi @Gonçalo Martins
The script was working well in standard scenarios, but I've run into an issue when grouping columns. Specifically, when grouping columns in an existing grid, the grouped columns are removed and then re-added according to the new grouping in the ColumnPicker.The problem I’m facing now is that, with the current script, all columns are always visible. When I click Select All, even the grouped columns appear, which is not the desired behavior.Do you have any suggestions or solutions for this issue?Here I attached OML and GIFThanks in advance!
Thank you for the solution for the “Select All” functionality. It will be very helpful in my development. I also need a solution for implementing a search option. Do you have any suggestions for that as well?
Give it a try based on the other use case since the base is already in place and after that share an oml with your attempts and the parts where you're struggling so it can be more efficient and collaborative for the community instead of asking without trying.
Hi @Gonçalo MartinsAdding Search to Columns Picker Menu We achieved this. Below Script Both Selectall and searchJS
function createColumnPickerWithSearch() {
// Create the main container
const columnPickerContainer = document.createElement('div');
columnPickerContainer.style.display = 'none';
columnPickerContainer.classList.add('column-picker-container');
// Create the column picker element
const columnPicker = document.createElement('div');
columnPicker.id = 'theColumnPicker';
columnPicker.classList.add('column-picker');
columnPickerContainer.appendChild(columnPicker);
// Create the search container
const searchContainer = document.createElement('div');
searchContainer.classList.add('column-picker-search-container', 'column-picker-data-child');
// Create the search icon element
// const searchIcon = document.createElement('i');
// searchIcon.classList.add('search-icon', 'fa', 'fa-search'); // Example for FontAwesome
// Create the search input element
const searchInput = document.createElement('input');
searchInput.type = 'text';
searchInput.classList.add('column-picker-search');
searchInput.placeholder = 'Search';
//searchContainer.appendChild(searchIcon);
searchContainer.appendChild(searchInput);
// Create the column picker data element
const columnPickerData = document.createElement('div');
columnPickerData.classList.add('column-picker-data', 'wj-listbox-item');
columnPickerContainer.appendChild(columnPickerData);
// Create the checkbox and label
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.classList.add('selectChk', 'column-picker-data-child');
const label = document.createElement('label');
label.textContent = 'Select All';
checkbox.classList.add('column-picker-data-child');
label.style.margin = '0 0 0 4px';
columnPickerData.appendChild(searchContainer);
columnPickerData.appendChild(checkbox);
columnPickerData.appendChild(label);
return columnPickerContainer;
}
var theGrid = OutSystems.GridAPI.GridManager.GetGridById($parameters.GridWidgetId);
if (theGrid) {
var theColumnPicker = theGrid.features.columnPicker._theColumnPicker;
var columnsToBeDisplayedOnColumnPicker = theGrid.features.columnPicker._getColumnsToBeDisplayedOnColumnPicker();
theColumnPicker.itemsSource = columnsToBeDisplayedOnColumnPicker;
const topLeftCell = theGrid.provider.hostElement.querySelector('.wj-topleft');
topLeftCell.addEventListener('mousedown', (event) => {
const target = event.target;
if (!wijmo.hasClass(target, 'column-picker-icon')) return;
let spanPrev = theGrid.provider.hostElement.querySelector('.column-picker-icon');
spanPrev.outerHTML = spanPrev.outerHTML; // This removes all events
const columnPickerHost = theColumnPicker.hostElement;
const isColumnPickerVisible = columnPickerHost.offsetHeight > 0;
if (!isColumnPickerVisible) {
const alreadyHaveSelectAll = columnPickerHost.querySelector('.column-picker-data') !== null;
const elemSelectAll = alreadyHaveSelectAll ? columnPickerHost.querySelector('.column-picker-data') : createColumnPickerWithSearch();
const columnPickerDataElement = elemSelectAll.querySelector('.column-picker-data');
if (columnPickerDataElement && !alreadyHaveSelectAll) {
const selectCheckbox = columnPickerDataElement.querySelector('.selectChk');
selectCheckbox.checked = true;
columnPickerHost.insertBefore(columnPickerDataElement, columnPickerHost.firstChild);
selectCheckbox.addEventListener('change', (ev) => {
const isChecked = ev.target.checked;
theColumnPicker.checkedItems = isChecked
? theColumnPicker.collectionView.items
: [];
});
columnPickerHost.addEventListener('click', (ev) => {
// Prevent select all checkbox action if the target is the search input
if (ev.target.classList.contains('column-picker-search')) return;
const target = ev.target;
if (wijmo.closestClass(target, 'column-picker-data') && !wijmo.hasClass(target, 'selectChk')) {
if (selectCheckbox.indeterminate) {
selectCheckbox.indeterminate = false;
theColumnPicker.checkedItems = theColumnPicker.collectionView.items;
} else {
selectCheckbox.checked = !selectCheckbox.checked;
theColumnPicker.checkedItems = selectCheckbox.checked
// Add search functionality
const searchInput = columnPickerHost.querySelector('.column-picker-search');
searchInput.addEventListener('input', (ev) => {
const query = ev.target.value.toLowerCase();
filterColumns(query);
updateSelectAllCheckboxState();
wijmo.showPopup(columnPickerHost, topLeftCell, false, true, false);
theColumnPicker.focus();
wijmo.hidePopup(columnPickerHost, true, true);
theGrid.provider.focus();
event.preventDefault();
function filterColumns(query) {
const columnPickerHost = document.getElementById('theColumnPicker');
const columnItems = columnPickerHost.querySelectorAll('.wj-listbox-item:not(.column-picker-data)');
columnItems.forEach(item => {
const label = item.querySelector('label').textContent.toLowerCase();
item.style.display = label.includes(query) ? '' : 'none';
function updateSelectAllCheckboxState() {
if (!theGrid) return;
if (!theColumnPicker) return;
var checkedItemsCount = theColumnPicker.checkedItems.length;
var totalColumnsCount = theGrid.features.columnPicker._getColumnsToBeDisplayedOnColumnPicker().length;
var isSelectAllColumns = (totalColumnsCount === checkedItemsCount);
var selectAllCheckbox = theColumnPicker.hostElement.querySelector('.selectChk');
if (!selectAllCheckbox) return;
selectAllCheckbox.checked = isSelectAllColumns;
selectAllCheckbox.indeterminate = false; // Ensure it's not in indeterminate state
function addCheckboxChangeListener() {
theColumnPicker.collectionView.collectionChanged.addHandler(() => {
addCheckboxChangeListener();
CSS
.wj-listbox.column-picker { display: grid; grid-template-columns: repeat(1, 1fr); grid-gap: 0 10px; columns: 1; /* IE fallback */ padding: 12px; margin-left: 12px; margin-top: 26px; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);}.wj-listbox .wj-listbox-item > label { display: block; margin: 0 0 3px 0;}.wj-listbox .wj-listbox-item.wj-state-selected { background: transparent; color: inherit;}.wj-listbox .wj-listbox-item:hover { background: rgba(0, 0, 0, 0.05);}.wj-listbox .drop-marker { position: absolute; background: #0085c7; opacity: 0.5; pointer-events: none; z-index: 1000;}.column-picker-data { padding: 4px 6px 3px 6px !important; display: flex; flex-wrap: wrap; max-width: 190px;}.column-picker-data .selectChk { margin: 4px;}.column-picker-data-child { flex: 0 1 auto;}.column-picker-data-child:nth-child(1) { flex-basis: 100%;}.column-picker-search-container { margin-bottom: 8px; display: flex; /* Ensure proper alignment of the icon and input */ align-items: center;}.search-icon { margin-right: 8px; /* Space between the icon and the input */ font-size: 16px; /* Size of the icon */ color: #888; /* Color of the icon */}.column-picker-search { border-color: var(--color-primary) !important; height: 30px; padding-left: 10px; /* Ensure padding accommodates the icon */ flex: 1; /* Ensure the input takes up remaining space */ width: 100px;}
The script was working well in standard scenarios, but I've run into an issue when grouping columns. Specifically, when grouping columns in an existing grid, the grouped columns are removed and then re-added according to the new grouping in the ColumnPicker.The problem I’m facing now is that, with the current script, all columns are always visible. When I click Select All, even the grouped columns appear, which is not the desired behavior.Do you have any suggestions or solutions for this issue?Thanks in advance!