Несколько моделей, связанных с пользователем разработки — заполните одну модель на основе выбора роли

Я использую устройство для регистрации пользователя с полями: электронная почта, пароль и роль.

Когда пользователь выбирает роль из поля выбора (Студент, Учитель, Администратор), я хочу, чтобы приложение отображало вложенные поля для одной из этих ролей. Каждая роль хранит разную информацию и существует как самостоятельная модель.

У меня есть javascript, который показывает и скрывает соответствующие элементы div на основе текущего выбора.

Проблема в том, что форма не отправляется, пока я не заполню поля для ВСЕХ моделей, а не только для текущей выбранной модели. Я понимаю, что это потому, что я визуализирую все частичные фрагменты, а затем просто скрываю их с помощью javascript.

Вопрос: Как мне использовать JavaScript для динамического отображения ТОЛЬКО партиала, содержащего поля модели для текущей выбранной модели?

Просмотр новых регистраций

h2>Sign up</h2>

<%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
  <%= f.error_notification %>

  <h3>Login Details</h3>

  <br />
  <div class = "row">
    <div class = "col-md-3"></div>
    <div class = "col-md-6"><div class = "panel panel-midnight">
      <div class = "panel-heading"><h3 class = "panel-title">Create an account</h3></div>
      <div class = "panel-body">
      <div class="form-inputs">

        <%= f.input :email, :required => true, :autofocus => true, :placeholder => "Enter email address" %>
        <br />
        <%= f.input :password, :required => true, :placeholder => "Password" %>
        <br />
        <%= f.input :password_confirmation, :required => true, :placeholder => "Confirm Password" %>
        <br />
        <%= f.input :role, :label => "I am a:", :collection => ["Student","Teacher","Admin"], :required => true %>
      </div>

      <h3>Profile</h3>


      <div id = "student_fields">
       <%= render partial: "student_fields", locals: {:f => f} %>
      </div>

      <div id = "teacher_fields">
        <%= render partial: "teacher_fields", locals: {:f => f} %>
      </div>

      <div id = "admin_fields">
        Admin
      </div>

      <br />

  <% end %>

  <br />

  </div>

  <div class = "col-md-3"></div>
  </div>
  </div>
  </div>


<! Javascript to show/hide specific fields for each role>


<script>


  $(document).ready(function(){
     if($('#user_role').val() != "Student"){
        $("#student_fields").css('display','none');
     }
     else{
        $("#student_fields").css('display','block');
     }

     $('#user_role').change(function(){
        if($(this).val() != "Student"){
          $("#student_fields").css('display','none');
        }
        else{
          $("#student_fields").css('display','block');
        }
     })
  });

  $(document).ready(function(){
       if($('#user_role').val() != "Teacher"){
          $("#teacher_fields").css('display','none');
       }
       else{
          $("#teacher_fields").css('display','block');
       }

       $('#user_role').change(function(){
          if($(this).val() != "Teacher"){
            $("#teacher_fields").css('display','none');
          }
          else{
            $("#teacher_fields").css('display','block');
          }
       })
    });

  $(document).ready(function(){
     if($('#user_role').val() != "Admin"){
        $("#admin_fields").css('display','none');
     }
     else{
        $("#admin_fields").css('display','block');
     }

     $('#user_role').change(function(){
        if($(this).val() != "Admin"){
          $("#admin_fields").css('display','none');
        }
        else{
          $("#admin_fields").css('display','block');
        }
     })
  });
</script>

person mike_eddie    schedule 02.12.2013    source источник


Ответы (1)


JavaScript не может «рендерить» только те поля, которые вам нужны. Он может либо показывать/скрывать (как вы пытаетесь это сделать), либо запрашивать динамическую загрузку контента (он же AJAX). Если вы хотите пойти по второму пути, рассмотрите возможность изменения раздела вашего профиля, чтобы он выглядел следующим образом:

<h3>Profile</h3>
<div id="profile"></div>

Затем вам нужно настроить javascript для отправки запроса на уникальный URL-адрес в зависимости от выбранной роли и заполнить раздел #profile результатами. Вот идея, основанная на jquery...

$('#user_role').on('change', function(){
  switch( $('#user_role').val() ){
    case 'Teacher': targetUrl = '...'; break;
    case 'Admin': targetUrl = '...'; break;
    default:  targetUrl = '...'; break;
  }
  $('#profile').load( targetUrl );
});

Предупреждение: часто лучше попытаться заставить все работать без ajax, а затем добавить ajax позже, особенно если вы только начинаете. Возможно, вы захотите рассмотреть слегка измененную регистрацию, которая больше похожа на мастер — пользователь может сначала предоставить сведения о пользователе (включая роль), а ответ может состоять в том, чтобы попросить пользователя предоставить сведения о своей роли, когда пользователь успешно созданный.

person AndyV    schedule 02.12.2013