context menu
This commit is contained in:
		| @ -19,6 +19,7 @@ window.onload = function() { | ||||
|             if (!box.disabled) { | ||||
|                 box.onfocus = onfocus | ||||
|                 box.oninput = oninput | ||||
|                 box.oncontextmenu = oncontextmenu | ||||
|             } | ||||
|             box.rowId = rowId | ||||
|             box.columnId = columnId | ||||
| @ -37,16 +38,18 @@ window.onload = function() { | ||||
|         box.neighbourhood = Array.from(box.neighbourhood) | ||||
|     }) | ||||
|     boxes.forEach(searchCandidatesOf) | ||||
|     boxes.forEach(showCandidatesOn) | ||||
|     enableButtons() | ||||
|     highlightAndTab() | ||||
|      | ||||
|     if (/Win/.test(navigator.platform) || /Linux/.test(navigator.platform)) accessKeyModifiers = "Alt+Maj+" | ||||
|     else if (/Mac/.test(navigator.platform)) accessKeyModifiers = "⌃⌥ " | ||||
|     for(node of document.querySelectorAll("*[accesskey]")) { | ||||
|         node.title += " [" + (node.accessKeyLabel || accessKeyModifiers + "+" + node.accessKey) + "]" | ||||
|         node.title += " [" + (node.accessKeyLabel || accessKeyModifiers + node.accessKey) + "]" | ||||
|     } | ||||
|      | ||||
|     document.body.onclick = function (event) { | ||||
|         contextMenu.style.display = "none" | ||||
|     } | ||||
|     suggestionTimer = setTimeout(showSuggestion, 30000) | ||||
| } | ||||
| 
 | ||||
| @ -55,20 +58,6 @@ function searchCandidatesOf(box) { | ||||
|     box.neighbourhood.forEach(neighbour => box.candidates.delete(neighbour.value)) | ||||
| } | ||||
| 
 | ||||
