const FORMFIELD_SEPARATOR = -1 ; const FORMFIELD_NONE = 0 ; const FORMFIELD_STRING = 1 ; const FORMFIELD_NUMBER = 2 ; const FORMFIELD_RANGE = 3 ; const FORMFIELD_BOOLEAN = 4 ; const FORMFIELD_TEXT = 5 ; const FORMFIELD_DATETIME = 6 ; const FORMFIELD_DATE = 7 ; const FORMFIELD_TIME = 8 ; const FORMFIELD_DROPLIST = 9 ; const FORMFIELD_FILE = 10 ; const FORMFIELD_RADIO = 11 ; const FORMFIELD_TAGS = 12 ; const FORMFIELD_PASSWORD = 13 ; const FORMFIELD_LIST = 14 ; const FORMFIELD_HTML = 15 ; const FORMFIELD_URL = 16 ; const FORMFIELD_COLOR = 17 ; const FORMFIELD_LOOKUP = 18 ; const FORMBUTTON_OK = 1 ; const FORMBUTTON_CANCEL = 2 ; const FORMBUTTON_RESET = 3 ; const FORMBUTTON_CUSTOM = 4 ; const SCRIPT_URL = new URL(document.currentScript.src) ; const emailRegexp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; const phoneNumberRegexp = /^[+]?[\d]{2,3}[\d\s\-.]*$/; const zipCodeRegexp = /^[\d]{4,6}$/; class winRegisterForm { container = false ; gameAppointmentCode = false ; fields = [] ; buttons = [] ; div = false ; dForm = false ; dButtons = false ; dResult = false ; error = false ; successMessage = 'Votre inscription a été prise en compte. ' ; failureMessage = 'Une erreur a eu lieu lors de votre inscription. Veuillez réessayer plus tard.' ; invalidAppointmentMessage = 'Désolé, vous ne pouvez pas vous inscrire actuellement, car le jeu n\'est pas ouvert.' ; onButtonClick = false ; winnerUrl = SCRIPT_URL.origin + SCRIPT_URL.pathname ; constructor() { this.div = document.createElement('div') ; this.div.style.border = 'solid 1px #C0C0C0' ; this.div.style.borderRadius = '5px' ; this.div.style.padding = '10px' ; this.dForm = document.createElement('div') ; this.dForm.style.marginBottom = '32px' ; this.dForm.style.display = 'none' ; this.div.appendChild(this.dForm) ; this.dButtons = document.createElement('div') ; this.dButtons.style.width = '-webkit-fill-available' ; this.dButtons.style.display = 'none' ; this.dButtons.style.flexDirection = 'row' ; this.dButtons.style.flexWrap = 'wrap' ; this.dButtons.style.justifyContent = 'flex-end' ; this.div.appendChild(this.dButtons) ; this.dError = document.createElement('div') ; this.dError.style.flexGrow = 1 ; this.dError.style.padding = '5px' ; this.dError.style.color = '#FF0000' ; this.dError.style.fontWeight = 'bold' ; this.dButtons.appendChild(this.dError) ; this.dResult = document.createElement('div') ; this.div.appendChild(this.dResult) ; } setContainer(aDiv) { var vDiv = false ; if (typeof aDiv == 'string') { vDiv = document.getElementById(aDiv) ; } else { vDiv = aDiv ; } this.container = vDiv ; this.container.appendChild(this.div) ; } setGameAppointmentCode(aGameAppointmentCode) { this.gameAppointmentCode = aGameAppointmentCode ; this.checkAppointmentCode(this.gameAppointmentCode) ; } addBloc(aBlocName) { switch (aBlocName) { case 'names' : this.addField('firstName', 'Prénom', FORMFIELD_STRING, '').setWidth('300px').setMandatory(true) ; this.addField('lastName', 'Nom de Famille', FORMFIELD_STRING, '').setWidth('300px').setMandatory(true) ; break ; case 'birthDate' : this.addField('birthDate', 'Date de Naissance', FORMFIELD_DATE, '') ; break ; case 'address' : this.addField('address', 'Adresse', FORMFIELD_TEXT, '').setSize(false, 2) ; this.addField('zipCode', 'Code Postal', FORMFIELD_NUMBER, '') ; this.addField('city', 'Ville', FORMFIELD_STRING, '').setWidth('300px') ; this.addField('country', 'Pays', FORMFIELD_DROPLIST, '').setWidth('300px') ; break ; case 'gdprMail' : this.addField('mail', 'Adresse Mail', FORMFIELD_STRING, '').setWidth('300px') ; this.addField('gdprMailGeneral', 'J\'accepte d\'être contacté sur cette adresse mail' , FORMFIELD_BOOLEAN, '') ; this.addField('gdprMailCommercial', 'J\'accepte de recevoir des propositions commerciales sur cette adresse mail' , FORMFIELD_BOOLEAN, '') ; break ; case 'gdprPhoneNumber' : this.addField('phoneNumber', 'N° de téléphone', FORMFIELD_STRING, '').setWidth('300px') ; this.addField('gdprPhoneGeneral', 'J\'accepte d\'être contacté sur ce numéro' , FORMFIELD_BOOLEAN, '') ; this.addField('gdprPhoneCommercial', 'J\'accepte de recevoir des propositions commerciales sur ce numéro' , FORMFIELD_BOOLEAN, '') ; break ; } } addField(aFieldName, aFieldTitle, aFieldType, aDefaultValue) { var vField = new winRegisterField(this, aFieldName, aFieldTitle, aFieldType, aDefaultValue) ; this.dForm.appendChild(vField.div) ; this.fields.push(vField) ; this.configureField(vField) ; return vField ; } configureField(aField) { switch (aField.name) { case 'country' : this.fetchCountries() ; break ; } } getField(aName) { for(var vField of this.fields) { if (vField.name == aName) return vField ; } return null ; } addButton(aButtonType, aButtonTitle) { var vButton = new winRegisterButton(this, aButtonType, aButtonTitle) ; this.dButtons.appendChild(vButton.div) ; this.buttons.push(vButton) ; return vButton ; } doOnButtonClick(aButton) { if (aButton) { switch (aButton.type) { case FORMBUTTON_OK : this.doSubmit() ; break ; case FORMBUTTON_CANCEL : this.doCancel() ; break ; } if (this.onButtonClick) { this.onButtonClick(aButton) ; } } } doOnFieldChange(aField) { this.doValidate() ; } doOnFieldType(aField) { var vValue = aField.getValue() ; switch (aField.name) { case 'firstName' : this.fetchFirstNames(vValue) ; break ; case 'zipCode' : this.fetchCities(vValue) ; break ; } } doValidate() { var vError = false ; if (!vError) { for(var vField of this.fields) { var vValue = vField.getValue() ; if (typeof vValue == 'string') { vField.setValue(vValue.trim()) ; switch (vField.name) { case 'lastName' : vField.setValue(vField.getValue().toUpperCase()) ; break ; } } if (vField.mandatory) { if (!vField.getValue()) { vField.setError('Ce champ est obligatoire') ; vError = 'Veuillez remplir tous les champs obligatoires.' ; } else { vField.setError(false) ; } } } } if (!vError) { for(var vField of this.fields) { var vValue = vField.getValue() ; vField.setError(false) ; if (vValue) { switch (vField.name) { case 'firstName' : case 'lastName' : if (vValue.length < 3) { vField.setError('Ce nom est trop court') ; vError = 'Certains champs ne sont pas remplis avec une valeur valide.' ; } break ; case 'birthDate' : if (vValue instanceof Date) { if (vValue.getTime() > (new Date()).getTime()) { vField.setError('Vous ne pouvez pas entrer une date dans le futur') ; vError = 'Certains champs ne sont pas remplis avec une valeur valide.' ; } if (vValue.getTime() < (new Date()).getTime() - (120 * 365 * 86400 * 1000) ) { vField.setError('Vous ne pouvez pas entrer une date si ancienne') ; vError = 'Certains champs ne sont pas remplis avec une valeur valide.' ; } } break ; case 'zipCode' : if (!zipCodeRegexp.test(vValue)) { vField.setError('Ce code postal n\'est pas valide') ; vError = 'Certains champs ne sont pas remplis avec une valeur valide.' ; } break ; case 'mail' : if (!emailRegexp.test(vValue)) { vField.setError('Cette adresse mail n\'est pas valide') ; vError = 'Certains champs ne sont pas remplis avec une valeur valide.' ; } break ; case 'phoneNumber' : if (!phoneNumberRegexp.test(vValue)) { vField.setError('Ce numéro de téléphone n\'est pas valide') ; vError = 'Certains champs ne sont pas remplis avec une valeur valide.' ; } break ; } } } } this.setError(vError) ; return (vError === false) ; } setError(aError) { this.error = aError ; if (this.error !== false) { this.dError.innerText = this.error ; } else { this.dError.innerText = '' ; } for (var vButton of this.buttons) { if (vButton.type == FORMBUTTON_OK) { vButton.setEnabled(aError === false) ; } } } buildFormObject() { var vFormData = {} ; for(var vField of this.fields) { if (vField.type > 0) vFormData[vField.name] = vField.getValue() ; } return vFormData ; } checkAppointmentCode(aAppointmentCode) { var vUrl = this.winnerUrl + '?register&act=checkAppointmentCode' ; fetch( vUrl, { method: 'POST', body: JSON.stringify( { gameAppointmentCode: aAppointmentCode } ) } ).then( (response) => { if (response.status == 200) { this.doShowForm() ; } else { this.doInvalidAppointement() ; } } ) ; } fetchCountries() { var vUrl = this.winnerUrl + '?register&act=getCountries' ; fetch( vUrl, { method: 'GET' } ).then( (response) => response.json() ).then( (data) => { this.fillCountries(data) ; } ) ; } fillCountries(aCountries) { var vField = this.getField('country') ; if (vField) { for(var vCountry of aCountries) { vField.addChoice(vCountry.code, vCountry.name) ; } } } fetchFirstNames(aFirstName) { var vFirstName = aFirstName.trim() ; if (vFirstName.length > 2) { var vUrl = this.winnerUrl + '?register&act=searchFirstNames&search=' + encodeURIComponent(vFirstName) ; fetch( vUrl, { method: 'GET' } ).then( (response) => response.json() ).then( (data) => { this.fillFirstNames(data) ; } ) ; } } fetchCities(aZipCode) { var vZipCode = aZipCode.trim() ; var vCountryCode = false ; var vCountryField = this.getField('country') ; if (vCountryField) { vCountryCode = vCountryField.getValue() ; } if (vZipCode.length > 4) { var vUrl = this.winnerUrl + '?register&act=getCities&zipCode=' + encodeURIComponent(vZipCode) + '&countryCode=' + encodeURIComponent(vCountryCode) ; fetch( vUrl, { method: 'GET' } ).then( (response) => response.json() ).then( (data) => { this.fillCities(data) ; } ) ; } } fillFirstNames(aFirstNames) { var vField = this.getField('firstName') ; if (vField) { vField.clearDataList() ; if (vField) { for(var vFirstName of aFirstNames) { vField.addDataListItem(vFirstName.firstName) ; } } } } fillCities(aCities) { var vField = this.getField('city') ; if (vField) { vField.clearDataList() ; if (vField) { for(var vCity of aCities) { vField.addDataListItem(vCity.name) ; } } } } doSubmit() { if (this.doValidate()) { var vData = this.buildFormObject() ; vData.gameAppointmentCode = this.gameAppointmentCode ; var vFormData = JSON.stringify(vData) ; for (var vButton of this.buttons) { if (vButton.type == FORMBUTTON_OK) { vButton.setEnabled(false) ; } } var vUrl = this.winnerUrl + '?register&act=submitForm' ; fetch( vUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: vFormData } ).then( (response) => response.json() ).then( (data) => { if (data === true) { this.doSuccess() ; } else { this.doFailed() ; } } ).catch( (error) => { this.doValidate() ; } ) ; } } doSuccess() { this.dForm.style.display = 'none' ; this.dButtons.style.display = 'none' ; this.dResult.style.display = 'block' ; this.dResult.innerText = this.successMessage ; } doFailed() { this.dForm.style.display = 'none' ; this.dButtons.style.display = 'none' ; this.dResult.style.display = 'block' ; this.dResult.innerText = this.failureMessage ; } doInvalidAppointement() { this.dForm.style.display = 'none' ; this.dButtons.style.display = 'none' ; this.dResult.style.display = 'block' ; this.dResult.innerText = this.invalidAppointmentMessage ; } doShowForm() { this.dForm.style.display = 'block' ; this.dButtons.style.display = 'inline-flex' ; this.dResult.style.display = 'none' ; this.dResult.innerText = '' ; } doCancel() { } } class winRegisterField { winRegisterForm = false ; name = '' ; title = '' ; type = FORMFIELD_NONE ; defaultValue = '' ; enabled = true ; mandatory = false ; error = false ; div = false ; dTitle = false ; input = false ; dataList = false ; delayQuery = false ; constructor(aWinRegisterForm, aName, aTitle, aType, aDefaultValue) { this.winRegisterForm = aWinRegisterForm ; this.name = aName ; this.title = aTitle ; this.type = aType ; this.defaultValue = aDefaultValue ; this.div = document.createElement('div') ; this.div.style.display = 'inline-flex' ; this.div.style.flexDirection = 'row' ; this.div.style.flexWrap = 'wrap' ; this.div.style.alignItems = 'baseline' ; this.div.style.gap = '5px' ; this.div.style.width = '-webkit-fill-available' ; this.div.style.marginBottom = '5px' ; this.dTitle = document.createElement('div') ; this.dTitle.style.width = '150px' ; this.dTitle.style.minWidth = '150px' ; this.dTitle.style.fontSize = '14px' ; this.dTitle.style.fontWeight = 'normal' ; this.dTitle.innerText = this.title ; this.div.appendChild(this.dTitle) ; switch (this.type) { case FORMFIELD_STRING : this.input = document.createElement('input') ; this.input.type = 'text' ; this.input.style.minWidth = '300px' ; this.input.style.flexGrow = '1' ; break ; case FORMFIELD_TEXT : this.input = document.createElement('textarea') ; this.input.style.minWidth = '300px' ; this.input.style.flexGrow = '1' ; break ; case FORMFIELD_DROPLIST : this.input = document.createElement('select') ; this.input.style.minWidth = '300px' ; this.input.style.flexGrow = '1' ; break ; case FORMFIELD_NUMBER : this.input = document.createElement('input') ; this.input.type = 'text' ; this.input.style.width = '100px' ; break ; case FORMFIELD_DATE : this.input = document.createElement('input') ; this.input.type = 'date' ; this.input.style.width = '200px' ; break ; case FORMFIELD_BOOLEAN : this.input = document.createElement('input') ; this.input.type = 'checkbox' ; this.dTitle.innerText = '' ; this.div.style.flexWrap = 'nowrap' ; break ; case FORMFIELD_SEPARATOR : this.div.style.marginTop = '10px' ; this.dTitle.style.fontWeight = 'bold' ; this.dTitle.style.fontSize = '16px' ; this.dTitle.style.width = '' ; this.input = false break ; } if (this.input) { this.input.style.maxWidth = '800px' ; this.input.style.minWidth = '300px' ; this.input.style.padding = '5px' ; this.input.style.border = 'solid 1px #808080' ; this.input.style.borderRadius = '5px' ; this.div.appendChild(this.input) ; this.input.addEventListener('change', (e) => { this.doOnChange(e) }, false) ; this.input.addEventListener('keyup', (e) => { this.doOnType(e) }, false) ; } this.dataList = document.createElement('datalist') ; this.dataList.id = aName + '_list' ; this.div.appendChild(this.dataList) ; if (this.input) { this.input.setAttribute('list', this.dataList.id) ; } this.dSuffix = document.createElement('div') ; this.dSuffix.style.fontSize = '14px' ; this.dSuffix.style.fontWeight = 'normal' ; this.dSuffix.style.flexGrow = '1' ; this.dSuffix.innerText = '' ; this.div.appendChild(this.dSuffix) ; switch (this.type) { case FORMFIELD_BOOLEAN : this.input.style.minWidth = '32px' ; this.dTitle.innerText = '' ; this.dSuffix.innerText = this.title ; break ; } this.updateField() ; } setWidth(aWidth) { if (this.input) { this.input.style.width = aWidth ; this.input.style.minWidth = aWidth ; this.input.style.flexGrow = '' ; } return this ; } setSize(aCols = false, aRows = false) { switch (this.type) { case FORMFIELD_TEXT : if (aCols) this.input.cols = aCols ; if (aRows) this.input.rows = aRows ; break ; } return this ; } setEnabled(aEnabled) { if (this.enabled != aEnabled) { this.enabled =(aEnabled !== false) ; this.updateField() ; } return this ; } setMandatory(aMandatory) { if (this.mandatory != aMandatory) { this.mandatory = (aMandatory !== false) ; this.updateField() ; } return this ; } setError(aError) { this.error = aError ; this.updateField() ; return this ; } addChoice(aValue, aTitle) { if (this.type == FORMFIELD_DROPLIST) { var vOption = document.createElement('option') ; vOption.innerText = aTitle ; vOption.value = aValue ; this.input.appendChild(vOption) ; } return this ; } updateField() { if (this.input) { this.input.disabled = !this.enabled ; if (this.error === false) { this.input.style.color = '' ; this.input.style.backgroundColor = '' ; this.input.title = '' ; } else { this.input.style.color = '#C00000' ; this.input.style.backgroundColor = '#FFC0C0' ; this.input.title = this.error ; } } } setValue(aValue) { switch (this.type) { case FORMFIELD_DATE : case FORMFIELD_DATETIME : this.input.valueAsDate = aValue ; break ; case FORMFIELD_BOOLEAN : this.input.checked = (aValue !== false); break ; case FORMFIELD_SEPARATOR : break ; default : this.input.value = aValue ; } return this ; } getValue(aValue) { switch (this.type) { case FORMFIELD_DATE : case FORMFIELD_DATETIME : return this.input.valueAsDate ; break ; case FORMFIELD_BOOLEAN : return this.input.checked ; break ; case FORMFIELD_SEPARATOR : return null ; break ; default : return this.input.value ; } } doOnChange(e) { if (this.winRegisterForm) { this.winRegisterForm.doOnFieldChange(this, e) ; } } doOnType(e) { if (this.winRegisterForm) { if (this.delayQuery) clearTimeout(this.delayQuery) ; this.delayQuery = setTimeout( (e) => { this.winRegisterForm.doOnFieldType(this, e) ; }, 250 ) ; } } clearDataList() { this.dataList.innerHTML = '' ; } addDataListItem(aValue, aTitle = false) { if (!aTitle) aTitle = aValue ; var vOption = document.createElement('option') ; vOption.value = aValue ; vOption.innerText = aTitle ; this.dataList.appendChild(vOption) ; return vOption ; } } class winRegisterButton { winRegisterForm = false ; type = FORMBUTTON_OK ; title = '' ; color = '#A0A0A0' ; enabled = true ; div = false ; constructor(aWinRegisterForm, aType, aTitle = false) { this.winRegisterForm = aWinRegisterForm ; this.type = aType ; switch (this.type) { case FORMBUTTON_OK : this.title = 'Envoyer' ; this.color = '#0080FF' ; break ; case FORMBUTTON_CANCEL : this.title = 'Annuler' ; this.color = '#A0A0A0' ; break ; } if (aTitle) this.title = aTitle ; this.div = document.createElement('div') ; this.div.style.padding = '10px' ; this.div.style.margin = '5px' ; this.div.style.borderRadius = '5px' ; this.div.style.fontWeight = 'bold' ; this.div.style.color = '#FFFFFF' ; this.div.style.cursor = 'pointer' ; this.div.tabIndex = 0 ; this.div.addEventListener('click', (e) => { this.doOnClick(e) }, false) ; this.updateButton() ; } setTitle(aTitle) { this.title = aTitle ; this.updateButton() ; return this ; } setColor(aColor) { this.color = aColor ; this.updateButton() ; return this ; } setEnabled(aEnabled) { if (this.enabled != aEnabled) { this.enabled = (aEnabled !== false) ; this.updateButton() ; } } updateButton() { this.div.innerText = this.title ; if (this.enabled) { this.div.style.color = '#FFFFFF' ; this.div.style.backgroundColor = this.color ; this.div.style.cursor = 'pointer' ; } else { this.div.style.color = '#A0A0A0' ; this.div.style.backgroundColor = '#C0C0C0' ; this.div.style.cursor = 'default' ; } } doOnClick(e) { if (this.winRegisterForm) this.winRegisterForm.doOnButtonClick(this) ; } }