0

As the title says, I'm using Spree 3.1.0 on Rails 4.2 to build a store. On the product Show page, I'm trying to use Deface to replace the radio buttons with a drop-down, as per the client's request. I have the dropdown functioning, but the price doesn't update on the page when you select an option like it did for the radio buttons.

Here is my override for the menu:

Deface::Override.new(
  virtual_path: 'spree/products/_cart_form',
  name: 'add_variants_dropdown_to_product_show',
  replace: "ul.list-group",
  text: "
    <%= select_tag 'variant_id', options_for_select(@product.variants_and_option_values(current_currency).collect{ |v| [create_dropdown(v), v.id] })%>
")

And the helper method:

def create_dropdown(variant)
  price = variant.stock_items.count > 0 ? variant.price : Spree.t(:out_of_stock)
  "#{variant.options_text.sub('Size: ', '')} - #{price}"
end

The dropdown menu displays as expected, but I would like the Price display on the page to show the price of the selected variant instead of the base price. I have been searching for this for a while, and the two answers I found were helpful for getting the dropdown working, but don't seem to go into maintaining the price functionality.

Thank you!

pholls
  • 35
  • 7

1 Answers1

1

For achieving this you need to modify product.js.coffee

it should look something like this

Spree.ready ($) ->
  Spree.addImageHandlers = ->
    thumbnails = ($ '#product-images ul.thumbnails')
    ($ '#main-image').data 'selectedThumb', ($ '#main-image img').attr('src')
    thumbnails.find('li').eq(0).addClass 'selected'
    thumbnails.find('a').on 'click', (event) ->
      ($ '#main-image').data 'selectedThumb', ($ event.currentTarget).attr('href')
      ($ '#main-image').data 'selectedThumbId', ($ event.currentTarget).parent().attr('id')
      thumbnails.find('li').removeClass 'selected'
      ($ event.currentTarget).parent('li').addClass 'selected'
      false

    thumbnails.find('li').on 'mouseenter', (event) ->
      ($ '#main-image img').attr 'src', ($ event.currentTarget).find('a').attr('href')

    thumbnails.find('li').on 'mouseleave', (event) ->
      ($ '#main-image img').attr 'src', ($ '#main-image').data('selectedThumb')

  Spree.showVariantImages = (variantId) ->
    ($ 'li.vtmb').hide()
    ($ 'li.tmb-' + variantId).show()
    currentThumb = ($ '#' + ($ '#main-image').data('selectedThumbId'))
    if not currentThumb.hasClass('vtmb-' + variantId)
      thumb = ($ ($ '#product-images ul.thumbnails li:visible.vtmb').eq(0))
      thumb = ($ ($ '#product-images ul.thumbnails li:visible').eq(0)) unless thumb.length > 0
      newImg = thumb.find('a').attr('href')
      ($ '#product-images ul.thumbnails li').removeClass 'selected'
      thumb.addClass 'selected'
      ($ '#main-image img').attr 'src', newImg
      ($ '#main-image').data 'selectedThumb', newImg
      ($ '#main-image').data 'selectedThumbId', thumb.attr('id')

  Spree.updateVariantPrice = (variant) ->
    variantPrice = variant.data('price')
    ($ '.price.selling').text(variantPrice) if variantPrice

  Spree.disableCartForm = (variant) ->
    inStock = variant.data('in-stock')
    $('#add-to-cart-button').attr('disabled', !inStock)

  radios = ($ '.variant_option')

  if radios.length > 0
    selectedRadio = $('#variant_id').find ':selected'
    Spree.showVariantImages selectedRadio.attr('value')
    Spree.updateVariantPrice selectedRadio
    Spree.disableCartForm selectedRadio

    $('#variant_id').change (event) ->
      selected = $(this).find ':selected'
      Spree.showVariantImages selected.value
      Spree.updateVariantPrice (selected)
      Spree.disableCartForm (selected)

  Spree.addImageHandlers()

See the changes I made to ensure the now all the events reflect on now select box instead of radio button I would also recommend you to go through this code and change the variable names to satisfy current situation. (radios -> options just for naming convention)

def create_dropdown(variant)
  price = variant.can_supply? ?  variant.price : Spree.t(:out_of_stock)
  "#{variant.options_text.sub('Size: ', '')} - #{price}"
end

Use spree can_supply? method instead of varaint.stock_items.count

Also, you need to change the way you are building your select box to add a class on all option of select_box_tag which I am using in product.js.coffee

Deface::Override.new(
  virtual_path: 'spree/products/_cart_form',
  name: 'add_variants_dropdown_to_product_show',
  replace: "ul.list-group",
  text: "
    <%= select_tag 'variant_id', options_for_select(@product.variants_and_option_values(current_currency).collect{ |v| [create_dropdown(v), v.id, {'data-price' => v.price_in(current_currency).money, 'data-in-stock' => v.can_supply?, class: 'variant_option' }] })%>
")

This should solve your problem. Please let me know if you are still unable to acheive your goal.

Nimish Gupta
  • 3,095
  • 1
  • 12
  • 20
  • Thanks @Nimish! Is there a "Spree Way" to override the coffeescript file with an extension? – pholls Jul 13 '17 at 15:35
  • Right now I just override the entire product.js.coffee file in my extension, and if I remove any of the functions where no changes were made (like `Spree.addImageHandlers` and `Spree.showVariantImages`), it stops working. – pholls Jul 13 '17 at 16:09
  • @pholls Nope, currently there is no such way. You have to override entire js file in your extension. – Nimish Gupta Jul 14 '17 at 08:32