2016-01-20 10 views
5

私はスプリー3.0を学習しています。私は、ショートを販売するテストショップを用意しています。バリエーションのオプション値のスプレードロップダウンボックス

ショーツ複数のオプションの種類があります。サイズ、色、長さ

私はそれがドロップダウンボックスにあるラジオチェックボックスからフロントエンドのバリアントオプションの表示方法を変更するようでした。

現在、シュプレーは、ラジオボタンとしてオプションの種類が表示されます。

Current Spree setup

私は、各オプションの種類のドロップダウンメニューを使用するために、これを変更したい、このように:

What I want Spree to do

私は以下を試しました:

<%= select_tag "variant_id", options_for_select(@product.variants_and_option_values(current_currency).collect{ |v| ["#{variant_options(v)} #{variant_price(v)}", v.id] })%> 

しかし、それは単に、各タグ内のすべてのオプションタイプの値が表示されます。

Dropdown with all the option types 1

Dropdown with all the option types 2

私は、個々のドロップダウンメニューにオプション値を分割するための最良の方法を知りたいと思いましたの?

ご協力いただきありがとうございます。ありがとうございます。

答えて

4

バリエーションの代わりにSpree::OptionValue個のレコードを使用しているため、これは簡単ではありません。また、ある時点でカートに追加するためにバリエーションに戻したい場合もあります。組み合わせが可能ではない可能性があり、在庫切れになる可能性があるため、option_valuesで作業することは非常に実用的ではありません。

しかし、それにもかかわらず、あなたは私が次の設定どのように知りたいと思った:

@options = Spree::OptionValue.joins(:option_value_variants).where(spree_option_value_variants: { variant_id: @product.variant_ids }).group_by(&:option_type) 

これはあなたのハッシュのキーはoption_types(サイズ、色、あなたのケースの長さ)であることと、ハッシュを与えます値はoption_valuesの配列です。

あなたは簡単にこのようなラジオにこれを形成することができます。

<% @options.each do |option_type, option_values| %> 
    <%= content_tag :h2, option_type.presentation %> 
    <% option_values.each do |option_value| %> 
    <%= radio_button_tag option_type.name, option_value.id %> 
    <%= label_tag option_value.presentation %> 
    <% end %> 
<% end %> 

またはドロップダウンのために:

<% @options.each do |option_type, option_values| %> 
    <%= content_tag :h2, option_type.presentation %> 
    <%= collection_select :variants, option_type.name, option_values, :id, :presentation %> 
<% end %> 

そして、あなたがいるかどうかを確認、これらの3つの条件に一致するバリアントを検索したいあなたのコントローラでin_stock,backorderableまたはtrack_inventory?falseであり、エラーまたは更新されたカートで応答します。

私はこれが助けてくれることを願っています

+0

感謝レスポンスファビアン。それは難しいようです。私は特にドロップダウンボックスを見ていました。たぶん、Javascriptの解決策が無線機を隠しているかもしれません。 –

+0

ラジオを簡単にセレクトに変換できます。その同じ種類のもの、コンテキスト内のオプションの配列から1つのオプションを選んでください。私はこれをSPAで前に実装していましたが、製品からすべてのバリアントを取得するためにAPIを使用しました。そして、 'in_stock:true'ではオプション値を収集し、ユーザーにoption_valuesのみを表示しました。または在庫切れのオプションのグレーアウトを外す –

+0

もう一度@Fabian de Pabianに感謝します。これを消化して実装する方法を理解する必要があります。私は単純にラジオをドロップダウンに変換することができますが、色ごとに個別にドロップダウンするのではなく、1回のドロップダウンで製品ごとにオプションの種類があります。サイズ; –

0

これは私がこの問題を解決するためにしたものです。基本的には、ラジオボタンで制御されたvariant_idのパラメータをとり、追加の通知とともにjQueryとAJAXによって制御される隠しフィールドに変換します。

