Skip to content

Commit 81d1f66

Browse files
committed
Add DropdownSearchFilter Class to add rules implementation and handle close button + update MainSearchBar
1 parent 3764b7b commit 81d1f66

File tree

8 files changed

+150
-21
lines changed

8 files changed

+150
-21
lines changed

assets/css/style.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

assets/scss/bootstrap-override/_variables.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ $h5-font-size: $font-size-base * 1.25 !default;
3838
$h6-font-size: $font-size-base * .85;
3939
$h7-font-size: $font-size-base * 1.05;
4040

41+
$badge-font-size: .6em;
42+
4143
// scss-docs-start font-sizes
4244
$font-sizes: (
4345
1: $h1-font-size,
@@ -88,7 +90,9 @@ $position-values: (
8890
0: 0,
8991
5: 5%,
9092
10: 10%,
93+
20: 20%,
9194
35: 35%,
95+
40: 40%,
9296
50: 50%,
9397
100: 100%
9498
);

index.html

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ <h1 class="d-flex flex-column align-items-center font-monospace text-uppercase t
9090
<!-- Filters -->
9191
<div class="row d-flex align-items-center mb-5">
9292
<div class="col-10">
93-
<!-- Custom select boxes -->
94-
<div class="row">
93+
<!-- Select boxes -->
94+
<div class="row search-filters">
9595
<!-- Ingredients dropdown -->
9696
<div class="col-12 col-md-4 col-lg-2">
9797
<div class="position-relative mb-3">
@@ -123,7 +123,9 @@ <h1 class="d-flex flex-column align-items-center font-monospace text-uppercase t
123123
type="search"
124124
class="form-control w-90 mx-auto rounded-0 opacity-50 bg-white"
125125
aria-label="Filtrer par ingrégrient">
126-
<span class="fa-solid fa-magnifying-glass position-absolute bottom-50 end-10 opacity-25" aria-hidden="true"></span>
126+
<button type="button" class="btn-close d-none position-absolute bottom-50 end-20 badge opacity-50" aria-label="Supprimer cet ingrédient">
127+
</button>
128+
<span class="fa-solid fa-magnifying-glass text-black-50 position-absolute bottom-50 end-10 z-1 bg-white" aria-hidden="true"></span>
127129
</li>
128130
</ul>
129131
</div>
@@ -159,7 +161,9 @@ <h1 class="d-flex flex-column align-items-center font-monospace text-uppercase t
159161
type="search"
160162
class="form-control w-90 mx-auto rounded-0 opacity-50 bg-white"
161163
aria-label="Filtrer par appareil">
162-
<span class="fa-solid fa-magnifying-glass position-absolute bottom-50 end-10 opacity-25" aria-hidden="true"></span>
164+
<button type="button" class="btn-close d-none position-absolute bottom-50 end-20 badge opacity-50" aria-label="Supprimer cet appareil">
165+
</button>
166+
<span class="fa-solid fa-magnifying-glass text-black-50 position-absolute bottom-50 end-10 z-1 bg-white" aria-hidden="true"></span>
163167
</li>
164168
</ul>
165169
</div>
@@ -195,12 +199,14 @@ <h1 class="d-flex flex-column align-items-center font-monospace text-uppercase t
195199
type="search"
196200
class="form-control w-90 mx-auto rounded-0 opacity-50 bg-white"
197201
aria-label="Filtrer par ustensile">
198-
<span class="fa-solid fa-magnifying-glass position-absolute bottom-50 end-10 opacity-25" aria-hidden="true"></span>
202+
<button type="button" class="btn-close d-none position-absolute bottom-50 end-20 badge opacity-50" aria-label="Supprimer cet ustensile">
203+
</button>
204+
<span class="fa-solid fa-magnifying-glass text-black-50 position-absolute bottom-50 end-10 z-1 bg-white" aria-hidden="true"></span>
199205
</li>
200206
</ul>
201207
</div>
202208
</div> <!-- End Ustensils dropdown -->
203-
</div> <!-- End Custom select boxes -->
209+
</div> <!-- End Select boxes -->
204210
<!-- Filtered tags -->
205211
<div class="row">
206212
<div class="col-12">
@@ -237,7 +243,8 @@ <h1 class="d-flex flex-column align-items-center font-monospace text-uppercase t
237243
<script src="js/pages/RecipesPage.js"></script>
238244
<!-- components -->
239245
<script src="/js/components/MainSearchBar.js"></script>
240-
<script src="/js/components/DropdownList.js"></script>
246+
<script src="/js/components/DropdownSearchFilter.js"></script>
247+
<script src="/js/components/DataDropdownList.js"></script>
241248
<!-- utils -->
242249
<script src="/js/utils/RecipesCounter.js"></script>
243250
<!-- Entry point -->

js/RecipesApp.js

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ class RecipesApp {
1111
this.dataApi = new DataApi('/data/recipes.json');
1212
this.recipesPage = new RecipesPage();
1313
this.tags = new Array();
14+
15+
// DOM
16+
this.$searchFilterInputs = document.querySelectorAll('.search-filters li input');
1417
}
1518

1619
async init() {
@@ -30,16 +33,16 @@ class RecipesApp {
3033
}
3134
});
3235

