Keep Form Fields Filled After an Error (Ror)

Keep form fields filled after an error (RoR)

Your View (new.html.erb) something like following

<%= error_message_for :user %>
<% form_for :user, :action=>"create" do|f|%>

<%= f.text_field :login %>

<% end %>

Controller Code (create method)

def create
@user=User.new(params[:user])
if @user.save
redirect_to :action=>'index'
else
render :action=>'new' #you should render to fill fields after error message
end
end

How does Rails keep the form data when validations fail?

Let's try to understand this whole process point-wise

Instance variables defined in the controller action are shared with the rendered views.

In your case I'm assuming that there's a new action something like

def new
@movie = Movie.new
end

And you have a corresponding view new.html.erb where you have created a form like this

= form_for @movie do |f|

Now, as you know the @movie object that you are passing in form_for method is defined in new action. Most of the times we don't pass any parameters to the new method in new action. The form fields are blank when you load the form because the attributes of the object(in your case @movie) are by default blank because we just initialize an empty object(Movie.new).

Let's assume your Movie model has a name attribute, Try doing this in your new action

def new
@movie = Movie.new(name: 'Hello World!')
end

Now when you will load the new action, you will see Hello World! populated in your name text field because your @movie object is initialized with this value.

Also, keep in mind that Rails Convention-Over-Configuration automatically generates the form URL in this case, by default it points to the create action. When you submit the form the request is made to the create action. This takes me to the next point.

When we submit the form all the filled in form values are sent to the action whose route matches with the form URL(in your case URL points to the create action)

In create action you are receiving parameters in the form of a hash with model attributes(Movie attributes) as keys and the filled in information as their values. The first line in your create action is

@movie = Movie.new(movie_params)

This is a very important line of code, try to understand this. Let's assume your form had only one text field, i.e., name. Now movie_params is a method that looks like this

def movie_params
params.require(:movie).permit(:name)
end

Now, the movie_params method will return a hash something like { 'name' => 'Hello World!' }, now you are passing this hash as a parameter to Movie.new method.

So now, after breaking up the code, the first line of your create action looks like

@movie = Movie.new({ name: 'Hello World!' })

That means your @movie instance variable contains an object of Movie class with name attribute set to Hello World!. Here, when after initialization, if you do @movie.name it will return Hello World!.

Now, in the second line you are calling @movie.save that returned false due to failed validation in your case as you have already mentioned in the question. As it returned false the execution will go to the else part. Now this takes me to the next point.

Calling render :action(in your case render :new) in the controller renders only the view that belongs to that action and does not execute that action code.

In your case, you called render :new, so there you are actually rendering the new.html.erb view in create action. In other words, you are just using the code in new.html.erb and not in new action. Here, render :new does not actually invoke the new action, it's still in the create action but rendering the new.html.erb view.

Now, in new.html.erb you have created a form that looks like

= form_for @movie do |f|

Now as my explained under my first point, the instance variables that are declared in the action are shared by the rendered view, in this case @movie object that you have defined in create action is shared by the rendered new.html.erb in create action. In our case, in create action the @movie object was initialized with some values that were received in the parameters(movie_params), now when new.html.erb is rendered in the else, the same @movie object is used in the form by default. You got the point right, you see the magic here?

This is how Rails works and that's why its awesome when we follow the convention! :)

https://gist.github.com/jcasimir/1210155

http://guides.rubyonrails.org/v4.2/layouts_and_rendering.html

Hope the above examples cleared your doubts, if not, feel free to drop your queries in the comment box below.

To maintain data in a form after doing a validation in rails

As soon as you put something into mensaje the repond will do a redirect to thenew action, which is why the form is empty. You have to clear out the controller, those validations do not belong there, I've only done some of that work for you.

def create
@farm = Farm.new(params[:farm])
if @farm.nombre == "" || !valid_prescence?(@farm.nombre)
flash[:notice] = "Favor de capturar los datos que se encuentran como requeridos"
else
@buscar = Farm.where(nombre: params[:farm][:nombre], tipo: params[:farm][:cliente_id])
if @buscar.any?
flash[:notice] = "La finca #{params[:farm][:nombre]} ya se encuentra registrada en el sistema, favor de verificar."
end
end

respond_to do |format|
if @farm.save
format.html { redirect_to @farm, notice: 'Finca creada correctamente.' }
format.json { render json: @farm, status: :created, location: @farm }
else
format.html { render action: "new" }
format.json { render json: @farm.errors, status: :unprocessable_entity }
end
end
end

Retain form fields after validation fail, render not working

You're right about this step:

format.html { render :template => "users/registrations/new" }

The problem is that you're not setting an instance for @user in the "after_step_controller", if you want to do the render, you should have to set an instance for @user, and it should contains the attributes that were submitted in the form, so you could show validations errors.

Hope it helps!

Ruby on Rails - Losing form values after failed validation on some fields

See how you have :value => '0' in the form fields for both :publiclyfundedteaching and :non_publicly_funded_teaching (the third one you mentioned is not in your form).
They will set the value in the fields to 0 even if you reload a previously filled form. You can either remove that or try to add an if statment like so (assuming submission is the model):

<%= f.input :publiclyfundedteaching, label: "Publicly funded teaching (PFT)", input_html: { style: 'width:7%', id: "publiclyfundedteaching", value: @submission.publiclyfundedteaching || 0, onkeyup: "myFunction()" } %>

Keep data form after submit using sessions in rails

The problem has nothing to do with one that you gave a link to. You explicitly set the value of the user_type parameter in the form, but you shouldn't.

Change

<%= f.input :user_type, as: :radio_buttons, collection: %w(personnal professional), checked: 'personnal' %>

To

<%= f.input :user_type, as: :radio_buttons, collection: %w(personnal professional) %>

The parameter is going to be set automatically, depending on resource. When you submit the form, the parameter should stay as it was set.

If you want to set a default value, you can do it like this:

<%= f.input :user_type, as: :radio_buttons, collection: %w(personnal professional), checked: resource.user_type || 'personnal' %>

Not the best way, but the simplest.

howto : form with multiple models - re-render form after errors (fields populated)

Answer

If your form is directly bound with a model it's in most cases better to use the form helper form_for.

To answer your question about repopulating the form and rendering errors. You should not redirect_back, since this will result in the loss of current values. Instead render the same page again. This will allow the form to have access to the previous result, and fill the form with them. This happens automatically when using the form_for helper (if you updated the attributes of your model instance).

In case you can't use the form_for helper and use separate tags instead, don't forget to set the values. <%= text_field :object_name, :attribute_name, value: object.attribute %> If the value is not set this will result in an empty text field, otherwise it will be filled with the attribute value.

There are some helpers that make form creating somewhat easier. For example Simple Form and Formtastic. But I would at least urge you to take a look at the Rails guide about forms first: Action View Form Helpers


Example

A good example, is the result of scaffolding an model. You end up with the following code in your controller:

class ChairsController < ApplicationController
# ...

def new
@chair = Chair.new
end

def create # I removed the json parts
@chair = Chair.new(chair_params)

if @chair.save
redirect_to @chair, notice: 'Chair was successfully'
else
render :new
end
end

# ...
end

With a chairs/new view allong the line of:

<%= form_for @chair do |form| %>
<% if @chair.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@chair.errors.count, "error") %> prohibited this chair from being saved:</h2>

<ul>
<% @chair.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>

<div class="field">
<%= form.label :name %>
<%= form.text_field :name, id: :chair_name %>
</div>

<div class="actions">
<%= form.submit %>
</div>
<% end %>


Related Topics



Leave a reply



Submit