diff --git a/app/assets/javascripts/locomotive/views/pages/list_view.js.coffee b/app/assets/javascripts/locomotive/views/pages/list_view.js.coffee index 100701b6..76c37807 100644 --- a/app/assets/javascripts/locomotive/views/pages/list_view.js.coffee +++ b/app/assets/javascripts/locomotive/views/pages/list_view.js.coffee @@ -5,12 +5,15 @@ class Locomotive.Views.Pages.ListView extends Backbone.View el: '#pages-list' render: -> - console.log('render list view'); + @make_foldable() @make_sortable() return @ + make_foldable: -> + @$('ul.folder img.toggler').toggleMe() + make_sortable: -> self = @ @@ -37,24 +40,3 @@ class Locomotive.Views.Pages.ListView extends Backbone.View on_failed_sort: (data, status, xhr) -> $.growl('error', xhr.getResponseHeader('Flash')); - - # $.post($(@).attr('data-url'), params, function(data) { - # var error = typeof(data.error) != 'undefined'; - # $.growl((error ? 'error' : 'success'), (error ? data.error : data.notice)); - # }, 'json'); - - # TODO - # $('#pages-list ul.folder').sortable({ - # 'handle': 'em', - # 'axis': 'y', - # 'update': function(event, ui) { - # var params = $(this).sortable('serialize', { 'key': 'children[]' }); - # params += '&_method=put'; - # params += '&' + $('meta[name=csrf-param]').attr('content') + '=' + $('meta[name=csrf-token]').attr('content'); - # - # $.post($(this).attr('data-url'), params, function(data) { - # var error = typeof(data.error) != 'undefined'; - # $.growl((error ? 'error' : 'success'), (error ? data.error : data.notice)); - # }, 'json'); - # } - # }); \ No newline at end of file diff --git a/app/assets/javascripts/locomotive/views/pages/new_view.js.coffee b/app/assets/javascripts/locomotive/views/pages/new_view.js.coffee new file mode 100644 index 00000000..10c9b613 --- /dev/null +++ b/app/assets/javascripts/locomotive/views/pages/new_view.js.coffee @@ -0,0 +1,41 @@ +Locomotive.Views.Pages ||= {} + +class Locomotive.Views.Pages.NewView extends Backbone.View + + el: '#content' + + render: -> + @enable_templatized_checkbox() + + @enable_redirect_checkbox() + + @enable_other_checkboxes() + + return @ + + enable_templatized_checkbox: -> + features = ['slug', 'redirect', 'listed'] + @$('li#page_templatized_input input[type=checkbox]').checkToggle + on_callback: => + _.each features, (exp) -> @$('li#page_' + exp + '_input').hide() + @$('li#page_content_type_id_input').show() + off_callback: => + _.each features, (exp) -> @$('li#page_' + exp + '_input').show() + @$('li#page_content_type_id_input').hide() + + enable_redirect_checkbox: -> + features = ['templatized', 'cache_strategy'] + @$('li#page_redirect_input input[type=checkbox]').checkToggle + on_callback: => + _.each features, (exp) -> @$('li#page_' + exp + '_input').hide() + off_callback: => + _.each features, (exp) -> @$('li#page_' + exp + '_input').show() + + enable_other_checkboxes: -> + _.each ['published', 'listed'], (exp) => + @$('li#page_' + exp + '_input input[type=checkbox]').checkToggle() + + _hide_last_seperator: -> + @$('fieldset').each (fieldset) => + fieldset.find('li.last').removeClass('last') + fieldset.find('li.input:visible').addClass('last') \ No newline at end of file diff --git a/app/assets/stylesheets/locomotive.css b/app/assets/stylesheets/locomotive.css index 72ff1483..8fcf79e8 100644 --- a/app/assets/stylesheets/locomotive.css +++ b/app/assets/stylesheets/locomotive.css @@ -6,6 +6,7 @@ *= require_tree ../../../vendor/assets/stylesheets/jquery *= require ../../../vendor/assets/stylesheets/blueprint/screen.css + *= require ../../../vendor/assets/stylesheets/toggle.css *= require formtastic *= require_tree ./locomotive */ diff --git a/app/assets/stylesheets/locomotive/application.scss b/app/assets/stylesheets/locomotive/application.scss index d5444682..11af22da 100644 --- a/app/assets/stylesheets/locomotive/application.scss +++ b/app/assets/stylesheets/locomotive/application.scss @@ -156,6 +156,15 @@ ul.theme-assets { } li.page { + position: relative; + + > .toggler { + position: absolute; + top: 10px; + left: -18px; + cursor: pointer; + } + .inner { position: relative; margin-bottom: 10px; @@ -178,13 +187,6 @@ ul.theme-assets { background: transparent image-url("locomotive/list/item-left.png") no-repeat 0 0; } - &.toggler { - position: absolute; - top: 9px; - left: -15px; - cursor: pointer; - } - a { @include hover-link; diff --git a/app/helpers/locomotive/base_helper.rb b/app/helpers/locomotive/base_helper.rb index 8b85f2dc..b599b9c9 100644 --- a/app/helpers/locomotive/base_helper.rb +++ b/app/helpers/locomotive/base_helper.rb @@ -32,10 +32,6 @@ module Locomotive::BaseHelper end end - # def admin_item_toggler(object) - # image_tag("admin/list/icons/node_#{(cookies["folder-#{object._id}"] != 'none') ? 'open' : 'closed'}.png", :class => 'toggler') - # end - def collection_to_js(collection, options = {}) js = collection.collect { |object| object.to_json } diff --git a/app/helpers/locomotive/pages_helper.rb b/app/helpers/locomotive/pages_helper.rb index 79f01909..4c4c4fa7 100644 --- a/app/helpers/locomotive/pages_helper.rb +++ b/app/helpers/locomotive/pages_helper.rb @@ -7,6 +7,10 @@ module Locomotive::PagesHelper end.join(' ') end + def page_toggler(page) + image_tag("locomotive/list/icons/node_#{(cookies["folder-#{page._id}"] != 'none') ? 'open' : 'closed'}.png", :class => 'toggler') + end + def parent_pages_options roots = current_site.pages.roots.where(:slug.ne => '404').and(:_id.ne => @page.id) diff --git a/app/views/locomotive/pages/_page.html.haml b/app/views/locomotive/pages/_page.html.haml index a45a40ee..a18fc008 100644 --- a/app/views/locomotive/pages/_page.html.haml +++ b/app/views/locomotive/pages/_page.html.haml @@ -8,7 +8,7 @@ - with_children = !children.empty? - if not page.index? and with_children - = admin_item_toggler(page) + = page_toggler(page) .inner diff --git a/lib/locomotive/responder.rb b/lib/locomotive/responder.rb index 75b72143..7e67643d 100644 --- a/lib/locomotive/responder.rb +++ b/lib/locomotive/responder.rb @@ -8,56 +8,36 @@ module Locomotive super || has_errors? end - # def api_behavior(error) - # raise error unless resourceful? - # - # if get? - # display resource - # elsif post? - # display resource, :status => :created, :location => api_location - # elsif has_empty_resource_definition? - # display empty_resource, :status => :ok - # else - # head :ok - # end - # end - def to_json - - if get? display resource elsif has_errors? - display resource.errors, :status => :unprocessable_entity + with_flash_message(:error) do |message| + display resource.errors, :status => :unprocessable_entity + end elsif post? - display resource, :status => :created, :location => api_location + with_flash_message do |message| + display resource, :location => api_location + end elsif put? - with_flash_message(:notice) do |message| - # puts "put ? yes #{controller.flash[:notice]} / #{resource.inspect}" - # controller.headers[:notice] => controller.flash[:notice] - puts "put ? yes, message = #{message}" - + with_flash_message do |message| display resource, :status => :ok, :location => api_location end elsif has_empty_resource_definition? display empty_resource, :status => :ok else - # head :ok - puts "youpi !!!" - display :notice => controller.flash[:notice], :status => :ok + with_flash_message do + head :ok + end end - - controller.flash.discard # reset flash messages ! end protected - def with_flash_message(type) - puts "@alert = #{@alert} / @notice = #{@notice}" + def with_flash_message(type = :notice) set_flash_message! message = controller.flash[type] - # controller.headers[:"flash-#{type.to_s.capitalize}"] = message controller.headers[:flash] = message yield(message) if block_given? @@ -65,24 +45,5 @@ module Locomotive controller.flash.discard # reset flash messages ! end - # def api_behavior(error) - # raise error unless resourceful? - # - # # generate flash messages - # set_flash_message! - # - # if get? - # display resource - # elsif has_errors? - # display({ :errors => resource.errors, :model => controller.send(:resource_instance_name), :alert => controller.flash[:alert] }) - # elsif post? - # display resource, :status => :created, :location => resource_location - # else - # display({ :notice => controller.flash[:notice] }) - # end - # - # controller.flash.discard # reset flash messages ! - # end - end end \ No newline at end of file diff --git a/vendor/assets/javascripts/cookies.js b/vendor/assets/javascripts/cookies.js new file mode 100644 index 00000000..6df1faca --- /dev/null +++ b/vendor/assets/javascripts/cookies.js @@ -0,0 +1,96 @@ +/** + * Cookie plugin + * + * Copyright (c) 2006 Klaus Hartl (stilbuero.de) + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + */ + +/** + * Create a cookie with the given name and value and other optional parameters. + * + * @example $.cookie('the_cookie', 'the_value'); + * @desc Set the value of a cookie. + * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true }); + * @desc Create a cookie with all available options. + * @example $.cookie('the_cookie', 'the_value'); + * @desc Create a session cookie. + * @example $.cookie('the_cookie', null); + * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain + * used when the cookie was set. + * + * @param String name The name of the cookie. + * @param String value The value of the cookie. + * @param Object options An object literal containing key/value pairs to provide optional cookie attributes. + * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. + * If a negative value is specified (e.g. a date in the past), the cookie will be deleted. + * If set to null or omitted, the cookie will be a session cookie and will not be retained + * when the the browser exits. + * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). + * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). + * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will + * require a secure protocol (like HTTPS). + * @type undefined + * + * @name $.cookie + * @cat Plugins/Cookie + * @author Klaus Hartl/klaus.hartl@stilbuero.de + */ + +/** + * Get the value of a cookie with the given name. + * + * @example $.cookie('the_cookie'); + * @desc Get the value of a cookie. + * + * @param String name The name of the cookie. + * @return The value of the cookie. + * @type String + * + * @name $.cookie + * @cat Plugins/Cookie + * @author Klaus Hartl/klaus.hartl@stilbuero.de + */ +jQuery.cookie = function(name, value, options) { + if (typeof value != 'undefined') { // name and value given, set cookie + options = options || {}; + if (value === null) { + value = ''; + options.expires = -1; + } + var expires = ''; + if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { + var date; + if (typeof options.expires == 'number') { + date = new Date(); + date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); + } else { + date = options.expires; + } + expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE + } + // CAUTION: Needed to parenthesize options.path and options.domain + // in the following expressions, otherwise they evaluate to undefined + // in the packed version for some reason... + var path = options.path ? '; path=' + (options.path) : ''; + var domain = options.domain ? '; domain=' + (options.domain) : ''; + var secure = options.secure ? '; secure' : ''; + document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); + } else { // only name given, get cookie + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } +}; \ No newline at end of file diff --git a/vendor/assets/javascripts/menu_toggler.js b/vendor/assets/javascripts/menu_toggler.js new file mode 100644 index 00000000..05cdb82f --- /dev/null +++ b/vendor/assets/javascripts/menu_toggler.js @@ -0,0 +1,33 @@ +/** + * Version 1.0.1 + * Init and deploy childs on menu (admin) + * Benjamin Athlan - Bewcultures + * Andrew Bennett - Delorum + */ +$.fn.toggleMe = function(settings) { + + settings = $.extend({}, settings); + + var toggle = function(event) { + var toggler = $(this); + var children = toggler.parent().find('> ul.folder'); + + children.each(function() { + var child = $(this); + if (child.is(':visible')) { + child.slideUp('fast', function() { + toggler.attr('src', toggler.attr('src').replace('open', 'closed')); + $.cookie(child.attr('id'), 'none'); + }); + } else { + child.slideDown('fast', function() { + toggler.attr('src', toggler.attr('src').replace('closed', 'open')); + $.cookie(child.attr('id'), 'block'); + }); + } + }); + }; + + return $(this).bind("click", toggle); + +}; \ No newline at end of file diff --git a/vendor/assets/javascripts/subscribe.js b/vendor/assets/javascripts/subscribe.js new file mode 100644 index 00000000..bd016962 --- /dev/null +++ b/vendor/assets/javascripts/subscribe.js @@ -0,0 +1,367 @@ +/* + * jquery.subscribe.1.1 + * + * Implementation of publish/subcription framework for jQuery + * Requires use of jQuery. Tested with jQuery 1.3 and above + * + * + * Copyright (c) 2008 Eric Chijioke (obinna a-t g mail dot c o m) + * + * + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Release Notes: + * + * version 1.1: + * + * Fixed unexpected behavior which can occur when a script in a embedded page (page loaded in div,tab etc.) subscribes a handler for a topic using + * the jQuery subscribe ($.subscribe) or a no-id element but this subscribe plugin is not reloaded within that embedded page (for example, when + * script is included in containing page) . In this case, if the embedded page is reloaded without reloading the entire page (and plugin), the + * subscription could be made multiple times for the topic, which will call the handler multiple times each time the topic is published. + * Code has been added to prevent this when the subscription is made using the non-element subscribe ($.subscribe()), which assures that only one + * subscription is made for a topic for a given window/frame. To prevent this from happening for an element subscription ($elem.subscribe()), make + * sure that the element has an id attribute. + */ + + +(function($){ + + _subscribe_topics = {}; + _subscribe_handlers = {}; + + _subscribe_getDocumentWindow = function(document){ + + return document.parentWindow || document.defaultView; + }; + + $.fn.extend({ + + /** + * Creates a new topic without any subscribers. + * Not usually used explicitly + */ + createTopic : function(topic) { + if(topic && !_subscribe_topics[topic]) { + + _subscribe_topics[topic] = {}; + _subscribe_topics[topic].objects = {}; + _subscribe_topics[topic].objects['__noId__'] = []; + } + + return this; + }, + + /** + * Destroy an existing topic and unsubscribe all subscribers + */ + destroyTopic : function(topic) { + + if(topic && _subscribe_topics[topic]) { + + for(i in _subscribe_topics[topic].objects) { + + var object = _subscribe_topics[topic].objects[i]; + + if($.isArray(object)) { // handle '__noId__' elements + + if(object.length > 0) { + + for(j in object) { + + object[j].unbind(topic); + } + } + + } else { + + object.unbind(topic,data); + } + } + } + + delete _subscribe_topics[topic]; + + return this; + }, + + /** + * Subscribes an object to particular topic with a handler. + * When the topic is published, this handler will be executed. + * + * Parameters: + * -topic- is the string name of the topic + * -handler- is a handler function and is of the form function(event, data), in which the 'this' refers to the element itself. + * handler can be a function or can be a string referring to a function previously registered using the $.subscribeHandler() function + * Note: returning 'false' from the handler will prevent subsequent handlers from being executed on this element during + * this call. + * -data- (optional) is additional data that is passed to the event handler as event.data when the topic is published + * + * Note: Unexpected behavior can occur when a script in a embedded page (page loaded in div,tab etc.) subscribes a handler for a topic using + * the jQuery subscribe ($.subscribe) or a no-id element but this subscribe plugin is not reloaded within that embedded page (for example, when + * script is included in containing page) . In this case, if the embedded page is reloaded without reloading the entire page (and plugin), the + * subscription could be made multiple times for the topic, which will call the handler multiple times each time the topic is published. + * Code has been added to prevent this when the subscription is made using the non-element subscribe ($.subscribe()), which assures that only one + * subscription is made for a topic for a given window/frame. To prevent this from happening for an element subscription ($elem.subscribe()), make + * sure that the element has an id attribute. + */ + subscribe : function(topic, handler, data) { + + if(this[0] && topic && handler) { + + this.createTopic(topic); + + if(this.attr('id')) { + + _subscribe_topics[topic].objects[this.attr('id')] = this; + + } else { + + //do not subscribe the same window/frame document multiple times, this causes unexpected behavior of executing embedded scripts multiple times + var noIdObjects = _subscribe_topics[topic].objects['__noId__']; + + if(this[0].nodeType == 9) { //if document is being bound (the case for non-element jQuery subscribing ($.subscribe) + + for ( var index in noIdObjects) { + + var noIdObject = noIdObjects[index]; + + if(noIdObject[0].nodeType == 9 && _subscribe_getDocumentWindow(this[0]).frameElement == _subscribe_getDocumentWindow(noIdObject[0]).frameElement ) { + + return this; + } + } + } + + var exists = false; + for(var i = 0; i < noIdObjects.length; i++){ + if(noIdObjects[i] == this){ + exists = true; + break; + } + } + + if(!exists) { + + _subscribe_topics[topic].objects['__noId__'].push(this); + } + } + + if(typeof(handler) == 'function') { + + this.bind(topic, data, handler); + + } else if(typeof(handler) == 'string' && typeof(_subscribe_handlers[handler]) == 'function') { + + this.bind(topic, data, _subscribe_handlers[handler]); + } + } + + return this; + }, + + /** + * Remove a subscription of an element to a topic. + * This will unbind stop all handlers from executing on this element when the topic + * is published + */ + unsubscribe : function(topic) { + + if(topic) { + + if(_subscribe_topics[topic]) { + + if(this.attr('id')) { + + var object = _subscribe_topics[topic].objects[this.attr('id')]; + + if(object) { + + delete _subscribe_topics[topic].objects[this.attr('id')]; + } + + } else { + + var noIdObjects = _subscribe_topics[topic].objects['__noId__']; + + for(var i = 0; i < noIdObjects.length; i++){ + + if(noIdObjects[i] == this){ + + subscribe_topics[topic].objects['__noId__'].splice(index,1); + break; + } + } + } + } + + this.unbind(topic); + } + + return this; + }, + + /** + * Publishes a topic (triggers handlers on all topic subscribers) + * This ends up calling any subscribed handlers which are functions of the form function (event, data) + * where: event - is a standard jQuery event object + * data - is the data parameter that was passed to this publish() method + * event.data - is the data parameter passed to the subscribe() function when this published topic was subscribed to + * event.target - is the dom element that subscribed to the event (or the document element if $.subscribe() was used) + * + * Parameters: + * -topic- is the string name of the topic + * -data- (optional) is additional data that is passed to the event handler 'data' parameter when the topic is published + * handler can be a function or can be a string referring to a function previously registered using the $.subscribeHandler() function + * -originalEvent- (optional) may be passed in a reference to an event which triggered this publishing. This will be passed as the + * 'originalEvent' field of the triggered event which will allow for controlling the propagation of higher level events + * from within the topic handler. In other words, this allows one to cancel execution of all subsequent handlers on the originalEvent + * for this element by return 'false' from a handler that is subscribed to the topic published here. This can be especially useful + * in conjunction with publishOnEvent(), where a topic is published when an event executes (such as a click) and we want our + * handler logic prevent additional topics from being published (For example if our topic displays a 'delete confirm' dialog on click and + * the user cancels, we may want to prevent subsequent topics bound to the original click event from being published). + */ + publish : function(topic, data, originalEvent) { + + if(topic) { + + this.createTopic(topic); + + //if an orginal event exists, need to modify the event object to prevent execution of all + //other handlers if the result of the handler is false (which calls stopPropagation()) + + var subscriberStopPropagation = function(){ + + this.isImmediatePropagationStopped = function(){ + return true; + }; + + (new $.Event).stopPropagation(); + + if(this.originalEvent) { + + this.originalEvent.isImmediatePropagationStopped = function(){ + return true; + }; + + this.originalEvent.stopPropagation = subscriberStopPropagation; + } + } + + var event = jQuery.Event(topic); + $.extend(event,{originalEvent: originalEvent, stopPropagation: subscriberStopPropagation}); + + for(i in _subscribe_topics[topic].objects) { + + var object = _subscribe_topics[topic].objects[i]; + + if($.isArray(object)) { // handle '__noId__' elements (if any) + + if(object.length > 0) { + + for(j in object) { + + object[j].trigger( event,data); + } + } + + } else { + + object.trigger( event,data); + } + } + + } + + return this; + }, + + /** + * Binds an objects event handler to a publish call + * + * Upon the event triggering, this ends up calling any subscribed handlers which are functions of the form function (event, data) + * where: event- is a standard jQuery event object + * event.data- is the data parameter passed to the subscribe() function when this published topic was subscribed to + * data- is the data parameter that was passed to this publishOnEvent() method + * Parameters: + * -event- is the string name of the event upon which to publish the topic + * -topic- is the string name of the topic to publish when the event occurs + * -data- (optional) is additional data which will be passed in to the publish() method ant hen available as the second ('data') + * parameter to the topic handler + */ + publishOnEvent : function(event, topic, data) { + + if(event && topic) { + + this.createTopic(topic); + + this.bind(event, data, function (e) { + + $(this).publish(topic, e.data, e); + }); + } + + return this; + } + }); + + /** + * Make publish(), createTopic() and destroyTopic() callable without an element context + * Often don't need a context to subscribe, publish, create or destroy a topic. + * We will call from the document context + */ + $.extend({ + + /** + * Subscribe an event handler to a topic without an element context + * + * Note: Caution about subscribing using same document to topic multiple time (maybe by loading subscribe script multiple times) + * + */ + subscribe : function(topic, handler, data) { + return $(window).subscribe(topic, handler, data); + + }, + + /** + * Unsubscribe an event handler for a topic without an element context + * + */ + unsubscribe : function(topic, handler, data) { + + return $(window).unsubscribe(topic, handler, data); + + }, + + /** + * Register a handler function which can then be referenced by name when calling subscribe() + */ + subscribeHandler: function(name, handler) { + + if(name && handler && typeof(handler) == "function") { + + _subscribe_handlers[name] = handler; + } + + return $(window); + }, + + publish: function(topic, data) { + + return $(window).publish(topic,data); + }, + + createTopic: function(topic) { + + return $(window).createTopic(topic); + }, + + destroyTopic: function(topic) { + + return $(window).destroyTopic(topic); + } + + }); + +})(jQuery); diff --git a/vendor/assets/javascripts/toggle.js b/vendor/assets/javascripts/toggle.js new file mode 100644 index 00000000..b8cdf3e4 --- /dev/null +++ b/vendor/assets/javascripts/toggle.js @@ -0,0 +1,120 @@ +/** + * + * Copyright (c) 2009 Tony Dewan (http://www.tonydewan.com/) + * Licensed under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + * Project home: + * http://www.tonydewan.com/code/checkToggle/ + * + */ + +(function($) { + /** + * Version 1.0 + * Replaces checkboxes with a toggle switch. + * usage: $("input[type='checkbox']").checkToggle(settings); + * + * @name checkToggle + * @type jquery + * @param Hash settings Settings + * @param String settings[on_label] Text used for the left-side (on) label. Defaults to "On" + * @param String settings[off_label] Text used for the right-side (off) label. Defaults to "Off" + * @param String settings[on_bg_color] Hex background color for On state + * @param String settings[off_bg_color] Hex background color for Off state + * @param String settings[skin_dir] Document relative (or absolute) path to the skin directory + * @param Bool settings[bypass_skin] Flags whether to bypass the inclusion of the skin.css file. Used if you've included the skin styles somewhere else already. + */ + + $.fn.checkToggle = function(settings) { + + settings = $.extend({ + on_label : 'Yes', + on_bg_color : '#8FE38D', + off_label : 'No', + off_bg_color: '#F8837C', + skin_dir : "skin/", + bypass_skin : false, + on_callback : function(el) {}, + off_callback : function(el) {} + }, settings); + + // FIXME (Didier Lafforgue) it works but it doesn't scale if we handle another locale + if (typeof I18nLocale != 'undefined' && I18nLocale == 'fr') { + settings.on_label = 'Oui'; + settings.off_label = 'Non'; + } + + // append the skin styles + // if(settings.bypass_skin == false){ + // $("head").append(''); + // } + + function toggle(element){ + + var checked = $(element).parent().parent().prev().attr("checked"); + + // if it's set to on + if(checked){ + + $(element).animate({marginLeft: '34px'}, 100, + + // callback function + function(){ + $(element).parent().prev().css("color","#cccccc"); + $(element).parent().next().css("color","#333333"); + $(element).parent().css("background-color", settings.off_bg_color); + $(element).parent().parent().prev().removeAttr("checked"); + $(element).removeClass("left").addClass("right"); + + if (typeof $.fn.publish != 'undefined') + $.publish('toggle.' + $(element).parent().parent().prev().attr('id') + '.unchecked', []); + + settings.off_callback(); + }); + + }else{ + + $(element).animate({marginLeft: '0em'}, 100, + + // callback function + function(){ + $(element).parent().prev().css("color","#333333"); + $(element).parent().next().css("color","#cccccc"); + $(element).parent().css("background-color", settings.on_bg_color); + $(element).parent().parent().prev().attr("checked","checked"); + $(element).removeClass("right").addClass("left"); + + if (typeof $.fn.publish != 'undefined') + $.publish('toggle.' + $(element).parent().parent().prev().attr('id') + '.checked', []); + + settings.on_callback(); + }); + + } + + }; + + return this.each(function () { + + if ($(this).hasClass('simple')) return; + + // hide the checkbox + $(this).css('display','none'); + + // insert the new toggle markup + if($(this).attr("checked") == true){ + $(this).after('