0

When I fill in all the input fields and choose an option in the select dropdown, for some reason the class will not be removed unless I start with the select dropdown. How come is that? I really don't get it.

var firstNameInput = document.getElementById('first_name_input');
var lastNameInput = document.getElementById('last_name_input');
var emailInput = document.getElementById('email_input');
var jobTitleInput = document.getElementById('job_title_input');
var departmentSelect = document.getElementById('department_select');

function checkForInput() {
var inputFields = firstNameInput.value && lastNameInput.value && emailInput.value && jobTitleInput.value && departmentSelect.options[departmentSelect.selectedIndex].value;
 
if(inputFields != '') {
    copyButton.classList.remove('disabled');
    } else {
    copyButton.classList.add('disabled');
    }
}
<form>
    <input id="first_name_input" type="text" onkeyup="checkForInput();">
    <input id="last_name_input" type="text" onkeyup="checkForInput();">
    <input id="email_input" type="email" onkeyup="checkForInput();">
    <input id="job_title_input" type="text" onkeyup="checkForInput();">

    <select id="department_select" onchange="checkForInput();">
        <option value="" disabled selected>Afdeling</option>
        <option value="administration">Administration</option>
        <option value="marketing">Marketing</option>
        <option value="support">Support</option>
        <option value="reklamation">Reklamation</option>
        <option value="produktion">Produktion</option>
    </select>
</form>

<a class="btn disabled" id="copyButton">Copy</a>
Brian
  • 76
  • 8
  • 2
    Please click the `<>` and create a [mcve] - we are missing departmentPrev – mplungjan Oct 01 '17 at 11:04
  • Where is the copy button? – Srikant Sahu Oct 01 '17 at 11:08
  • You are creating a boolean and asking if it is not "" - change your && to + to concatenate or change the test to `if (inputFields)` – mplungjan Oct 01 '17 at 11:08
  • Also onkeyup on a select does not make sense – mplungjan Oct 01 '17 at 11:09
  • Maybe "[updating] the code for better overview" fixed the problem? Your current example already does exactly what you are asking for. It removes the class as soon as all 5 inputs have a value, in whatever order they are entered. – skylize Oct 01 '17 at 12:57
  • @skylize And as I mentioned, it does work, but only if the user starts with the select option (which on the webpage is the last "input" from the user, so that's not good). But if the user fills out all the inputs and selects at the end, it never removes the class. – Brian Oct 01 '17 at 18:34
  • @Brian. I don't know what the situation is for your website. But your example code does not have this issue (or at least not in Chrome). If I run your snippet, and then open devtools and select the "Copy" anchor element, I can fill in the form in any order. Once every input has a value the classname disappears. If I delete the text from one of the inputs, the classname appears again. – skylize Oct 01 '17 at 21:09

1 Answers1

0

Here is a functional version:

<style>
    .btn {
        color: blue;
    }
    .disabled {
        color: red;
        font-size: 20px;
    }
</style>
<form>
    <input id="first_name_input" type="text" onkeyup="checkForInput();">
    <input id="last_name_input" type="text" onkeyup="checkForInput();">
    <input id="email_input" type="email" onkeyup="checkForInput();">
    <input id="job_title_input" type="text" onkeyup="checkForInput();">

    <select id="department_select" onchange="checkForInput();">
        <option value="" disabled selected>Afdeling</option>
        <option value="administration">Administration</option>
        <option value="marketing">Marketing</option>
        <option value="support">Support</option>
        <option value="reklamation">Reklamation</option>
        <option value="produktion">Produktion</option>
    </select>
</form>

<a class="btn disabled" id="copyButton">Copy</a>

<script>
    const checkForInput = () => {
        // start a tally to see how many fields have values
        let allDone = 0

        // get value of each element
        const firstNameInput = document.getElementById('first_name_input').value
        const lastNameInput = document.getElementById('last_name_input').value
        const emailInput = document.getElementById('email_input').value
        const jobTitleInput = document.getElementById('job_title_input').value
        const departmentSelect = document.getElementById('department_select').value

        // put values into an array
        const currentValues = [
            firstNameInput,
            lastNameInput,
            emailInput,
            jobTitleInput,
            departmentSelect
        ]

        // map over array and if value has any length, (1 character or greater)
        // increment tally by 1
        currentValues.map((value) => value.length ? allDone += 1 : false)

        // if tally = 5, all fields have data in them, remove disabled class
        if (allDone === 5) return copyButton.classList.remove('disabled')

        // else add disabled class (just incase they wipe out a field)
        return copyButton.classList.add('disabled')
    }
</script>

I demonstrated several techniques that you can research further:

  1. fat arrow syntax, http://wesbos.com/arrow-functions/
  2. array literal, What is array literal notation in javascript and when should you use it?
  3. Array.map, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
  4. ternary operator, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
  5. inline IF statement shorthand, you can omit { and } for if statements that only have one expression, such as if (something === 'ok') console.log(something)
  6. I used that along with explicit returns to get rid of the else { } block
  7. const and let, http://wesbos.com/let-vs-const/
  8. implicit return, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

This code will be easy to extend and maintain if you need to add or remove fields.

Put a console.log(currentValues) right above currentValues.map() if you want to see how it is behaving on keypress.

If you want to see even more, change the map part to this:

currentValues.map((value) => {
    console.log('Examining:', value)
    console.log('Character length:', value.length)
    console.log('Number of completed fields:', allDone)
    return value.length ? allDone += 1 : false
})
agm1984
  • 9,418
  • 3
  • 51
  • 69