diff --git a/AdvancedSearch.php b/AdvancedSearch.php index 5bea37844ef47116e47c14ea6f3c2991f29784f1..40811b238975453119682a74396109b8c934ce3a 100644 --- a/AdvancedSearch.php +++ b/AdvancedSearch.php @@ -10,18 +10,29 @@ </head> <body> + <?php + include 'scripts/Functions.php'; + $ingredientsList = getAllIngredients(); + ?> + <div id="content"> - <span id="elementInput" class="autocomplete"> + <div id="elementInput" class="autocomplete"> <span> - <h2>Rechercher un aliment : </h2> + <h2 style="margin-right: 10px;">Rechercher un aliment :</h2> </span> <span> - <input id="myInput" autocomplete="off" type="text" name="myIngredient" oninput="elementInputChange(this.value)" onchange="elementInputChange(this.value)" onblur="elementInputChange(this.value)" placeholder="Ingrédient"> + <input name="ingredients" list="ingredients" value="" id="myInput" autocomplete="off" type="search" oninput="elementInputChange(this.value)" onchange="elementInputChange(this.value)" placeholder="Ingrédient"> + + <datalist id="ingredients"> + <?php + foreach($ingredientsList as $ingredient) echo '<option value="' . $ingredient . '" />' ; + ?> + </datalist> </span> <span> <link href="https://cdn.jsdelivr.net/css-toggle-switch/latest/toggle-switch.css" rel="stylesheet" /> - <div disabled="true" id="toggleWanted" class="switch-toggle switch-3 switch-candy"> + <div id="toggleWanted" class="switch-toggle switch-3 switch-candy unclickable"> <input id="on" name="state-d" type="radio" checked="" /> <label for="on" onclick="setElementWanted();">✓</label> @@ -34,22 +45,29 @@ <a></a> </div> </span> - </span> + </div> + <div id="searchDiv"> + <button onclick="performSearch();">Rechercher</button> + </div> + <div id="chosenItemsOverview"> + + </div> </div> - <script src="scripts/DataQuery.js"></script> - <script src="scripts/Functions.js"></script> <script> let chosenIngredients = new Map(); - let allIngredients = [<?php include 'scripts/Functions.php'; $first = true; foreach(getAllIngredients() as $ingredient) { if(!$first) echo ','; else $first = false; echo '"' . $ingredient . '"'; } ?>]; - autocomplete(document.getElementById("myInput"), allIngredients); + let allIngredients = [<?php $first = true; foreach($ingredientsList as $ingredient) { if(!$first) echo ','; else $first = false; echo '"' . $ingredient . '"'; } ?>]; + + var allowUnwanted = false; + var allowMissing = false; + var maxUnsatisfied = 0; function elementInputChange(val) { var toggleSwitch = document.getElementById('toggleWanted'); if(allIngredients.includes(val)) { - toggleSwitch.disabled = "false"; + toggleSwitch.classList.remove('unclickable'); if(chosenIngredients.get(val) == 'wanted') { document.getElementById('on').checked = "checked"; @@ -68,7 +86,7 @@ } else { - toggleSwitch.disabled = "true"; + toggleSwitch.classList.add('unclickable'); document.getElementById('on').checked = ""; document.getElementById('na').checked = "checked"; document.getElementById('off').checked = ""; @@ -93,6 +111,28 @@ chosenIngredients.set(element, 'unwanted'); } + function performSearch() + { + var wanted = new Array(); + var unwanted = new Array(); + chosenIngredients.forEach((value, key) => { + if(value == 'wanted') wanted.push(key); + else if(value == 'unwanted') unwanted.push(key); + }); + getRecipes(wanted, unwanted, maxUnsatisfied, allowMissing, allowUnwanted, function(e) { + notifyParent(e); + }); + } + + function notifyParent(e) // Send a message to the parent window, asking to display the recipe #e + { + var data = { + event: 'recipelist', + value: e + }; + window.top.postMessage(data, [data.event, data.value]); + } + </script> </body> diff --git a/Home.php b/Home.php index 24ea6049f7bf438f5f9f1bbf1c010cdb3e73f243..d72643b7a4ad5bf29dee2be33526a277285bff18 100644 --- a/Home.php +++ b/Home.php @@ -19,7 +19,7 @@ <button id="tabBtnF" class="right" value="MyFavouriteRecipes.php" onclick="tabButtonClicked(this)">Favoris</button> </div> - <iframe id="tabFrame" frameborder="0" src="Hierarchy.php"> + <iframe id="tabFrame" onload="stopLoadingScreen();" frameborder="0" src="Hierarchy.php"> </iframe> </div> @@ -29,11 +29,17 @@ <button id="BlurredElementCenteredClose">X</button> </div> + <div id="loadingScreen"> + <img id="loadingScreenImage" src=""></img> + </div> + <script> let wrapper = document.getElementById('BlurredElementCenteredContainer'); let content = document.getElementById('content'); let embed = document.getElementById('BlurredElementEmbed'); + let loadingScreen = document.getElementById('loadingScreen'); + let loadingScreenImage = document.getElementById('loadingScreenImage'); let activeTabButton = document.getElementById('tabBtnI'); @@ -46,13 +52,17 @@ { if(m_value == 27) { - hideRecipe(); + hideBlurred(); } } else if(m_event == 'recipeselect') { showRecipe(m_value); } + else if(m_event == 'recipelist') + { + switchView('RecipeList.php?ids=' + m_value); + } else if(m_event == 'hierarchyDisplay') { setActiveTab('tabBtnI'); @@ -60,16 +70,17 @@ } } - function hideRecipe() + function hideBlurred() { wrapper.classList.remove('active'); content.classList.remove('blur'); wraper.disabled = false; + embed.setAttribute('src',''); } - function showRecipe(id) // Show the Recipe with the id 'id' in the file 'Donnees.inc.php' + function showInBlurred(address) { - embed.setAttribute('src','RecipeView.php?id_recipe=' + id); + embed.setAttribute('src',address); wrapper.classList.add('active'); // Set the RecipeView wrapper active content.classList.add('blur'); // Blurs the original content of the page @@ -81,13 +92,24 @@ { if(e.keyCode === 27) { - hideRecipe(); + hideBlurred(); } }); } + + function showRecipe(id) // Show the Recipe with the id 'id' in the file 'Donnees.inc.php' + { + showInBlurred('RecipeView.php?id_recipe=' + id); + } + + function showRecipeList(idsStr) + { + showInBlurred('RecipeList.php?ids=' + idsStr); + } function switchView(viewSrc) { + startLoadingScreen(); var tabFrame = document.getElementById('tabFrame'); tabFrame.setAttribute('src', viewSrc); } @@ -102,16 +124,25 @@ function tabButtonClicked(b) { - if(b.id != activeTabButton.id) - { setActiveTab(b.id); switchView(activeTabButton.value); - } + } + + function startLoadingScreen() + { + loadingScreen.classList.add('active'); + loadingScreenImage.src = 'images/loading.gif?' + (new Date().getTime()); + } + + function stopLoadingScreen() + { + loadingScreen.classList.remove('active'); + loadingScreenImage.src = ''; } let closeBtn = document.getElementById('BlurredElementCenteredClose'); - closeBtn.addEventListener('click', hideRecipe); + closeBtn.addEventListener('click', hideBlurred); </script> diff --git a/RecipeList.php b/RecipeList.php index a06c9d8c506c8de1652f55fff41ee24db21fc923..c6021ac71ca3d121b550e928bc69e017953d9ed0 100644 --- a/RecipeList.php +++ b/RecipeList.php @@ -13,29 +13,64 @@ <?php include "Donnees.inc.php"; + include "scripts/Functions.php"; - $recipesIds = explode('|', $_GET['ids']); + if ($_GET['ids'] == '') echo '<h1>No recipe found</h1>'; - foreach($recipesIds as $id) - { - echo '<li>'; - echo '<div class="listElement">'; + else{ - $recipe = $Recettes[(int)$id]; + $recipesIds = explode('|', $_GET['ids']); + + $count = count($recipesIds); + + for($i = 0; $i < $count; $i++) + { + $re = explode(':', $recipesIds[$i]); + + echo '<li>'; + echo '<div class="listElement" onclick="showRecipe(' . intval($re[0]) . ');">'; + + $recipe = $Recettes[intval($re[0])]; + + $image_url = getRecipeImage($recipe['titre']); + $image_url = '' . 'Photos/' . $image_url; + if(file_exists($image_url)) echo '<img src="' . $image_url . '"></img>'; + else echo '<img src="images/missing.jfif"></img>'; + + echo '<h1>' . $recipe['titre'] . '</h1>'; - $image_url = getRecipeImage((int)$id); - if($image_url != '') echo '<img src="Photos/' . $image_url . '">'; - - echo '<h1>' . $recipe['titre'] . '</h1>'; - - echo '</div>'; - echo '</li>'; + echo '</div>'; + echo '</li>'; + } } ?> </ul> + + <script> + document.addEventListener('keyup', function (e) + { + if(e.keyCode == 27) + { + var data = { + event: 'keyup', + value: e.keyCode + }; + window.top.postMessage(data, [data.event, data.value]); + } + }); + + function showRecipe(id) + { + var data = { + event: 'recipeselect', + value: id + }; + window.top.postMessage(data, [data.event, data.value]); + } + </script> </body> diff --git a/RecipeView.php b/RecipeView.php index 4f3f23458b8190e64ea4370bc4b08b9b533eee90..66bbab9e7a53ef684ff3924c9aa119a4bcb32304 100644 --- a/RecipeView.php +++ b/RecipeView.php @@ -16,13 +16,13 @@ $r_ingredients = $recipe['ingredients']; $r_recipe = $recipe['preparation']; - $r_image = getRecipeImage($r_name); - $exists = false; - if(file_exists('Photos/'.$r_image)) $exists = true;; + $image_url = getRecipeImage($r_name); + $image_url = '' . 'Photos/' . $image_url; + if(!file_exists($image_url)) $image_url = 'images/missing.jfif'; ?> <div> - <img src=<?php echo "\"Photos/" . $r_image . "\"" ?> width="128" height="128" hidden=<?php if(file_exists("Photos/" . $r_image)) echo "\"true\""; else echo "\"false\""; ?>> + <img src=<?php echo "\"" . $image_url . "\"" ?> width="128" height="128"; ?> <span> <h1> <?php echo $r_name; ?> diff --git a/css/AdvancedSearch.css b/css/AdvancedSearch.css index 90728eb00ac28dcdd4720216cdfedb8e8233fd02..c6bcfa80f995752f25ba164867ed561ca465df48 100644 --- a/css/AdvancedSearch.css +++ b/css/AdvancedSearch.css @@ -9,10 +9,10 @@ body { #content { display: flex; + flex-direction: column; justify-content: center; background-color: rgba(255, 255, 255, 0.75); width: 80vw; - height: max-content; border-radius: 25px; } @@ -29,4 +29,28 @@ body { display: inline-flex; justify-content: center; align-items: center; +} + +.unclickable { + opacity: 25%; + pointer-events: none; +} + +#searchDiv { + display: flex; + justify-content: center; + align-items: center; +} + +#searchDiv button { + font-size: xx-large; + font-weight: bold; + border-radius: 10px; + background-color: darkgray; + margin: 25px; + padding: 15px; +} + +#searchDiv button:hover { + background-color: grey; } \ No newline at end of file diff --git a/css/AutoComplete.css b/css/AutoComplete.css index 8442b74e6b7f323b08669cad7d6ba99b1942d57e..a471f0e731c7bb9606ffa5f9eb0fd50a822ae514 100644 --- a/css/AutoComplete.css +++ b/css/AutoComplete.css @@ -5,8 +5,8 @@ } input { width: 400px; - border: 1px solid transparent; background-color: #BBBBBB; + border-radius: 5px; padding: 10px; font-size: 20px; } diff --git a/css/Home.css b/css/Home.css index be2e61fe3e7e3566bb092df53f6016e621f8c399..4553330d188f5dea0a2d68020aa09e326d8045d6 100644 --- a/css/Home.css +++ b/css/Home.css @@ -17,16 +17,19 @@ body { .topnav { overflow: hidden; + z-index: 2; + background-color: rgba(200, 200, 200, 0.76); } .topnav button { float: left; border-style: none; - background-color: rgba( 200, 200, 200, 100); + background-color: transparent; text-align: center; - padding: 14px 16px; + padding: 9px 12px; text-decoration: none; - font-size: 17px; + font-weight: bold; + font-size: 20px; } .topnav button.right { @@ -35,10 +38,27 @@ body { .topnav button:hover { font-weight: bolder; + cursor: pointer; } .topnav button.active { - font-weight: bolder; + text-decoration: underline; +} + +#loadingScreen { + position: absolute; + top: 0; + left: 0; + z-index: 1; + width: 100%; + height: 100%; + display: none; + justify-content: center; + align-items: center; +} + +#loadingScreen.active { + display: flex; } #content { @@ -50,6 +70,7 @@ body { #content.blur { filter: blur(5px); + -webkit-filter: blur(5px); } #BlurredElementCenteredContainer { diff --git a/css/RecipeList.css b/css/RecipeList.css index 6d770d7374bfa28e46628775251f348bacff4ef6..770bd676178b48015637e8d3311ee3af721628b6 100644 --- a/css/RecipeList.css +++ b/css/RecipeList.css @@ -1,22 +1,47 @@ body { padding: 20px; - background-color: darkgray; + background-color: rgba(169, 169, 169, 0.5); } ul { list-style-type: none; padding: 0; border: 1px solid black; + border-radius: 15px; } ul li { padding: 8px 16px; height: 75px; border-bottom: 1px solid black; - background-color: #888888; + background-color: rgba(88, 88, 88, 0.5); display: block; } + +ul li:first-child { + border-top-left-radius: 15px; + border-top-right-radius: 15px; +} ul li:last-child { - border-bottom: none + border-bottom: none; + border-bottom-left-radius: 15px; + border-bottom-right-radius: 15px; +} + +.listElement { + display: flex; + flex-direction: row; + justify-content: left; + align-items: center; +} + +.listElement img { + border-radius: 7px; + border-color: black; + border-width: 2px; + border-style: solid; + width: 64px; + height: 64px; + margin-right: 15px; } \ No newline at end of file diff --git a/images/loading.gif b/images/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..3fd3a7ae27f664244c16f3482587e929abee6d7b Binary files /dev/null and b/images/loading.gif differ diff --git a/images/missing.jfif b/images/missing.jfif new file mode 100644 index 0000000000000000000000000000000000000000..24a107825f923a88c49cbef12c5a8a97b22f9f2b Binary files /dev/null and b/images/missing.jfif differ diff --git a/images/pattern.jfif b/images/pattern.jfif deleted file mode 100644 index 2fabf936cd10096cf4d748b5cb468f4cc5d6d71e..0000000000000000000000000000000000000000 Binary files a/images/pattern.jfif and /dev/null differ diff --git a/scripts/DataQuery.js b/scripts/DataQuery.js index 4a3cd091495aa9093c268c851ca36de801a0f1b9..8122cb25a42bfa8ae03026159151c9aea2c5e3c8 100644 --- a/scripts/DataQuery.js +++ b/scripts/DataQuery.js @@ -7,24 +7,20 @@ function query(func_name, args, callback) function getRecipes(wanted_ingredients = [], unwanted_ingredients = [], max_unsatisfied = 0, allow_missing = true, allow_unwanted = true, callback) { - alert('hi'); - query('getRecipe', [wanted_ingredients, unwanted_ingredients, max_unsatisfied, allow_missing, allow_unwanted], callback); + query('getRecipes', [wanted_ingredients.join('|'), unwanted_ingredients.join('|'), max_unsatisfied, allow_missing, allow_unwanted], callback); } function getIngredients(parent_category = 'Aliment', callback) { - alert('hi'); query('getIngredients', [parent_category], callback); } function getRecipeImage(id, callback) { - alert('hi'); query('getRecipeImage', [id], callback); } function getAllIngredients(callback) { - alert('getAllIngredients'); query('getAllIngredients', [], callback); } \ No newline at end of file diff --git a/scripts/DataQuery.php b/scripts/DataQuery.php index 2d26428907803f02e007f9974ced8741137beb11..6e024dd80fde62eb86b8180f57603d63aa9998be 100644 --- a/scripts/DataQuery.php +++ b/scripts/DataQuery.php @@ -10,6 +10,8 @@ } else if($funcName == 'getRecipes') { + $str = ''; + foreach($_POST['arguments'] as $arg) $str = $str . ' - ' . $arg; echo getRecipesForJS($_POST['arguments'][0], $_POST['arguments'][1], $_POST['arguments'][2], $_POST['arguments'][3], $_POST['arguments'][4]); } else if($funcName == 'getIngredients') diff --git a/scripts/Functions.js b/scripts/Functions.js index 2c451f5f03b23e24c066ecd0a9cfeee51610f1ea..0f5215a457439932af7258b6fef641df1c3073e5 100644 --- a/scripts/Functions.js +++ b/scripts/Functions.js @@ -25,11 +25,11 @@ function autocomplete(inp, arr) { b.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>"; b.innerHTML += arr[i].substr(val.length); /*insert a input field that will hold the current array item's value:*/ - b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>"; + b.innerHTML += "<input type='hidden' value='" + i + "'>"; /*execute a function when someone clicks on the item value (DIV element):*/ b.addEventListener("click", function(e) { /*insert the value for the autocomplete text field:*/ - inp.value = this.getElementsByTagName("input")[0].value; + inp.value = arr[parseInt(this.getElementsByTagName("input")[0].value)]; /*close the list of autocompleted values, (or any other open lists of autocompleted values:*/ closeAllLists(); @@ -87,6 +87,8 @@ function autocomplete(inp, arr) { if (elmnt != x[i] && elmnt != inp) { x[i].parentNode.removeChild(x[i]); } + var input = document.getElementsByTagName("input")[0]; + input.dispatchEvent(new Event('change')); } } /*execute a function when someone clicks in the document:*/ diff --git a/scripts/Functions.php b/scripts/Functions.php index 6849697ae2e84c6be831865baa12e94fc28a80a7..8cb2ac6d90571454628fc6e59d13342ab2e9fcba 100644 --- a/scripts/Functions.php +++ b/scripts/Functions.php @@ -8,19 +8,22 @@ function recipeContains($recipe, $ingredient) function getRecipesForJS($wanted_ingredients, $unwanted_ingredients, $max_unsatisfied, $allow_missing, $allow_unwanted) { - $res = ""; $validRecipes = getRecipes($wanted_ingredients, $unwanted_ingredients, $max_unsatisfied, $allow_missing, $allow_unwanted); + $vrArray = []; foreach($validRecipes as $recipe) { - $res .= $recipe['id'] . ':' . $recipe['score'] . '|'; + $vrArray[] = $recipe['id'] . ':' . $recipe['score']; } - return $res; + return implode('|', $vrArray); } -function getRecipes($wanted_ingredients, $unwanted_ingredients, $max_unsatisfied, $allow_missing, $allow_unwanted) +function getRecipes($wanted_ing, $unwanted_ing, $max_unsatisfied, $allow_missing, $allow_unwanted) { include "Donnees.inc.php"; + $wanted_ingredients = array_filter(explode('|', $wanted_ing)); + $unwanted_ingredients = array_filter(explode('|', $unwanted_ing)); + $Recipes = array(); for($i = 0; $i < count($Recettes); $i++) { @@ -36,7 +39,6 @@ function getRecipes($wanted_ingredients, $unwanted_ingredients, $max_unsatisfied if(!$allow_missing) { $valid = false; - break; } $score++; } @@ -50,7 +52,6 @@ function getRecipes($wanted_ingredients, $unwanted_ingredients, $max_unsatisfied if(!$allow_unwanted) { $valid = false; - break; } $score++; } @@ -59,7 +60,6 @@ function getRecipes($wanted_ingredients, $unwanted_ingredients, $max_unsatisfied { if($score <= $max_unsatisfied) { - //$Recipes .= $i . ':' . $score . '|'; $Recipes[] = array( 'id'=> $i, 'score'=> $score @@ -79,11 +79,10 @@ function getIngredients($parent_category) if(isset($Hierarchie[$parent_category])) { $ingredients = $Hierarchie[$parent_category]['sous-categorie']; + + sort($ingredients); - foreach($ingredients as $i) - { - $res .= $i . '|'; - } + $res = implode('|', $ingredients); } return $res; @@ -100,24 +99,22 @@ function getSubIngredients($cat) { include "Donnees.inc.php"; - $sub_list = array(); + $sub_list[] = $cat; if(!isset($Hierarchie[$cat]['sous-categorie'])) $sub_list[] = $cat; - - else foreach($Hierarchie[$cat]['sous-categorie'] as $ing) - { - foreach(getSubIngredients($ing) as $sub) - { + else foreach($Hierarchie[$cat]['sous-categorie'] as $ing){ + foreach(getSubIngredients($ing) as $sub){ if(!in_array($sub, $sub_list)) $sub_list[] = $sub; } } - return $sub_list; } function getAllIngredients() { - return getSubIngredients('Aliment'); + $res = getSubIngredients('Aliment'); + sort($res); + return $res; } // Renvoie un tableau de sous-categories de l'aliment en cours, null si l'aliment n'en a pas