0

that's the task :

Implement a Contact form component. Your form should have: 2 text inputs, 1 radio button, 1 text area, 1 submit button and an optional image on the right, just to make the form look a little better. ● When clicking the “Submit” button, you should validate the required fields , and display a red border around the input if validation fails. ● If user corrects the error, you should remove the red border. ● When the form is successfully submitted (no validation errors) you should display a Confirmation banner (which is hidden initially) containing the user’s first name that you just collected from the input fields. Also all the info from the input fields should be printed in the Console.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ContactFormValidation</title>
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>
<body>
<div id="contactFormContainer">
    <div class="container my-4">
        <div class="row">
            <div class="col-md-12">
                <div id="alert" class="alert" role="alert">
                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                  </div>
            </div>
            <div id="fields" class="col-md-6 mb-3">
                <form id="contactForm" action="#">
                    <div class="form-group">
                        <input type="text" id="firstName" class="form-control field" placeholder="First Name">
                    </div>
                    <div class="form-group">
                        <input type="text" id="lastName" class="form-control field" placeholder="Last Name">
                    </div>
                    <div class="form-group">
                        <label for="">Gender</label>
                        <fieldset id="gender">
                            <input type="radio" value="M" name="gender" checked> M
                            <input type="radio" value="F" name="gender"> F
                          </fieldset>
                    </div>
                    <div class="form-group">
                        <textarea name="message" id="message" class="form-control field" placeholder="Your message here ..."></textarea>
                    </div>
                    <div class="text-right">
                        <button class="btn btn-primary btn-submit">
                            Submit
                        </button>
                    </div>
            
                </form>
            </div>
            <div class="col-md-6">
                <img src="images/contact-us.jpeg" class="img-fluid" alt="contact us">
            </div>
        </div>
    </div>
</div>
<script src="app.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>

style.css

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: Verdana, Geneva, Tahoma, sans-serif;
}

.alert {
    display: none;
}

.check {
    float: left;
    margin: 0;
    width: 24px;
    height: 24px;
    padding: 0;
    margin-right: 20px;
    background: #2B8F35;
    color: white;
    border-radius: 50%;
    text-align: center;
}

app.js

// get element from DOM : inputs, textarea and alert div and submit button
var alertMessage = document.getElementById('alert');
var inputFirstName = document.getElementById('firstName');
var inputLastName = document.getElementById('lastName');
var inputGender = document.getElementsByName('gender');
var textAreaMessage = document.getElementById('message');
var submitBtnForm = document.querySelector('.btn-submit');

// add event listener to inputs&textarea and button
inputFirstName.addEventListener('keyup', checkInputFirstNameFunction);
inputLastName.addEventListener('keyup', checkInputLastNameFunction);
textAreaMessage.addEventListener('keyup', checkTextAreaMessageFunction);
submitBtnForm.addEventListener('click', submitForm);

function checkInputFirstNameFunction(e){
    // console.log(e.target);
    if(e.target.value == 0){
        // console.log('is empty');
        inputFirstName.classList.add('is-invalid');
    } else {
        inputFirstName.classList.remove('is-invalid');
    }
}

function checkInputLastNameFunction(e){
    if(e.target.value == 0){
        inputLastName.classList.add('is-invalid');
    } else {
        inputLastName.classList.remove('is-invalid');
    }
}

function checkTextAreaMessageFunction(e){
    if(e.target.value == 0){
        textAreaMessage.classList.add('is-invalid');
    } else {
        textAreaMessage.classList.remove('is-invalid');
    }
    if (e.keyCode == 13) {
        submitForm(e);
    }
    e.preventDefault();
}

function submitForm(e){
    if  ( 
        inputFirstName.value == 0 ||   
        inputLastName.value == 0 || 
        textAreaMessage == 0 
        )
    {
        inputFirstName.classList.add('is-invalid');
        inputLastName.classList.add('is-invalid');
        textAreaMessage.classList.add('is-invalid');
    } 
    else {    
        inputFirstName.classList.remove('is-invalid');
        inputLastName.classList.remove('is-invalid');
        textAreaMessage.classList.remove('is-invalid');  
            alertMessage.classList.add('alert-success', 'd-block', 'show' ,'fade');
            alertMessage.innerHTML = 
                "<span class='check'>✓</span>" + 
                "Thank you for contacting us, " +
                inputFirstName.value +
                "<button type='button' class='close' data-dismiss='alert' aria-label='Close'>" + 
                "<span aria-hidden='true'>&times;</span>" + 
                "</button>";
            console.log('Firstname : ' + inputFirstName.value);
            console.log('Lastname : ' + inputLastName.value);
            for (i = 0; i < inputGender.length; i++) {
                if (inputGender[i].checked) {
                    console.log('Gender : ' + inputGender[i].value);       
                }        
            }  
            console.log('Message : ' + textAreaMessage.value);
    }
    e.preventDefault();
}

