# JQuery `opal-jquery` offers a nicer ruby-like syntax for JQuery (and Zepto). It is useful for projects which cannot use `opal-browser` due to a reliance on jquery for plugins or other libraries. ```ruby foos = Element.find('.foo') # => [
, ...] foos.class # => JQuery foos.on(:click) do alert "element was clicked" end ``` ### Getting Started #### Installation `opal-jquery` is distributed as a gem, and needs to be added to your `Gemfile`: ```ruby # Gemfile gem 'opal' gem 'opal-jquery' ``` #### Usage `opal-jquery` can now be easily added to your opal application sources using a standard require: ```ruby # app/application.rb require 'opal' require 'jquery' require 'opal-jquery' alert "Hello from jquery + opal" ``` > **Note**: this file requires two important dependencies, `jquery` and `opal-jquery`. > You need to bring your own `jquery.js` file as the gem does not include one. If > you are using the asset pipeline with rails, then this should be available > already, otherwise download a copy and place it into `app/` or whichever directory > you are compiling assets from. You can alternatively require a zepto instance. The `#alert` method is provided by `opal-jquery`. If the message displays, then `jquery` support should be working. ### How does opal-jquery work `opal-jquery` provides an `Element` class, whose instances are toll-free bridged instances of jquery objects. Just like ruby arrays are just javascript arrays, `Element` instances are just jquery objects. This makes interaction with jquery plugins much easier. Also, `Element` will try to bridge with Zepto if it cannot find jQuery loaded, making it ideal for mobile applications as well. ### Interacting with the DOM #### Finding Elements opal-jquery provides the `Element` class, which can be used to find elements in the current document: ```ruby Element.find('#header') ``` `Element.find` is aliased to `Element[]`: ```ruby Element['.my-class'] ``` These methods acts just like `$('selector')`, and can use any jQuery compatible selector: ```ruby Element.find('#navigation li:last') ``` The result is just a jQuery instance, which is toll-free bridged to instances of the `Element` class in ruby: ```ruby Element.find('.foo').class # => Element ``` Instances of `Element` also have the `#find` method available for finding elements within the scope of each DOM node represented by the instance: ```ruby el = Element.find('#header') el.find '.foo' # => # ``` #### Running code on document ready Just like jQuery, opal-jquery requires the document to be ready to be able to fully interact with the page. Any top level access should use the `ready?` method: ```ruby Document.ready? do alert "document is ready to go!" end ``` The `Kernel#alert` method is shown above too. #### Event handling The `Element#on` method is used to attach event handlers to elements: ```ruby Element.find('#header').on :click do puts "The header was clicked!" end ``` Selectors can also be passed as a second argument to handle events on certain children: ```ruby Element.find('#header').on(:click, '.foo') do puts "An element with a 'foo' class was clicked" end ``` An `Event` instance is optionally passed to block handlers as well, which is toll-free bridged to jquery events: ```ruby Element.find('#my_link').on(:click) do |evt| evt.stop_propagation puts "stopped the event!" end ``` You can access the element which triggered the event by `#current_target`. ```ruby Document.on :click do |evt| puts "clicked on: #{evt.current_target}" end ``` #### CSS styles and classnames The various jQuery methods are available on `Element` instances: ```ruby foo = Element.find('.foo') foo.add_class 'blue' foo.remove_class 'foo' foo.toggle_class 'selected' ``` There are also added convenience methods for opal-jquery: ```ruby foo = Element.find('#header') foo.class_name # => 'red lorry' foo.class_name = 'yellow house' foo.class_name # => 'yellow house' ``` `Element#css` also exists for getting/setting css styles: ```ruby el = Element.find('#container') el.css 'color', 'blue' el.css 'color' # => 'blue' ``` ### HTTP/AJAX requests jQuery's Ajax implementation is also wrapped in the top level HTTP class. ```ruby HTTP.get("/users/1.json") do |response| puts response.body # => "{\"name\": \"Adam Beynon\"}" end ``` The block passed to this method is used as the handler when the request succeeds, as well as when it fails. To determine whether the request was successful, use the `ok?` method: ```ruby HTTP.get("/users/2.json") do |response| if response.ok? alert "successful!" else alert "request failed :(" end end ``` It is also possible to use a different handler for each case: ```ruby request = HTTP.get("/users/3.json") request.callback { puts "Request worked!" } request.errback { puts "Request didn't work :(" } ``` The request is actually triggered inside the `HTTP.get` method, but due to the async nature of the request, the callback and errback handlers can be added anytime before the request returns. #### Handling responses Web apps deal with JSON responses quite frequently, so there is a useful `#json` helper method to get the JSON content from a request: ```ruby HTTP.get("/users.json") do |response| puts response.body puts response.json end # => "[{\"name\": \"Adam\"},{\"name\": \"Ben\"}]" # => [{"name" => "Adam"}, {"name" => "Ben"}] ``` The `#body` method will always return the raw response string. If an error is encountered, then the `#status_code` method will hold the specific error code from the underlying request: ```ruby request = HTTP.get("/users/3.json") request.callback { puts "it worked!" } request.errback { |response| puts "failed with status #{response.status_code}" } ```