Reputation: 103
I want to disable the submit button until my input fields have been filled in. I am new to rails and not so much with JS and Coffee, I have been trying to run this feature but it is not getting to work. I also tried to validate on client side but could not make it work, the code passes but the button is still not enabled even when all fields are filled out. The button continues to be disenabled for some reason.
Html.haml
= simple_form_for @post, html: { multipart: true } do |f|
- if @post.errors.any?
#errors
%h2
= pluralize(@post.errors.count, "error")
prevented this Post from saving
%ul
- @post.errors.full_messages.each do |msg|
%li= msg
.form-group
= f.input :title,:label => "Project Name", input_html: { class: 'form-control' }
.form-group
%label{:for => "Image"} image
%input#image.form-control-file{"aria-describedby" => "fileHelp", :type => "file"}/
.form-group
%label{:for => "url-input"} Project Link
%input#url-input.form-control{:type => "url", :value => "https://"}/
.form-group
%label{:for => "description"} Description
%textarea#description.form-control{:rows => "3"}
%small#descriptionHelp.form-text.text-muted Clear it up please
%button#add.btn.btn-info{:type => "submit", :disabled => "disabled" } submit
Thanks in advance.
Upvotes: 3
Views: 4593
Reputation: 530
Hi this can be can be frustrating, when doing client side validation and you want to ensure that you do not render new view and allow the client to see the server side validation errors. So it's best to ensure your client side validation form has solid customized JS validations. Client to see all errors in the form for each field until all fields are green and satisfactory and only then the submit button can be enabled. Finally, as a backup if form gets submitted anyways, the client will see the server side validations in the create action else statement.
First in your new.html.erb view weather you're using simple form or just form_for, it's the same concept.
Note: the form contains novalidate:true because I want to create custom validations for each field, because default browser validations lack so much. So I can simply make my own validations as I wish.
In the view, ensure you have disabled:true, data: {disable_with: false}
by default, this button will always disabled and disable with false is permited.
<%= form_for @post, html: {class: 'some-class some-validation-class', novalidate:true } do |f| %>
...
# All my fields are here
# My submit button important to note data_disabled
<%= f.submit "Publish", class: 'btn btn-sm btn-primary mb-0', id: "publish", disabled:true, data: {disable_with: false} %>
<% end %>
In your Javscript, I assume you have all your variables done, and you have all your eventListeners myField.addEventListener("input", (event) => {});
and showErrors();
and call the functions appropriately as the user inputs and fills the fields, radio-boxes, selectors etc. Show red/green and errors and utilize validity.valueMissing
or validity.tooShort
or validity.tooLong
or even customize them even further. When you have your validations complete. You need to add an event listener on keyup
The Javascript at the end of your validations to enable disable submit button
const publishButton = document.getElementById("publish");
document.addEventListener('keyup', function(){
if (isNameValid && isLocationValid && isPhoneValid && isSomethingValid){
publishButton.disabled = false;
} else {
publishButton.disabled = true;
// do more stuff
}
});
Finally in your controller, you don't want to render new if create action fails, or even end up with url /posts. So I suggest in create action
posts_controller.rb
def create
@post = current_user.posts.build(posts_params)
if @post.save
# or you can redirect to posts index, or root path or whatever.
redirect_to edit_post_path(@post), notice: "Your post has been created successfully"
else
redirect_to request.referrer, flash: { error: @post.errors.full_messages.join(", ") }
end
end
If user in front end does something weird and purposely submits the post or by misshap, they will still get the full validation errors, but of course, will have to fill the form all over again.
Upvotes: 0
Reputation: 510
You can use javascript or jquery to handle that validation.
$('#url-input, #description').on('blur keypress', function() {
var urlInputLength = $('#url-input').val().length;
var descriptionInputLength = $('#description').val().length;
if (urlInputLength == 0 || descriptionInputLength == 0) {
$('button').prop('disabled',true);
} else {
$('button').prop('disabled',false);
}
});
So determine which input element(s) are required before the form can be submitted. Use those elements to add a blur
or keypress
event. Use an if statement to determine if the button will be enabled or disabled. If the length of the input is blank (0), then you can disable the button element using the .prop()
method or if there is text in the input then enable the button.
Upvotes: 5