33-
// Select boxes
34-
const dropdownList = new DropdownList();
35-
dropdownList.displaySelectBoxesWithData(this.recipesData);
36-
3736
// Cards
3837
this.displayRecipeCardsWithData();
3938

4039
// Main search bar
4140
new MainSearchBar();
4241

42+
// Select boxes
43+
this.displayDropDownListOnSearchFilters();
44+
this.isUserInputValueMatchesOnSearchFilter();
45+
4346
// Tags
4447
this.tags.push('item 1', 'item 2', 'item 3');
4548
const tags = this.tags;
@@ -59,6 +62,32 @@ class RecipesApp {
5962
this.recipesPage.displayRecipesCounter(this.recipesData);
6063
}
6164

65+
/**
66+
* Displays initial data on dropdown search filter
67+
*/
68+
displayDropDownListOnSearchFilters() {
69+
const dataDropdownList = new DataDropdownList();
70+
dataDropdownList.displaySelectBoxesWithData(this.recipesData);
71+
}
72+
73+
isUserInputValueMatchesOnSearchFilter() {
74+
const dropdownSearchFilter = new DropdownSearchFilter();
75+
76+
this.$searchFilterInputs.forEach(input => {
77+
78+
input.addEventListener('input', (e) => {
79+
80+
const userInputValue = e.target.value;
81+
82+
const isInputValid = dropdownSearchFilter.IsUserInputValid(userInputValue, input);
83+
84+
if (isInputValid) {
85+
86+
}
87+
});
88+
});
89+
}
90+
6291
/**
6392
* @type {(string|Array)}
6493
* @param {Object} items

js/components/DropdownList.js renamed to js/components/DataDropdownList.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/**
22
* ------------------------------------------------------------
3-
* Les Petits Plats components/DropdownList.js
3+
* Les Petits Plats components/DataDropdownList.js
44
* ------------------------------------------------------------
55
*/
66

