zoukankan      html  css  js  c++  java
  • 通过弹出层实现新建功能 ruby on rails

    (1) 在布局文件中将弹出层的代码和主体代码分开

          </footer>
    
        <%= yield(:page_modal) if content_for?(:page_modal) %>
        <%= javascript_include_tag "application" %>
        <%= yield(:page_javascript) if content_for?(:page_javascript) %>
        </div> <!-- /container -->
    
      </body>
    </html>

    (2)改写添加商品的时候按钮的方法,增加data属性,里面设定当按钮点击的时候,

    打开哪一个model,在model的代码里,调用form这个局部模板,

    在下面的js代码里声明这个model,并且声明这个model在加载的时候不显示。

    app/views/products/index.html.erb

     1 <%- model_class = Product -%>
     2 <div class="page-header">
     3   <h1><%=t '.title', :default => model_class.model_name.human.pluralize.titleize %></h1>
     4 </div>
     5 <table class="table table-striped">
     6   <thead>
     7     <tr>
     8       <th><%= model_class.human_attribute_name(:id) %></th>
     9       <th><%= model_class.human_attribute_name(:name) %></th>
    10       <th><%= model_class.human_attribute_name(:price) %></th>
    11       <th><%= model_class.human_attribute_name(:description) %></th>
    12       <th><%= model_class.human_attribute_name(:created_at) %></th>
    13       <th><%=t '.actions', :default => t("helpers.actions") %></th>
    14     </tr>
    15   </thead>
    16   <tbody id="productsTable">
    17     <%= render @products %>
    18   </tbody>
    19 </table>
    20 <%= link_to t('.new', :default => t("helpers.links.new")),
    21             new_product_path,
    22             :class => 'btn btn-primary',
    23             data: {toggle: "modal", target: "#newProductFormModal"} %>
    24 
    25 <%= content_for :page_modal do %>
    26   <div class="modal fade" id="newProductFormModal" role="dialog" aria-labelledby="myModalLabel"
    27     aira-hidden="true">
    28     <div class="modal-dialog">
    29       <%= form_for @product, remote: true, :html => {:class => 'form-horizontal',
    30         id: "newProductForm"} do |f| %>
    31         <div class = "modal-content">
    32           <div class="modal-header">
    33             <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
    34             <h4 class="modal-title">添加一个商品</h4>
    35           </div>
    36 
    37           <div class="modal-body">
    38             <%= render partial: "input", locals: {f: f} %>
    39           </div>
    40 
    41           <div class="modal-footer">
    42             <%= link_to t('.cancel', :default => t('helpers.links.cancel')), '#',
    43               :class => 'btn btn-default', data: {dismiss: "modal"} %>
    44               <%= f.submit nil, :class => 'btn btn-primary', :data => { :"disable-with" => "请稍等..."} %>
    45           </div>
    46         </div>
    47       <% end %>
    48     </div>
    49   </div>
    50  <div class="modal fade" id="editProductFormModal" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    51     <div class="modal-dialog">
    52       <%= form_tag "", method: :put, remote: true, data: { type: "json" }, id: "editProductForm", class: "form" do %>
    53         <div class="modal-content">
    54           <div class="modal-header">
    55             <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
    56             <h4 class="modal-title">编辑一个商品</h4>
    57           </div>
    58           <div class="modal-body">
    59             <div class="alert alert-dismissible alert-danger" id="alert-content">
    60               <button type="button" class="close" data-dismiss="alert">×</button>
    61               <div id="msg"></div>
    62             </div>
    63             <div class="form-group">
    64               <%= label_tag "product[name]", Product.human_attribute_name("name"), :class => 'control-label' %>
    65               <%= text_field_tag "product[name]", "", :class => 'form-control', id: "editProductName" %>
    66             </div>
    67             <div class="form-group">
    68               <%= label_tag "product[description]", Product.human_attribute_name("description"), :class => 'control-label' %>
    69               <%= text_field_tag "product[description]", "", :class => 'form-control', id: "editProductDescription" %>
    70             </div>
    71             <div class="form-group">
    72               <%= label_tag "product[price]", Product.human_attribute_name("price"), :class => 'control-label' %>
    73               <%= text_field_tag "product[price]", "", :class => 'form-control', id: "editProductPrice" %>
    74             </div>
    75           </div>
    76           <div class="modal-footer">
    77             <%= link_to t('.cancel', :default => t("helpers.links.cancel")), '#', :class => 'btn btn-default', data: {dismiss: "modal"} %>
    78             <%= submit_tag t('.confirm', :default => t("helpers.links.confirm")), :class => 'btn btn-primary', :data => { :"disable-with" => "请稍等..
    79           </div>
    80         </div>
    81       <% end %>
    82     </div>
    83   </div>
    84 
    85 <% end %>
    86 
    87 <%= content_for :page_javascript do %>
    88   <script>
    89     $('#newProductFormModal').modal({
    90       show: false,
    91     })
    92     $('#editProductFormModal').modal({
    93       show: false,
    94     })
    95   </script>
    96 <% end %>

    (3) 点击新建我们可以看到弹出层的效果已经实现了,但是form里又包含了相同的功能的按钮,

    这个时候我们需要对form再进行一个拆解,将它的控件部分提供给弹出层。

    新建模板app/views/products/_input.html.erb

    <div class="control-group">
      <%= f.label :name, :class => 'control-label' %>
      <div class="controls">
        <%= f.text_field :name, :class => 'form-control' %>
      </div>      
      <%= error_span(@product[:name]) %>
    </div>      
    <div class="control-group">
      <%= f.label :price, :class => 'control-label' %>
      <div class="controls">
        <%= f.text_field :price, :class => 'form-control' %>
      </div>  
      <%= error_span(@product[:price]) %>
    </div>      
    <div class="control-group">
      <%= f.label :description, :class => 'control-label' %>
      <div class="controls">
        <%= f.text_field :description, :class => 'form-control' %>
      </div>
      <%= error_span(@product[:description]) %>
    </div>

    在form里引用这个模板app/views/products/_form.html.erb

    <%= form_for @product, :html => { :class => "form-horizontal product" } do |f| %>
    
        <% if @product.errors.any? %>
        <div id="error_expl" class="panel panel-danger">
          <div class="panel-heading">
            <h3 class="panel-title"><%= pluralize(@product.errors.count, "error") %> prohibited this product from being saved:</h3>
          </div>
          <div class="panel-body">
            <ul>
            <% @product.errors.full_messages.each do |msg| %>
              <li><%= msg %></li>
            <% end %>
            </ul>
          </div>
        </div>
      <% end %>
    
      <%= render partial: "input", locals: {f: f} %>
      
      <%= f.submit nil, :class => 'btn btn-primary', :data => { :"disable-with" => "请稍等..." } %>
      <%= link_to t('.cancel', :default => t("helpers.links.cancel")),
                products_path, :class => 'btn btn-default' %>
    
    <% end %>

    (4)刷新页面,再次点击新建按钮,弹出层效果已经实现了,在弹出层新建一个商品,可以看到页面没有关闭,

    页面上也没有显示新添加的商品,进到log里可以看到,刚才我们提交的是一个post操作,产生的是js响应,

    在完成之后,它返回的也是一个js响应。在脚手架为我们创建代码的时候,里面并没有添加如何执行js的响应,

    我们需要手动添加一个,比如在create方法里,进入respond_to,

      def create
        @product = Product.new(product_params)
    
        respond_to do |format|
          if @product.save
            format.html { redirect_to @product, notice: 'Product was successfully created.' }
            format.json { render :show, status: :created, location: @product }
          else
            format.html { render :new }
            format.json { render json: @product.errors, status: :unprocessable_entity }
          end
          format.js
        end
      end
      def update
        respond_to do |format|
          if @product.update(product_params)
            format.html { redirect_to @product, notice: 'Product was successfully updated.' }
            format.json
          else
            format.html { render :edit }
            format.json { render json: @product.errors.full_message.join(', '), status: :error}
          end
          format.js
        end
      end
    
      def destroy
        @product.destroy
        respond_to do |format|
          format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
          format.json { head :no_content }
          format.js
        end
      end
    
      def edit
        respond_to do |format|
          format.html
          format.json {render json: @product, status: :ok, location: @product }
        end
      end

    创建新文件app/views/products/create.js.erb ,这样做的好处是,我们可以在js文件里使用erb语法,

    在文件中先判断商品是否保存成功,如果保存失败,需要演示它的错误信息,

    如果保存成功,需要先将商品添加到列表里,然后关闭这个弹出层,最后将这个弹出层里的表单重置一下,

    否则再次点击添加按钮的时候,刚才添加的文字还在弹出层表单里

    <% if @product.errors.any? %>
      $('#newProductInput').prepend('<%= j render "errors" %>');
    <% else %>
      $('#productsTable').prepend('<%= j render(@product) %>')
      $('#newProductFormModal').modal('hide');
      $('#newProductForm')[0].reset();
    <% end %>

    需要注意一下上面使用了j 这个辅助方法,它会将我们产生的信息转移成js方法

  • 相关阅读:
    使用 logger 在脚本中输出多个日志
    MySQL 5.7 安装完成后,立即要调整的性能选项
    多线程练习2_龟兔赛跑
    多线程练习1_网图下载
    【BFS(预处理)+SPFA】【NOIP2013】华容道
    【数学】【NOIP2013】解方程
    【二分答案+倍增】【NOIP2015】运输计划
    std::strncpy 简介
    text 文本去重行
    关于string::copy()的比较详细的示例
  • 原文地址:https://www.cnblogs.com/iwangzheng/p/4915047.html
Copyright © 2011-2022 走看看