Structuration++ & Début JS
This commit is contained in:
		| @@ -1,6 +1,4 @@ | ||||
| <school-info> | ||||
|     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css"> | ||||
|  | ||||
|     <div> | ||||
|         <div> | ||||
|         </div> | ||||
| @@ -9,7 +7,7 @@ | ||||
|     <script> | ||||
|         export default { | ||||
|             onMounted() { | ||||
|  | ||||
|                 console.log("Test!") | ||||
|             } | ||||
|         } | ||||
|     </script> | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
|         import model from '../javascript/modelSearch.js'; | ||||
|     	import Controller from '../javascript/controllerSearch.js'; | ||||
|     	import View from '../javascript/viewSearch.js'; | ||||
|  | ||||
|         export default function search(){ | ||||
| 			return { | ||||
| 				onBeforeMount(props, state) { | ||||
|   | ||||
							
								
								
									
										14
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								index.html
									
									
									
									
									
								
							| @@ -4,19 +4,13 @@ | ||||
| 		<title>Parcoursup</title> | ||||
| 		<meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||||
| 		<link rel="stylesheet" href="style/parcoursup.css"> | ||||
| 		<script src="search.riot" type="riot"></script> | ||||
| 		<script src="https://cdnjs.cloudflare.com/ajax/libs/riot/7.1.0/riot+compiler.min.js" integrity="sha512-sSGKGR9MvL0bUx3CScaBb56crXwspwDkL/JnB0IrLFQfw3uvSUlITQtsTtDZctshhv5wdwIt+qZeN8zThRF4Dw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> | ||||
| 		<script src="riot.min.js"></script> | ||||
| 		<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css"> | ||||
| 		<script src="loader.js" type="module"></script> | ||||
| 	</head> | ||||
|  | ||||
| 	<body> | ||||
| 		<search></search> | ||||
| 		<script src="javascript/school-info.js" type="javascript"></script> | ||||
| 		<script> | ||||
| 			riot.compile().then(() => { | ||||
| 				riot.mount('search', { | ||||
| 					formation:'Formation' | ||||
| 				}) | ||||
| 			}) | ||||
| 		</script> | ||||
| 		<school-info></school-info> | ||||
| 	</body> | ||||
| </html> | ||||
|   | ||||
| @@ -1,9 +1,11 @@ | ||||
| var schoolInfo = { | ||||
|   css: null, | ||||
|   exports: { | ||||
|     onMounted() {} | ||||
|     onMounted() { | ||||
|       console.log("Test!"); | ||||
|     } | ||||
|   }, | ||||
|   template: (template, expressionTypes, bindingTypes, getComponent) => template('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css"/><div><div></div></div>', []), | ||||
|   template: (template, expressionTypes, bindingTypes, getComponent) => template('<div><div></div></div>', []), | ||||
|   name: 'school-info' | ||||
| }; | ||||
|  | ||||
|   | ||||
							
								
								
									
										120
									
								
								javascript/search.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								javascript/search.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | ||||
| let model = { | ||||
|   getFormations(search) { | ||||
|     return new Promise((resolve, reject) => { | ||||
|       let xhr = new XMLHttpRequest(); | ||||
|       xhr.open("GET", "/api/records/1.0/search/?dataset=fr-esr-parcoursup&q=&sort=tri&facet=fili&timezone=Europe%2FBerlin"); | ||||
|       xhr.responseType = "json"; | ||||
|       xhr.onload = ev => { | ||||
|         if (xhr.status == 200) resolve(xhr.response); | ||||
|       }; | ||||
|       xhr.onerror = () => { | ||||
|         reject("error"); | ||||
|       }; | ||||
|       xhr.send(); | ||||
|     }); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| class Controller { | ||||
|   constructor(view, model) { | ||||
|     this.view = view; | ||||
|     this.model = model; | ||||
|     this.loading = false; | ||||
|     this.lastSearch = null; | ||||
|     this.error = null; | ||||
|     this.results = []; | ||||
|     this.view.setLoading(false); | ||||
|     this.view.bindSearch(this.search.bind(this)); | ||||
|   } | ||||
|   reset() { | ||||
|     this.loading = false; | ||||
|     this.error = null; | ||||
|     this.results = []; | ||||
|   } | ||||
|   async search(formation) { | ||||
|     this.model.getFormations(formation).then(response => { | ||||
|       let table = response["facet groups"][0]["facets"]; | ||||
|       this.view.renderList(table); | ||||
|     }).catch(error => { | ||||
|       this.view.renderMessage(error); | ||||
|     }); | ||||
|   } | ||||
| } | ||||
|  | ||||
| function debounce(fn, wait) { | ||||
|   let timeout; | ||||
|   return (...args) => { | ||||
|     clearTimeout(timeout); | ||||
|     timeout = setTimeout(() => fn(...args), wait); | ||||
|   }; | ||||
| } | ||||
| class View { | ||||
|   constructor() { | ||||
|     this.listFormations = document.querySelector("#list-formations"); | ||||
|     this.inputSearch = document.querySelector("input"); | ||||
|     this.message = document.querySelector("p.error"); | ||||
|   } | ||||
|   _getInput() { | ||||
|     return this.inputSearch.value; | ||||
|   } | ||||
|   renderMessage(error) { | ||||
|     this.message.style.display = "block"; | ||||
|     this.message.textContent = error; | ||||
|   } | ||||
|   renderList(formations) { | ||||
|     let ul = document.createElement("ul"); | ||||
|     formations.forEach(formation => { | ||||
|       let li = document.createElement("li"); | ||||
|       let a = document.createElement("a"); | ||||
|       let span = document.createElement("span"); | ||||
|       //a.href = `test` | ||||
|       a.target = "_blank"; | ||||
|       a.textContent = formation.name; | ||||
|       span.textContent = formation.name; | ||||
|       li.appendChild(a); | ||||
|       li.appendChild(span); | ||||
|       ul.appendChild(li); | ||||
|     }); | ||||
|     this.listFormations.replaceChildren(ul); | ||||
|   } | ||||
|   bindSearch(handler) { | ||||
|     this.inputSearch.addEventListener("input", debounce(e => { | ||||
|       handler(this._getInput()); | ||||
|     }, 500)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| var search = { | ||||
|   css: null, | ||||
|   exports: function search() { | ||||
|     return { | ||||
|       onBeforeMount(props, state) { | ||||
|         // initial state | ||||
|         this.state = { | ||||
|           formation: props.formation | ||||
|         }; | ||||
|       }, | ||||
|       search() { | ||||
|         console.log("test1"); | ||||
|         const view = new View(); | ||||
|         new Controller(view, model); | ||||
|       } | ||||
|     }; | ||||
|   }, | ||||
|   template: (template, expressionTypes, bindingTypes, getComponent) => template('<label><input expr1="expr1" type="input"/><p class="error"></p><div id="list-formations"></div></label>', [{ | ||||
|     redundantAttribute: 'expr1', | ||||
|     selector: '[expr1]', | ||||
|     expressions: [{ | ||||
|       type: expressionTypes.EVENT, | ||||
|       name: 'oninput', | ||||
|       evaluate: _scope => _scope.search | ||||
|     }, { | ||||
|       type: expressionTypes.ATTRIBUTE, | ||||
|       name: 'placeholder', | ||||
|       evaluate: _scope => _scope.state.formation | ||||
|     }] | ||||
|   }]), | ||||
|   name: 'search' | ||||
| }; | ||||
|  | ||||
| export { search as default }; | ||||
							
								
								
									
										12
									
								
								loader.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								loader.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| /* | ||||
|     Charge tous les fichiers riot compilés. | ||||
| */ | ||||
|  | ||||
| import SchoolInfo from './javascript/school-info.js' | ||||
| import Search from './javascript/search.js' | ||||
|  | ||||
| riot.register("school-info", SchoolInfo) | ||||
| riot.register("search", Search) | ||||
|  | ||||
| riot.mount("school-info") | ||||
| riot.mount("search") | ||||
							
								
								
									
										1
									
								
								riot.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								riot.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Reference in New Issue
	
	Block a user