| function showCandidatesOn(box) { | ||||
|     if (!box.disabled) { | ||||
|         while (box.list.firstChild) box.list.firstChild.remove() | ||||
|         if (!box.value && box.candidates.size) { | ||||
|             const candidatesArray = Array.from(box.candidates).sort() | ||||
|             candidatesArray.forEach(candidate => { | ||||
|                 option = document.createElement('option') | ||||
|                 option.value = candidate | ||||
|                 box.list.appendChild(option) | ||||
|             }) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function onfocus() { | ||||
|     this.previousValue = this.value | ||||
|     this.select() | ||||
| @ -94,31 +83,30 @@ function refresh(box) { | ||||
| 
 | ||||
|     box.neighbourhood.concat([box]).forEach(neighbour => { | ||||
|         searchCandidatesOf(neighbour) | ||||
|         showCandidatesOn(neighbour) | ||||
|         neighbour.setCustomValidity("") | ||||
|         neighbour.required = false | ||||
|     }) | ||||
|      | ||||
|     enableButtons() | ||||
|     highlightAndTab() | ||||
|      | ||||
|     for (neighbour1 of box.neighbourhood) { | ||||
|         neighbour1.setCustomValidity("") | ||||
|         if (neighbour1.value.length) { | ||||
|             if (neighbour1.value) { | ||||
|                 for (area of [ | ||||
|                     {name: "région", neighbours: regions[neighbour1.regionId]}, | ||||
|                     {name: "ligne", neighbours: rows[neighbour1.rowId]}, | ||||
|                     {name: "colonne", neighbours: columns[neighbour1.columnId]}, | ||||
|                 ]) | ||||
|                     for (neighbour2 of area.neighbours) | ||||
|                         if (neighbour2 != neighbour1 && neighbour2.value == neighbour1.value) { | ||||
|                             for (neighbour of [neighbour1, neighbour2]) { | ||||
|                                 neighbour.setCustomValidity(`Il y a un autre ${neighbour.value} dans cette ${area.name}.`) | ||||
|                             } | ||||
|             for (area of [ | ||||
|                 {name: "région", neighbours: regions[neighbour1.regionId]}, | ||||
|                 {name: "ligne", neighbours: rows[neighbour1.rowId]}, | ||||
|                 {name: "colonne", neighbours: columns[neighbour1.columnId]}, | ||||
|             ]) | ||||
|                 for (neighbour2 of area.neighbours) | ||||
|                     if (neighbour2 != neighbour1 && neighbour2.value == neighbour1.value) { | ||||
|                         for (neighbour of [neighbour1, neighbour2]) { | ||||
|                             neighbour.setCustomValidity(`Il y a un autre ${neighbour.value} dans cette ${area.name}.`) | ||||
|                         } | ||||
|             } else { | ||||
|                 if (neighbour1.candidates.size == 0) | ||||
|                     neighbour1.setCustomValidity("Aucun value possible !") | ||||
|                     } | ||||
|         } else { | ||||
|             if (neighbour1.candidates.size == 0) { | ||||
|                 neighbour1.setCustomValidity("Aucun chiffre possible !") | ||||
|                 neighbour1.required = true | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @ -131,7 +119,7 @@ function refresh(box) { | ||||
|             suggestionTimer = setTimeout(showSuggestion, SUGESTION_DELAY) | ||||
|         } | ||||
|     } else { // Errors on grid
 | ||||
|         box.reportValidity() | ||||
|         box.form.reportValidity() | ||||
|         box.select() | ||||
|     } | ||||
| } | ||||
| @ -216,7 +204,35 @@ function clearAll() { | ||||
|         box.placeholder = "" | ||||
|     }) | ||||
|     boxes.forEach(searchCandidatesOf) | ||||
|     boxes.forEach(showCandidatesOn) | ||||
|     enableButtons() | ||||
|     highlightAndTab() | ||||
| } | ||||
| 
 | ||||
| function oncontextmenu(event) { | ||||
|     event.preventDefault() | ||||
|     while (contextMenu.firstChild) contextMenu.firstChild.remove() | ||||
|     const box = event.target | ||||
|     if (box.value == "") { | ||||
|         if (box.candidates.size) { | ||||
|             candidatesArray = Array.from(box.candidates).sort().forEach(candidate => { | ||||
|                 li = document.createElement("li") | ||||
|                 li.innerText = candidate | ||||
|                 li.onclick = function (event) { | ||||
|                     contextMenu.style.display = "none" | ||||
|                     box.value = event.target.innerText | ||||
|                     refresh(box) | ||||
|                 } | ||||
|                 contextMenu.appendChild(li) | ||||
|             }) | ||||
|         } else { | ||||
|             li = document.createElement("li") | ||||
|             li.innerText = "Aucun chiffre possible" | ||||
|             li.className = "error" | ||||
|             contextMenu.appendChild(li) | ||||
|         } | ||||
|         contextMenu.style.left = `${event.pageX}px` | ||||
|         contextMenu.style.top = `${event.pageY}px` | ||||
|         contextMenu.style.display = "block" | ||||
|     } | ||||
|     return false | ||||
| } | ||||
							
								
								
									
										8
									
								
								game.php
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								game.php
									
									
									
									
									
								
							| @ -12,7 +12,7 @@ | ||||
|         <meta name='viewport' content='width=device-width' /> | ||||
|         <title>Sudoku</title> | ||||
|         <link rel='stylesheet' type='text/css' href='style.css' /> | ||||
|         <script src='sudoku.js'></script> | ||||
|         <script src='app.js'></script> | ||||
|         <link rel="icon" type="image/png" href="favicon.png"> | ||||
|     </head> | ||||
|     <body> | ||||
| @ -38,8 +38,8 @@ | ||||
|                 } | ||||
| ?> | ||||
|                             <td> | ||||
|                                 <input type='number' min='1' max='9' step='1' value='<?=$value?>' list='<?=$row.$column?>' <?=$disabled?>/> | ||||
|                                 <datalist id='<?=$row.$column?>'></datalist> | ||||
|                                 <input type='number' min='1' max='9' step='1' value='<?=$value?>' list='list<?=$row.$column?>' title='[Clic-droit]' <?=$disabled?>/> | ||||
|                                 <datalist id='list<?=$row.$column?>'></datalist> | ||||
|                             </td> | ||||
| <?php | ||||
|             } | ||||
| @ -67,6 +67,8 @@ | ||||
|         <section> | ||||
|             Remplissez la grille de sorte que chaque ligne, colonne et région (carré de 3×3 cases) contienne tous les chiffres de 1 à 9. | ||||
|         </section> | ||||
|         <ul id="contextMenu" class="context-menu"> | ||||
|         </ul> | ||||
|         <footer> | ||||
|             <a href=''>Lien vers cette grille</a><br/> | ||||
|             <a href='.'>Nouvelle grille</a> | ||||
|  | ||||
							
								
								
									
										35
									
								
								style.css
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								style.css
									
									
									
									
									
								
							| @ -143,3 +143,38 @@ input[type="color"] { | ||||
| a { | ||||
|     text-decoration: none; | ||||
| } | ||||
|  | ||||
| .context-menu { | ||||
|     display: none; | ||||
|     z-index: 1000; | ||||
|     position: absolute; | ||||
|     overflow: hidden; | ||||
|     border: 1px solid #CCC; | ||||
|     white-space: nowrap; | ||||
|     font-family: sans-serif; | ||||
|     background: #EEE; | ||||
|     color: #333; | ||||
|     border-radius: 3px; | ||||
|     padding: 0; | ||||
| } | ||||
|  | ||||
| .context-menu li { | ||||
|     padding: 6px 10px; | ||||
|     cursor: default; | ||||
|     list-style-type: none; | ||||
|     transition: all .3s ease; | ||||
|     user-select: none; | ||||
|     font-size: 0.8em; | ||||
| } | ||||
|  | ||||
| .context-menu li:hover { | ||||
|     background-color: #DEF; | ||||
| } | ||||
|  | ||||
| .context-menu li.error { | ||||
|     color: #888 | ||||
| } | ||||
|  | ||||
| .context-menu li.error:hover { | ||||
|     background-color: #EEE; | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user