通过多个下拉列表过滤对象
filter objects by multiple dropdowns
我有很多按钮,每个按钮有三个 class。第一个 class 可以是 "a1"、"a2" 或 "a3"。第二个 class 可以是 "b1"、"b2" 或 "b3"。第三个 class 与 "c" 相同。例如:
<body>
<button type="button" class="a1 b3 c3">Button 1</button>
<button type="button" class="a1 b3 c1">Button 2</button>
<button type="button" class="a2 b2 c2">Button 3</button>
<button type="button" class="a3 b1 c3">Button 4</button>
</body>
我想做的是过滤这些按钮,使它们仅在每种 class:
的下拉菜单中选择合适的 classes 时可见
<select name="a">
<option>all</option>
<option>a1</option>
<option>a2</option>
<option>a3</option>
</select>
<select name="b">
<option>all</option>
<option>b1</option>
<option>b2</option>
<option>b3</option>
</select>
<select name="c">
<option>all</option>
<option>c1</option>
<option>c2</option>
<option>c3</option>
</select>
例如:如果在下拉菜单中选择了 a "a1" 和 b "b3" 以及 c "all",则按钮 1 和按钮 2 应该是可见的。
另一点是,如果在下拉菜单中选择 "a1",则在菜单 b 中应该只有 "all" 和 "b3" 可见。
感谢您的帮助
好的。所以我在每个按钮上添加了一个 group-class 这样就可以更容易地 select 某个特定的组。如果你想离开组classes,你需要另一种算法all
过滤器。
但这里有一个可能的解决方案:
// Define default filters
const filters = {
a: 'all',
b: 'all',
c: 'all',
};
function filterButtons() {
// Hide all buttons for now
setDisplay( document.querySelectorAll( 'button' ), 'none' );
// Iterate over filters
Object.keys( filters ).forEach( key => {
const className = filters[ key ];
// Determine to show all buttons of a certain group or just a certain class
let selector = className === 'all' ? key : className;
setDisplay( document.querySelectorAll( `.${ selector }` ), 'inline' );
} );
}
// Helper function to set display style on a HTMLCollection
function setDisplay( collection, display ) {
[ ...collection ].forEach( button => button.style.display = display );
}
// Adding eventListeners so we recognize changes
[ ...document.querySelectorAll( 'select' ) ].forEach( selector => {
selector.addEventListener( 'change', ( event ) => {
// Set filters on dropdown change
filters[ event.target.name ] = event.target.value;
// Filter buttons on change
filterButtons();
} );
} );
<div>
<select name="a">
<option>all</option>
<option>a1</option>
<option>a2</option>
<option>a3</option>
</select>
<select name="b">
<option>all</option>
<option>b1</option>
<option>b2</option>
<option>b3</option>
</select>
<select name="c">
<option>all</option>
<option>c1</option>
<option>c2</option>
<option>c3</option>
</select>
</div>
<div>
<!-- I added the base class so it would be easier to select all of a certain group -->
<button type="button" class="a b c a1 b3 c3">Button 1</button>
<button type="button" class="a b c a1 b3 c1">Button 2</button>
<button type="button" class="a b c a2 b2 c2">Button 3</button>
<button type="button" class="a b c a3 b1 c3">Button 4</button>
</div>
我有很多按钮,每个按钮有三个 class。第一个 class 可以是 "a1"、"a2" 或 "a3"。第二个 class 可以是 "b1"、"b2" 或 "b3"。第三个 class 与 "c" 相同。例如:
<body>
<button type="button" class="a1 b3 c3">Button 1</button>
<button type="button" class="a1 b3 c1">Button 2</button>
<button type="button" class="a2 b2 c2">Button 3</button>
<button type="button" class="a3 b1 c3">Button 4</button>
</body>
我想做的是过滤这些按钮,使它们仅在每种 class:
的下拉菜单中选择合适的 classes 时可见 <select name="a">
<option>all</option>
<option>a1</option>
<option>a2</option>
<option>a3</option>
</select>
<select name="b">
<option>all</option>
<option>b1</option>
<option>b2</option>
<option>b3</option>
</select>
<select name="c">
<option>all</option>
<option>c1</option>
<option>c2</option>
<option>c3</option>
</select>
例如:如果在下拉菜单中选择了 a "a1" 和 b "b3" 以及 c "all",则按钮 1 和按钮 2 应该是可见的。 另一点是,如果在下拉菜单中选择 "a1",则在菜单 b 中应该只有 "all" 和 "b3" 可见。
感谢您的帮助
好的。所以我在每个按钮上添加了一个 group-class 这样就可以更容易地 select 某个特定的组。如果你想离开组classes,你需要另一种算法all
过滤器。
但这里有一个可能的解决方案:
// Define default filters
const filters = {
a: 'all',
b: 'all',
c: 'all',
};
function filterButtons() {
// Hide all buttons for now
setDisplay( document.querySelectorAll( 'button' ), 'none' );
// Iterate over filters
Object.keys( filters ).forEach( key => {
const className = filters[ key ];
// Determine to show all buttons of a certain group or just a certain class
let selector = className === 'all' ? key : className;
setDisplay( document.querySelectorAll( `.${ selector }` ), 'inline' );
} );
}
// Helper function to set display style on a HTMLCollection
function setDisplay( collection, display ) {
[ ...collection ].forEach( button => button.style.display = display );
}
// Adding eventListeners so we recognize changes
[ ...document.querySelectorAll( 'select' ) ].forEach( selector => {
selector.addEventListener( 'change', ( event ) => {
// Set filters on dropdown change
filters[ event.target.name ] = event.target.value;
// Filter buttons on change
filterButtons();
} );
} );
<div>
<select name="a">
<option>all</option>
<option>a1</option>
<option>a2</option>
<option>a3</option>
</select>
<select name="b">
<option>all</option>
<option>b1</option>
<option>b2</option>
<option>b3</option>
</select>
<select name="c">
<option>all</option>
<option>c1</option>
<option>c2</option>
<option>c3</option>
</select>
</div>
<div>
<!-- I added the base class so it would be easier to select all of a certain group -->
<button type="button" class="a b c a1 b3 c3">Button 1</button>
<button type="button" class="a b c a1 b3 c1">Button 2</button>
<button type="button" class="a b c a2 b2 c2">Button 3</button>
<button type="button" class="a b c a3 b1 c3">Button 4</button>
</div>