Question
I have the following HTML:
<input type="text" name="textField" />
<input type="submit" value="send" />
How can I make the submit button behave like this?
- When the text field is empty, the submit button should be disabled.
- When the user types something into the text field, the disabled state should be removed.
- If the text field becomes empty again, the submit button should be disabled once more.
I tried this jQuery code:
$(document).ready(function () {
$('input[type="submit"]').attr('disabled', 'disabled');
$('input[type="text"]').change(function () {
if ($(this).val != '') {
$('input[type="submit"]').removeAttr('disabled');
}
});
});
However, it does not work. What is the correct way to do this in jQuery?
Short Answer
By the end of this page, you will understand how to detect input changes with jQuery, read the current value of a text field correctly, and enable or disable a submit button based on whether the field is empty. You will also learn why .change() is often not enough for this task and why .val() must be called as a function.
Concept
The main concept here is reacting to user input and updating element state dynamically.
In jQuery, form elements can be changed after the page loads. A common example is disabling a submit button until the user enters valid input. This improves usability and can prevent incomplete form submissions.
There are two important ideas behind this:
1. Reading the current value of an input
To get the text currently inside an input field, jQuery uses:
$(selector).val()
Notice the parentheses. .val() is a function. If you write .val without parentheses, you are referring to the function itself, not the input's value.
2. Listening for the right event
The .change() event only fires when the input loses focus after its value has changed. That means it does not react immediately while the user is typing.
For live typing behavior, .input event is a better fit:
$('input').on('input', function () {
// runs every time the value changes
});
Why this matters
This pattern appears often in real applications:
- search boxes
- login forms
- signup forms
- comment forms
- validation before submission
The general rule is simple:
- if the input is empty -> disable submit
- if the input has content -> enable submit
In modern jQuery, using .prop('disabled', true) and .prop('disabled', false) is preferred for boolean properties like disabled.
Mental Model
Think of the submit button as a door with an electronic lock.
- The text input is like a sensor.
- If the sensor detects no text, the door stays locked.
- If the sensor detects some text, the door unlocks.
- If the text is removed, the door locks again.
Your code's job is to keep checking the sensor and update the lock state immediately whenever the input changes.
Syntax and Examples
The most common jQuery solution is:
$(document).ready(function () {
const $text = $('input[type="text"]');
const $submit = $('input[type="submit"]');
$submit.prop('disabled', true);
$text.on('input', function () {
if ($(this).val().trim() !== '') {
$submit.prop('disabled', false);
} else {
$submit.prop('disabled', true);
}
});
});
What this does
- Selects the text input and submit button
- Disables the submit button initially
- Listens for every input change
- Checks whether the field is empty
- Enables or disables the button accordingly
Better version with less repeated code
$(document).ready(function () {
const $text = $('input[type="text"]');
const $submit = $('input[type="submit"]');
function toggleSubmit() {
$submit.prop('disabled', $text.val().trim() === '');
}
toggleSubmit();
$text.on('input', toggleSubmit);
});
This version is cleaner because the logic lives in one function.
Matching HTML example
<input type="text" name="textField" />
<input type="submit" value="send" />
Why trim() helps
trim() removes spaces from the start and end of a string.
Without trim(), a user could type only spaces and still enable the button.
' '.trim() === ''
That evaluates to true, so spaces-only input is treated as empty.
Step by Step Execution
Consider this code:
$(document).ready(function () {
const $text = $('input[type="text"]');
const $submit = $('input[type="submit"]');
function toggleSubmit() {
$submit.prop('disabled', $text.val().trim() === '');
}
toggleSubmit();
$text.on('input', toggleSubmit);
});
Step-by-step trace
- The page finishes loading.
- jQuery runs the function inside
$(document).ready(...). $textstores the text input element.$submitstores the submit button.- The
toggleSubmit()function is created. toggleSubmit()runs immediately.- If the input is empty,
disabledbecomestrue. - So the submit button starts disabled.
- If the input is empty,
- An
inputevent listener is attached to the text field. - The user types
H. - The
inputevent fires. toggleSubmit()runs again.$text.val().trim()is now'H'.'H' === ''isfalse.$submit.prop('disabled', false)enables the button.- The user deletes all text.
- The
inputevent fires again. $text.val().trim()is now''.'' === ''istrue.$submit.prop('disabled', true)disables the button again.
Small trace table
| Input value | After trim() | Disabled? |
|---|---|---|
"" | "" | Yes |
"hello" | "hello" | No |
" " | "" | Yes |
"a" | "a" | No |
Real World Use Cases
This pattern is used in many practical situations:
Form validation
Disable the submit button until required fields are filled in.
Examples:
- contact forms
- login forms
- newsletter signup forms
Search interfaces
Enable a search button only when the user has typed a query.
Comment or message forms
Prevent empty comments or blank chat messages from being submitted.
Admin panels
Require a value before allowing an action such as creating a category, tag, or user role.
Filters and dashboards
Only allow a filter action when the user has entered meaningful criteria.
In all of these cases, the idea is the same: use the current form state to control whether an action is allowed.
Real Codebase Usage
In real projects, developers usually avoid scattering UI logic across many event handlers. Instead, they place the rule in one reusable function.
Common pattern: one validation function
function updateFormState() {
const hasText = $text.val().trim() !== '';
$submit.prop('disabled', !hasText);
}
This makes the code easier to maintain.
Guarding against invalid submission
Even if the button is disabled in the UI, validation should still happen when the form submits.
$('form').on('submit', function (event) {
if ($text.val().trim() === '') {
event.preventDefault();
}
});
UI rules improve user experience, but submit-time validation protects correctness.
Using selectors efficiently
In larger codebases, developers often cache jQuery selectors instead of querying the DOM repeatedly.
const $form = $('form');
const $text = $form.find('input[name="textField"]');
const $submit = $form.find('input[type="submit"]');
Handling multiple fields
If a form has several required inputs, the same idea scales well.
function updateFormState() {
const isValid = $('#firstName').val().trim() !== '' && $('#email').val().trim() !== '';
$('#submitBtn').prop('disabled', !isValid);
}
$('input').on('input', updateFormState);
Why .prop() is preferred
In real code, boolean DOM states like checked, selected, and disabled are usually handled with .prop(), not .attr(), because they represent live properties of the element.
Common Mistakes
Here are the most common mistakes beginners make with this pattern.
1. Using .val instead of .val()
Broken code:
if ($(this).val != '') {
// wrong
}
Why it fails:
.valis a function reference.val()actually calls the function and returns the input value
Correct code:
if ($(this).val() !== '') {
// correct
}
2. Using .change() when you want live typing
Broken expectation:
$('input[type="text"]').change(function () {
// this may not run while the user is typing
});
Why it fails:
.change()usually fires after the field loses focus- You want immediate feedback while typing
Correct code:
$('input[type="text"]').on('input', function () {
// runs every time the value changes
});
3. Only enabling, never disabling again
Broken code:
$text.on('input', function () {
if ($(this).val() !== '') {
$submit.prop('disabled', false);
}
});
Why it fails:
- It enables the button
- But it never turns it off again when the field becomes empty
Correct code:
$text.on('input', function () {
$submit.prop('disabled', $(this).val().trim() === '');
});
4. Using .attr() instead of .prop() for boolean state
Older code often uses:
$submit.attr('disabled', 'disabled');
$submit.removeAttr('disabled');
This can work, but for boolean properties, modern jQuery code usually prefers:
$submit.prop('disabled', true);
$submit.prop('disabled', false);
5. Ignoring whitespace-only input
Broken code:
if ($text.val() !== '') {
$submit.prop('disabled', false);
}
Problem:
- A value like
' 'is not technically empty - But it is usually not useful input
Better code:
$submit.prop('disabled', $text.val().trim() === '');
Comparisons
| Approach | Best used for | Notes |
|---|---|---|
.change() | Reacting after the user finishes editing | Usually fires when the input loses focus |
.on('input', ...) | Reacting immediately while typing | Best choice for live enable/disable behavior |
.attr('disabled', 'disabled') | Older jQuery style | Works, but less ideal for boolean properties |
.prop('disabled', true) | Modern jQuery boolean property handling | Preferred for disabled, checked, selected |
removeAttr('disabled') | Removing disabled attribute in older code | Often replaced by .prop('disabled', false) |
.change() vs .input
$('input').change(function () {
console.log('Changed after focus leaves');
});
$('input').on('input', function () {
console.log('Changed immediately');
});
.attr() vs .prop()
$submit.attr('disabled', 'disabled'); // older style
$submit.prop('disabled', true); // preferred
For this use case, .on('input', ...) plus .prop('disabled', ...) is usually the clearest combination.
Cheat Sheet
// Select elements
const $text = $('input[type="text"]');
const $submit = $('input[type="submit"]');
// Disable button
$submit.prop('disabled', true);
// Enable button
$submit.prop('disabled', false);
// Check current value
$text.val()
// Treat spaces as empty
$text.val().trim() === ''
// Update on every keystroke
$text.on('input', function () {
$submit.prop('disabled', $(this).val().trim() === '');
});
Key rules
- Use
.val()not.val - Use
.on('input', ...)for live updates - Use
.prop('disabled', true/false)for boolean state - Use
.trim()if spaces should count as empty - Run the logic once on page load so the initial state is correct
Recommended pattern
$(document).ready(function () {
const $text = $('input[type="text"]');
const $submit = $('input[type="submit"]');
function toggleSubmit() {
$submit.prop('disabled', $text.val().trim() === '');
}
toggleSubmit();
$text.on('input', toggleSubmit);
});
FAQ
Why is my jQuery submit button code not working?
A common reason is using .val instead of .val(), or using .change() when you actually need the input event.
Should I use .attr() or .prop() to disable a button in jQuery?
Use .prop() for boolean properties like disabled. It is the preferred modern jQuery approach.
Why does .change() not fire while I type?
Because .change() usually runs only after the input loses focus and its value has changed. For live typing, use .on('input', ...).
How do I prevent users from submitting only spaces?
Use .trim() before checking the value:
$text.val().trim() === ''
Do I still need form validation if the button is disabled?
Yes. Client-side disabling improves user experience, but you should still validate on form submission and on the server.
Can I use the same logic for multiple fields?
Yes. Put the validation logic in a function and check all required fields before enabling the submit button.
Mini Project
Description
Build a small message form where the submit button stays disabled until the user types a real message. This demonstrates how to listen for input changes, inspect field values, and keep the button state in sync with the form content.
Goal
Create a form that enables the submit button only when the text field contains non-whitespace text.
Requirements
- Create one text input and one submit button.
- Disable the submit button when the page loads.
- Enable the button when the user types non-empty text.
- Disable the button again if the user deletes the text.
- Treat whitespace-only input as empty.
Keep learning
Related questions
Allow Only Numeric Input (0-9) in HTML Input Using jQuery
Learn how to allow only digits 0-9 in an HTML input using jQuery, with examples, validation tips, common mistakes, and best practices.
Apply CSS !important with jQuery .css()
Learn why jQuery .css() cannot set !important and how to use CSSStyleDeclaration.setProperty() to apply inline important styles safely.
CSS ::before and ::after on Input Elements
Learn why CSS ::before and ::after usually do not work on input elements, what replaced elements are, and practical alternatives.