I fail to make it, when the user presses Submit or enter in the text, to disappear the corrected errors, That is, if a field is already red, and I type something in it, the error disappears, if I enter directly in that input / textarea, the error reappears on the corrected field

6
  • If you copy and paste the code into an online sandbox, everything seems to work as prescribed by the requirements (see: jsfiddle.net/2hxq7Lar). In your HTML file, try moving <script src="app.js"></script> after all other script tags; that might do the trick Commented Aug 3, 2021 at 16:53
  • ... no, wait, it does not work as intended: even if you leave only one field empty, the red border is be added to all fields Commented Aug 3, 2021 at 16:58
  • I tried and it doesn't work, if I take and fill in the first two fields and give send, it validates my form and the "message" appears When I enter on the textarea or press the send button, I need to add a red border to the blank fields, and when I fill them in and press the send or enter button again in the textarea, I need to remove the red border. from the completed fields and remain to the incomplete ones Commented Aug 3, 2021 at 17:00
  • The problem is that your submitForm(e) is trying to validate all fields with a single if ... else ... statement, therefore even if just one field is empty, all fields will be styled as not valid. Furthermore you should re-use the validation logic you have for each single field rather than repeating it of the submit event. Finally, the value of an empty text input or text area is an empty string '' not zero 0 Commented Aug 3, 2021 at 17:07
  • function submitForm(e){ if ( inputFirstName.value == 0 ){ inputFirstName.classList.add('is-invalid'); } else if ( inputLastName.value == 0 ) { inputLastName.classList.add('is-invalid') } else if ( textAreaMessage.value == 0 ) { textAreaMessage.classList.add('is-invalid'); } But with that, he checks them for me separately, that is, he blushes each one of me Commented Aug 3, 2021 at 17:07

1 Answer 1

1

The trick is to split your validation logic as much as possible into reusable blocks and to run them at the right moment and in the right order.

Try the following:

// USE const INSTEAD OF var FOR PERFORMANCE.
const submitBtnForm = document.querySelector('.btn-submit');

const inputs = [
    document.getElementById('firstName'),
    document.getElementById('lastName'),
    document.getElementById('message')
];

// USE keydown EVENT TO HAVE MORE CONTROL ON USER INPUT ACTION (ACCESS PRESSED KEY AND EVENTUALLY PREVENT IT).
// USE input EVENT TO TRACK input CONTENT.
inputs.forEach((input) => {
    input.addEventListener('keydown', handler);
    input.addEventListener('input', handler);
});

submitBtnForm.addEventListener('click', submitForm);

function checkLength(target) {
    return !!target.value;
}

function submitOnEnterKey(e) {
    // USE === INSTEAD OF == FOR EQUALITY COMPARISON TO TAKE INTO ACCOUNT ALSO DATA TYPE.
    if (e.keyCode === 13) {
        submitForm(e);
        if (e.cancelable) {
            e.preventDefault();
        }
    }
}

function validate(target) {
    const result = checkLength(target);

    if (result) {
        target.classList.remove('is-invalid');
    } else {
        target.classList.add('is-invalid');
    }

    return result;
}

function handler(e) {
    if (e.type === 'input') {
        validate(e.target);
    } else {
        submitOnEnterKey(e);
    }
}

function submitForm(e) {
    const result = inputs.map((input) => validate(input)).every((val) => val);

    if (result) {
        alert('SUCCESS');
    } else {
        alert('FAILURE');
    }

    e.preventDefault();
}
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: Verdana, Geneva, Tahoma, sans-serif;
}

.alert {
    display: none;
}

.check {
    float: left;
    margin: 0;
    width: 24px;
    height: 24px;
    padding: 0;
    margin-right: 20px;
    background: #2B8F35;
    color: white;
    border-radius: 50%;
    text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ContactFormValidation</title>
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>
<body>
<div id="contactFormContainer">
    <div class="container my-4">
        <div class="row">
            <div class="col-md-12">
                <div id="alert" class="alert" role="alert">
                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                  </div>
            </div>
            <div id="fields" class="col-md-6 mb-3">
                <form id="contactForm" action="#">
                    <div class="form-group">
                        <input type="text" id="firstName" class="form-control field" placeholder="First Name">
                    </div>
                    <div class="form-group">
                        <input type="text" id="lastName" class="form-control field" placeholder="Last Name">
                    </div>
                    <div class="form-group">
                        <label for="">Gender</label>
                        <fieldset id="gender">
                            <input type="radio" value="M" name="gender" checked> M
                            <input type="radio" value="F" name="gender"> F
                          </fieldset>
                    </div>
                    <div class="form-group">
                        <textarea name="message" id="message" class="form-control field" placeholder="Your message here ..."></textarea>
                    </div>
                    <div class="text-right">
                        <button class="btn btn-primary btn-submit">
                            Submit
                        </button>
                    </div>
            
                </form>
            </div>
            <div class="col-md-6">
                <img src="images/contact-us.jpeg" class="img-fluid" alt="contact us">
            </div>
        </div>
    </div>
</div>
<script src="app.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.