Hot questions for Using Spree in jquery

Question:

Preamble: This problem is within the context of Spree and the jQuery-select2 library, however it should be answerable for anyone not familiar with those libraries as it mostly pertains to CSS styling.

General problem statement: I have a page with two select boxes, which are being created and handled using jQuery-select2. The first one is a simple flat list. The second, however, is a grouped list. The alternating colour styled applied by Spree is botched on the second list as a result of how select2 creates the sublist and the styles being applied to it, coming from Spree.

Problem Details:

The structure of the select box created by select2 for a simple flat list looks something like this:

<ul class="select2-results">

   <li class="some-other-classes">List item 1</li>
    ... other list items

</ul>

And Spree applies styling to the class select2-results and the list elements. Specifically, the alternating list colour styling is:

.select2-results li:nth-child(odd) {
    background: #efefef;
}

In the case of a grouped list, select2 creates the following structure instead:

<ul class="select2-results">

   <li class="many-classes">
       <div>Label for group list #1</div>

       <ul class="select2-result-sub">
           <li class="many-sub-list-classes">
               <div class="select2-result-label">List item for group #1</div>
           </li>
       </ul>

   </li>
    ... other list items

</ul>

Note: I have omitted most of the classes applied to these elements because I fear it would make the example unreadable. If anybody would like me to add them all here, let me know. Barring that, they are properly represented in the jFiddle example (link below).

The problem is that the nth-child(odd) styling is being applied to both the inner AND outer li elements. As a result, I end up with one list group that is one solid colour, like so:

