简体   繁体   中英

How to clear text input and re focus in JavaScript

In my code I want to make disable the button if text input field is empty. It was working fine. But when I add the code to clear and re focus the input box it makes the button enabled and this allows the user to create empty divs by clicking the button. Here I am attaching my whole JavaScript code, please someone help me with this to make this work as I want.

custom_script.js

const subBtn = document.getElementById("btn");
const inptTxt = document.getElementById("text");
const contDiv = document.getElementById("container");

//check input box is empty or not and enable Colorize button
subBtn.disabled = true

inptTxt.addEventListener('input', evt => {
    const value = inptTxt.value.trim()

    if (value) {
        inptTxt.dataset.state = 'valid'
        subBtn.disabled = false
    } else {
        inptTxt.dataset.state = 'invalid'
        subBtn.disabled = true
    }
})

var xhttp = new XMLHttpRequest();

subBtn.addEventListener("click",function(){

    xhttp.onload=function() {
        var crd = document.createElement("div");
        var div = contDiv.getElementsByTagName("div");
        var crdCount = div.length;
        crd.setAttribute("id", "card" + crdCount);
        crd.innerHTML = inptTxt.value;

        //change html title with input text
        document.title = inptTxt.value;

        contDiv .appendChild(crd);
        document.getElementById("card" + crdCount).style.background = JSON.parse(this.responseText).color;  

        //getting inverse value of hex color
        const inv = (hex) => '#' + hex.match(/[a-f0-9]{2}/ig).map(e => (255 - parseInt(e, 16) | 0).toString(16).replace(/^([a-f0-9])$/, '0$1')).join('')
        const invert = () =>
        document.querySelectorAll('circle')
        .forEach(c => 
        (hex = c.getAttribute('fill')) && 
        c.setAttribute('fill', inv(hex))
        )
        var invColor = inv(JSON.parse(this.responseText).color);

        //setting the inverse value to card text
        var crdText = document.getElementById("card" + crdCount).innerHTML;
        var setColor = "<span style='color:" + invColor + "'>" + crdText + "</span>";
        document.getElementById("card" + crdCount).innerHTML = setColor;

        //clear input and refocus
        inptTxt.value = "";
        inptTxt.focus();
        inptTxt.select();
    };

    xhttp.onerror=function() {
        var crd = document.createElement("div");
        var div = contDiv.getElementsByTagName("div");
        var crdCount = div.length;
        crd.setAttribute("id", "card" + crdCount);
        crd.innerHTML = inptTxt.value;

        //change html title with input text
        document.title = inptTxt.value;

        contDiv .appendChild(crd);
        document.getElementById("card" + crdCount).style.background = "#6d4298";  

        var crdText = document.getElementById("card" + crdCount).innerHTML;
        var setColor = "<span style='color:#ffffff'>" + crdText + "</span>";
        document.getElementById("card" + crdCount).innerHTML = setColor;
    };

    xhttp.open("GET","http://api.creativehandles.com/getRandomColor");
    xhttp.send(); 

})

//submit quote using Enter key
inptTxt.addEventListener("keyup", function(event) {
    if (event.keyCode === 13) {
    event.preventDefault();
    subBtn.click();
  }
});

Here is a simple snippet of input and button.

I used the onInput event to detect whenever the input is changing. When it does, I just set the disable property of the button to be the answer of whether the input is empty or not.

Note that I'm initializing the button with disabled attribute because at the start it should be disabled.

 let button = document.getElementById('button'); let input = document.getElementById('input'); function doSomething() { input.value = ''; input.focus(); inputHasChanged(); } function inputHasChanged() { button.disabled = input.value === ''; }
 <button disabled id="button" onclick="doSomething()">click</button> <input id="input" type="text" onInput="inputHasChanged()">

Because setting the value of an input via javascript doesn't trigger it's input event.

You need to trigger its event manually after you set its value.

Here's the solution, notice the comments marked with FIX :

const subBtn = document.getElementById("btn");
const inptTxt = document.getElementById("text");
const contDiv = document.getElementById("container");

//check input box is empty or not and enable Colorize button
subBtn.disabled = true

// FIX: make a dedicated function for validation
function validateInput() {
    const value = inptTxt.value.trim()

    if (value) {
        inptTxt.dataset.state = 'valid'
        subBtn.disabled = false
    } else {
        inptTxt.dataset.state = 'invalid'
        subBtn.disabled = true
    }
}

// FIX: call the validation function when the input is changed
inptTxt.addEventListener('input', validateInput);

var xhttp = new XMLHttpRequest();

subBtn.addEventListener("click", function () {

    xhttp.onload = function () {
        var crd = document.createElement("div");
        var div = contDiv.getElementsByTagName("div");
        var crdCount = div.length;
        crd.setAttribute("id", "card" + crdCount);
        crd.innerHTML = inptTxt.value;

        //change html title with input text
        document.title = inptTxt.value;

        contDiv.appendChild(crd);
        document.getElementById("card" + crdCount).style.background = JSON.parse(this.responseText).color;

        //getting inverse value of hex color
        const inv = (hex) => '#' + hex.match(/[a-f0-9]{2}/ig).map(e => (255 - parseInt(e, 16) | 0).toString(16).replace(/^([a-f0-9])$/, '0$1')).join('')
        const invert = () =>
            document.querySelectorAll('circle')
                .forEach(c =>
                    (hex = c.getAttribute('fill')) &&
                    c.setAttribute('fill', inv(hex))
                )
        var invColor = inv(JSON.parse(this.responseText).color);

        //setting the inverse value to card text
        var crdText = document.getElementById("card" + crdCount).innerHTML;
        var setColor = "<span style='color:" + invColor + "'>" + crdText + "</span>";
        document.getElementById("card" + crdCount).innerHTML = setColor;

        //clear input and refocus
        inptTxt.value = "";
        inptTxt.focus();
        inptTxt.select();
        // FIX: call the validation function when the input is cleared
        validateInput();
    };

    xhttp.onerror = function () {
        var crd = document.createElement("div");
        var div = contDiv.getElementsByTagName("div");
        var crdCount = div.length;
        crd.setAttribute("id", "card" + crdCount);
        crd.innerHTML = inptTxt.value;

        //change html title with input text
        document.title = inptTxt.value;

        contDiv.appendChild(crd);
        document.getElementById("card" + crdCount).style.background = "#6d4298";

        var crdText = document.getElementById("card" + crdCount).innerHTML;
        var setColor = "<span style='color:#ffffff'>" + crdText + "</span>";
        document.getElementById("card" + crdCount).innerHTML = setColor;
    };

    xhttp.open("GET", "http://api.creativehandles.com/getRandomColor");
    xhttp.send();

})

//submit quote using Enter key
inptTxt.addEventListener("keyup", function (event) {
    if (event.keyCode === 13) {
        event.preventDefault();
        subBtn.click();
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM