Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.

Commit dd2fed0

Browse files
authored
Merge pull request #646 from ghiscoding/feat/multiple-select-left-position
feat(filters): add auto position (left/right) to multiple-select lib
2 parents 6459035 + 1b23b84 commit dd2fed0

File tree

2 files changed

+76
-34
lines changed

2 files changed

+76
-34
lines changed

src/app/examples/grid-graphql-nopage.component.ts

Lines changed: 58 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -73,36 +73,6 @@ export class GridGraphqlWithoutPaginationComponent implements OnInit {
7373
{ id: 'countryPhone', field: 'phone', name: 'Phone Area Code', maxWidth: 110, sortable: true, filterable: true, columnGroup: 'Country' },
7474
{ id: 'countryCurrency', field: 'currency', name: 'Currency', maxWidth: 90, sortable: true, filterable: true, columnGroup: 'Country' },
7575
{ id: 'countryEmoji', field: 'emoji', name: 'Emoji', maxWidth: 90, sortable: true, columnGroup: 'Country' },
76-
{
77-
id: 'continentCode', field: 'continent.code', name: 'Code', maxWidth: 90,
78-
sortable: true,
79-
filterable: true,
80-
filter: {
81-
model: Filters.singleSelect,
82-
collectionAsync: this.getContinents(),
83-
collectionOptions: {
84-
// the data is not at the root of the array, so we must tell the Select Filter where to pull the data
85-
collectionInsideObjectProperty: 'data.continents',
86-
addBlankEntry: true,
87-
separatorBetweenTextLabels: ': ',
88-
},
89-
customStructure: {
90-
value: 'code',
91-
label: 'code',
92-
labelSuffix: 'name',
93-
}
94-
},
95-
formatter: Formatters.complexObject, columnGroup: 'Continent',
96-
},
97-
{
98-
id: 'continentName', field: 'continent.name', name: 'Name', width: 60, sortable: true,
99-
filterable: true, formatter: Formatters.complexObject, columnGroup: 'Continent'
100-
},
101-
{
102-
id: 'languageCode', field: 'languages.code', name: 'Codes', maxWidth: 100,
103-
formatter: Formatters.arrayObjectToCsv, params: { propertyNames: ['code'], useFormatterOuputToFilter: true }, columnGroup: 'Language',
104-
filterable: true,
105-
},
10676
{
10777
id: 'languageName', field: 'languages.name', name: 'Names', width: 60,
10878
formatter: Formatters.arrayObjectToCsv, columnGroup: 'Language',
@@ -139,7 +109,63 @@ export class GridGraphqlWithoutPaginationComponent implements OnInit {
139109
},
140110
{
141111
id: 'languageNative', field: 'languages.native', name: 'Native', width: 60,
142-
formatter: Formatters.arrayObjectToCsv, params: { propertyNames: ['native'] }, columnGroup: 'Language',
112+
formatter: Formatters.arrayObjectToCsv, params: { propertyNames: ['native'], useFormatterOuputToFilter: true }, columnGroup: 'Language',
113+
filterable: true,
114+
filter: {
115+
model: Filters.multipleSelect,
116+
collectionAsync: this.getLanguages(),
117+
operator: OperatorType.inContains,
118+
collectionOptions: {
119+
addBlankEntry: true,
120+
// the data is not at the root of the array, so we must tell the Select Filter where to pull the data
121+
collectionInsideObjectProperty: 'data.languages'
122+
},
123+
collectionFilterBy: [
124+
// filter out any empty values
125+
{ property: 'native', value: '', operator: 'NE' },
126+
{ property: 'native', value: null, operator: 'NE' },
127+
],
128+
collectionSortBy: {
129+
property: 'native'
130+
},
131+
customStructure: {
132+
value: 'native',
133+
label: 'native',
134+
},
135+
filterOptions: {
136+
filter: true
137+
} as MultipleSelectOption
138+
},
139+
},
140+
{
141+
id: 'languageCode', field: 'languages.code', name: 'Codes', maxWidth: 100,
142+
formatter: Formatters.arrayObjectToCsv, params: { propertyNames: ['code'], useFormatterOuputToFilter: true }, columnGroup: 'Language',
143+
filterable: true,
144+
},
145+
{
146+
id: 'continentName', field: 'continent.name', name: 'Name', width: 60, sortable: true,
147+
filterable: true, formatter: Formatters.complexObject, columnGroup: 'Continent'
148+
},
149+
{
150+
id: 'continentCode', field: 'continent.code', name: 'Code', maxWidth: 90,
151+
sortable: true,
152+
filterable: true,
153+
filter: {
154+
model: Filters.singleSelect,
155+
collectionAsync: this.getContinents(),
156+
collectionOptions: {
157+
// the data is not at the root of the array, so we must tell the Select Filter where to pull the data
158+
collectionInsideObjectProperty: 'data.continents',
159+
addBlankEntry: true,
160+
separatorBetweenTextLabels: ': ',
161+
},
162+
customStructure: {
163+
value: 'code',
164+
label: 'code',
165+
labelSuffix: 'name',
166+
}
167+
},
168+
formatter: Formatters.complexObject, columnGroup: 'Continent',
143169
},
144170
];
145171

@@ -212,7 +238,7 @@ export class GridGraphqlWithoutPaginationComponent implements OnInit {
212238
* We also need to resolve the data in a flat array (singleSelect/multipleSelect Filters only accept data at the root of the array)
213239
*/
214240
getLanguages() {
215-
const languageQuery = `query { languages { code, name }}`;
241+
const languageQuery = `query { languages { code, name, native }}`;
216242
return this.http.post<GraphqlResult<Country>>(COUNTRIES_API, { query: languageQuery });
217243
}
218244
}

src/assets/lib/multiple-select/multiple-select.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @author zhixin wen <[email protected]>
3-
* @version 1.3.7
3+
* @version 1.3.9
44
*
55
* http://wenzhixin.net.cn/p/multiple-select/
66
*
@@ -14,7 +14,7 @@
1414
* - width option was not working when using "container", added some code to support it
1515
* - "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)
1616
* - "autoAdjustDropHeight" (defaults to False) when set will automatically adjust the drop (up or down) height
17-
* - "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)
17+
* - "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)
1818
* - "autoDropWidth" (defaults to False) when set will automatically adjust the dropdown width with the same size as the select element width
1919
* - "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)
2020
* - "adjustHeightPadding" (defaults to 10) when using "autoAdjustDropHeight" we might want to add a bottom (or top) padding instead of taking the entire available space
@@ -629,9 +629,13 @@
629629
adjustDropPosition: function (forceToggle) {
630630
var position = 'bottom';
631631
var msDropHeight = this.$drop.outerHeight() || 0;
632+
var msDropWidth = this.$drop.outerWidth() || 0;
632633
var selectOffsetTop = this.$parent.offset().top;
634+
var selectParentWidth = this.$parent.width();
633635
var spaceBottom = this.availableSpaceBottom();
636+
var spaceLeft = this.availableSpaceLeft();
634637
var spaceTop = this.availableSpaceTop();
638+
var windowWidth = $(window).width();
635639

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

664+
// auto-adjust left/right position
665+
if ((windowWidth - msDropWidth) < spaceLeft) {
666+
var newLeftOffset = spaceLeft - (msDropWidth - selectParentWidth);
667+
this.$drop.offset({ left: newLeftOffset });
668+
}
669+
660670
return position;
661671
},
662672

@@ -715,6 +725,12 @@
715725
return windowHeight - (msDropOffsetTop - pageScroll);
716726
},
717727

728+
availableSpaceLeft: function () {
729+
var pageScrollLeft = $(window).scrollLeft() || 0;
730+
var msDropOffsetLeft = this.$parent.offset().left;
731+
return msDropOffsetLeft - pageScrollLeft;
732+
},
733+
718734
availableSpaceTop: function () {
719735
var pageScroll = $(window).scrollTop() || 0;
720736
var msDropOffsetTop = this.$parent.offset().top;

0 commit comments

Comments
 (0)