Skip to content

Commit

Permalink
feat(filters): add auto position (left/right) to multiple-select lib
Browse files Browse the repository at this point in the history
- `autoAdjustDropPosition` option should not only adjust top/bottom, it should also adjust left/right
  • Loading branch information
ghiscoding committed Dec 10, 2020
1 parent 6459035 commit 1b23b84
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 34 deletions.
90 changes: 58 additions & 32 deletions src/app/examples/grid-graphql-nopage.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,36 +73,6 @@ export class GridGraphqlWithoutPaginationComponent implements OnInit {
{ id: 'countryPhone', field: 'phone', name: 'Phone Area Code', maxWidth: 110, sortable: true, filterable: true, columnGroup: 'Country' },
{ id: 'countryCurrency', field: 'currency', name: 'Currency', maxWidth: 90, sortable: true, filterable: true, columnGroup: 'Country' },
{ id: 'countryEmoji', field: 'emoji', name: 'Emoji', maxWidth: 90, sortable: true, columnGroup: 'Country' },
{
id: 'continentCode', field: 'continent.code', name: 'Code', maxWidth: 90,
sortable: true,
filterable: true,
filter: {
model: Filters.singleSelect,
collectionAsync: this.getContinents(),
collectionOptions: {
// the data is not at the root of the array, so we must tell the Select Filter where to pull the data
collectionInsideObjectProperty: 'data.continents',
addBlankEntry: true,
separatorBetweenTextLabels: ': ',
},
customStructure: {
value: 'code',
label: 'code',
labelSuffix: 'name',
}
},
formatter: Formatters.complexObject, columnGroup: 'Continent',
},
{
id: 'continentName', field: 'continent.name', name: 'Name', width: 60, sortable: true,
filterable: true, formatter: Formatters.complexObject, columnGroup: 'Continent'
},
{
id: 'languageCode', field: 'languages.code', name: 'Codes', maxWidth: 100,
formatter: Formatters.arrayObjectToCsv, params: { propertyNames: ['code'], useFormatterOuputToFilter: true }, columnGroup: 'Language',
filterable: true,
},
{
id: 'languageName', field: 'languages.name', name: 'Names', width: 60,
formatter: Formatters.arrayObjectToCsv, columnGroup: 'Language',
Expand Down Expand Up @@ -139,7 +109,63 @@ export class GridGraphqlWithoutPaginationComponent implements OnInit {
},
{
id: 'languageNative', field: 'languages.native', name: 'Native', width: 60,
formatter: Formatters.arrayObjectToCsv, params: { propertyNames: ['native'] }, columnGroup: 'Language',
formatter: Formatters.arrayObjectToCsv, params: { propertyNames: ['native'], useFormatterOuputToFilter: true }, columnGroup: 'Language',
filterable: true,
filter: {
model: Filters.multipleSelect,
collectionAsync: this.getLanguages(),
operator: OperatorType.inContains,
collectionOptions: {
addBlankEntry: true,
// the data is not at the root of the array, so we must tell the Select Filter where to pull the data
collectionInsideObjectProperty: 'data.languages'
},
collectionFilterBy: [
// filter out any empty values
{ property: 'native', value: '', operator: 'NE' },
{ property: 'native', value: null, operator: 'NE' },
],
collectionSortBy: {
property: 'native'
},
customStructure: {
value: 'native',
label: 'native',
},
filterOptions: {
filter: true
} as MultipleSelectOption
},
},
{
id: 'languageCode', field: 'languages.code', name: 'Codes', maxWidth: 100,
formatter: Formatters.arrayObjectToCsv, params: { propertyNames: ['code'], useFormatterOuputToFilter: true }, columnGroup: 'Language',
filterable: true,
},
{
id: 'continentName', field: 'continent.name', name: 'Name', width: 60, sortable: true,
filterable: true, formatter: Formatters.complexObject, columnGroup: 'Continent'
},
{
id: 'continentCode', field: 'continent.code', name: 'Code', maxWidth: 90,
sortable: true,
filterable: true,
filter: {
model: Filters.singleSelect,
collectionAsync: this.getContinents(),
collectionOptions: {
// the data is not at the root of the array, so we must tell the Select Filter where to pull the data
collectionInsideObjectProperty: 'data.continents',
addBlankEntry: true,
separatorBetweenTextLabels: ': ',
},
customStructure: {
value: 'code',
label: 'code',
labelSuffix: 'name',
}
},
formatter: Formatters.complexObject, columnGroup: 'Continent',
},
];

Expand Down Expand Up @@ -212,7 +238,7 @@ export class GridGraphqlWithoutPaginationComponent implements OnInit {
* We also need to resolve the data in a flat array (singleSelect/multipleSelect Filters only accept data at the root of the array)
*/
getLanguages() {
const languageQuery = `query { languages { code, name }}`;
const languageQuery = `query { languages { code, name, native }}`;
return this.http.post<GraphqlResult<Country>>(COUNTRIES_API, { query: languageQuery });
}
}
20 changes: 18 additions & 2 deletions src/assets/lib/multiple-select/multiple-select.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @author zhixin wen <wenzhixin2010@gmail.com>
* @version 1.3.7
* @version 1.3.9
*
* http://wenzhixin.net.cn/p/multiple-select/
*
Expand All @@ -14,7 +14,7 @@
* - width option was not working when using "container", added some code to support it
* - "offsetLeft" (defaults to 0) if we want the drop to be offset from the select element (by default it is aligned left to the element with 0 offset)
* - "autoAdjustDropHeight" (defaults to False) when set will automatically adjust the drop (up or down) height
* - "autoAdjustDropPosition" (defaults to False) when set will automatically calculate the area with the most available space and use best possible choise for the drop to show (up or down)
* - "autoAdjustDropPosition" (defaults to False) when set will automatically calculate the area with the most available space and use best possible choice for the drop to show (up/down and left/right)
* - "autoDropWidth" (defaults to False) when set will automatically adjust the dropdown width with the same size as the select element width
* - "autoAdjustDropWidthByTextSize" (defaults to false) when set will automatically adjust the drop (up or down) width by the text size (it will use largest text width)
* - "adjustHeightPadding" (defaults to 10) when using "autoAdjustDropHeight" we might want to add a bottom (or top) padding instead of taking the entire available space
Expand Down Expand Up @@ -629,9 +629,13 @@
adjustDropPosition: function (forceToggle) {
var position = 'bottom';
var msDropHeight = this.$drop.outerHeight() || 0;
var msDropWidth = this.$drop.outerWidth() || 0;
var selectOffsetTop = this.$parent.offset().top;
var selectParentWidth = this.$parent.width();
var spaceBottom = this.availableSpaceBottom();
var spaceLeft = this.availableSpaceLeft();
var spaceTop = this.availableSpaceTop();
var windowWidth = $(window).width();

// find the optimal position of the drop (always choose "bottom" as the default to use)
if (spaceBottom > msDropHeight) {
Expand All @@ -657,6 +661,12 @@
this.$drop.removeClass('bottom');
}

// auto-adjust left/right position
if ((windowWidth - msDropWidth) < spaceLeft) {
var newLeftOffset = spaceLeft - (msDropWidth - selectParentWidth);
this.$drop.offset({ left: newLeftOffset });
}

return position;
},

Expand Down Expand Up @@ -715,6 +725,12 @@
return windowHeight - (msDropOffsetTop - pageScroll);
},

availableSpaceLeft: function () {
var pageScrollLeft = $(window).scrollLeft() || 0;
var msDropOffsetLeft = this.$parent.offset().left;
return msDropOffsetLeft - pageScrollLeft;
},

availableSpaceTop: function () {
var pageScroll = $(window).scrollTop() || 0;
var msDropOffsetTop = this.$parent.offset().top;
Expand Down

0 comments on commit 1b23b84

Please sign in to comment.