javascript for add/edit page (wip)
This commit is contained in:
parent
596eb78a55
commit
80a9a11c7b
@ -5,12 +5,15 @@ class Locomotive.Views.Pages.ListView extends Backbone.View
|
|||||||
el: '#pages-list'
|
el: '#pages-list'
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
console.log('render list view');
|
@make_foldable()
|
||||||
|
|
||||||
@make_sortable()
|
@make_sortable()
|
||||||
|
|
||||||
return @
|
return @
|
||||||
|
|
||||||
|
make_foldable: ->
|
||||||
|
@$('ul.folder img.toggler').toggleMe()
|
||||||
|
|
||||||
make_sortable: ->
|
make_sortable: ->
|
||||||
self = @
|
self = @
|
||||||
|
|
||||||
@ -37,24 +40,3 @@ class Locomotive.Views.Pages.ListView extends Backbone.View
|
|||||||
|
|
||||||
on_failed_sort: (data, status, xhr) ->
|
on_failed_sort: (data, status, xhr) ->
|
||||||
$.growl('error', xhr.getResponseHeader('Flash'));
|
$.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');
|
|
||||||
# }
|
|
||||||
# });
|
|
@ -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')
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
*= require_tree ../../../vendor/assets/stylesheets/jquery
|
*= require_tree ../../../vendor/assets/stylesheets/jquery
|
||||||
*= require ../../../vendor/assets/stylesheets/blueprint/screen.css
|
*= require ../../../vendor/assets/stylesheets/blueprint/screen.css
|
||||||
|
*= require ../../../vendor/assets/stylesheets/toggle.css
|
||||||
*= require formtastic
|
*= require formtastic
|
||||||
*= require_tree ./locomotive
|
*= require_tree ./locomotive
|
||||||
*/
|
*/
|
||||||
|
@ -156,6 +156,15 @@ ul.theme-assets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
li.page {
|
li.page {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
> .toggler {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
left: -18px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.inner {
|
.inner {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
@ -178,13 +187,6 @@ ul.theme-assets {
|
|||||||
background: transparent image-url("locomotive/list/item-left.png") no-repeat 0 0;
|
background: transparent image-url("locomotive/list/item-left.png") no-repeat 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.toggler {
|
|
||||||
position: absolute;
|
|
||||||
top: 9px;
|
|
||||||
left: -15px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@include hover-link;
|
@include hover-link;
|
||||||
|
|
||||||
|
@ -32,10 +32,6 @@ module Locomotive::BaseHelper
|
|||||||
end
|
end
|
||||||
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 = {})
|
def collection_to_js(collection, options = {})
|
||||||
js = collection.collect { |object| object.to_json }
|
js = collection.collect { |object| object.to_json }
|
||||||
|
|
||||||
|
@ -7,6 +7,10 @@ module Locomotive::PagesHelper
|
|||||||
end.join(' ')
|
end.join(' ')
|
||||||
end
|
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
|
def parent_pages_options
|
||||||
roots = current_site.pages.roots.where(:slug.ne => '404').and(:_id.ne => @page.id)
|
roots = current_site.pages.roots.where(:slug.ne => '404').and(:_id.ne => @page.id)
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
- with_children = !children.empty?
|
- with_children = !children.empty?
|
||||||
|
|
||||||
- if not page.index? and with_children
|
- if not page.index? and with_children
|
||||||
= admin_item_toggler(page)
|
= page_toggler(page)
|
||||||
|
|
||||||
.inner
|
.inner
|
||||||
|
|
||||||
|
@ -8,56 +8,36 @@ module Locomotive
|
|||||||
super || has_errors?
|
super || has_errors?
|
||||||
end
|
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
|
def to_json
|
||||||
|
|
||||||
|
|
||||||
if get?
|
if get?
|
||||||
display resource
|
display resource
|
||||||
elsif has_errors?
|
elsif has_errors?
|
||||||
display resource.errors, :status => :unprocessable_entity
|
with_flash_message(:error) do |message|
|
||||||
|
display resource.errors, :status => :unprocessable_entity
|
||||||
|
end
|
||||||
elsif post?
|
elsif post?
|
||||||
display resource, :status => :created, :location => api_location
|
with_flash_message do |message|
|
||||||
|
display resource, :location => api_location
|
||||||
|
end
|
||||||
elsif put?
|
elsif put?
|
||||||
with_flash_message(:notice) do |message|
|
with_flash_message do |message|
|
||||||
# puts "put ? yes #{controller.flash[:notice]} / #{resource.inspect}"
|
|
||||||
# controller.headers[:notice] => controller.flash[:notice]
|
|
||||||
puts "put ? yes, message = #{message}"
|
|
||||||
|
|
||||||
display resource, :status => :ok, :location => api_location
|
display resource, :status => :ok, :location => api_location
|
||||||
end
|
end
|
||||||
elsif has_empty_resource_definition?
|
elsif has_empty_resource_definition?
|
||||||
display empty_resource, :status => :ok
|
display empty_resource, :status => :ok
|
||||||
else
|
else
|
||||||
# head :ok
|
with_flash_message do
|
||||||
puts "youpi !!!"
|
head :ok
|
||||||
display :notice => controller.flash[:notice], :status => :ok
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
controller.flash.discard # reset flash messages !
|
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def with_flash_message(type)
|
def with_flash_message(type = :notice)
|
||||||
puts "@alert = #{@alert} / @notice = #{@notice}"
|
|
||||||
set_flash_message!
|
set_flash_message!
|
||||||
message = controller.flash[type]
|
message = controller.flash[type]
|
||||||
|
|
||||||
# controller.headers[:"flash-#{type.to_s.capitalize}"] = message
|
|
||||||
controller.headers[:flash] = message
|
controller.headers[:flash] = message
|
||||||
|
|
||||||
yield(message) if block_given?
|
yield(message) if block_given?
|
||||||
@ -65,24 +45,5 @@ module Locomotive
|
|||||||
controller.flash.discard # reset flash messages !
|
controller.flash.discard # reset flash messages !
|
||||||
end
|
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
|
||||||
end
|
end
|
96
vendor/assets/javascripts/cookies.js
vendored
Normal file
96
vendor/assets/javascripts/cookies.js
vendored
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
};
|
33
vendor/assets/javascripts/menu_toggler.js
vendored
Normal file
33
vendor/assets/javascripts/menu_toggler.js
vendored
Normal file
@ -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);
|
||||||
|
|
||||||
|
};
|
367
vendor/assets/javascripts/subscribe.js
vendored
Normal file
367
vendor/assets/javascripts/subscribe.js
vendored
Normal file
@ -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);
|
120
vendor/assets/javascripts/toggle.js
vendored
Normal file
120
vendor/assets/javascripts/toggle.js
vendored
Normal file
@ -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('<link type="text/css" rel="stylesheet" href="'+settings.skin_dir+'skin.css" media="screen" />');
|
||||||
|
// }
|
||||||
|
|
||||||
|
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('<div class="toggleSwitch"><span class="leftLabel">'+settings.on_label+'<\/span><div class="switchArea" style="background-color: '+settings.on_bg_color+'"><span class="switchHandle left" style="margin-left: 0em;"><\/span><\/div><span class="rightLabel" style="color:#cccccc">'+settings.off_label+'<\/span><\/div>');
|
||||||
|
}else{
|
||||||
|
$(this).after('<div class="toggleSwitch"><span class="leftLabel" style="color:#cccccc;">'+settings.on_label+'<\/span><div class="switchArea" style="background-color: '+settings.off_bg_color+'"><span class="switchHandle right" style="margin-left:34px"><\/span><\/div><span class="rightLabel">'+settings.off_label+'<\/span><\/div>');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind the switchHandle click events to the internal toggle function
|
||||||
|
$(this).next().find('div.switchArea').bind("click", function () {
|
||||||
|
toggle($(this).find('.switchHandle')); })
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
})(jQuery);
|
BIN
vendor/assets/javascripts/toggle/toggle_handle-bg.png
vendored
Normal file
BIN
vendor/assets/javascripts/toggle/toggle_handle-bg.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 355 B |
BIN
vendor/assets/javascripts/toggle/toggle_handle_left-bg.png
vendored
Normal file
BIN
vendor/assets/javascripts/toggle/toggle_handle_left-bg.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 698 B |
BIN
vendor/assets/javascripts/toggle/toggle_handle_right-bg.png
vendored
Normal file
BIN
vendor/assets/javascripts/toggle/toggle_handle_right-bg.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 727 B |
BIN
vendor/assets/javascripts/toggle/toggle_shadow-bg.png
vendored
Normal file
BIN
vendor/assets/javascripts/toggle/toggle_shadow-bg.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 344 B |
8
vendor/assets/stylesheets/toggle.css
vendored
8
vendor/assets/stylesheets/toggle.css
vendored
@ -16,7 +16,7 @@ div.toggleSwitch span.leftLabel, div.toggleSwitch span.rightLabel{
|
|||||||
|
|
||||||
div.toggleSwitch div.switchArea {
|
div.toggleSwitch div.switchArea {
|
||||||
float: left;
|
float: left;
|
||||||
background: transparent url(/assets/locomotive//plugins/toggle_shadow-bg.png) top left no-repeat;
|
background: transparent url("./toggle/toggle_shadow-bg.png") top left no-repeat;
|
||||||
width: 64px;
|
width: 64px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -25,7 +25,7 @@ div.toggleSwitch div.switchArea {
|
|||||||
div.toggleSwitch span.switchHandle {
|
div.toggleSwitch span.switchHandle {
|
||||||
display: block;
|
display: block;
|
||||||
background: #aaa;
|
background: #aaa;
|
||||||
background: transparent url(/assets/locomotive//plugins/toggle_handle-bg.png) top left no-repeat;
|
background: transparent url("./toggle/toggle_handle-bg.png") top left no-repeat;
|
||||||
width: 30px;
|
width: 30px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -34,9 +34,9 @@ div.toggleSwitch span.switchHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
div.toggleSwitch span.switchHandle.left {
|
div.toggleSwitch span.switchHandle.left {
|
||||||
background-image: url(/assets/locomotive//plugins/toggle_handle_left-bg.png);
|
background-image: url("./toggle/toggle_handle_left-bg.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
div.toggleSwitch span.switchHandle.right {
|
div.toggleSwitch span.switchHandle.right {
|
||||||
background-image: url(/assets/locomotive//plugins/toggle_handle_right-bg.png);
|
background-image: url("./toggle/toggle_handle_right-bg.png");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user