While the second list appears correctly (because, of course, the nth-child(odd) is not being applied on the even numbered list items.

The styling for these lists is coming from here in the Spree framework.

This is a jFiddle containing an example representing this exact scenario. You can see how the styling is affected as I described.

As I said at the top, this is more related to a styling / CSS problem, as I can potentially omit / override the Spree styling. Ultimately, I am at a loss as to how I can solve this problem. In plain English, I feel like I want the CSS to express "apply this style UNLESS the <li> has a child <ul>", or something to that effect. However, as far as I know, it is not possible.

The Question: how can I apply an alternating list item styling such that both a flat list, and a grouped list with sub lists are styled correctly without one overriding or blanketing another?


Answer:

The select2 classes that you omitted on the li allow you to revert the backgrounds.

select2-result-unselectable select2-result-with-children

So, adding the following after your nth-child should revert the background-color of those top li tags:

li:nth-child(odd).select2-result-unselectable {
    background-color: #ffffff;
}

Question:

I have installed spree gem to my rails project and I got this error couldn't find file 'jquery.ui.all' I saw too many problems, and solutions for that but I didn't get any solution yet. My rvm version:

rvm list

ruby-2.0.0-p353 [ x86_64 ]

=* ruby-2.2.0 [ x86_64 ]

Rails version: Rails 4.1.8

Here is my view error page:

Sprockets::FileNotFound in Spree::Home#index
Showing /home/sadk/.rvm/gems/ruby-2.2.0/gems/spree_frontend-2.4.2/app/views/spree/shared/_head.html.erb where line #11 raised:

couldn't find file 'jquery.ui.all'
  (in /home/sadk/.rvm/gems/ruby-2.2.0/bundler/gems/spree_fancy-bdeaeb9ced29/app/assets/javascripts/spree/fancy.js:3)
Extracted source (around line #11):

   <%= stylesheet_link_tag 'spree/frontend/all', :media => 'screen' %>

   <%= stylesheet_link_tag 'spree/fancy/print', :media => 'print' %><%= csrf_meta_tags %>
   <%= javascript_include_tag 'spree/frontend/all' %>
   <!--[if lt IE 9]>
     <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.6/html5shiv.min.js"></script>
   <![endif]-->

<%= javascript_include_tag 'spree/frontend/all' %> is 11th line which has error.

I tried to add

//= require jquery.ui.all

to my application.js but the problem is same. Could you help me about what I should do?

after bundle I can see these lines in the list

 ...
 Using jquery-rails 3.1.2
 Using jquery-ui-rails 5.0.3 
 ...

Answer:

So how are you including jquery in your project?

Instead of

//= require jquery.ui.all

Try

//= require jquery.ui

and remember to bundle install

Question:

I'm trying to use jquery-ui-rails in my rails app (running spree 3.0).

$ bundle list | grep jq
  * jquery-rails (4.0.5)
  * jquery-ui-rails (5.0.5)

No matter what I do, I can't seem to get jquery-ui to load (neither the css or the js file). Things I've tried in app/assets/javascripts/application.js:

//= require jquery-ui
//= require jquery-ui/menu
//= require jquery.ui.all

None of these seemed to make a difference, and I even tried

//= require file-that-does-not-exist

and saw no error. What's going on here? Is the file even being loaded?


Answer:

This is not the proper way to add assets when using spree. Spree's main layout does not include the application.js file! The proper way to include more assets is documented here: https://guides.spreecommerce.com/developer/asset.html

In short, add the require statements to app/assets/javascripts/spree/frontend/all.js. This file is loaded by spree. If you want to add it to the backend as well, add it to app/assets/javascripts/spree/backend/all.js. Stylesheets go in app/assets/stylesheets/spree/frontend/all.js and app/assets/stylesheets/spree/backend/all.js as you might expect. You may want to add

//= require application 

to the all.js files and

/*
 *= require application
 */

to the all.css files to make things behave as expected, or add a warning to the top of your application files something like:

!!!!! THIS FILE IS NOT LOADED BY SPREE. ADDING THINGS HERE DOES NOTHING !!!!!

It may save you hours and hours of work in the future.

Question:

I have a fresh 3.0 version installation of Spree Commerce running on my Rails app. I added Slick Slider (slick.js) to my installation using the following methods:

  • Added slick.js to vendor/assets/javascripts/spree/frontend
  • Put the relevant SCSS files in vendor/assets/stylesheets/spree/frontend
  • setup a custom homepage Deface layout, and then called slick slider at the bottom using <script></script>
  • It all worked swimmingly, and I even setup some slick-custom.scss styling. So I commit changes, shut-off Codekit, and then move locations. Open my Macbook again and suddenly it's throwing a blasted Uncaught TypeError: undefined is not a function. It is called on $(".slider-for").slick({ ...

    I have been all up and down this thing, and I cannot tell what's changed, nor why it isn't loading. Slick is in resources, jQuery is loaded, filepaths and elements are all named appropriately. It's driving me insane, and I don't know what to do.

    Relevant files:

    Homepage setup

    <div class="slider-for">
        <% @products.each do |product| %>
            <div>
              <div class="product-image">
                <%= link_to product_image(product), product %>
              </div>
              <div class="product-info">
                <h2 class="product-title"><%= product.name %></h2>
                <div class="product-description">
                  <%= product.description.to_s.html_safe %>
                </div>
                <div class="product-link">
                    <div class="product-price">
                      <%= product.display_price %>
                    </div>
                    <div class="product-more">
                      <%= link_to "Read More", product, class: "more-link" %>
                    </div>
                </div>
              </div>
            </div>
        <% end %>
    </div>
    
    <div class="slider-nav">
        <% @products.each do |product| %>
            <div>
                <div class="product-image">
                  <%= product_image(product) %>
                </div>
                <h4 class="product-title"><%= product.name %></h4>
            </div>
        <% end %>
    </div>
    
    <script type="text/javascript">
      $(document).ready(function(){
         $(".slider-for").slick({
          slidesToShow: 1,
          slidesToScroll: 1,
          arrows: false,
          fade: true,
          asNavFor: '.slider-nav'
        });
        $(".slider-nav").slick({
          slidesToShow: 3,
          slidesToScroll: 1,
          asNavFor: '.slider-for',
          dots: true,
          centerMode: true,
          focusOnSelect: true
        });
      });
    </script>
    

    Head section:

    <head data-hook="inside_head">
        <meta charset="utf-8">
    <title>Grand on Oak Boutique Store - Grand on Oak</title>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1" name="viewport">
    <meta name="keywords" content="boutique, boutique shop, clothing, clothing store">
    <meta name="description" content="High-end shopping in Conway, Arkansas">
    <link href="http://grandonoak.com/" rel="canonical">
    <link rel="shortcut icon" type="image/x-icon" href="/assets/favicon-69231eed30cd5a922a19b067ccf8b243.ico">
    <link rel="stylesheet" media="screen" href="/assets/spree/frontend/frontend_bootstrap-f5a4d0dbd069cabee02f14c2de1040d5.css?body=1">
    <link rel="stylesheet" media="screen" href="/assets/spree/frontend-c946bacb82835ce1f9a9de94acfa7948.css?body=1">
    <link rel="stylesheet" media="screen" href="/assets/spree/frontend/_variables-75e303a624880e205110a476763b276e.css?body=1">
    <link rel="stylesheet" media="screen" href="/assets/spree/frontend/all-a523e282aabcd1ab0ec90f62c8f67344.css?body=1">
    <meta name="csrf-param" content="authenticity_token">
    <meta name="csrf-token" content="QD3LmjLGnTCtGkIX9NZw/W9UK5cP+LTB+aW5fQOErSCb/RgsfNOWvKDMNOJxbjXHkO5TS91cE54nKYDPeZJyow==">
    <script src="/assets/jquery-87424c3c19e96d4fb033c10ebe21ec40.js?body=1"></script>
    <script src="/assets/jquery_ujs-e27bd20a10d28155845a22d71ef94f2f.js?body=1"></script>
    <script src="/assets/bootstrap/affix-86647d01ace516e05ddf78d2b6e85e20.js?body=1"></script>
    <script src="/assets/bootstrap/alert-2a2796d28d7833f423ee421a3ad297bb.js?body=1"></script>
    <script src="/assets/bootstrap/button-6b326d9b5034209f30109e77c264a190.js?body=1"></script>
    <script src="/assets/bootstrap/carousel-31dbb9c732fc2da02b8d5a97d9ae0047.js?body=1"></script>
    <script src="/assets/bootstrap/collapse-624b0c6035c65b5be6ae581d8dc4e196.js?body=1"></script>
    <script src="/assets/bootstrap/dropdown-ce1bbc536745c41510513f7274f9897c.js?body=1"></script>
    <script src="/assets/bootstrap/modal-77a0e72df31a788e4f6a3f28370eb69e.js?body=1"></script>
    <script src="/assets/bootstrap/scrollspy-3892c697f57b7e7b9d5993044235a210.js?body=1"></script>
    <script src="/assets/bootstrap/tab-6f45b70c6440bd0222c171dd7a926b5d.js?body=1"></script>
    <script src="/assets/bootstrap/transition-264673896da1e31c3b865db964cd6592.js?body=1"></script>
    <script src="/assets/bootstrap/tooltip-718496fb53635605964fb77613425c8d.js?body=1"></script>
    <script src="/assets/bootstrap/popover-3dcfaa462d273d183ef52064ce120a5b.js?body=1"></script>
    <script src="/assets/bootstrap-sprockets-830839b3b00123a30d090955aa74da5c.js?body=1"></script>
    <script src="/assets/jquery.validate/jquery.validate.min-2d81074928b8de12627110241d1e7b82.js?body=1"></script>
    <script src="/assets/jsuri-b9ca271e978b987b894cb0a92de921d9.js?body=1"></script>
    <script src="/assets/spree-8ac8776671ec803cc33e03272659d498.js?body=1"></script>
    <script src="/assets/spree/frontend/cart-1590808ff9329c79b63acdc5a84bc498.js?body=1"></script>
    <script src="/assets/jquery.payment-99cc3707e9b4c29e1d1be187415f6415.js?body=1"></script>
    <script src="/assets/spree/frontend/checkout-82e3443fe70333ace69246f9b31b9507.js?body=1"></script>
    <script src="/assets/spree/frontend/checkout/address-616b9ad86f44c5fa74398e99accc9eee.js?body=1"></script>
    <script src="/assets/spree/frontend/checkout/payment-4df84c09e7418b7aa6394f472f10fec9.js?body=1"></script>
    <script src="/assets/spree/frontend/product-09bee3d334f4f5507d01406128c60330.js?body=1"></script>
    <script src="/assets/spree/frontend-54fe02bb1f643864d4c75b951a66652e.js?body=1"></script>
    <script src="/assets/spree/frontend/slick-6fd6b8e406e07fa296d234cc3a4b2a72.js?body=1"></script>
    <script src="/assets/spree/frontend/all-5a6ef0f53abed7a46fdc4793b7e2a630.js?body=1"></script>
    <!--[if lt IE 9]>
      <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.6/html5shiv.min.js"></script>
    <![endif]-->
        <link rel="next" href="/?page=2">
    
    
      </head>
    

    All Slick Slider files are concurrent with Git master. Have tried variations, but currently have slick.js, slick.scss, slick-theme.scss in appropriate root folders.


    Answer:

    Got it sorted out! Because I used Heroku to deploy after initial Rails install, I had a bunch of precompiled assets that were apparently causing problems.

    If jQuery is acting a fool for no obvious reason, just delete public/assets and you'll be good to go. Optionally, I'd think you could also re-precompile and that'd do the trick.

    Hope this helps someone else out! Rookie mistake on my part, I'm sure, but I definitely ended up a day behind schedule because of it.

    Question:

    my controller is the extended version of shipments_controller.rb inside the file, shipments_controller_decorator.rb.

    Spree::Api::ShipmentsController.class_eval do
      before_filter :find_and_update_shipment, only: [:ship, :ready, :add, :remove, :deliver]
    
      def deliver
        @shipment.deliver!
        respond_with(@shipment, default_template: :show)
      end
    end
    

    My route is :

    put '/api/shipments/:id/deliver', :to => 'spree/api/shipments#deliver', :constraints => {:format => /json/} ,:as => "shipment_deliver"
    

    Inside the application.js file, I have

    //= require jquery
    //= require jquery_ujs
    //= require bootstrap
    $(document).ready(function(){
      $('a.deliver.button.fa.fa-arrow-right').on('ajax:success', function(data, status, xhr) {
        console.log("Hey!! I am there....")
        location.reload();
      });
    })
    

    I have the view _shipment.html.erb :

    <div id="<%= "shipment_#{shipment.id}" %>" data-hook="admin_shipment_form">
      <%= render :partial => "spree/admin/variants/split", :formats => :js %>
      <fieldset class="no-border-bottom">
        <legend align="center" class="stock-location" data-hook="stock-location">
          <span class="shipment-number"><%= shipment.number %></span>
          -
          <span class="shipment-state"><%= Spree.t("shipment_states.#{shipment.state}") %></span>
          <%= Spree.t(:package_from) %>
          <strong class="stock-location-name" data-hook="stock-location-name">'<%= shipment.stock_location.name %>'</strong>
          <% if shipment.ready? and can? :update, shipment %>
            -
            <%= link_to Spree.t(:ship), '#', :class => 'ship button fa fa-arrow-right', :data => {'shipment-number' => shipment.number} %>
          <% elsif shipment.shipped? and can? :update, shipment %>
            -
            <%= link_to Spree.t(:deliver), main_app.shipment_deliver_path(shipment), {method: :put, :remote => true, data: {'shipment-number' => shipment.number}, :class => 'deliver button fa fa-arrow-right'} %>
          <% end %>
        </legend>
      </fieldset>
    

    Now, when click on the Deliver link, the correct controller action is executing, and all data is getting updated to. But the only thing that is not happening page reload. The debugging console.log also not printing anything.

    I looked jquery-ujs wiki link too, no luck!

    Any idea how to fix ?


    Answer:

    If none of the following gist suggestions worked, I think you will have to send a json response back to ajax to make it receive a response it understands. Like so:

    respond_with(@shipment, default_template: :show) do |format|
      format.html { render }
      format.json { render json: @shipment }
    end