简体   繁体   中英

rails forms:how do i blur a field when a particular option is selected in another field

This is gonna be my first attempt at javascript. When someone selects a particular option in a select list, I want another field in the form to go dull because it's no longer applicable. I guess I have to write an onchange event handler and have it execute a javascript script that detects the selected option and renders a form with the relevant field dull if the option's selected or renders a different form if a different option was selected ... anyone can give me a start please ~ thanks

You may try something like this:

$(document).on('blur', "selector", function (e) { 
  // do what you want to do, change background, color, etc...
});

Instead of selector type in the class, id, or other selector for the element you need to change.

You can add this snippet to any javascript file included in app/assets/javascripts/application.js . You can create a new one and add it there if none existing suits you...

If application.js ends with //= require_tree . it means that it will require all files in that directory and you do not need to manually require them.

Btw, concerning the terminology, element has focus when it is clicked on. When element looses focus (for example some other element is clicked, or tab is pressed), it gets blured. That is when on('blur') gets called.

This is how you can write on('change') for a select:

$(document).on('change', 'select', function (e) {
  // do something
});

Instead of 'select' you need to type in the correct selector, otherwise it will get triggered each time any select changes.

I need the action to be triggered only when i specific value in the select list is selected

No problem, try this:

$(document).on('change', 'select', function (e) {
  if ($(this).val() == 'specific_value'){
    // do something
  }
});

UPDATE

I wanna make the call to jquery from my view and replace the element in the view with the output of the jquery filename.js.erb file

jQuery, and all other javascript is being executed within the client (the web browser), and your file filename.js.erb is located on the server, and it needs to be processed by rails.

This is how it can be done:

  1. ajax request is sent to the server
  2. it gets picked up by rails, and it is routed to a controller
  3. it is processed by a controller action
  4. a javascript view is rendered and posted as a response

There are two ways to achieve this. First I will explain the steps that are common for both approaches.

You will need to add a new route to your routes.rb that you will use as an endpoint for your ajax call. Here you can read more about adding routes to rails, but for the purpose of this answer, I will use this simple route (with a dumb name, you should change that for sure):

resource :my_ajax, only: :create

And this is what the route looks like:

rake routes|grep my_ajax
# my_ajax POST    /my_ajax(.:format)   my_ajaxes#create

It expects that you have MyAjaxesController , and within it create action. You should also make your controller able to respond to javascript requests by adding this to the controller:

class MyAjaxesController < AdminController
  # ...
  respond_to :js
  # ...

  def create
    # ...
  end
end

You also need to have a view for that action: create.js.erb . You can add javascript to that view, but there you can also make use of everything rails controller makes available for you. So, you can use any instance variables or you can render partials.

This is how a partial can be rendered:

$('#element').html('<%= j(render partial: "_my_partial", locals: { my_var: @my_var }) %>');

When the response to ajax request is received by the browser, it just replaces the contents of #element with whatever html got rendered by that partial.

Ok, coming now to the differences to the approaches.

You could send an ajax request (by jQuery) aiming to the endpoint that you created (mind the method, the route I created expects POST). In that case you need to manually manage any response you receive.

However, there is a rails way of doing it. You could create a form with all of its fields hidden (you don't need it in the view, you just need it as a means to send a request). You need to specify the action for the form, the method, and also set remote: true , to make sure that it is submitted asynchronously.

Here's an example:

<%= form_tag(my_ajax_path, remote: true, method: :post) do %>
  <%= hidden_field_tag :some_field %>
<% end %>

All you need to do is submit this form whenever you want (for example by looking it up with an id and calling submit: $('#my_form').submit(); and it will do the rest. You can also dynamically change any hidden inputs of the form prior to submitting.

$(document).on('change', 'select', function (e) {
  if ($(this).val() == 'specific_value'){
    $('#my_form').submit();
  }
});

As for the testing the controller action by rspec, in order for it to work, do not forget that what controller expects and renders is javascript requests, so you need to specify the format:

it 'my test' do
  # expectations
  response = post :my_ajax, format: :js
  # assertions
end

You can do this by using change event of jquery. For example your option select like this:

<%= f.select :state, [['NSW'], ['VIC'], ['SA'], ['WA'], ['QLD']] %>

Then, you have to create jquery event to do your next action. For example:

<script>
  $(document).ready(function(){ 
   // hidding form
   $("#form_1").hide();
   $("#form_2").hide();
   // showing form after user changes the select option
    $("#user_state").change(function(){
      var selected = $(this).val();
      if(selected == "VIC") {
        $("#form_1").show();
      } else {
        $("#form_2").show();
      }
    });
  });
</script>

I hope this help you to attempt the first experience for trying jquery. Good luck!

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