-
Notifications
You must be signed in to change notification settings - Fork 0
Obj/contact us updates #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,136 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>Document</title> | ||
| </head> | ||
| <body> | ||
| </body> | ||
| </html> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <title>Contact Us</title> | ||
| <link rel="stylesheet" href="./styles/styles.css" /> | ||
| </head> | ||
| <body> | ||
| <header> | ||
| <h1>Contact us</h1> | ||
| </header> | ||
| <main> | ||
| <form class="form"> | ||
| <fieldset class="inputContainer name"> | ||
| <legend>Name</legend> | ||
| <input type="text" name="Name" placeholder="Name" /> | ||
| <label class="invalidText">Input character range is (1 - 50)</label> | ||
| </fieldset> | ||
| <fieldset class="inputContainer lastname"> | ||
| <legend>Last Name</legend> | ||
| <input type="text" name="Last Name" placeholder="Last Name" /> | ||
| <label class="invalidText">Input character range is (1 - 50)</label> | ||
| </fieldset> | ||
| <fieldset class="inputContainer email"> | ||
| <legend>Email</legend> | ||
| <input type="email" name="Email" placeholder="Email" /> | ||
| <label class="invalidText">Enter a valid email address</label> | ||
| </fieldset> | ||
| <fieldset class="inputContainer tel"> | ||
| <legend>Tel</legend> | ||
| <input type="tel" name="Tel" placeholder="Tel" /> | ||
| <label class="invalidText">Enter a valid telephone number</label> | ||
| </fieldset> | ||
| <fieldset class="inputContainer"> | ||
| <legend>Purpose of contact</legend> | ||
| <select id="purpose" class="dropdown" name="Purpose of contact"> | ||
| <option value="" hidden>Select an option</option> | ||
| <option value="General-inquiry">General Inquiry</option> | ||
| <option value="Product-support">Product Support</option> | ||
| <option value="Sales-inquiry">Sales Inquiry</option> | ||
| <option value="Media-press-inquiry">Media/Press Inquiry</option> | ||
| <option value="Feedback-suggestions">Feedback/Suggestions</option> | ||
| <option value="Other">Other</option> | ||
| </select> | ||
| <label class="invalidText">Select an option</label> | ||
| </fieldset> | ||
| <fieldset class="inputContainer"> | ||
| <legend>Contact me via</legend> | ||
| <label class="radioLabel telEmailLabel" | ||
| <input type="radio" name="Contact via" id="email" value="Email" | ||
| /></label> | ||
| <label class="radioLabel telEmailLabel" | ||
| >Tel <input type="radio" name="Contact via" id="tel" value="Tel" | ||
| /></label> | ||
| <label class="invalidText">Select an option</label> | ||
| <br /> | ||
| <label class="hidden" id="emailSpecificationLabel1" | ||
| >Use entered email | ||
| <input | ||
| type="radio" | ||
| name="Email specification" | ||
| value="Use entered email" | ||
| /></label> | ||
| <label class="hidden" id="emailSpecificationLabel2" | ||
| >Use another email | ||
| <input | ||
| type="radio" | ||
| name="Email specification" | ||
| value="Use another email" | ||
| /></label> | ||
| <label class="invalidText">Select an option</label> | ||
| </fieldset> | ||
| <fieldset class="inputContainer message"> | ||
| <legend>Message</legend> | ||
| <label | ||
| ><input | ||
| type="checkbox" | ||
| name="checkboxMessage" | ||
| class="notRequired" | ||
| id="message" | ||
| />Leave a Message</label | ||
| > | ||
| <input | ||
| type="text" | ||
| name="MessageText" | ||
| class="hidden" | ||
| placeholder="...Write something" | ||
| /> | ||
| <label class="invalidText">Input character range is (1 - 50)</label> | ||
| </fieldset> | ||
| <label class="termsLabel" | ||
| ><input type="checkbox" name="checkboxTerms" id="terms" /> | ||
| Accept terms | ||
| <label class="invalidText">Check this box to proceed</label></label | ||
| > | ||
| <button type="submit" class="registerButton">Submit</button> | ||
| </form> | ||
| </main> | ||
|
|
||
| <dialog class="modal"> | ||
| <h3 class="modalTitle">Terms and policies</h3> | ||
| <p class="modalText"> | ||
| 1. ACCEPTANCE THE USE OF LOREM IPSUM TERMS AND CONDITIONS Your access to | ||
| and use of Lorem Ipsum (the app) is subject exclusively to these Terms | ||
| and Conditions. You will not use the app for any purpose that is | ||
| unlawful or prohibited by these Terms and Conditions. By using the app | ||
| you are fully accepting the terms, conditions and disclaimers contained | ||
| in this notice. If you do not accept these Terms and Conditions you must | ||
| immediately stop using the app.<br /><br /> | ||
| 2. CREDIT CARD DETAILS All Lorem Ipsum purchases are managed by the | ||
| individual App Stores (Apple, Google Windows) and Lorem Ipsum will never | ||
| store your credit card information or make it available to any third | ||
| parties. Any purchasing information provided will be provided directly | ||
| from you to the respective App Store and you will be subject to their | ||
| credit card policies.<br /><br /> | ||
| 3. LEGAL ADVICE The contents of Lorem Ipsum app do not constitute advice | ||
| and should not be relied upon in making or refraining from making, any | ||
| decision. All material contained on Lorem Ipsum is provided without any | ||
| or warranty of any kind. You use the material on Lorem Ipsum at your own | ||
| discretion <br /><br /> | ||
| 4. CHANGE OF USE Lorem Ipsum reserves the right to:<br /> | ||
| 4.1 change or remove (temporarily or permanently) the app or any part of | ||
| it without notice and you confirm that Lorem Ipsum shall not be liable | ||
| to you for any such change or removal and.<br /> | ||
| 4.2 change these Terms and Conditions at any time, and your continued | ||
| use of the app following any changes shall be deemed to be your | ||
| acceptance of such change. | ||
| </p> | ||
| <button class="closeModalButton">Close</button> | ||
| <button class="continueModalButton" disabled>Continue</button> | ||
| </dialog> | ||
| <script src="./js/script.js"></script> | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,184 @@ | ||
| const form = document.querySelector("form"); | ||
| const checkboxMessage = document.querySelector("input[name='checkboxMessage']"); | ||
| const checkboxTerms = document.querySelector("input[name='checkboxTerms']"); | ||
| const radioButtonsContactVia = Array.from( | ||
| document.querySelectorAll("input[name='Contact via']") | ||
| ); | ||
| const dropdown = document.querySelector("select"); | ||
| const modal = document.querySelector(".modal"); | ||
| const modalText = document.querySelector(".modalText"); | ||
| const modalCloseButton = document.querySelector(".closeModalButton"); | ||
| const modalContinueButton = document.querySelector(".continueModalButton"); | ||
|
|
||
| function initializeInputs() { | ||
| // refresh all inputs on reload (Firefox) and add event listeners | ||
| const textInputs = document.querySelectorAll( | ||
| 'select,input:not([type="checkbox"],[type="radio"],.notRequired)' | ||
| ); | ||
| const buttons = document.querySelectorAll( | ||
| 'input:is([type="checkbox"],[type="radio"]):not(.notRequired)' | ||
| ); | ||
|
|
||
| textInputs.forEach((textInput) => { | ||
| textInput.value = ""; | ||
| textInput.addEventListener("input", (e) => validateInput(e.target)); | ||
| }); | ||
| dropdown.addEventListener("change", () => | ||
| dropdown.classList.remove("invalid") | ||
| ); | ||
| buttons.forEach((button) => { | ||
| button.checked = false; | ||
| button.addEventListener("click", (e) => validateInput(e.target)); | ||
| }); | ||
| checkboxMessage.checked = false; | ||
| } | ||
|
|
||
| window.addEventListener("load", () => initializeInputs()); | ||
|
|
||
| function handleRadioButtonTelEmailClick(clickedRadioButtonTelEmail) { | ||
| const radioButtonsEmailSpecification = Array.from( | ||
| document.querySelectorAll("input[name='Email specification']") | ||
| ); | ||
|
|
||
| radioButtonsEmailSpecification.forEach((radioButtonEmailSpecification) => { | ||
| if (clickedRadioButtonTelEmail.id === "email") { | ||
| radioButtonEmailSpecification.parentElement.classList.remove("hidden"); | ||
| } else { | ||
| radioButtonEmailSpecification.parentElement.classList.add("hidden"); | ||
| radioButtonEmailSpecification.parentElement.classList.remove("invalid"); | ||
| radioButtonEmailSpecification.checked = false; | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| radioButtonsContactVia.forEach((radioButtonContactVia) => { | ||
| radioButtonContactVia.addEventListener("click", () => | ||
| handleRadioButtonTelEmailClick(radioButtonContactVia) | ||
| ); | ||
| }); | ||
|
|
||
| checkboxMessage.addEventListener("click", () => { | ||
| const messageTextInput = document.querySelector("input[name='MessageText']"); | ||
| if (messageTextInput.classList.contains("hidden")) { | ||
| messageTextInput.classList.remove("hidden"); | ||
| } else { | ||
| messageTextInput.value = ""; | ||
| messageTextInput.classList.add("hidden"); | ||
| messageTextInput.classList.remove("invalid"); | ||
| } | ||
| }); | ||
|
|
||
| function validateButton(buttonName) { | ||
| const buttons = Array.from( | ||
| document.querySelectorAll(`input[name='${buttonName}']`) | ||
| ); | ||
| let isAnyButtonClicked = false; | ||
|
|
||
| buttons.forEach((button) => { | ||
| button.parentElement.classList.remove("invalid"); | ||
| if (button.checked) { | ||
| isAnyButtonClicked = true; | ||
| button.classList.remove("notRequired"); | ||
| } else { | ||
| button.classList.add("notRequired"); | ||
| } | ||
| }); | ||
| if (!isAnyButtonClicked) { | ||
| //none of the buttons are clicked | ||
| buttons.forEach((button) => { | ||
| button.parentElement.classList.add("invalid"); | ||
| button.classList.remove("notRequired"); | ||
| }); | ||
| } | ||
|
|
||
| return isAnyButtonClicked; | ||
| } | ||
|
|
||
| function validateInput(input) { | ||
| let isInputValid = false; | ||
|
|
||
| switch (input.type) { | ||
| case "text": | ||
| isInputValid = | ||
| input.value.trim().length > 0 && input.value.trim().length <= 50; | ||
| break; | ||
| case "email": | ||
| const EmailRegEx = /^[\w-.]+@([\w-]+\.)+[\w-]{2,}$/; | ||
| isInputValid = EmailRegEx.test(input.value); | ||
| break; | ||
| case "tel": | ||
| const TelRegEx = /^\d{9,10}$/; | ||
| input.value = input.value.replace(/\D/g, ""); | ||
| isInputValid = TelRegEx.test(input.value); | ||
| break; | ||
| case "select-one": | ||
| isInputValid = input.value !== ""; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Used strict equality (===) instead of loose equality (==) for comparison to ensure consistent behavior. |
||
| break; | ||
| case "radio": | ||
| isInputValid = validateButton(input.name); | ||
| break; | ||
| default: | ||
| return true; | ||
| } | ||
|
|
||
| if (isInputValid) input.classList.remove("invalid"); | ||
| else input.classList.add("invalid"); | ||
| return isInputValid; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refactor to: return isInputValid; |
||
| } | ||
|
|
||
| function validateForm(formEvent) { | ||
| formEvent.preventDefault(); | ||
|
|
||
| const inputs = Array.from( | ||
| document.querySelectorAll( | ||
| "select,input:not(.hidden,.hidden *,.notRequired,[type='checkbox'])" | ||
| ) | ||
| ); | ||
| let isFormValid = true; | ||
|
|
||
| inputs.forEach((input) => { | ||
| if (!validateInput(input)) isFormValid = false; | ||
| }); | ||
|
|
||
| if (!checkboxTerms.checked) { | ||
| isFormValid = false; | ||
| checkboxTerms.parentElement.classList.add("invalid"); | ||
| } | ||
|
|
||
| if (!isFormValid) return; | ||
|
|
||
| const inputsText = inputs | ||
| .filter((input) => input.value !== "on") | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Used strict equality (===) instead of loose equality (==) for comparison to ensure consistent behavior. |
||
| .map((filteredInput) => `${filteredInput.name}: ${filteredInput.value}`) | ||
| .join("\n"); | ||
|
|
||
| alert(inputsText); | ||
| } | ||
|
|
||
| form.addEventListener("submit", (e) => validateForm(e)); | ||
|
|
||
| checkboxTerms.addEventListener("click", (e) => { | ||
| if (!modalContinueButton.disabled) modalContinueButton.disabled = true; | ||
|
|
||
| if (checkboxTerms.checked) { | ||
| e.preventDefault(); | ||
| modal.showModal(); | ||
| } else checkboxTerms.checked = false; | ||
| }); | ||
|
|
||
| modalCloseButton.addEventListener("click", () => { | ||
| modalText.scrollTop = 0; | ||
| modal.close(); | ||
| }); | ||
| modalContinueButton.addEventListener("click", () => { | ||
| checkboxTerms.checked = true; | ||
| checkboxTerms.parentElement.classList.remove("invalid"); | ||
| modalText.scrollTop = 0; | ||
| modal.close(); | ||
| }); | ||
|
|
||
| modalText.addEventListener("scroll", (e) => { | ||
| const { scrollHeight, scrollTop, clientHeight } = e.target; | ||
| if (Math.abs(scrollHeight - clientHeight - scrollTop) < 1) | ||
| modalContinueButton.disabled = false; | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplified the selectors for text inputs and buttons to exclude the unnecessary :is and :not pseudo-classes.