Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9da995a

Browse filesBrowse files
committed
Add isUserInputValueMatches() method - Binary search
1 parent 24c9515 commit 9da995a
Copy full SHA for 9da995a

File tree

Expand file treeCollapse file tree

3 files changed

+137
-5
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+137
-5
lines changed

‎index.html

Copy file name to clipboardExpand all lines: index.html
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ <h1 class="d-flex flex-column align-items-center font-monospace text-uppercase t
237237
<script src="js/pages/RecipesPage.js"></script>
238238
<!-- Utils -->
239239
<script src="/js/utils/MainSearchBar.js"></script>
240+
<script src="/js/utils/BinarySearch.js"></script>
240241
<!-- Entry point -->
241242
<script src="js/RecipesApp.js"></script>
242243
</body>

‎js/RecipesApp.js

Copy file name to clipboardExpand all lines: js/RecipesApp.js
+75-5Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ class RecipesApp {
1212
this.recipesPage = new RecipesPage();
1313
this.tags = new Array();
1414

15+
// DOM
16+
this.$userInput = document.querySelector('#recipes_search');
1517
this.$ingredientsList = document.querySelector('#ingredients_list');
1618
this.$appliancesList = document.querySelector('#appliances_list');
1719
this.$ustensilsList = document.querySelector('#ustensils_list');
18-
1920
this.$ingredientsSelect = document.querySelector('select#ingredients');
2021
this.$appliancesSelect = document.querySelector('#appliances');
2122
this.$ustensilsSelect = document.querySelector('#ustensils');
@@ -27,10 +28,6 @@ class RecipesApp {
2728
this.recipesData = recipesData
2829
.map(recipe => new RecipeFactories(recipe, 'recipe'));
2930

30-
// Search form data
31-
new MainSearchBar;
32-
this.recipesDataForMainSearchBar();
33-
3431
// Select boxes
3532
this.displayIngredientsDropdownWithData();
3633
this.displayAppliancesDropdownWithData();
@@ -39,12 +36,85 @@ class RecipesApp {
3936
// Cards
4037
this.displayRecipeCardsWithData();
4138

39+
// Main search bar
40+
this.isUserInputValueMatches();
41+
4242
// Tags
4343
this.tags.push('item 1', 'item 2', 'item 3');
4444
const tags = this.tags;
4545
this.displayActiveTags(tags);
4646
}
4747

48+
isUserInputValueMatches() {
49+
50+
this.$userInput.addEventListener('input', (e) => {
51+
52+
this.displayMatchingRecipe(e);
53+
54+
this.sortRecipeByDescendingMatching();
55+
});
56+
}
57+
58+
sortRecipeByDescendingMatching() {
59+
const cardsContainer = document.querySelector('.recipe-cards');
60+
const containerArray = Array.from(cardsContainer.children);
61+
62+
const sorted = containerArray
63+
.filter(child => {
64+
if (child.hasAttribute('data-matches')) {
65+
const matches = child.dataset.matches > parseInt(0);
66+
if (matches) {
67+
return child;
68+
}
69+
}
70+
})
71+
.sort((a, b) => {
72+
return b.dataset.matches - a.dataset.matches;
73+
});
74+
75+
sorted
76+
.forEach(el => cardsContainer.append(el));
77+
}
78+
79+
/**
80+
* Displays matching recipe
81+
* By main search bar
82+
* @param {Event & {target: HTMLInputElement}} e
83+
*/
84+
displayMatchingRecipe(e) {
85+
const cards = Array.from(document.querySelectorAll('.recipe-cards article'));
86+
87+
cards
88+
.forEach(card => {
89+
const recipesDataForMainSearchBar = this.recipesDataForMainSearchBar().sort();
90+
const binarySearch = new BinarySearch();
91+
const userInputValue = e.target.value;
92+
const cardTextContent = card.textContent.toLowerCase();
93+
94+
const userInputMatchingList = binarySearch.isUserValueMatches(userInputValue, recipesDataForMainSearchBar);
95+
96+
const isUserInputMatching = userInputMatchingList
97+
.some(element => card.textContent.includes(element));
98+
99+
if (isUserInputMatching) {
100+
card.style.display = 'block';
101+
102+
let position = cardTextContent.indexOf(userInputValue);
103+
let count = 0;
104+
105+
while (position !== -1) {
106+
count++;
107+
position = cardTextContent.indexOf(userInputValue, position + 1);
108+
}
109+
// Number of occurrences of user input value matching
110+
card.dataset.matches = count;
111+
} else {
112+
card.dataset.matches = 0;
113+
card.style.display = 'none';
114+
}
115+
});
116+
}
117+
48118
/**
49119
* Returns an array of not duplicated data for search form
50120
* Data about name, description and ingredients of recipes

‎js/utils/BinarySearch.js

Copy file name to clipboard
+61Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* ------------------------------------------------------------
3+
* Les Petits Plats utils/BinarySearch.js
4+
* ------------------------------------------------------------
5+
*/
6+
7+
class BinarySearch extends MainSearchBar {
8+
constructor() {
9+
super();
10+
}
11+
12+
isUserValueMatches(subtring, array) {
13+
14+
let result = [];
15+
16+
this.isUserValueMatchesByRegex(subtring, array, result);
17+
18+
return result;
19+
20+
}
21+
22+
isUserValueMatchesByRegex(substring, array, matchingArray) {
23+
// First and last index of array
24+
let left = 0;
25+
let right = array.length - 1;
26+
27+
while (left <= right) {
28+
let middle = Math.floor((left + right) / 2);
29+
let middleElement = array[middle];
30+
const regExp = new RegExp(substring, 'gmi');
31+
32+
if (middleElement.toLowerCase().match(regExp)) {
33+
34+
matchingArray.push(middleElement);
35+
36+
// Checks if other elements to the left of middle element match
37+
let i = middle - 1;
38+
while (i >= left && array[i].toLowerCase().match(regExp)) {
39+
matchingArray.push(array[i]);
40+
i--;
41+
}
42+
43+
// Checks if other elements to the right of middle element match
44+
let j = middle + 1;
45+
while (j < right && array[j].toLowerCase().match(regExp)) {
46+
matchingArray.push(array[j]);
47+
j++;
48+
}
49+
50+
return;
51+
52+
} else if (middleElement.toLowerCase() < substring.toLowerCase()) {
53+
left = middle + 1;
54+
} else {
55+
right = middle - 1;
56+
}
57+
}
58+
// No substring matches
59+
return -1;
60+
}
61+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.