私はこれが誰かを助けてくれることを願っています。

のconfig/routes.rbを

# Mount the core routes 
Rails.application.routes.draw do 
    mount Spree::Core::Engine, at: '/' 
end 

# Create new routes 
Spree::Core::Engine.routes.draw do 
    post "products/:product_id/get_variant", 
     to: "products#toggle_like", 
     as: "get_variant", 
     constraints: { :format => /(js)/ } 
end 

アプリ/モデル/酒宴/ product_decorator.rb

Spree::Product.class_eval do 

    # Find the Product's Variant from an array of OptionValue ids 
    def find_variant_by_options(array) 
    option_values = Spree::OptionValue.where(id: array) 
    variants = [] 
    option_values.each do |option_value| 
     variants.push(option_value.variants.ids) 
    end 
    self.variants.find_by(:id => variants.inject(:&).first) 
    end 
end 

アプリ/コントローラ/酒宴/ products_controller_decorator.rb

アプリ/ビュー/酒宴/製品/ get_variant.js.erb

// Update hidden field #varient_id's value. 
$("#variant_id").val("<%= @variant.id %>") 
// Update price 
$(".price.selling").html("<%= number_to_currency @variant.price %>"); 
<% if @variant.in_stock? && @variant.available? %> 
// If in stock and available 
    $("#add-to-cart-button").prop("disabled", false); // Enable button 
    $(".out-of-stock").hide(); // Hide 'out of stock' message 
<% else %> 
// Otherwise 
    $("#add-to-cart-button").prop("disabled", true); // Disable button 
    $(".out-of-stock").show(); // Show 'out of stock' message 
<% end %> 

アプリ/ビュー/酒宴/製品/ _cart_form.html.erb

<%= form_for order, url: populates_orders_path do |f| %> 
    ... 
    <% if @product.variants_and_option_values(current_currency).any? %> 
    <div id="product_variants" class="col-md-6"> 
     <h3 class="product-section-title"><%= Spree.t(:variants) %></h3> 
     <% @product.option_types.each do |option_type| %> 
     <%= f.label "option_type_#{option_type.id}", option_type.name %> 
     <br> 
     <%= f.select "option_type_value_#{option_type.id}", 
        option_type.option_values.all.collect { |v| [ v.name, v.id ] }, 
        { include_blank: true }, 
        { class: "form-control" } %> 
     <br> 
     <% end %> 
     <%= hidden_field_tag "variant_id", value: "0" %> 
     ... 
    </div> 
    <% else %> 
    <%= hidden_field_tag "variant_id", @product.master.id %> 
    <% end %> 
    ... 
    <span class="price selling" 
      itemprop="price" 
      content="<%= @product.price_in(current_currency).amount.to_d %>"> 
     <%= display_price(@product) %> 
    </span> 
    ... 
    <%= button_tag class: "btn btn-success", 
         id: "add-to-cart-button", 
       disabled: @product.variants.any?, 
        type: :submit do %> 
     <%= Spree.t(:add_to_cart) %> 
    <% end %> 
    ... 
    <span class="out-of-stock" style="display: none;"> 
    <%= Spree.(:out_of_stock) %> 
    </span> 
<% end %> 

<script> 
    // Call AJAX if all options are selected, otherwise clean up. 
    $("#product-variants select").change(function(){ 
    var option_value_ids = []; 
    $("#product-variants select").each(function(){ 
     option_value_ids.push($(this).val()); 
    }); 
    if(option_value_ids.indexOf("") == -1){ 
     $.ajax({ 
     url: "<%= get_variant_path(@product) %>?ids=" + option_value_ids.join(','), 
     method: "post" 
     }); 
    }else{ 
     $("#variant_id").val("0"); 
     $("#add-to-cart-button").prop("disabled", true); 
     $(".out-of-stock").hide(); 
    } 
    }); 
</script> 
関連する問題