7-
class DropdownList {
7+
class DataDropdownList {
88

99
constructor() {
1010
this.recipesPage = new RecipesPage();
@@ -59,11 +59,11 @@ class DropdownList {
5959
this.recipesDataForDropdown(recipesData, key, value)
6060
.forEach(item => {
6161

62-
// Displays items dropdown
63-
this.recipesPage.displayItemForDropdown(item, customSelect);
62+
// Displays item on custom select
63+
this.recipesPage.displayItemInDropdown(item, customSelect);
6464

65-
// Displays items option
66-
this.recipesPage.displayOptionForDropdown(item, select);
65+
// Displays option on select
66+
this.recipesPage.displayOptionInDropdown(item, select);
6767
});
6868
}
6969

js/components/DropdownSearchFilter.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* ------------------------------------------------------------
3+
* Les Petits Plats components/DropdownSearchFilter.js
4+
* ------------------------------------------------------------
5+
*/
6+
7+
class DropdownSearchFilter {
8+
constructor() {
9+
this.inputRules = new RegExp('^[a-zA-Z]([a-zA-Z\-\s]){2,30}$', 'g');
10+
this.$searchFilters = document.querySelectorAll('.search-filters ul');
11+
this.$closeBtn = document.querySelectorAll('.search-filters li .btn-close');
12+
13+
this.init();
14+
}
15+
16+
init() {
17+
this.handleCloseBtn();
18+
}
19+
20+
handleCloseBtn() {
21+
22+
this.$closeBtn.forEach(btn => {
23+
btn.addEventListener('click', (e) => {
24+
25+
this.closeBtn(btn);
26+
this.removeUserInputValue(e.target);
27+
}, false);
28+
});
29+
}
30+
31+
/**
32+
* Returns result from rules implementation - About data input filter
33+
* @param {string} inputValue - Input value
34+
* @param {*} currentInput
35+
* @returns {boolean} - If user data is set to true or false that means required field is correct or not
36+
*/
37+
IsUserInputValid(inputValue, currentInput) {
38+
39+
const btn = currentInput.nextElementSibling;
40+
41+
const isValid = inputValue.match(this.inputRules);
42+
43+
let result = true;
44+
45+
if (!isValid) {
46+
result = false;
47+
48+
if (btn.classList.contains('d-inline-block')) {
49+
this.closeBtn(btn);
50+
}
51+
}
52+
53+
if (result === true) {
54+
this.launchBtn(btn);
55+
}
56+
57+
return result;
58+
}
59+
60+
/**
61+
* Launches search input button
62+
* @param {HTMLElement} btn
63+
*/
64+
launchBtn(btn) {
65+
btn.classList.replace('d-none', 'd-inline-block');
66+
}
67+
68+
/**
69+
* Closes search input button
70+
* @param {HTMLElement} btn
71+
*/
72+
closeBtn(btn) {
73+
btn.classList.replace('d-inline-block', 'd-none');
74+
}
75+
76+
/**
77+
* Removes search input value of user
78+
* @param {HTMLElement} btn
79+
*/
80+
removeUserInputValue(btn) {
81+
btn.previousElementSibling.value = '';
82+
}
83+
}

js/components/MainSearchBar.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class MainSearchBar {
3333

3434
this.$form.querySelector('button').addEventListener("click", () => {
3535
this.closeBtn();
36+
this.removeInputValue();
3637
}, false);
3738

3839
document.addEventListener('keyup', e => {
@@ -113,6 +114,12 @@ class MainSearchBar {
113114
this.$form.querySelector('label').classList.replace('btn-primary', 'btn-secondary');
114115
this.$form.querySelector('label svg').style.fill = '#EDEDED';
115116

117+
if (this.$closeBtn.classList.contains('d-inline-block')) {
118+
this.closeBtn();
119+
}
120+
121+
this.errorMessage('');
122+
116123
result = false;
117124
}
118125

@@ -132,7 +139,6 @@ class MainSearchBar {
132139
* Close form button
133140
*/
134141
closeBtn() {
135-
this.removeInputValue();
136142
this.$closeBtn.classList.replace('d-inline-block', 'd-none');
137143
}
138144

js/pages/RecipesPage.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* @param {string} data
1717
* @param {HTMLElement} list
1818
*/
19-
async displayItemForDropdown(data, list) {
19+
async displayItemInDropdown(data, list) {
2020
const itemDropdown = new ItemDropdown();
2121
itemDropdown.createItemForDropdown(data, list);
2222
}
@@ -27,7 +27,7 @@
2727
* @param {string} data
2828
* @param {HTMLElement} select
2929
*/
30-
async displayOptionForDropdown(data, select) {
30+
async displayOptionInDropdown(data, select) {
3131
const itemDropdown = new ItemDropdown();
3232
itemDropdown.createOptionForDropdown(data, select);
3333
}

0 commit comments

Comments
 (0)