hobo_jquery_ui 1.4.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ [submodule "documentation"]
2
+ path = documentation
3
+ url = git://github.com/bryanlarsen/hobo-jquery.git
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2006 Tom Locke
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,20 @@
1
+ This plugin provides the jQuery UI widgets in a Hobo friendly manner.
2
+
3
+ ### Usage
4
+
5
+ The jQuery UI tags support all of the [options that the corresponding jQuery UI widgets provide](http://docs.jquery.com/UI). For example:
6
+
7
+ <datepicker dateFormat="yy-mm-dd" />
8
+
9
+ Options that expect a type other than string can be provided by passing a ruby object:
10
+
11
+ <datepicker dayNamesMin="&['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa']" />
12
+
13
+ Events are also supported. Pass in a global Javascript function name:
14
+
15
+ <datepicker onSelect="hjq.util.log" />
16
+
17
+
18
+ ### Installation
19
+
20
+ hobo generate install_plugin hobo_jquery_ui git://github.com/tablatom/hobo
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.4.0.pre2
@@ -0,0 +1,24 @@
1
+ name = File.basename( __FILE__, '.gemspec' )
2
+ version = File.read(File.expand_path('../VERSION', __FILE__)).strip
3
+ require 'date'
4
+
5
+ spec = Gem::Specification.new do |s|
6
+ s.name = "hobo_jquery_ui"
7
+ s.summary = "JQuery UI support for Hobo"
8
+ s.description = "JQuery UI support for Hobo"
9
+ s.authors = ["Bryan Larsen"]
10
+ s.email = "bryan@larsen.st"
11
+ s.files = `git ls-files -x #{name}/* -z`.split("\0")
12
+ s.homepage = 'http://hobocentral.net'
13
+ s.version = version
14
+ s.date = Date.today.to_s
15
+
16
+ s.required_rubygems_version = ">= 1.3.6"
17
+ s.rdoc_options = ["--charset=UTF-8"]
18
+ s.require_paths = ["lib", "vendor", "taglibs"]
19
+
20
+ s.add_runtime_dependency("jquery-ui-themes", ["~> 0.0.4"])
21
+ s.add_runtime_dependency('hobo', ["= #{version}"])
22
+ s.add_runtime_dependency('hobo_jquery', ["= #{version}"])
23
+
24
+ end
@@ -0,0 +1,11 @@
1
+ module HoboJqueryUi
2
+ @@root = Pathname.new File.expand_path('../..', __FILE__)
3
+ def self.root; @@root; end
4
+
5
+ EDIT_LINK_BASE = "https://github.com/tablatom/hobo_tree_table/edit/master/hobo_jquery_ui"
6
+
7
+ require 'hobo_jquery_ui/railtie' if defined?(Rails)
8
+
9
+ class Engine < ::Rails::Engine
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ require 'hobo_jquery_ui'
2
+ require 'rails'
3
+ module HoboJqueryUi
4
+ class Railtie < Rails::Railtie
5
+ end
6
+ end
@@ -0,0 +1,27 @@
1
+ <%#
2
+ The `<accordion>` tag implements the [jQuery-UI accordion](http://jqueryui.com/demos/accordion/). It works the same as the `<tabs>` tag, so see the [tabs documentation](/api_tag_defs/tabs) for more information
3
+
4
+ <accordion>
5
+ <section1:>Hello</section1:>
6
+ <section2:>Hey</section2:>
7
+ </accordion>
8
+
9
+ There is one difference: accordion does not support the `href` option.
10
+ %>
11
+ <def tag="accordion" attrs="sortable">
12
+ <% options, attrs = attributes.partition_hash(['disabled', 'active', 'animated', 'autoHeight', 'clearStyle', 'collapsible', 'event', 'fillSpace', 'icons', 'navigation'])
13
+ events, html_attrs = attrs.partition_hash(['navigationFilter', 'create', 'change', 'changestart'])
14
+ add_classes!(html_attrs, "accordion")
15
+ add_data_rapid!(html_attrs, "accordion", :options => options, :events => events, :sortable => sortable)
16
+ %>
17
+ <div merge-attrs="&html_attrs">
18
+ <repeat with="&parameters">
19
+ <div class="hjq-accordion-element">
20
+ <% attrs, params = this.call %>
21
+ <% merge_attrs = attrs - [:name] %>
22
+ <h3><a href="#"><%= attrs[:name] || this_key.to_s.titleize %></a></h3>
23
+ <div merge-attrs="&merge_attrs"><%= params[:default]._?.call %></div>
24
+ </div>
25
+ </repeat>
26
+ </div>
27
+ </def>
@@ -0,0 +1,66 @@
1
+ <!-- This tag, when given a list, chunks the list using the [jQuery-UI accordion](jqueryui.com/demos/accordion).
2
+
3
+ If you do not specify the `chunker` attribute, the list is chunked into sections of equal length. The default is 20 items, but that may be adjusted by setting the `per-section` attribute.
4
+
5
+ The `chunker` may be passed a block to specify custom chunking. This block is passed to [Enumerable#chunk](http://www.ruby-doc.org/core-1.9.3/Enumerable.html#method-i-chunk) For example, to divide a sorted list of users based on the first letter of their name:
6
+
7
+ <accordion-collection:users chunker="&Proc.new{|u| u.name[0..1]}"/>
8
+
9
+ The scoped variable `chunk` is set to the chunker output. If you didn't specify the chunker, it's set to the chunk number. In the example above, it would be set to the first letter of the user's name. Here's an example of it being used to customize the chunk heading:
10
+
11
+ <heading:>Section <%= scope.chunk %></heading:>
12
+
13
+ The context is set to the chunked list for all parameters. This allows us to further customize the heading:
14
+
15
+ <header:><name:first/> &mdash; <name:last/></header:>
16
+
17
+ Replacing the collection with a table is easy:
18
+
19
+ <default:><table fields="this,email"/></default:>
20
+
21
+ Remember that the default parameter is a list, even if you set per-section="1". The easiest way to explode a list is with `<repeat>`:
22
+
23
+ <accordion-collection per-section="1">
24
+ <header:><name:first/></header:>
25
+ <default:>
26
+ <repeat>
27
+ This is my content: <view/>
28
+ </repeat>
29
+ </default:>
30
+ </accordion-collection>
31
+
32
+
33
+ ### Note:
34
+
35
+ This tag uses Enumerable#chunk, which is only available with Ruby 1.9.2 and later. If you are using Ruby 1.8.7, you must include the `backports` gem in your project.
36
+
37
+ -->
38
+ <def tag="accordion-collection" attrs="per-section,chunker,sortable">
39
+ <% options, attrs = attributes.partition_hash(['disabled', 'active', 'animated', 'autoHeight', 'clearStyle', 'collapsible', 'event', 'fillSpace', 'header', 'icons', 'navigation'])
40
+ events, html_attrs = attrs.partition_hash(['navigationFilter', 'create', 'change', 'changestart'])
41
+ add_classes!(html_attrs, "accordion-collection")
42
+ add_data_rapid!(html_attrs, "accordion", :options => options, :events => events, :sortable => sortable)
43
+ %>
44
+ <div merge-attrs="&html_attrs">
45
+ <% per_section ||= 20 %>
46
+ <% per_section = per_section.to_i %>
47
+ <% counter = 0 %>
48
+ <% chunker ||= Proc.new{|el| counter=counter+1; (counter-1)/per_section+1} %>
49
+ <repeat with="&this.to_a.chunk(&chunker)">
50
+ <% chunk, list = this %>
51
+ <% list.member_class = this.member_class if this._?.member_class%>
52
+ <set-scoped chunk="&chunk">
53
+ <do with="&list">
54
+ <div class="hjq-accordion-element">
55
+ <h3 param="header-wrapper">
56
+ <a param="header" href="#"><%= scope.chunk %></a>
57
+ </h3>
58
+ <div param="default">
59
+ <collection without-empty-message param/>
60
+ </div>
61
+ </div>
62
+ </do>
63
+ </set-scoped>
64
+ </repeat>
65
+ </div>
66
+ </def>
@@ -0,0 +1,54 @@
1
+ <!--
2
+ This is the [jQuery-UI autocompleter](http://jqueryui.com/demos/autocomplete/). All options and events provided by the jQuery autocompleter are supported in this Hobo tag. Refer to the jquery autocomplete documentation for more details.
3
+
4
+ If you do not provide a `source` option, this tag will essentially provide a default similar to this:
5
+
6
+ <autocomplete:project source="&Project.find(:all, :limit => 5000).map {|p| p.name}" />
7
+
8
+ This will provide a local autocomplete, putting all possible options into your HTML. This is useful when you have too many options to make a `select-one` infeasible, but will overload your server and crash your browser if you have millions of options.
9
+
10
+ To do server side autocomplete, you need a controller action like:
11
+
12
+ class FoosController < ActionController:Base
13
+ hobo_user_controller
14
+ autocomplete :bar
15
+ end
16
+
17
+ <autocomplete:foo source="&complete_bar_foos_path" />
18
+
19
+ The argument to the controller's `autocomplete` is optional. If not supplied the name attribute for the model should be used in the source attribute.
20
+
21
+ If you do not wish to use the Hobo autocomplete or hobo_completions functions in your controller, it is very easy to roll your own. For example:
22
+
23
+ <autocomplete:project source="&query_projects_path" delay="500" minLength="3" />
24
+
25
+ Could be served by:
26
+
27
+ index_action :query do
28
+ render :json => Project.name_contains(params[:term]).limit(100).*.name
29
+ end
30
+
31
+ -->
32
+ <def tag="autocomplete" attrs="nil-value">
33
+ <%
34
+ options, attrs = attributes.partition_hash(['disabled', 'appendTo', 'autoFocus', 'delay', 'minLength', 'position', 'source'])
35
+ events, html_attrs = attrs.partition_hash(['create', 'search', 'open', 'focus', 'select', 'close', 'change'])
36
+ options["source"] ||= begin
37
+ complete_target = this_field_reflection.klass
38
+ complete_target.find(:all, :limit => 5000).*.send(complete_target.name_attribute)
39
+ end
40
+
41
+ html_attrs["name"] ||= param_name_for_this
42
+ html_attrs["value"] ||= name(:no_wrapper => true, :if_present => true)
43
+
44
+ if(html_attrs["value"].empty?)
45
+ add_classes!(html_attrs, "nil-value")
46
+ html_attrs["value"] = nil_value
47
+ end
48
+
49
+ add_data_rapid!(html_attrs, "autocomplete", :options => options, :events => events)
50
+ %>
51
+ <wrap tag="span" class="field-with-errors" when="&!this_parent.errors[this_field].empty?">
52
+ <input type="text" merge-attrs="&html_attrs"/>
53
+ </wrap>
54
+ </def>
@@ -0,0 +1,48 @@
1
+ <!-- Creates an enhanced version of the [jQuery-UI demo combobox](http://jqueryui.com/demos/autocomplete/#combobox). This will turn any select (even a select-many) into a combobox.
2
+
3
+ Standard usage:
4
+
5
+ <combobox>
6
+ <select .../>
7
+ </combobox>
8
+
9
+ If you don't supply the select, it will use Hobo's `<input>` tag. This is usually the right default.
10
+
11
+ You can tell Hobo to always use a combobox for select-one, select-many, select-input and/or select-menu. Notice that we also changed the limit - 100 is the default, which makes sense for a select, but not for a combobox.
12
+
13
+ <extend tag="select-one">
14
+ <combobox tag="select-one">
15
+ <old-select-one limit="5000" merge/>
16
+ </combobox>
17
+ </extend>
18
+
19
+ To make the behavior more like the demo's, turn off autoFill and clearButton:
20
+
21
+ <combobox autoFill="&false" clearButton="&false"/>
22
+
23
+ Combobox is a new control that is built on autocomplete. The autocomplete options may not be used directly. If you need any of them let me know, they should not be too hard to add if you volunteer to test them.
24
+
25
+ ### Attributes
26
+
27
+ - `autoFill` (default: true): select first value rather than clearing if there's a match
28
+
29
+ - `clearButton` (default: true): add a "clear" button
30
+
31
+ - `adjustWidth` (default: true): if true, will set the autocomplete width the same as the old select. (requires jQuery 1.4.4 to work on IE8)
32
+
33
+ - uiStyle (default: false): if true, will add classes so that the autocomplete input takes a jQuery-UI style. If false, the standard Hobo style is used.
34
+
35
+ ### Events
36
+
37
+ - `selected` (default: `$(this).trigger('change');`):
38
+ -->
39
+ <def tag="combobox">
40
+ <%
41
+ options, attrs = attributes.partition_hash(['autoFill', 'clearButton', 'adjustWidth', 'uiStyle'])
42
+ events, html_attrs = attrs.partition_hash(['selected'])
43
+ add_data_rapid!(html_attrs, "combobox", :options => options, :events => events)
44
+ %>
45
+ <span class="combobox" param="default" merge-attrs="&html_attrs">
46
+ <input merge param />
47
+ </span>
48
+ </def>
@@ -0,0 +1,46 @@
1
+ <!--
2
+ This is the [jQuery-UI datepicker](http://docs.jquery.com/UI/Datepicker). All options and events are supported.
3
+
4
+ It's probably easiest to add this to your application.dryml:
5
+
6
+ <def tag="input" for="Date">
7
+ <datepicker dateFormat="yy-mm-dd" merge />
8
+ </def>
9
+
10
+ It's probably useful to set global options such as dateFormat in application.dryml and set local options such as yearRange in the tag invocation:
11
+
12
+ <input:birthdate yearRange="1900:#{Date.today.year}" />
13
+
14
+ New in version 1.4:
15
+
16
+ If you do not specify dateFormat, we will attempt to convert I18n.t(:"date.formats.default") from strftime format into the format that the JQuery-UI datepicker likes.
17
+
18
+ -->
19
+ <def attrs="name" tag="datepicker">
20
+ <%
21
+ options, attrs = attributes.partition_hash(['altField', 'altFormat', 'appendText', 'buttonImage', 'buttonImageOnly', 'buttonText', 'changeMonth', 'changeYear', 'closeText', 'constrainInput', 'currentText', 'dateFormat', 'dayNames', 'dayNamesMin', 'dayNamesShort', 'defaultDate', 'duration', 'firstDay', 'gotoCurrent', 'hideIfNoPrevNext', 'isRTL', 'maxDate', 'minDate', 'monthNames', 'monthNamesShort', 'navigationAsDateFormat', 'nextText', 'numberOfMonths', 'prevText', 'selectOtherMonths','shortYearCutoff', 'showAnim', 'showButtonPanel', 'showCurrentAtPos', 'showMonthAfterYear', 'showOn', 'showOptions', 'showOtherMonths', 'stepMonths', 'yearRange'])
22
+ options["dateFormat"]||=begin
23
+ d=I18n.t(:"date.formats.default")
24
+ {"%Y" => "yy",
25
+ "%y" => "y",
26
+ "%m" => "mm",
27
+ "%_m" => "m",
28
+ "%-m" => "m",
29
+ "%B" => "MM",
30
+ "%^B" => "MM",
31
+ "%b" => "M",
32
+ "%^b" => "M",
33
+ "%h" => "M",
34
+ "%d" => "dd",
35
+ "%-d" => "d",
36
+ "%j" => "oo",
37
+ "%D" => "mm/dd/y",
38
+ "%F" => "yy-mm-dd",
39
+ "%x" => "mm/dd/y"}.each {|rb, js| d.gsub!(rb,js)}
40
+ d
41
+ end
42
+ events, html_attrs = attrs.partition_hash(['beforeShow', 'beforeShowDay', 'onChangeMonthYear', 'onClose', 'onSelect'])
43
+ add_data_rapid!(html_attrs, "datepicker", :options => options, :events => events)
44
+ %>
45
+ <%= text_field_tag(name, this, deunderscore_attributes(html_attrs)) %>
46
+ </def>
@@ -0,0 +1,70 @@
1
+ <!--
2
+ The JQuery UI [dialog](http://jqueryui.com/demos/dialog/). All options and methods are supported.
3
+
4
+ The default for [autoOpen](http://jqueryui.com/demos/dialog/#option-autoOpen) has been changed to `"&false"`. To display the dialog set autoOpen to `"&true"`, use a `<dialog-open-button>`, use `<dialog-and-button>` or use javascript (`$('#foo-dialog').hjq_dialog('open');`).
5
+
6
+ The [buttons](http://jqueryui.com/demos/dialog/#option-buttons) option has been changed slightly. Because of quoting issues, it's usually easier to assign the list to a variable and then include the list:
7
+
8
+ <% buttons = [ ["cancel", "jQuery(this).dialog('close')"] ] %>
9
+ <dialog-box buttons="&buttons">My dialog text</dialog>
10
+
11
+ or
12
+
13
+ <dialog-box id="story-dialog" buttons='&{"cancel" => "jQuery(this).dialog(\"close\")"}' >My dialog text</dialog>
14
+
15
+ or
16
+
17
+ <dialog-box id="story-dialog" buttons='&{"cancel" => "hjq.dialog.close"}' > FIXME</dialog>
18
+
19
+ Because Ruby 1.8 Hash's do not preserve order, you may use a list of pairs instead of a Hash.
20
+
21
+ If you do not set [position](http://jqueryui.com/demos/dialog/#option-position) the dialog will appear where it is defined in your DRYML.
22
+
23
+ JQuery UI is sometimes picky about types. For instance, the width option must be a number, not a string. By default Hobo options are strings, but you can easily send a number by using the ampersand to switch to ruby mode:
24
+
25
+ <dialog-box width="&640"/>
26
+
27
+ The following functions are predefined for use in dialog buttons: FIXME
28
+
29
+ * `hjq.dialog.close`: close the dialog box
30
+ * `hjq.dialog.submitFormlet`: submits all formlets inside the dialog
31
+ * `hjq.dialog.submitFormletAndClose`: submits any enclosed formlets, then closes the dialog.
32
+ -->
33
+ <def tag="dialog-box" attrs="buttons">
34
+ <%
35
+ options, attrs = attributes.partition_hash(["autoOpen", "bgiframe", "closeOnEscape", "dialogClass", "draggable", "height", "hide", "maxHeight", "maxWidth", "minWidth", "modal", "position", "resizable", "show", "stack", "title", "width", "zIndex"])
36
+ events, html_attrs = attrs.partition_hash(["beforeclose", "open", "focus", "dragStart", "drag", "dragStop", "resizeStart", "resize", "resizeStop", "close"])
37
+ options["autoOpen"]=false unless options.has_key?("autoOpen")
38
+ %>
39
+ <span class="dialog-position"></span>
40
+ <% html_attrs = add_classes(html_attrs, "hidden dialog-box") %>
41
+ <div merge-attrs="&html_attrs" data-rapid="&data_rapid('dialog-box', :options => options, :events => events, :buttons => buttons)" param="default" />
42
+ </def>
43
+
44
+ <!--
45
+ When pressed, will open a `<dialog-box>`.
46
+
47
+ ### Attributes
48
+ * `dialog` (required):a CSS selector (AKA jQuery selector) to locate the dialog in the DOM. Remember, if you're passing an ID, place a '#' in front of the ID.
49
+ * supports all button attributes
50
+
51
+ ### Example
52
+ <dialog id="hello-dialog">Hello!</dialog>
53
+ <dialog-open-button dialog="#hello-dialog">Press Me!</dialog-open-button>
54
+ -->
55
+ <def tag="dialog-open-button" attrs="dialog">
56
+ <button data-rapid="&data_rapid('dialog-open-button', :selector => dialog)" param="default" class="dialog-open-button" merge />
57
+ </def>
58
+
59
+ <!--
60
+ Defines an `<dialog-box>` and a `<dialog-open-button>` and links the two together.
61
+
62
+ ### Attributes
63
+ * `id` (optional): the DOM id to use for the dialog
64
+ -->
65
+ <def tag="dialog-and-button">
66
+ <% # we can't use jQuery traversal functions since the dialog will move around in the DOM %>
67
+ <% attributes["id"]="dialog-#{(rand*1000000000).to_i}" unless attributes.has_key?("id") %>
68
+ <dialog-box param merge />
69
+ <dialog-open-button dialog="##{attributes['id']}" param />
70
+ </def>
@@ -0,0 +1,7 @@
1
+ <!--
2
+
3
+ This plugin provides the jQuery UI widgets in a Hobo friendly manner.
4
+
5
+ -->
6
+
7
+ <include src="*"/>
@@ -0,0 +1,67 @@
1
+ <!-- An `<input type="text">` with auto-completion. Allows the user to chose the target of a `belongs_to` association by name.
2
+
3
+ This tag relies on an autocompleter being defined in a controller. A simple example:
4
+
5
+ <form with="&ProjectMembership.new">
6
+ <name-one:user>
7
+ </form>
8
+
9
+ class ProjectMembership < ActiveRecord::Base
10
+ hobo_model
11
+ belongs_to :user
12
+ end
13
+
14
+ class User < ActiveRecord::Base
15
+ hobo_user_model
16
+ has_many :project_memberships, :accessible => true, :dependent => :destroy
17
+ end
18
+
19
+ class UsersController < ApplicationController
20
+ autocomplete
21
+ end
22
+
23
+ The route used by the autocompleter looks something like `/users/complete_name`. The first part of this route is specified by the `complete-target` attribute, and the second part is specified by the `completer` attribute.
24
+
25
+ `complete-target` specifies the controller for the route. It can be specified by either supplying a model class or a model. If a model is supplied, the id of the model is passed as a parameter to the controller. (`?id=7`, for example) The default for this attribute is the class of the context. In other words, the class that contains the `has_many / has_one`, not the class with the `belongs_to`.
26
+
27
+ `completer` specifies the action for the route. `name-one` prepends `complete_` to the value given here. This should be exactly the same as the first parameter to `autocomplete` in your controller. As an example: `autocomplete :email_address` would correspond to `completer="email_address"`. The default for this attribute is the name field for the model being searched, which is usually `name`, but not always.
28
+
29
+ The query string is passed to the controller in the `query` parameter. (`?query=hello` for example).
30
+
31
+ For more information on how to customize the controller, see the [controller manual](http://cookbook.hobocentral.net/manual/controllers#autocompleters)
32
+
33
+ Here's a more complex example. This used to be a part of [agility](http://cookbook.hobocentral.net/tutorials/agility) until it was simplified.
34
+
35
+ class ProjectsController < ApplicationController
36
+ autocomplete :new_member_name do
37
+ project = find_instance
38
+ hobo_completions :name, User.without_project(project).is_not(project.owner)
39
+ end
40
+ end
41
+
42
+ Note that this was added to the projects controller, rather than the users controller as in the first example. You can read this as: create an auto-complete action called `new_member_name` that finds users that are not already members of the project, and not the owner of the project, and completes the :name field.
43
+
44
+ <name-one:user complete-target="&@project" completer="new_member_name"/>
45
+
46
+ We're using an object as the complete-target rather than a class. This allows the `find_instance` in our controller action to function.
47
+
48
+ There's another example of `<name-one>` use in the [recipes](http://cookbook.hobocentral.net/recipes/36-using-a-name-one-one-a).
49
+
50
+ ### Attributes:
51
+
52
+ All other attributes are passed through to the `<autocomplete>` that provides the core functionality for this widget.
53
+
54
+ - `complete-target`, `completer`: see above
55
+ - `min-chars`: The minimum number of characters that must be entered in the input field before an Ajax request is made.
56
+ - `nil-value`: If there is no current value, this text will appear greyed out inside the control, and will disappear on focus.
57
+
58
+ -->
59
+ <def tag="name-one" attrs="complete-target, completer, min-chars">
60
+ <%
61
+ complete_target ||= this_field_reflection.klass
62
+ completer ||= (complete_target.is_a?(Class) ? complete_target : complete_target.class).name_attribute
63
+ source = polymorphic_url(complete_target, :action => "complete_#{completer}", :routing_type => :path)
64
+ value = name(:no_wrapper => true, :if_present => true)
65
+ -%>
66
+ <autocomplete source="&source" minLength="&min_chars || 1" merge/>
67
+ </def>
@@ -0,0 +1,61 @@
1
+ <%# This tag allows you to easily use [jQuery-UI tabs](http://jqueryui.com/demos/tabs/)
2
+
3
+ <tabs>
4
+ <first:>tab 1 content</first:>
5
+ <tab2:>tab 2 content</tab2:>
6
+ </tabs>
7
+
8
+ If you don't specify any attributes to the parameters, the parameter name is used for the tab name and ID. You can adjust this behaviour by specifying attributes to your parameters:
9
+
10
+ <tabs>
11
+ <tab1: name="1" id="id1">tab 1 content</tab1:>
12
+ </tabs:>
13
+
14
+ If you specify an href rather than an id, the tab content is loaded dynamically:
15
+
16
+ <tabs>
17
+ <remote: href="/front/hello"/>
18
+ </tabs>
19
+
20
+ Attributes are passed through to jQuery-UI, so options and events defined in the [jQuery-ui tabs documentation](http://jqueryui.com/demos/tabs/) may be used:
21
+
22
+ <tabs collapsible selected="2">
23
+ ...
24
+ </tabs>
25
+
26
+ ### Attributes
27
+
28
+ Note that `tabs` supports attributes both on the `tabs` tag as well as on the parameters.
29
+
30
+ The parameters support three attributes: `id`, `name`, `href`, described above.
31
+
32
+ The `tabs` tag supports all options and events supported in jQuery-UI, plus one additional attribute:
33
+
34
+ * sortable: if set, the tabs are sortable rather than fixed.
35
+
36
+ ### Notes
37
+
38
+ Usage of Ruby 1.8 will result in an undefined tab order. Ruby 1.9 is recommended.
39
+
40
+ %>
41
+ <def tag="tabs" attrs="sortable">
42
+ <% options, attrs = attributes.partition_hash(['disabled', 'ajaxOptions', 'cache', 'collapsible', 'cookie', 'deselectable', 'disabled', 'event', 'fx', 'idPrefix', 'panelTemplate', 'selected', 'spinner', 'tabTemplate'])
43
+ events, html_attrs = attrs.partition_hash(['create', 'select', 'load', 'show', 'add', 'remove', 'enable', 'disable'])
44
+ add_classes!(html_attrs, "tabs")
45
+ add_data_rapid!(html_attrs, "tabs", :options => options, :events => events, :sortable => sortable)
46
+ %>
47
+ <div merge-attrs="&html_attrs">
48
+ <ul>
49
+ <repeat with="&parameters">
50
+ <% attrs, params = this.call %>
51
+ <li><a href="#{attrs[:href] || '#'+(attrs[:id] || this_key.to_s)}"><%= attrs[:name] || this_key.to_s.titleize %></a></li>
52
+ </repeat>
53
+ </ul>
54
+
55
+ <repeat with="&parameters">
56
+ <% attrs, params = this.call %>
57
+ <% merge_attrs = attrs - [:id, :href, :name] %>
58
+ <div id="#{attrs[:id] || this_key}" merge-attrs="&merge_attrs"><%= params[:default]._?.call %></div>
59
+ </repeat>
60
+ </div>
61
+ </def>
@@ -0,0 +1,168 @@
1
+ /* stolen from http://jqueryui.com/demos/autocomplete/#combobox
2
+ *
3
+ * and these options added.
4
+ *
5
+ * - autoFill (default: true): select first value rather than clearing if there's a match
6
+ *
7
+ * - clearButton (default: true): add a "clear" button
8
+ *
9
+ * - adjustWidth (default: true): if true, will set the autocomplete width the same as
10
+ * the old select. (requires jQuery 1.4.4 to work on IE8)
11
+ *
12
+ * - uiStyle (default: false): if true, will add classes so that the autocomplete input
13
+ * takes a jQuery-UI style
14
+ */
15
+ (function( $ ) {
16
+ $.widget( "ui.combobox", {
17
+ options: {
18
+ autoFill: true,
19
+ clearButton: true,
20
+ adjustWidth: true,
21
+ uiStyle: false,
22
+ selected: null,
23
+ },
24
+ _create: function() {
25
+ var self = this,
26
+ select = this.element.hide(),
27
+ selected = select.children( ":selected" ),
28
+ value = selected.val() ? selected.text() : "",
29
+ found = false;
30
+ var input = this.input = $( "<input>" )
31
+ .attr('title', '' + select.attr("title") + '')
32
+ .insertAfter( select )
33
+ .val( value )
34
+ .autocomplete({
35
+ delay: 0,
36
+ minLength: 0,
37
+ source: function( request, response ) {
38
+ var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
39
+ var resp = select.children( "option" ).map(function() {
40
+ var text = $( this ).text();
41
+ if ( this.value && ( !request.term || matcher.test(text) ) )
42
+ return {
43
+ label: text.replace(
44
+ new RegExp(
45
+ "(?![^&;]+;)(?!<[^<>]*)(" +
46
+ $.ui.autocomplete.escapeRegex(request.term) +
47
+ ")(?![^<>]*>)(?![^&;]+;)", "gi"
48
+ ), "<strong>$1</strong>" ),
49
+ value: text,
50
+ option: this
51
+ };
52
+ });
53
+ found = resp.length > 0;
54
+ response( resp );
55
+ },
56
+ select: function( event, ui ) {
57
+ ui.item.option.selected = true;
58
+ self._trigger( "selected", event, {
59
+ item: ui.item.option
60
+ });
61
+ },
62
+ change: function( event, ui ) {
63
+ if ( !ui.item ) {
64
+ var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $(this).val() ) + "$", "i" ),
65
+ valid = false;
66
+ select.children( "option" ).each(function() {
67
+ if ( $( this ).text().match( matcher ) ) {
68
+ this.selected = valid = true;
69
+ return false;
70
+ }
71
+ });
72
+ if ( !valid || input.data("autocomplete").term=="" ) {
73
+ // set to first suggestion, unless blank or autoFill is turned off
74
+ var suggestion;
75
+ if(!self.options.autoFill || input.data("autocomplete").term=="") found=false;
76
+ if(found) {
77
+ suggestion = jQuery(input.data("autocomplete").widget()).find("li:first");
78
+ var option = select.find("option:contains('"+suggestion.text()+"')").attr('selected', true);
79
+ $(this).val(suggestion.text());
80
+ input.data("autocomplete").term = suggestion.text();
81
+ self._trigger( "selected", event, { item: option[0] });
82
+ } else {
83
+ select.find("option:selected").removeAttr("selected");
84
+ $(this).val('');
85
+ input.data( "autocomplete" ).term = '';
86
+ self._trigger( "selected", event, { item: null });
87
+ }
88
+ return found;
89
+ }
90
+ }
91
+ }
92
+ });
93
+
94
+ if( self.options.adjustWidth ) { input.width(select.width()); }
95
+
96
+ if( self.options.uiStyle ) {
97
+ input.addClass( "ui-widget ui-widget-content ui-corner-left" );
98
+ }
99
+
100
+
101
+ input.data( "autocomplete" )._renderItem = function( ul, item ) {
102
+ return $( "<li></li>" )
103
+ .data( "item.autocomplete", item )
104
+ .append( "<a>" + item.label + "</a>" )
105
+ .appendTo( ul );
106
+ };
107
+
108
+ this.button = $( "<button type='button'>&nbsp;</button>" )
109
+ .attr( "tabIndex", -1 )
110
+ .attr( "title", "Show All Items" )
111
+ .insertAfter( input )
112
+ .button({
113
+ icons: {
114
+ primary: "ui-icon-triangle-1-s"
115
+ },
116
+ text: false
117
+ })
118
+ .removeClass( "ui-corner-all" )
119
+ .addClass( "ui-corner-right ui-button-icon" )
120
+ .click(function() {
121
+ // close if already visible
122
+ if ( input.autocomplete( "widget" ).is( ":visible" ) ) {
123
+ input.autocomplete( "close" );
124
+ return;
125
+ }
126
+
127
+ // work around a bug (likely same cause as #5265)
128
+ $( this ).blur();
129
+
130
+ // pass empty string as value to search for, displaying all results
131
+ input.autocomplete( "search", "" );
132
+ input.focus();
133
+ });
134
+
135
+ if( self.options.clearButton ) {
136
+ this.clear_button = $( "<button type='button'>&nbsp;</button>" )
137
+ .attr( "tabIndex", -1 )
138
+ .attr( "title", "Clear Entry" )
139
+ .insertAfter( input )
140
+ .button({
141
+ icons: {
142
+ primary: "ui-icon-close"
143
+ },
144
+ text: false
145
+ })
146
+ .removeClass( "ui-corner-all" )
147
+ .click(function(event, ui) {
148
+
149
+ select.find("option:selected").removeAttr("selected");
150
+ input.val( "" );
151
+ input.data( "autocomplete" ).term = "";
152
+ self._trigger( "selected", event, { item: null });
153
+
154
+ // work around a bug (likely same cause as #5265)
155
+ $( this ).blur();
156
+ });
157
+ }
158
+
159
+ },
160
+
161
+ destroy: function() {
162
+ this.input.remove();
163
+ this.button.remove();
164
+ this.element.show();
165
+ $.Widget.prototype.destroy.call( this );
166
+ }
167
+ });
168
+ })( jQuery );
@@ -0,0 +1,24 @@
1
+ /* accordion & accordion-collection */
2
+ (function($) {
3
+ $.fn.hjq_accordion = function(annotations) {
4
+ var stop = false;
5
+ if(annotations.sortable) {
6
+ this.on("click", "div.hjq-accordion-element > h3", function(event) {
7
+ if(stop) {
8
+ event.stopImmediatePropagation();
9
+ event.preventDefault();
10
+ stop = false;
11
+ }
12
+ });
13
+ }
14
+ var that=this.accordion($.extend({header: "> div.hjq-accordion-element > h3"}, this.hjq('getOptions', annotations)));
15
+ if (annotations.sortable) {
16
+ that.sortable({axis: "y",
17
+ handle: "h3",
18
+ stop: function() {
19
+ stop = true;
20
+ }
21
+ });
22
+ }
23
+ };
24
+ })( jQuery );
@@ -0,0 +1,12 @@
1
+ /* autocomplete */
2
+ (function($) {
3
+ $.fn.hjq_autocomplete = function(annotations) {
4
+ this.autocomplete(this.hjq('getOptions', annotations)).on("focus", function() {
5
+ if($(this).hasClass("nil-value")) {
6
+ this.value='';
7
+ $(this).removeClass("nil-value");
8
+ }
9
+ });
10
+ };
11
+ })( jQuery );
12
+
@@ -0,0 +1,13 @@
1
+ /* combobox */
2
+ (function($) {
3
+ $.fn.hjq_combobox = function(annotations) {
4
+ var select = this.find('select');
5
+ if(!select.attr('disabled')) {
6
+ var options = this.hjq('getOptions', annotations);
7
+ options.selected = options.selected || function(event, ui) {
8
+ $(this).trigger('change');
9
+ }
10
+ select.combobox(options);
11
+ }
12
+ }
13
+ })( jQuery );
@@ -0,0 +1,22 @@
1
+ /* datepicker */
2
+ (function($) {
3
+ var methods = {
4
+ init: function(annotations) {
5
+ if(!this.attr('disabled')) {
6
+ this.datepicker(this.hjq('getOptions', annotations));
7
+ }
8
+ }
9
+ };
10
+
11
+ $.fn.hjq_datepicker = function( method ) {
12
+
13
+ if ( methods[method] ) {
14
+ return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
15
+ } else if ( typeof method === 'object' || ! method ) {
16
+ return methods.init.apply( this, arguments );
17
+ } else {
18
+ $.error( 'Method ' + method + ' does not exist on hjq_datepicker' );
19
+ }
20
+ };
21
+
22
+ })( jQuery );
@@ -0,0 +1,97 @@
1
+ /* dialog */
2
+ (function($) {
3
+ var methods = {
4
+ init: function(annotations) {
5
+ var options=this.hjq('getOptions', annotations);
6
+ if(!options.position) { options.position = {}; }
7
+ if($.isPlainObject(options.position)) {
8
+ this.data('hjq-dialog-position', $.extend({}, {my: 'center', at: 'center center', of: this.prev('.dialog-position')}, options.position));
9
+ delete options.position;
10
+ }
11
+ if(annotations.buttons) {
12
+ options.buttons = {};
13
+ for(var i=0; i<annotations.buttons.length; i++) {
14
+ options.buttons[annotations.buttons[i][0]] = this.hjq('createFunction',annotations.buttons[i][1])
15
+ }
16
+ }
17
+ this.dialog(options);
18
+ },
19
+
20
+ open: function() {
21
+ this.dialog('open');
22
+ if(this.data('hjq-dialog-position')) {
23
+ this.parent().position(this.data('hjq-dialog-position'));
24
+ }
25
+ },
26
+
27
+ close: function() {
28
+ if(!this.hasClass("dialog-box")) this.parents(".dialog-box").dialog('close');
29
+ else this.dialog('close');
30
+ },
31
+
32
+ /* open if closed, close if open */
33
+ toggle: function() {
34
+ var dialog=this;
35
+ if(!this.hasClass("dialog-box")) dialog=this.parents(".dialog_box");
36
+ if(dialog.dialog('isOpen')) {
37
+ methods.close.call(dialog);
38
+ } else {
39
+ methods.open.call(dialog);
40
+ }
41
+ },
42
+
43
+ /* useful in the "buttons" option. Will submit any enclosed
44
+ forms or formlets. */
45
+ submit: function(extra_options, extra_attrs) {
46
+ var dialog=this;
47
+ if(!this.hasClass("dialog-box")) dialog=this.parents(".dialog_box");
48
+ dialog.find("form").trigger('submit');
49
+ dialog.find(".formlet").hjq_formlet('submit', extra_options, extra_attrs);
50
+ },
51
+
52
+ /* calls submit, and then closes the dialog box. */
53
+ /* useful in the "buttons" option. */
54
+ submitAndClose: function() {
55
+ var that=this;
56
+ methods.submit.call(this, {success: function() {methods.close.call(that);}});
57
+ }
58
+ };
59
+
60
+ $.fn.hjq_dialog_box = function( method ) {
61
+
62
+ if ( methods[method] ) {
63
+ return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
64
+ } else if ( typeof method === 'object' || ! method ) {
65
+ return methods.init.apply( this, arguments );
66
+ } else {
67
+ $.error( 'Method ' + method + ' does not exist on hjq_dialog' );
68
+ }
69
+ };
70
+
71
+ $.fn.hjq_dialog_open_button = function(annotations) {
72
+ this.on('click', function() {
73
+ $(annotations.selector).hjq_dialog_box('toggle');
74
+ return false;
75
+ });
76
+ };
77
+
78
+ })( jQuery );
79
+
80
+
81
+ // to make the DRYML interface cleaner, these provide direct access to
82
+ // a couple of plugin functions.
83
+ var hjq_dialog_box=(function($) {
84
+ return {
85
+ close: function() {
86
+ $(this).hjq_dialog_box('close');
87
+ },
88
+
89
+ submit: function() {
90
+ $(this).hjq_dialog_box('submit');
91
+ },
92
+
93
+ submitAndClose: function() {
94
+ $(this).hjq_dialog_box('submitAndClose');
95
+ }
96
+ }
97
+ })(jQuery);
@@ -0,0 +1,9 @@
1
+ /* tabs */
2
+ (function($) {
3
+ $.fn.hjq_tabs = function(annotations) {
4
+ this.tabs(this.hjq('getOptions', annotations));
5
+ if(annotations.sortable) {
6
+ this.find(".ui-tabs-nav").sortable();
7
+ }
8
+ };
9
+ })( jQuery );
@@ -0,0 +1,2 @@
1
+ //= require_tree .
2
+
@@ -0,0 +1,7 @@
1
+
2
+ // stolen from clean.css
3
+ .combobox .ui-button { margin-left: -1px; }
4
+ .combobox .ui-button-icon-only .ui-button-text { padding: 0; }
5
+ .combobox button.ui-button-icon-only { width: 20px; }
6
+ .combobox .ui-autocomplete-input { margin-right: 0; }
7
+ .combobox {white-space: nowrap;}
@@ -0,0 +1,3 @@
1
+ /*
2
+ * require_tree .
3
+ */
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hobo_jquery_ui
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: 6
5
+ version: 1.4.0.pre2
6
+ platform: ruby
7
+ authors:
8
+ - Bryan Larsen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-03-28 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: jquery-ui-themes
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.4
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: hobo
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - "="
33
+ - !ruby/object:Gem::Version
34
+ version: 1.4.0.pre2
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: hobo_jquery
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - "="
44
+ - !ruby/object:Gem::Version
45
+ version: 1.4.0.pre2
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ description: JQuery UI support for Hobo
49
+ email: bryan@larsen.st
50
+ executables: []
51
+
52
+ extensions: []
53
+
54
+ extra_rdoc_files: []
55
+
56
+ files:
57
+ - .gitmodules
58
+ - LICENSE.txt
59
+ - README.markdown
60
+ - VERSION
61
+ - hobo_jquery_ui.gemspec
62
+ - lib/hobo_jquery_ui.rb
63
+ - lib/hobo_jquery_ui/railtie.rb
64
+ - taglibs/accordion.dryml
65
+ - taglibs/accordion_collection.dryml
66
+ - taglibs/autocomplete.dryml
67
+ - taglibs/combobox.dryml
68
+ - taglibs/datepicker.dryml
69
+ - taglibs/dialog_box.dryml
70
+ - taglibs/hobo_jquery_ui.dryml
71
+ - taglibs/name_one.dryml
72
+ - taglibs/tabs.dryml
73
+ - vendor/assets/javascripts/combobox.js
74
+ - vendor/assets/javascripts/hobo-jquery-ui/hjq-accordion.js
75
+ - vendor/assets/javascripts/hobo-jquery-ui/hjq-autocomplete.js
76
+ - vendor/assets/javascripts/hobo-jquery-ui/hjq-combobox.js
77
+ - vendor/assets/javascripts/hobo-jquery-ui/hjq-datepicker.js
78
+ - vendor/assets/javascripts/hobo-jquery-ui/hjq-dialog.js
79
+ - vendor/assets/javascripts/hobo-jquery-ui/hjq-tabs.js
80
+ - vendor/assets/javascripts/hobo_jquery_ui.js
81
+ - vendor/assets/stylesheets/combobox.css
82
+ - vendor/assets/stylesheets/hobo_jquery_ui.css
83
+ homepage: http://hobocentral.net
84
+ licenses: []
85
+
86
+ post_install_message:
87
+ rdoc_options:
88
+ - --charset=UTF-8
89
+ require_paths:
90
+ - lib
91
+ - vendor
92
+ - taglibs
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: "0"
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: 1.3.6
105
+ requirements: []
106
+
107
+ rubyforge_project:
108
+ rubygems_version: 1.8.17
109
+ signing_key:
110
+ specification_version: 3
111
+ summary: JQuery UI support for Hobo
112
+ test_files: []
113
+
114
+ has_rdoc: