Fixed tests by getting rid of valid_session
6
Gemfile
@@ -22,11 +22,12 @@ group :assets do
|
||||
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
||||
# long term, we'll probably want node.js for performance, but this will do for now as it's easier for new people to install
|
||||
gem 'therubyracer', :platforms => :ruby
|
||||
gem "less-rails"
|
||||
gem "twitter-bootstrap-rails"
|
||||
|
||||
gem 'uglifier', '>= 1.0.3'
|
||||
|
||||
gem 'compass-rails', '~> 1.0.3'
|
||||
gem 'zurb-foundation', '~> 3.0.9'
|
||||
end
|
||||
|
||||
gem 'jquery-rails'
|
||||
@@ -48,7 +49,8 @@ gem 'capistrano-ext'
|
||||
# To use debugger
|
||||
# gem 'debugger'
|
||||
|
||||
# GROWSTUFF ADDITIONS BELOW HERE
|
||||
# Markdown formatting for updates etc
|
||||
gem 'bluecloth'
|
||||
|
||||
# user signup/login/etc
|
||||
gem 'devise'
|
||||
|
||||
41
Gemfile.lock
@@ -30,9 +30,10 @@ GEM
|
||||
multi_json (~> 1.0)
|
||||
arel (3.0.2)
|
||||
bcrypt-ruby (3.0.1)
|
||||
bluecloth (2.2.0)
|
||||
builder (3.0.4)
|
||||
cape (1.5.0)
|
||||
capistrano (2.13.4)
|
||||
capistrano (2.13.5)
|
||||
highline
|
||||
net-scp (>= 1.0.0)
|
||||
net-sftp (>= 2.0.0)
|
||||
@@ -48,13 +49,14 @@ GEM
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.4.0)
|
||||
commonjs (0.2.6)
|
||||
compass (0.12.2)
|
||||
chunky_png (~> 1.2)
|
||||
fssm (>= 0.2.7)
|
||||
sass (~> 3.1)
|
||||
compass-rails (1.0.3)
|
||||
compass (>= 0.12.2, < 0.14)
|
||||
daemon_controller (1.0.0)
|
||||
daemon_controller (1.1.0)
|
||||
devise (2.1.2)
|
||||
bcrypt-ruby (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
@@ -65,7 +67,7 @@ GEM
|
||||
execjs (1.4.0)
|
||||
multi_json (~> 1.0)
|
||||
fastthread (1.0.7)
|
||||
friendly_id (4.0.8)
|
||||
friendly_id (4.0.9)
|
||||
fssm (0.2.9)
|
||||
haml (3.1.7)
|
||||
haml-rails (0.3.5)
|
||||
@@ -81,16 +83,18 @@ GEM
|
||||
railties (>= 3.1.0, < 5.0)
|
||||
thor (~> 0.14)
|
||||
json (1.7.5)
|
||||
less (2.2.2)
|
||||
commonjs (~> 0.2.6)
|
||||
less-rails (2.2.6)
|
||||
actionpack (>= 3.1)
|
||||
less (~> 2.2.0)
|
||||
libv8 (3.3.10.4)
|
||||
mail (2.4.4)
|
||||
i18n (>= 0.4.0)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
mime-types (1.19)
|
||||
modular-scale (1.0.2)
|
||||
compass (>= 0.11.5)
|
||||
sassy-math (>= 1.2)
|
||||
multi_json (1.3.6)
|
||||
multi_json (1.3.7)
|
||||
net-scp (1.0.4)
|
||||
net-ssh (>= 1.99.1)
|
||||
net-sftp (2.0.5)
|
||||
@@ -100,7 +104,7 @@ GEM
|
||||
net-ssh (>= 1.99.1)
|
||||
nokogiri (1.5.5)
|
||||
orm_adapter (0.4.0)
|
||||
passenger (3.0.17)
|
||||
passenger (3.0.18)
|
||||
daemon_controller (>= 1.0.0)
|
||||
fastthread (>= 1.0.1)
|
||||
rack
|
||||
@@ -147,13 +151,11 @@ GEM
|
||||
rspec (~> 2.11.0)
|
||||
rvm-capistrano (1.2.7)
|
||||
capistrano (>= 2.0.0)
|
||||
sass (3.2.1)
|
||||
sass (3.2.2)
|
||||
sass-rails (3.2.5)
|
||||
railties (~> 3.2.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3)
|
||||
sassy-math (1.2)
|
||||
compass (~> 0.11)
|
||||
spork (0.9.2)
|
||||
sprockets (2.1.3)
|
||||
hike (~> 1.2)
|
||||
@@ -164,10 +166,14 @@ GEM
|
||||
libv8 (~> 3.3.10)
|
||||
thor (0.16.0)
|
||||
tilt (1.3.3)
|
||||
treetop (1.4.11)
|
||||
treetop (1.4.12)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.33)
|
||||
twitter-bootstrap-rails (2.1.6)
|
||||
actionpack (>= 3.1)
|
||||
execjs
|
||||
railties (>= 3.1)
|
||||
tzinfo (0.3.35)
|
||||
uglifier (1.3.0)
|
||||
execjs (>= 0.3.0)
|
||||
multi_json (~> 1.0, >= 1.0.2)
|
||||
@@ -178,16 +184,12 @@ GEM
|
||||
nokogiri (>= 1.2.0)
|
||||
rack (>= 1.0)
|
||||
rack-test (>= 0.5.3)
|
||||
zurb-foundation (3.0.9)
|
||||
compass (>= 0.12.2)
|
||||
modular-scale (>= 1.0.2)
|
||||
rake
|
||||
sass (>= 3.2.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
bluecloth
|
||||
bundler (>= 1.1.5)
|
||||
cape
|
||||
capistrano
|
||||
@@ -200,6 +202,7 @@ DEPENDENCIES
|
||||
haml
|
||||
haml-rails
|
||||
jquery-rails
|
||||
less-rails
|
||||
passenger
|
||||
pg
|
||||
rails (= 3.2.8)
|
||||
@@ -210,7 +213,7 @@ DEPENDENCIES
|
||||
spork (~> 0.9.0.rc)
|
||||
sqlite3
|
||||
therubyracer
|
||||
twitter-bootstrap-rails
|
||||
uglifier (>= 1.0.3)
|
||||
watchr
|
||||
webrat
|
||||
zurb-foundation (~> 3.0.9)
|
||||
|
||||
|
Before Width: | Height: | Size: 657 B |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 522 B |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 526 B |
|
Before Width: | Height: | Size: 288 B |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 536 B |
|
Before Width: | Height: | Size: 526 B |
@@ -12,7 +12,6 @@
|
||||
//
|
||||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require foundation
|
||||
//= require foundation/app
|
||||
//= require twitter/bootstrap
|
||||
//= require_tree .
|
||||
|
||||
|
||||
4
app/assets/javascripts/bootstrap.js.coffee
Normal file
@@ -0,0 +1,4 @@
|
||||
jQuery ->
|
||||
$("a[rel=popover]").popover()
|
||||
$(".tooltip").tooltip()
|
||||
$("a[rel=tooltip]").tooltip()
|
||||
@@ -1,22 +0,0 @@
|
||||
(function ($) {
|
||||
|
||||
$(function(){
|
||||
$(document).foundationAlerts();
|
||||
$(document).foundationButtons();
|
||||
$(document).foundationAccordion();
|
||||
$(document).foundationNavigation();
|
||||
$(document).foundationCustomForms();
|
||||
$(document).foundationMediaQueryViewer();
|
||||
$(document).foundationTabs({callback:$.foundation.customForms.appendCustomMarkup});
|
||||
|
||||
$(document).tooltips();
|
||||
$('input, textarea').placeholder();
|
||||
|
||||
// UNCOMMENT THE LINE YOU WANT BELOW IF YOU WANT IE8 SUPPORT AND ARE USING .block-grids
|
||||
// $('.block-grid.two-up>li:nth-child(2n+1)').css({clear: 'both'});
|
||||
// $('.block-grid.three-up>li:nth-child(3n+1)').css({clear: 'both'});
|
||||
// $('.block-grid.four-up>li:nth-child(4n+1)').css({clear: 'both'});
|
||||
// $('.block-grid.five-up>li:nth-child(5n+1)').css({clear: 'both'});
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,15 +0,0 @@
|
||||
(function ($){
|
||||
|
||||
$.fn.foundationAccordion = function (options) {
|
||||
|
||||
$(document).on('click.fndtn', '.accordion li', function () {
|
||||
var flyout = $(this).children('.content').first();
|
||||
$('.accordion .content').not(flyout).hide().parent('li').removeClass('active');
|
||||
flyout.show(0, function () {
|
||||
flyout.parent('li').addClass('active');
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
})( jQuery );
|
||||
@@ -1,19 +0,0 @@
|
||||
(function ($) {
|
||||
|
||||
$.fn.foundationAlerts = function (options) {
|
||||
var settings = $.extend({
|
||||
callback: $.noop
|
||||
}, options);
|
||||
|
||||
$(document).on("click", ".alert-box a.close", function (event) {
|
||||
event.preventDefault();
|
||||
$(this).closest(".alert-box").fadeOut(function (event) {
|
||||
$(this).remove();
|
||||
// Do something else after the alert closes
|
||||
settings.callback();
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,49 +0,0 @@
|
||||
(function ($) {
|
||||
|
||||
$.fn.foundationButtons = function(options) {
|
||||
// Prevent event propagation on disabled buttons
|
||||
$(document).on('click.fndtn', '.button.disabled', function (e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$('.button.dropdown > ul', this).addClass('no-hover');
|
||||
|
||||
$(document).on('click.fndtn', '.button.dropdown, .button.dropdown.split span', function (e) {
|
||||
// Stops further propagation of the event up the DOM tree when clicked on the button.
|
||||
// Events fired by its descendants are not being blocked.
|
||||
if (e.target === this) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
$(document).on('click.fndtn', '.button.dropdown.split span', function (e) {
|
||||
e.preventDefault();
|
||||
$('.button.dropdown', this).not($(this).parent()).children('ul').removeClass('show-dropdown');
|
||||
$(this).siblings('ul').toggleClass('show-dropdown');
|
||||
});
|
||||
$(document).on('click.fndtn', '.button.dropdown:not(.split)', function (e) {
|
||||
$('.button.dropdown', this).not(this).children('ul').removeClass('show-dropdown');
|
||||
$(this).children('ul').toggleClass('show-dropdown');
|
||||
});
|
||||
$(document).on('click.fndtn', 'body, html', function () {
|
||||
$('.button.dropdown ul').removeClass('show-dropdown');
|
||||
});
|
||||
|
||||
// Positioning the Flyout List
|
||||
var normalButtonHeight = $('.button.dropdown:not(.large):not(.small):not(.tiny)', this).outerHeight() - 1,
|
||||
largeButtonHeight = $('.button.large.dropdown', this).outerHeight() - 1,
|
||||
smallButtonHeight = $('.button.small.dropdown', this).outerHeight() - 1,
|
||||
tinyButtonHeight = $('.button.tiny.dropdown', this).outerHeight() - 1;
|
||||
|
||||
$('.button.dropdown:not(.large):not(.small):not(.tiny) > ul', this).css('top', normalButtonHeight);
|
||||
$('.button.dropdown.large > ul', this).css('top', largeButtonHeight);
|
||||
$('.button.dropdown.small > ul', this).css('top', smallButtonHeight);
|
||||
$('.button.dropdown.tiny > ul', this).css('top', tinyButtonHeight);
|
||||
|
||||
$('.button.dropdown.up:not(.large):not(.small):not(.tiny) > ul', this).css('top', 'auto').css('bottom', normalButtonHeight - 2);
|
||||
$('.button.dropdown.up.large > ul', this).css('top', 'auto').css('bottom', largeButtonHeight - 2);
|
||||
$('.button.dropdown.up.small > ul', this).css('top', 'auto').css('bottom', smallButtonHeight - 2);
|
||||
$('.button.dropdown.up.tiny > ul', this).css('top', 'auto').css('bottom', tinyButtonHeight - 2);
|
||||
|
||||
};
|
||||
|
||||
})( jQuery );
|
||||
@@ -1,483 +0,0 @@
|
||||
/*
|
||||
* jQuery Custom Forms Plugin 1.0
|
||||
* www.ZURB.com
|
||||
* Copyright 2010, ZURB
|
||||
* Free to use under the MIT license.
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
|
||||
(function( $ ){
|
||||
|
||||
/**
|
||||
* Helper object used to quickly adjust all hidden parent element's, display and visibility properties.
|
||||
* This is currently used for the custom drop downs. When the dropdowns are contained within a reveal modal
|
||||
* we cannot accurately determine the list-item elements width property, since the modal's display property is set
|
||||
* to 'none'.
|
||||
*
|
||||
* This object will help us work around that problem.
|
||||
*
|
||||
* NOTE: This could also be plugin.
|
||||
*
|
||||
* @function hiddenFix
|
||||
*/
|
||||
var hiddenFix = function() {
|
||||
|
||||
return {
|
||||
/**
|
||||
* Sets all hidden parent elements and self to visibile.
|
||||
*
|
||||
* @method adjust
|
||||
* @param {jQuery Object} $child
|
||||
*/
|
||||
|
||||
// We'll use this to temporarily store style properties.
|
||||
tmp : [],
|
||||
|
||||
// We'll use this to set hidden parent elements.
|
||||
hidden : null,
|
||||
|
||||
adjust : function( $child ) {
|
||||
// Internal reference.
|
||||
var _self = this;
|
||||
|
||||
// Set all hidden parent elements, including this element.
|
||||
_self.hidden = $child.parents().andSelf().filter( ":hidden" );
|
||||
|
||||
// Loop through all hidden elements.
|
||||
_self.hidden.each( function() {
|
||||
|
||||
// Cache the element.
|
||||
var $elem = $( this );
|
||||
|
||||
// Store the style attribute.
|
||||
// Undefined if element doesn't have a style attribute.
|
||||
_self.tmp.push( $elem.attr( 'style' ) );
|
||||
|
||||
// Set the element's display property to block,
|
||||
// but ensure it's visibility is hidden.
|
||||
$elem.css( { 'visibility' : 'hidden', 'display' : 'block' } );
|
||||
});
|
||||
|
||||
}, // end adjust
|
||||
|
||||
/**
|
||||
* Resets the elements previous state.
|
||||
*
|
||||
* @method reset
|
||||
*/
|
||||
reset : function() {
|
||||
// Internal reference.
|
||||
var _self = this;
|
||||
// Loop through our hidden element collection.
|
||||
_self.hidden.each( function( i ) {
|
||||
// Cache this element.
|
||||
var $elem = $( this ),
|
||||
_tmp = _self.tmp[ i ]; // Get the stored 'style' value for this element.
|
||||
|
||||
// If the stored value is undefined.
|
||||
if( _tmp === undefined )
|
||||
// Remove the style attribute.
|
||||
$elem.removeAttr( 'style' );
|
||||
else
|
||||
// Otherwise, reset the element style attribute.
|
||||
$elem.attr( 'style', _tmp );
|
||||
|
||||
});
|
||||
// Reset the tmp array.
|
||||
_self.tmp = [];
|
||||
// Reset the hidden elements variable.
|
||||
_self.hidden = null;
|
||||
|
||||
} // end reset
|
||||
|
||||
}; // end return
|
||||
|
||||
};
|
||||
|
||||
jQuery.foundation = jQuery.foundation || {};
|
||||
jQuery.foundation.customForms = jQuery.foundation.customForms || {};
|
||||
|
||||
$.foundation.customForms.appendCustomMarkup = function ( options ) {
|
||||
|
||||
var defaults = {
|
||||
disable_class: "js-disable-custom"
|
||||
};
|
||||
|
||||
options = $.extend( defaults, options );
|
||||
|
||||
function appendCustomMarkup(idx, sel) {
|
||||
var $this = $(sel).hide(),
|
||||
type = $this.attr('type'),
|
||||
$span = $this.next('span.custom.' + type);
|
||||
|
||||
if ($span.length === 0) {
|
||||
$span = $('<span class="custom ' + type + '"></span>').insertAfter($this);
|
||||
}
|
||||
|
||||
$span.toggleClass('checked', $this.is(':checked'));
|
||||
$span.toggleClass('disabled', $this.is(':disabled'));
|
||||
}
|
||||
|
||||
function appendCustomSelect(idx, sel) {
|
||||
var hiddenFixObj = hiddenFix();
|
||||
//
|
||||
// jQueryify the <select> element and cache it.
|
||||
//
|
||||
var $this = $( sel ),
|
||||
//
|
||||
// Find the custom drop down element.
|
||||
//
|
||||
$customSelect = $this.next( 'div.custom.dropdown' ),
|
||||
//
|
||||
// Find the custom select element within the custom drop down.
|
||||
//
|
||||
$customList = $customSelect.find( 'ul' ),
|
||||
//
|
||||
// Find the custom a.current element.
|
||||
//
|
||||
$selectCurrent = $customSelect.find( ".current" ),
|
||||
//
|
||||
// Find the custom a.selector element (the drop-down icon).
|
||||
//
|
||||
$selector = $customSelect.find( ".selector" ),
|
||||
//
|
||||
// Get the <options> from the <select> element.
|
||||
//
|
||||
$options = $this.find( 'option' ),
|
||||
//
|
||||
// Filter down the selected options
|
||||
//
|
||||
$selectedOption = $options.filter( ':selected' ),
|
||||
//
|
||||
// Initial max width.
|
||||
//
|
||||
maxWidth = 0,
|
||||
//
|
||||
// We'll use this variable to create the <li> elements for our custom select.
|
||||
//
|
||||
liHtml = '',
|
||||
//
|
||||
// We'll use this to cache the created <li> elements within our custom select.
|
||||
//
|
||||
$listItems
|
||||
;
|
||||
var $currentSelect = false;
|
||||
//
|
||||
// Should we not create a custom list?
|
||||
//
|
||||
if ( $this.hasClass( 'no-custom' ) ) return;
|
||||
|
||||
//
|
||||
// Did we not create a custom select element yet?
|
||||
//
|
||||
if ( $customSelect.length === 0 ) {
|
||||
//
|
||||
// Let's create our custom select element!
|
||||
//
|
||||
|
||||
//
|
||||
// Determine what select size to use.
|
||||
//
|
||||
var customSelectSize = $this.hasClass( 'small' ) ? 'small' :
|
||||
$this.hasClass( 'medium' ) ? 'medium' :
|
||||
$this.hasClass( 'large' ) ? 'large' :
|
||||
$this.hasClass( 'expand' ) ? 'expand' : ''
|
||||
;
|
||||
//
|
||||
// Build our custom list.
|
||||
//
|
||||
$customSelect = $('<div class="' + ['custom', 'dropdown', customSelectSize ].join( ' ' ) + '"><a href="#" class="selector"></a><ul /></div>"');
|
||||
//
|
||||
// Grab the selector element
|
||||
//
|
||||
$selector = $customSelect.find( ".selector" );
|
||||
//
|
||||
// Grab the unordered list element from the custom list.
|
||||
//
|
||||
$customList = $customSelect.find( "ul" );
|
||||
//
|
||||
// Build our <li> elements.
|
||||
//
|
||||
liHtml = $options.map( function() { return "<li>" + $( this ).html() + "</li>"; } ).get().join( '' );
|
||||
//
|
||||
// Append our <li> elements to the custom list (<ul>).
|
||||
//
|
||||
$customList.append( liHtml );
|
||||
//
|
||||
// Insert the the currently selected list item before all other elements.
|
||||
// Then, find the element and assign it to $currentSelect.
|
||||
//
|
||||
|
||||
$currentSelect = $customSelect.prepend( '<a href="#" class="current">' + $selectedOption.html() + '</a>' ).find( ".current" );
|
||||
//
|
||||
// Add the custom select element after the <select> element.
|
||||
//
|
||||
$this.after( $customSelect )
|
||||
//
|
||||
//then hide the <select> element.
|
||||
//
|
||||
.hide();
|
||||
|
||||
} else {
|
||||
//
|
||||
// Create our list item <li> elements.
|
||||
//
|
||||
liHtml = $options.map( function() { return "<li>" + $( this ).html() + "</li>"; } ).get().join( '' );
|
||||
//
|
||||
// Refresh the ul with options from the select in case the supplied markup doesn't match.
|
||||
// Clear what's currently in the <ul> element.
|
||||
//
|
||||
$customList.html( '' )
|
||||
//
|
||||
// Populate the list item <li> elements.
|
||||
//
|
||||
.append( liHtml );
|
||||
|
||||
} // endif $customSelect.length === 0
|
||||
|
||||
//
|
||||
// Determine whether or not the custom select element should be disabled.
|
||||
//
|
||||
$customSelect.toggleClass( 'disabled', $this.is( ':disabled' ) );
|
||||
//
|
||||
// Cache our List item elements.
|
||||
//
|
||||
$listItems = $customList.find( 'li' );
|
||||
|
||||
//
|
||||
// Determine which elements to select in our custom list.
|
||||
//
|
||||
$options.each( function ( index ) {
|
||||
|
||||
if ( this.selected ) {
|
||||
//
|
||||
// Add the selected class to the current li element
|
||||
//
|
||||
$listItems.eq( index ).addClass( 'selected' );
|
||||
//
|
||||
// Update the current element with the option value.
|
||||
//
|
||||
if ($currentSelect) {
|
||||
$currentSelect.html( $( this ).html() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
//
|
||||
// Update the custom <ul> list width property.
|
||||
//
|
||||
$customList.css( 'width', 'inherit' );
|
||||
//
|
||||
// Set the custom select width property.
|
||||
//
|
||||
$customSelect.css( 'width', 'inherit' );
|
||||
|
||||
//
|
||||
// If we're not specifying a predetermined form size.
|
||||
//
|
||||
if ( !$customSelect.is( '.small, .medium, .large, .expand' ) ) {
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// This is a work-around for when elements are contained within hidden parents.
|
||||
// For example, when custom-form elements are inside of a hidden reveal modal.
|
||||
//
|
||||
// We need to display the current custom list element as well as hidden parent elements
|
||||
// in order to properly calculate the list item element's width property.
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Show the drop down.
|
||||
// This should ensure that the list item's width values are properly calculated.
|
||||
//
|
||||
$customSelect.addClass( 'open' );
|
||||
//
|
||||
// Quickly, display all parent elements.
|
||||
// This should help us calcualate the width of the list item's within the drop down.
|
||||
//
|
||||
hiddenFixObj.adjust( $customList );
|
||||
//
|
||||
// Grab the largest list item width.
|
||||
//
|
||||
maxWidth = ( $listItems.outerWidth() > maxWidth ) ? $listItems.outerWidth() : maxWidth;
|
||||
//
|
||||
// Okay, now reset the parent elements.
|
||||
// This will hide them again.
|
||||
//
|
||||
hiddenFixObj.reset();
|
||||
//
|
||||
// Finally, hide the drop down.
|
||||
//
|
||||
$customSelect.removeClass( 'open' );
|
||||
//
|
||||
// Set the custom list width.
|
||||
//
|
||||
$customSelect.width( maxWidth + 18);
|
||||
//
|
||||
// Set the custom list element (<ul />) width.
|
||||
//
|
||||
$customList.width( maxWidth + 16 );
|
||||
|
||||
} // endif
|
||||
|
||||
}
|
||||
|
||||
$('form.custom input:radio[data-customforms!=disabled]').each(appendCustomMarkup);
|
||||
$('form.custom input:checkbox[data-customforms!=disabled]').each(appendCustomMarkup);
|
||||
$('form.custom select[data-customforms!=disabled]').each(appendCustomSelect);
|
||||
};
|
||||
|
||||
var refreshCustomSelect = function($select) {
|
||||
var maxWidth = 0,
|
||||
$customSelect = $select.next();
|
||||
$options = $select.find('option');
|
||||
$customSelect.find('ul').html('');
|
||||
|
||||
$options.each(function () {
|
||||
$li = $('<li>' + $(this).html() + '</li>');
|
||||
$customSelect.find('ul').append($li);
|
||||
});
|
||||
|
||||
// re-populate
|
||||
$options.each(function (index) {
|
||||
if (this.selected) {
|
||||
$customSelect.find('li').eq(index).addClass('selected');
|
||||
$customSelect.find('.current').html($(this).html());
|
||||
}
|
||||
});
|
||||
|
||||
// fix width
|
||||
$customSelect.removeAttr('style')
|
||||
.find('ul').removeAttr('style');
|
||||
$customSelect.find('li').each(function () {
|
||||
$customSelect.addClass('open');
|
||||
if ($(this).outerWidth() > maxWidth) {
|
||||
maxWidth = $(this).outerWidth();
|
||||
}
|
||||
$customSelect.removeClass('open');
|
||||
});
|
||||
$customSelect.css('width', maxWidth + 18 + 'px');
|
||||
$customSelect.find('ul').css('width', maxWidth + 16 + 'px');
|
||||
|
||||
};
|
||||
|
||||
var toggleCheckbox = function($element) {
|
||||
var $input = $element.prev(),
|
||||
input = $input[0];
|
||||
|
||||
if (false === $input.is(':disabled')) {
|
||||
input.checked = ((input.checked) ? false : true);
|
||||
$element.toggleClass('checked');
|
||||
}
|
||||
};
|
||||
|
||||
var toggleRadio = function($element) {
|
||||
var $input = $element.prev(),
|
||||
input = $input[0];
|
||||
|
||||
if (false === $input.is(':disabled')) {
|
||||
$('input:radio[name="' + $input.attr('name') + '"]').each(function () {
|
||||
$(this).next().removeClass('checked');
|
||||
});
|
||||
input.checked = ((input.checked) ? false : true);
|
||||
$element.toggleClass('checked');
|
||||
|
||||
$input.trigger('change');
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('click', 'form.custom span.custom.checkbox', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
toggleCheckbox($(this));
|
||||
});
|
||||
|
||||
$(document).on('click', 'form.custom span.custom.radio', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
toggleRadio($(this));
|
||||
});
|
||||
|
||||
$(document).on('change', 'form.custom select[data-customforms!=disabled]', function (event) {
|
||||
refreshCustomSelect($(this));
|
||||
});
|
||||
|
||||
$(document).on('click', 'form.custom label', function (event) {
|
||||
var $associatedElement = $('#' + $(this).attr('for')),
|
||||
$customCheckbox,
|
||||
$customRadio;
|
||||
if ($associatedElement.length !== 0) {
|
||||
if ($associatedElement.attr('type') === 'checkbox') {
|
||||
event.preventDefault();
|
||||
$customCheckbox = $(this).find('span.custom.checkbox');
|
||||
toggleCheckbox($customCheckbox);
|
||||
} else if ($associatedElement.attr('type') === 'radio') {
|
||||
event.preventDefault();
|
||||
$customRadio = $(this).find('span.custom.radio');
|
||||
toggleRadio($customRadio);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('click', 'form.custom div.custom.dropdown a.current, form.custom div.custom.dropdown a.selector', function (event) {
|
||||
var $this = $(this),
|
||||
$dropdown = $this.closest('div.custom.dropdown'),
|
||||
$select = $dropdown.prev();
|
||||
|
||||
event.preventDefault();
|
||||
$('div.dropdown').removeClass('open');
|
||||
|
||||
if (false === $select.is(':disabled')) {
|
||||
$dropdown.toggleClass('open');
|
||||
|
||||
if ($dropdown.hasClass('open')) {
|
||||
$(document).bind('click.customdropdown', function (event) {
|
||||
$dropdown.removeClass('open');
|
||||
$(document).unbind('.customdropdown');
|
||||
});
|
||||
} else {
|
||||
$(document).unbind('.customdropdown');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('click', 'form.custom div.custom.dropdown li', function (event) {
|
||||
var $this = $(this),
|
||||
$customDropdown = $this.closest('div.custom.dropdown'),
|
||||
$select = $customDropdown.prev(),
|
||||
selectedIndex = 0;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
$('div.dropdown').removeClass('open');
|
||||
|
||||
$this
|
||||
.closest('ul')
|
||||
.find('li')
|
||||
.removeClass('selected');
|
||||
$this.addClass('selected');
|
||||
|
||||
$customDropdown
|
||||
.removeClass('open')
|
||||
.find('a.current')
|
||||
.html($this.html());
|
||||
|
||||
$this.closest('ul').find('li').each(function (index) {
|
||||
if ($this[0] == this) {
|
||||
selectedIndex = index;
|
||||
}
|
||||
|
||||
});
|
||||
$select[0].selectedIndex = selectedIndex;
|
||||
|
||||
$select.trigger('change');
|
||||
});
|
||||
|
||||
|
||||
$.fn.foundationCustomForms = $.foundation.customForms.appendCustomMarkup;
|
||||
|
||||
})( jQuery );
|
||||
@@ -1,25 +0,0 @@
|
||||
(function ($) {
|
||||
|
||||
$.fn.foundationMediaQueryViewer = function (options) {
|
||||
|
||||
var settings = $.extend(options,{toggleKey:77}); // // Press 'M'
|
||||
$(document).on("keyup.mediaQueryViewer", ":input", function(e){
|
||||
if (e.which === settings.toggleKey) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
$(document).on("keyup.mediaQueryViewer", function(e) {
|
||||
var $mqViewer = $('#fqv');
|
||||
|
||||
if (e.which === settings.toggleKey) {
|
||||
if ($mqViewer.length > 0) {
|
||||
$mqViewer.remove();
|
||||
} else {
|
||||
$('body').prepend('<div id="fqv" style="position:fixed;top:4px;left:4px;z-index:999;color:#fff;"><p style="font-size:12px;background:rgba(0,0,0,0.75);padding:5px;margin-bottom:1px;line-height:1.2;"><span class="left">Media:</span> <span style="font-weight:bold;" class="show-for-xlarge">Extra Large</span><span style="font-weight:bold;" class="show-for-large">Large</span><span style="font-weight:bold;" class="show-for-medium">Medium</span><span style="font-weight:bold;" class="show-for-small">Small</span><span style="font-weight:bold;" class="show-for-landscape">Landscape</span><span style="font-weight:bold;" class="show-for-portrait">Portrait</span><span style="font-weight:bold;" class="show-for-touch">Touch</span></p></div>');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,30 +0,0 @@
|
||||
(function ($){
|
||||
|
||||
$.fn.foundationNavigation = function (options) {
|
||||
|
||||
var lockNavBar = false;
|
||||
// Windows Phone, sadly, does not register touch events :(
|
||||
if (Modernizr.touch || navigator.userAgent.match(/Windows Phone/i)) {
|
||||
$(document).on('click.fndtn touchstart.fndtn', '.nav-bar a.flyout-toggle', function (e) {
|
||||
e.preventDefault();
|
||||
var flyout = $(this).siblings('.flyout').first();
|
||||
if (lockNavBar === false) {
|
||||
$('.nav-bar .flyout').not(flyout).slideUp(500);
|
||||
flyout.slideToggle(500, function () {
|
||||
lockNavBar = false;
|
||||
});
|
||||
}
|
||||
lockNavBar = true;
|
||||
});
|
||||
$('.nav-bar>li.has-flyout', this).addClass('is-touch');
|
||||
} else {
|
||||
$('.nav-bar>li.has-flyout', this).hover(function () {
|
||||
$(this).children('.flyout').show();
|
||||
}, function () {
|
||||
$(this).children('.flyout').hide();
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
})( jQuery );
|
||||
@@ -1,634 +0,0 @@
|
||||
/*
|
||||
* jQuery Orbit Plugin 1.4.0
|
||||
* www.ZURB.com/playground
|
||||
* Copyright 2010, ZURB
|
||||
* Free to use under the MIT license.
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
|
||||
|
||||
(function ($) {
|
||||
'use strict';
|
||||
$.fn.findFirstImage = function () {
|
||||
return this.first()
|
||||
.find('img')
|
||||
.andSelf().filter('img')
|
||||
.first();
|
||||
};
|
||||
|
||||
var ORBIT = {
|
||||
|
||||
defaults: {
|
||||
animation: 'horizontal-push', // fade, horizontal-slide, vertical-slide, horizontal-push, vertical-push
|
||||
animationSpeed: 600, // how fast animtions are
|
||||
timer: true, // true or false to have the timer
|
||||
advanceSpeed: 4000, // if timer is enabled, time between transitions
|
||||
pauseOnHover: false, // if you hover pauses the slider
|
||||
startClockOnMouseOut: false, // if clock should start on MouseOut
|
||||
startClockOnMouseOutAfter: 1000, // how long after MouseOut should the timer start again
|
||||
directionalNav: true, // manual advancing directional navs
|
||||
directionalNavRightText: 'Right', // text of right directional element for accessibility
|
||||
directionalNavLeftText: 'Left', // text of left directional element for accessibility
|
||||
captions: true, // do you want captions?
|
||||
captionAnimation: 'fade', // fade, slideOpen, none
|
||||
captionAnimationSpeed: 600, // if so how quickly should they animate in
|
||||
resetTimerOnClick: false, // true resets the timer instead of pausing slideshow progress on manual navigation
|
||||
bullets: false, // true or false to activate the bullet navigation
|
||||
bulletThumbs: false, // thumbnails for the bullets
|
||||
bulletThumbLocation: '', // location from this file where thumbs will be
|
||||
afterSlideChange: $.noop, // empty function
|
||||
afterLoadComplete: $.noop, //callback to execute after everything has been loaded
|
||||
fluid: true,
|
||||
centerBullets: true // center bullet nav with js, turn this off if you want to position the bullet nav manually
|
||||
},
|
||||
|
||||
activeSlide: 0,
|
||||
numberSlides: 0,
|
||||
orbitWidth: null,
|
||||
orbitHeight: null,
|
||||
locked: null,
|
||||
timerRunning: null,
|
||||
degrees: 0,
|
||||
wrapperHTML: '<div class="orbit-wrapper" />',
|
||||
timerHTML: '<div class="timer"><span class="mask"><span class="rotator"></span></span><span class="pause"></span></div>',
|
||||
captionHTML: '<div class="orbit-caption"></div>',
|
||||
directionalNavHTML: '<div class="slider-nav"><span class="right"></span><span class="left"></span></div>',
|
||||
bulletHTML: '<ul class="orbit-bullets"></ul>',
|
||||
|
||||
init: function (element, options) {
|
||||
var $imageSlides,
|
||||
imagesLoadedCount = 0,
|
||||
self = this;
|
||||
|
||||
// Bind functions to correct context
|
||||
this.clickTimer = $.proxy(this.clickTimer, this);
|
||||
this.addBullet = $.proxy(this.addBullet, this);
|
||||
this.resetAndUnlock = $.proxy(this.resetAndUnlock, this);
|
||||
this.stopClock = $.proxy(this.stopClock, this);
|
||||
this.startTimerAfterMouseLeave = $.proxy(this.startTimerAfterMouseLeave, this);
|
||||
this.clearClockMouseLeaveTimer = $.proxy(this.clearClockMouseLeaveTimer, this);
|
||||
this.rotateTimer = $.proxy(this.rotateTimer, this);
|
||||
|
||||
this.options = $.extend({}, this.defaults, options);
|
||||
if (this.options.timer === 'false') this.options.timer = false;
|
||||
if (this.options.captions === 'false') this.options.captions = false;
|
||||
if (this.options.directionalNav === 'false') this.options.directionalNav = false;
|
||||
|
||||
this.$element = $(element);
|
||||
this.$wrapper = this.$element.wrap(this.wrapperHTML).parent();
|
||||
this.$slides = this.$element.children('img, a, div');
|
||||
|
||||
this.$element.bind('orbit.next', function () {
|
||||
self.shift('next');
|
||||
});
|
||||
|
||||
this.$element.bind('orbit.prev', function () {
|
||||
self.shift('prev');
|
||||
});
|
||||
|
||||
this.$element.bind('orbit.goto', function (event, index) {
|
||||
self.shift(index);
|
||||
});
|
||||
|
||||
this.$element.bind('orbit.start', function (event, index) {
|
||||
self.startClock();
|
||||
});
|
||||
|
||||
this.$element.bind('orbit.stop', function (event, index) {
|
||||
self.stopClock();
|
||||
});
|
||||
|
||||
$imageSlides = this.$slides.filter('img');
|
||||
|
||||
if ($imageSlides.length === 0) {
|
||||
this.loaded();
|
||||
} else {
|
||||
$imageSlides.bind('imageready', function () {
|
||||
imagesLoadedCount += 1;
|
||||
if (imagesLoadedCount === $imageSlides.length) {
|
||||
self.loaded();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
loaded: function () {
|
||||
this.$element
|
||||
.addClass('orbit')
|
||||
.css({width: '1px', height: '1px'});
|
||||
|
||||
this.$slides.addClass('orbit-slide');
|
||||
|
||||
this.setDimentionsFromLargestSlide();
|
||||
this.updateOptionsIfOnlyOneSlide();
|
||||
this.setupFirstSlide();
|
||||
|
||||
if (this.options.timer) {
|
||||
this.setupTimer();
|
||||
this.startClock();
|
||||
}
|
||||
|
||||
if (this.options.captions) {
|
||||
this.setupCaptions();
|
||||
}
|
||||
|
||||
if (this.options.directionalNav) {
|
||||
this.setupDirectionalNav();
|
||||
}
|
||||
|
||||
if (this.options.bullets) {
|
||||
this.setupBulletNav();
|
||||
this.setActiveBullet();
|
||||
}
|
||||
|
||||
this.options.afterLoadComplete.call(this);
|
||||
},
|
||||
|
||||
currentSlide: function () {
|
||||
return this.$slides.eq(this.activeSlide);
|
||||
},
|
||||
|
||||
setDimentionsFromLargestSlide: function () {
|
||||
//Collect all slides and set slider size of largest image
|
||||
var self = this,
|
||||
$fluidPlaceholder;
|
||||
|
||||
self.$element.add(self.$wrapper).width(this.$slides.first().outerWidth());
|
||||
self.$element.add(self.$wrapper).height(this.$slides.first().height());
|
||||
self.orbitWidth = this.$slides.first().outerWidth();
|
||||
self.orbitHeight = this.$slides.first().height();
|
||||
$fluidPlaceholder = this.$slides.first().findFirstImage().clone();
|
||||
|
||||
|
||||
this.$slides.each(function () {
|
||||
var slide = $(this),
|
||||
slideWidth = slide.outerWidth(),
|
||||
slideHeight = slide.height();
|
||||
|
||||
if (slideWidth > self.$element.outerWidth()) {
|
||||
self.$element.add(self.$wrapper).width(slideWidth);
|
||||
self.orbitWidth = self.$element.outerWidth();
|
||||
}
|
||||
if (slideHeight > self.$element.height()) {
|
||||
self.$element.add(self.$wrapper).height(slideHeight);
|
||||
self.orbitHeight = self.$element.height();
|
||||
$fluidPlaceholder = $(this).findFirstImage().clone();
|
||||
}
|
||||
self.numberSlides += 1;
|
||||
});
|
||||
|
||||
if (this.options.fluid) {
|
||||
if (typeof this.options.fluid === "string") {
|
||||
$fluidPlaceholder = $('<img src="http://placehold.it/' + this.options.fluid + '" />')
|
||||
}
|
||||
|
||||
self.$element.prepend($fluidPlaceholder);
|
||||
$fluidPlaceholder.addClass('fluid-placeholder');
|
||||
self.$element.add(self.$wrapper).css({width: 'inherit'});
|
||||
self.$element.add(self.$wrapper).css({height: 'inherit'});
|
||||
|
||||
$(window).bind('resize', function () {
|
||||
self.orbitWidth = self.$element.outerWidth();
|
||||
self.orbitHeight = self.$element.height();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
//Animation locking functions
|
||||
lock: function () {
|
||||
this.locked = true;
|
||||
},
|
||||
|
||||
unlock: function () {
|
||||
this.locked = false;
|
||||
},
|
||||
|
||||
updateOptionsIfOnlyOneSlide: function () {
|
||||
if(this.$slides.length === 1) {
|
||||
this.options.directionalNav = false;
|
||||
this.options.timer = false;
|
||||
this.options.bullets = false;
|
||||
}
|
||||
},
|
||||
|
||||
setupFirstSlide: function () {
|
||||
//Set initial front photo z-index and fades it in
|
||||
var self = this;
|
||||
this.$slides.first()
|
||||
.css({"z-index" : 3})
|
||||
.fadeIn(function() {
|
||||
//brings in all other slides IF css declares a display: none
|
||||
self.$slides.css({"display":"block"})
|
||||
});
|
||||
},
|
||||
|
||||
startClock: function () {
|
||||
var self = this;
|
||||
|
||||
if(!this.options.timer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.$timer.is(':hidden')) {
|
||||
this.clock = setInterval(function () {
|
||||
self.$element.trigger('orbit.next');
|
||||
}, this.options.advanceSpeed);
|
||||
} else {
|
||||
this.timerRunning = true;
|
||||
this.$pause.removeClass('active');
|
||||
this.clock = setInterval(this.rotateTimer, this.options.advanceSpeed / 180, false);
|
||||
}
|
||||
},
|
||||
|
||||
rotateTimer: function (reset) {
|
||||
var degreeCSS = "rotate(" + this.degrees + "deg)";
|
||||
this.degrees += 2;
|
||||
this.$rotator.css({
|
||||
"-webkit-transform": degreeCSS,
|
||||
"-moz-transform": degreeCSS,
|
||||
"-o-transform": degreeCSS,
|
||||
"-ms-transform": degreeCSS
|
||||
});
|
||||
if(this.degrees > 180) {
|
||||
this.$rotator.addClass('move');
|
||||
this.$mask.addClass('move');
|
||||
}
|
||||
if(this.degrees > 360 || reset) {
|
||||
this.$rotator.removeClass('move');
|
||||
this.$mask.removeClass('move');
|
||||
this.degrees = 0;
|
||||
this.$element.trigger('orbit.next');
|
||||
}
|
||||
},
|
||||
|
||||
stopClock: function () {
|
||||
if (!this.options.timer) {
|
||||
return false;
|
||||
} else {
|
||||
this.timerRunning = false;
|
||||
clearInterval(this.clock);
|
||||
this.$pause.addClass('active');
|
||||
}
|
||||
},
|
||||
|
||||
setupTimer: function () {
|
||||
this.$timer = $(this.timerHTML);
|
||||
this.$wrapper.append(this.$timer);
|
||||
|
||||
this.$rotator = this.$timer.find('.rotator');
|
||||
this.$mask = this.$timer.find('.mask');
|
||||
this.$pause = this.$timer.find('.pause');
|
||||
|
||||
this.$timer.click(this.clickTimer);
|
||||
|
||||
if (this.options.startClockOnMouseOut) {
|
||||
this.$wrapper.mouseleave(this.startTimerAfterMouseLeave);
|
||||
this.$wrapper.mouseenter(this.clearClockMouseLeaveTimer);
|
||||
}
|
||||
|
||||
if (this.options.pauseOnHover) {
|
||||
this.$wrapper.mouseenter(this.stopClock);
|
||||
}
|
||||
},
|
||||
|
||||
startTimerAfterMouseLeave: function () {
|
||||
var self = this;
|
||||
|
||||
this.outTimer = setTimeout(function() {
|
||||
if(!self.timerRunning){
|
||||
self.startClock();
|
||||
}
|
||||
}, this.options.startClockOnMouseOutAfter)
|
||||
},
|
||||
|
||||
clearClockMouseLeaveTimer: function () {
|
||||
clearTimeout(this.outTimer);
|
||||
},
|
||||
|
||||
clickTimer: function () {
|
||||
if(!this.timerRunning) {
|
||||
this.startClock();
|
||||
} else {
|
||||
this.stopClock();
|
||||
}
|
||||
},
|
||||
|
||||
setupCaptions: function () {
|
||||
this.$caption = $(this.captionHTML);
|
||||
this.$wrapper.append(this.$caption);
|
||||
this.setCaption();
|
||||
},
|
||||
|
||||
setCaption: function () {
|
||||
var captionLocation = this.currentSlide().attr('data-caption'),
|
||||
captionHTML;
|
||||
|
||||
if (!this.options.captions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Set HTML for the caption if it exists
|
||||
if (captionLocation) {
|
||||
//if caption text is blank, don't show captions
|
||||
if ($.trim($(captionLocation).text()).length < 1){
|
||||
return false;
|
||||
}
|
||||
captionHTML = $(captionLocation).html(); //get HTML from the matching HTML entity
|
||||
this.$caption
|
||||
.attr('id', captionLocation) // Add ID caption TODO why is the id being set?
|
||||
.html(captionHTML); // Change HTML in Caption
|
||||
//Animations for Caption entrances
|
||||
switch (this.options.captionAnimation) {
|
||||
case 'none':
|
||||
this.$caption.show();
|
||||
break;
|
||||
case 'fade':
|
||||
this.$caption.fadeIn(this.options.captionAnimationSpeed);
|
||||
break;
|
||||
case 'slideOpen':
|
||||
this.$caption.slideDown(this.options.captionAnimationSpeed);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
//Animations for Caption exits
|
||||
switch (this.options.captionAnimation) {
|
||||
case 'none':
|
||||
this.$caption.hide();
|
||||
break;
|
||||
case 'fade':
|
||||
this.$caption.fadeOut(this.options.captionAnimationSpeed);
|
||||
break;
|
||||
case 'slideOpen':
|
||||
this.$caption.slideUp(this.options.captionAnimationSpeed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
setupDirectionalNav: function () {
|
||||
var self = this,
|
||||
$directionalNav = $(this.directionalNavHTML);
|
||||
|
||||
$directionalNav.find('.right').html(this.options.directionalNavRightText);
|
||||
$directionalNav.find('.left').html(this.options.directionalNavLeftText);
|
||||
|
||||
this.$wrapper.append($directionalNav);
|
||||
|
||||
this.$wrapper.find('.left').click(function () {
|
||||
self.stopClock();
|
||||
if (self.options.resetTimerOnClick) {
|
||||
self.rotateTimer(true);
|
||||
self.startClock();
|
||||
}
|
||||
self.$element.trigger('orbit.prev');
|
||||
});
|
||||
|
||||
this.$wrapper.find('.right').click(function () {
|
||||
self.stopClock();
|
||||
if (self.options.resetTimerOnClick) {
|
||||
self.rotateTimer(true);
|
||||
self.startClock();
|
||||
}
|
||||
self.$element.trigger('orbit.next');
|
||||
});
|
||||
},
|
||||
|
||||
setupBulletNav: function () {
|
||||
this.$bullets = $(this.bulletHTML);
|
||||
this.$wrapper.append(this.$bullets);
|
||||
this.$slides.each(this.addBullet);
|
||||
this.$element.addClass('with-bullets');
|
||||
if (this.options.centerBullets) this.$bullets.css('margin-left', -this.$bullets.outerWidth() / 2);
|
||||
},
|
||||
|
||||
addBullet: function (index, slide) {
|
||||
var position = index + 1,
|
||||
$li = $('<li>' + (position) + '</li>'),
|
||||
thumbName,
|
||||
self = this;
|
||||
|
||||
if (this.options.bulletThumbs) {
|
||||
thumbName = $(slide).attr('data-thumb');
|
||||
if (thumbName) {
|
||||
$li
|
||||
.addClass('has-thumb')
|
||||
.css({background: "url(" + this.options.bulletThumbLocation + thumbName + ") no-repeat"});;
|
||||
}
|
||||
}
|
||||
this.$bullets.append($li);
|
||||
$li.data('index', index);
|
||||
$li.click(function () {
|
||||
self.stopClock();
|
||||
if (self.options.resetTimerOnClick) {
|
||||
self.rotateTimer(true);
|
||||
self.startClock();
|
||||
}
|
||||
self.$element.trigger('orbit.goto', [$li.data('index')])
|
||||
});
|
||||
},
|
||||
|
||||
setActiveBullet: function () {
|
||||
if(!this.options.bullets) { return false; } else {
|
||||
this.$bullets.find('li')
|
||||
.removeClass('active')
|
||||
.eq(this.activeSlide)
|
||||
.addClass('active');
|
||||
}
|
||||
},
|
||||
|
||||
resetAndUnlock: function () {
|
||||
this.$slides
|
||||
.eq(this.prevActiveSlide)
|
||||
.css({"z-index" : 1});
|
||||
this.unlock();
|
||||
this.options.afterSlideChange.call(this, this.$slides.eq(this.prevActiveSlide), this.$slides.eq(this.activeSlide));
|
||||
},
|
||||
|
||||
shift: function (direction) {
|
||||
var slideDirection = direction;
|
||||
|
||||
//remember previous activeSlide
|
||||
this.prevActiveSlide = this.activeSlide;
|
||||
|
||||
//exit function if bullet clicked is same as the current image
|
||||
if (this.prevActiveSlide == slideDirection) { return false; }
|
||||
|
||||
if (this.$slides.length == "1") { return false; }
|
||||
if (!this.locked) {
|
||||
this.lock();
|
||||
//deduce the proper activeImage
|
||||
if (direction == "next") {
|
||||
this.activeSlide++;
|
||||
if (this.activeSlide == this.numberSlides) {
|
||||
this.activeSlide = 0;
|
||||
}
|
||||
} else if (direction == "prev") {
|
||||
this.activeSlide--
|
||||
if (this.activeSlide < 0) {
|
||||
this.activeSlide = this.numberSlides - 1;
|
||||
}
|
||||
} else {
|
||||
this.activeSlide = direction;
|
||||
if (this.prevActiveSlide < this.activeSlide) {
|
||||
slideDirection = "next";
|
||||
} else if (this.prevActiveSlide > this.activeSlide) {
|
||||
slideDirection = "prev"
|
||||
}
|
||||
}
|
||||
|
||||
//set to correct bullet
|
||||
this.setActiveBullet();
|
||||
|
||||
//set previous slide z-index to one below what new activeSlide will be
|
||||
this.$slides
|
||||
.eq(this.prevActiveSlide)
|
||||
.css({"z-index" : 2});
|
||||
|
||||
//fade
|
||||
if (this.options.animation == "fade") {
|
||||
this.$slides
|
||||
.eq(this.activeSlide)
|
||||
.css({"opacity" : 0, "z-index" : 3})
|
||||
.animate({"opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock);
|
||||
}
|
||||
|
||||
//horizontal-slide
|
||||
if (this.options.animation == "horizontal-slide") {
|
||||
if (slideDirection == "next") {
|
||||
this.$slides
|
||||
.eq(this.activeSlide)
|
||||
.css({"left": this.orbitWidth, "z-index" : 3})
|
||||
.animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
|
||||
}
|
||||
if (slideDirection == "prev") {
|
||||
this.$slides
|
||||
.eq(this.activeSlide)
|
||||
.css({"left": -this.orbitWidth, "z-index" : 3})
|
||||
.animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
|
||||
}
|
||||
}
|
||||
|
||||
//vertical-slide
|
||||
if (this.options.animation == "vertical-slide") {
|
||||
if (slideDirection == "prev") {
|
||||
this.$slides
|
||||
.eq(this.activeSlide)
|
||||
.css({"top": this.orbitHeight, "z-index" : 3})
|
||||
.animate({"top" : 0}, this.options.animationSpeed, this.resetAndUnlock);
|
||||
}
|
||||
if (slideDirection == "next") {
|
||||
this.$slides
|
||||
.eq(this.activeSlide)
|
||||
.css({"top": -this.orbitHeight, "z-index" : 3})
|
||||
.animate({"top" : 0}, this.options.animationSpeed, this.resetAndUnlock);
|
||||
}
|
||||
}
|
||||
|
||||
//horizontal-push
|
||||
if (this.options.animation == "horizontal-push") {
|
||||
if (slideDirection == "next") {
|
||||
this.$slides
|
||||
.eq(this.activeSlide)
|
||||
.css({"left": this.orbitWidth, "z-index" : 3})
|
||||
.animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
|
||||
this.$slides
|
||||
.eq(this.prevActiveSlide)
|
||||
.animate({"left" : -this.orbitWidth}, this.options.animationSpeed);
|
||||
}
|
||||
if (slideDirection == "prev") {
|
||||
this.$slides
|
||||
.eq(this.activeSlide)
|
||||
.css({"left": -this.orbitWidth, "z-index" : 3})
|
||||
.animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock);
|
||||
this.$slides
|
||||
.eq(this.prevActiveSlide)
|
||||
.animate({"left" : this.orbitWidth}, this.options.animationSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
//vertical-push
|
||||
if (this.options.animation == "vertical-push") {
|
||||
if (slideDirection == "next") {
|
||||
this.$slides
|
||||
.eq(this.activeSlide)
|
||||
.css({top: -this.orbitHeight, "z-index" : 3})
|
||||
.animate({top : 0}, this.options.animationSpeed, this.resetAndUnlock);
|
||||
this.$slides
|
||||
.eq(this.prevActiveSlide)
|
||||
.animate({top : this.orbitHeight}, this.options.animationSpeed);
|
||||
}
|
||||
if (slideDirection == "prev") {
|
||||
this.$slides
|
||||
.eq(this.activeSlide)
|
||||
.css({top: this.orbitHeight, "z-index" : 3})
|
||||
.animate({top : 0}, this.options.animationSpeed, this.resetAndUnlock);
|
||||
this.$slides
|
||||
.eq(this.prevActiveSlide)
|
||||
.animate({top : -this.orbitHeight}, this.options.animationSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
this.setCaption();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.orbit = function (options) {
|
||||
return this.each(function () {
|
||||
var orbit = $.extend({}, ORBIT);
|
||||
orbit.init(this, options);
|
||||
});
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
|
||||
/*!
|
||||
* jQuery imageready Plugin
|
||||
* http://www.zurb.com/playground/
|
||||
*
|
||||
* Copyright 2011, ZURB
|
||||
* Released under the MIT License
|
||||
*/
|
||||
(function ($) {
|
||||
|
||||
var options = {};
|
||||
|
||||
$.event.special.imageready = {
|
||||
|
||||
setup: function (data, namespaces, eventHandle) {
|
||||
options = data || options;
|
||||
},
|
||||
|
||||
add: function (handleObj) {
|
||||
var $this = $(this),
|
||||
src;
|
||||
|
||||
if ( this.nodeType === 1 && this.tagName.toLowerCase() === 'img' && this.src !== '' ) {
|
||||
if (options.forceLoad) {
|
||||
src = $this.attr('src');
|
||||
$this.attr('src', '');
|
||||
bindToLoad(this, handleObj.handler);
|
||||
$this.attr('src', src);
|
||||
} else if ( this.complete || this.readyState === 4 ) {
|
||||
handleObj.handler.apply(this, arguments);
|
||||
} else {
|
||||
bindToLoad(this, handleObj.handler);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
teardown: function (namespaces) {
|
||||
$(this).unbind('.imageready');
|
||||
}
|
||||
};
|
||||
|
||||
function bindToLoad(element, callback) {
|
||||
var $this = $(element);
|
||||
|
||||
$this.bind('load.imageready', function () {
|
||||
callback.apply(element, arguments);
|
||||
$this.unbind('load.imageready');
|
||||
});
|
||||
}
|
||||
|
||||
}(jQuery));
|
||||
@@ -1,773 +0,0 @@
|
||||
/*
|
||||
* jQuery Reveal Plugin 1.1
|
||||
* www.ZURB.com
|
||||
* Copyright 2010, ZURB
|
||||
* Free to use under the MIT license.
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
/*globals jQuery */
|
||||
|
||||
(function ($) {
|
||||
'use strict';
|
||||
//
|
||||
// Global variable.
|
||||
// Helps us determine if the current modal is being queued for display.
|
||||
//
|
||||
var modalQueued = false;
|
||||
|
||||
//
|
||||
// Bind the live 'click' event to all anchor elemnets with the data-reveal-id attribute.
|
||||
//
|
||||
$(document).on('click', 'a[data-reveal-id]', function ( event ) {
|
||||
//
|
||||
// Prevent default action of the event.
|
||||
//
|
||||
event.preventDefault();
|
||||
//
|
||||
// Get the clicked anchor data-reveal-id attribute value.
|
||||
//
|
||||
var modalLocation = $( this ).attr( 'data-reveal-id' );
|
||||
//
|
||||
// Find the element with that modalLocation id and call the reveal plugin.
|
||||
//
|
||||
$( '#' + modalLocation ).reveal( $( this ).data() );
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* @module reveal
|
||||
* @property {Object} [options] Reveal options
|
||||
*/
|
||||
$.fn.reveal = function ( options ) {
|
||||
/*
|
||||
* Cache the document object.
|
||||
*/
|
||||
var $doc = $( document ),
|
||||
/*
|
||||
* Default property values.
|
||||
*/
|
||||
defaults = {
|
||||
/**
|
||||
* Possible options: fade, fadeAndPop, none
|
||||
*
|
||||
* @property animation
|
||||
* @type {String}
|
||||
* @default fadeAndPop
|
||||
*/
|
||||
animation: 'fadeAndPop',
|
||||
/**
|
||||
* Speed at which the reveal should show. How fast animtions are.
|
||||
*
|
||||
* @property animationSpeed
|
||||
* @type {Integer}
|
||||
* @default 300
|
||||
*/
|
||||
animationSpeed: 300,
|
||||
/**
|
||||
* Should the modal close when the background is clicked?
|
||||
*
|
||||
* @property closeOnBackgroundClick
|
||||
* @type {Boolean}
|
||||
* @default true
|
||||
*/
|
||||
closeOnBackgroundClick: true,
|
||||
/**
|
||||
* Specify a class name for the 'close modal' element.
|
||||
* This element will close an open modal.
|
||||
*
|
||||
@example
|
||||
<a href='#close' class='close-reveal-modal'>Close Me</a>
|
||||
*
|
||||
* @property dismissModalClass
|
||||
* @type {String}
|
||||
* @default close-reveal-modal
|
||||
*/
|
||||
dismissModalClass: 'close-reveal-modal',
|
||||
/**
|
||||
* Specify a callback function that triggers 'before' the modal opens.
|
||||
*
|
||||
* @property open
|
||||
* @type {Function}
|
||||
* @default function(){}
|
||||
*/
|
||||
open: $.noop,
|
||||
/**
|
||||
* Specify a callback function that triggers 'after' the modal is opened.
|
||||
*
|
||||
* @property opened
|
||||
* @type {Function}
|
||||
* @default function(){}
|
||||
*/
|
||||
opened: $.noop,
|
||||
/**
|
||||
* Specify a callback function that triggers 'before' the modal prepares to close.
|
||||
*
|
||||
* @property close
|
||||
* @type {Function}
|
||||
* @default function(){}
|
||||
*/
|
||||
close: $.noop,
|
||||
/**
|
||||
* Specify a callback function that triggers 'after' the modal is closed.
|
||||
*
|
||||
* @property closed
|
||||
* @type {Function}
|
||||
* @default function(){}
|
||||
*/
|
||||
closed: $.noop
|
||||
}
|
||||
;
|
||||
//
|
||||
// Extend the default options.
|
||||
// This replaces the passed in option (options) values with default values.
|
||||
//
|
||||
options = $.extend( {}, defaults, options );
|
||||
|
||||
//
|
||||
// Apply the plugin functionality to each element in the jQuery collection.
|
||||
//
|
||||
return this.each( function () {
|
||||
//
|
||||
// Cache the modal element
|
||||
//
|
||||
var modal = $( this ),
|
||||
//
|
||||
// Get the current css 'top' property value in decimal format.
|
||||
//
|
||||
topMeasure = parseInt( modal.css( 'top' ), 10 ),
|
||||
//
|
||||
// Calculate the top offset.
|
||||
//
|
||||
topOffset = modal.height() + topMeasure,
|
||||
//
|
||||
// Helps determine if the modal is locked.
|
||||
// This way we keep the modal from triggering while it's in the middle of animating.
|
||||
//
|
||||
locked = false,
|
||||
//
|
||||
// Get the modal background element.
|
||||
//
|
||||
modalBg = $( '.reveal-modal-bg' ),
|
||||
//
|
||||
// Show modal properties
|
||||
//
|
||||
cssOpts = {
|
||||
//
|
||||
// Used, when we show the modal.
|
||||
//
|
||||
open : {
|
||||
//
|
||||
// Set the 'top' property to the document scroll minus the calculated top offset.
|
||||
//
|
||||
'top': 0,
|
||||
//
|
||||
// Opacity gets set to 0.
|
||||
//
|
||||
'opacity': 0,
|
||||
//
|
||||
// Show the modal
|
||||
//
|
||||
'visibility': 'visible',
|
||||
//
|
||||
// Ensure it's displayed as a block element.
|
||||
//
|
||||
'display': 'block'
|
||||
},
|
||||
//
|
||||
// Used, when we hide the modal.
|
||||
//
|
||||
close : {
|
||||
//
|
||||
// Set the default 'top' property value.
|
||||
//
|
||||
'top': topMeasure,
|
||||
//
|
||||
// Has full opacity.
|
||||
//
|
||||
'opacity': 1,
|
||||
//
|
||||
// Hide the modal
|
||||
//
|
||||
'visibility': 'hidden',
|
||||
//
|
||||
// Ensure the elment is hidden.
|
||||
//
|
||||
'display': 'none'
|
||||
}
|
||||
|
||||
},
|
||||
//
|
||||
// Initial closeButton variable.
|
||||
//
|
||||
$closeButton
|
||||
;
|
||||
|
||||
//
|
||||
// Do we have a modal background element?
|
||||
//
|
||||
if ( modalBg.length === 0 ) {
|
||||
//
|
||||
// No we don't. So, let's create one.
|
||||
//
|
||||
modalBg = $( '<div />', { 'class' : 'reveal-modal-bg' } )
|
||||
//
|
||||
// Then insert it after the modal element.
|
||||
//
|
||||
.insertAfter( modal );
|
||||
//
|
||||
// Now, fade it out a bit.
|
||||
//
|
||||
modalBg.fadeTo( 'fast', 0.8 );
|
||||
}
|
||||
|
||||
//
|
||||
// Helper Methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Unlock the modal for animation.
|
||||
*
|
||||
* @method unlockModal
|
||||
*/
|
||||
function unlockModal() {
|
||||
locked = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock the modal to prevent further animation.
|
||||
*
|
||||
* @method lockModal
|
||||
*/
|
||||
function lockModal() {
|
||||
locked = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes all open modals.
|
||||
*
|
||||
* @method closeOpenModal
|
||||
*/
|
||||
function closeOpenModals() {
|
||||
//
|
||||
// Get all reveal-modal elements with the .open class.
|
||||
//
|
||||
var $openModals = $( ".reveal-modal.open" );
|
||||
//
|
||||
// Do we have modals to close?
|
||||
//
|
||||
if ( $openModals.length === 1 ) {
|
||||
//
|
||||
// Set the modals for animation queuing.
|
||||
//
|
||||
modalQueued = true;
|
||||
//
|
||||
// Trigger the modal close event.
|
||||
//
|
||||
$openModals.trigger( "reveal:close" );
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Animates the modal opening.
|
||||
* Handles the modal 'open' event.
|
||||
*
|
||||
* @method openAnimation
|
||||
*/
|
||||
function openAnimation() {
|
||||
//
|
||||
// First, determine if we're in the middle of animation.
|
||||
//
|
||||
if ( !locked ) {
|
||||
//
|
||||
// We're not animating, let's lock the modal for animation.
|
||||
//
|
||||
lockModal();
|
||||
//
|
||||
// Close any opened modals.
|
||||
//
|
||||
closeOpenModals();
|
||||
//
|
||||
// Now, add the open class to this modal.
|
||||
//
|
||||
modal.addClass( "open" );
|
||||
|
||||
//
|
||||
// Are we executing the 'fadeAndPop' animation?
|
||||
//
|
||||
if ( options.animation === "fadeAndPop" ) {
|
||||
//
|
||||
// Yes, we're doing the 'fadeAndPop' animation.
|
||||
// Okay, set the modal css properties.
|
||||
//
|
||||
//
|
||||
// Set the 'top' property to the document scroll minus the calculated top offset.
|
||||
//
|
||||
cssOpts.open.top = $doc.scrollTop() - topOffset;
|
||||
//
|
||||
// Flip the opacity to 0.
|
||||
//
|
||||
cssOpts.open.opacity = 0;
|
||||
//
|
||||
// Set the css options.
|
||||
//
|
||||
modal.css( cssOpts.open );
|
||||
//
|
||||
// Fade in the background element, at half the speed of the modal element.
|
||||
// So, faster than the modal element.
|
||||
//
|
||||
modalBg.fadeIn( options.animationSpeed / 2 );
|
||||
|
||||
//
|
||||
// Let's delay the next animation queue.
|
||||
// We'll wait until the background element is faded in.
|
||||
//
|
||||
modal.delay( options.animationSpeed / 2 )
|
||||
//
|
||||
// Animate the following css properties.
|
||||
//
|
||||
.animate( {
|
||||
//
|
||||
// Set the 'top' property to the document scroll plus the calculated top measure.
|
||||
//
|
||||
"top": $doc.scrollTop() + topMeasure + 'px',
|
||||
//
|
||||
// Set it to full opacity.
|
||||
//
|
||||
"opacity": 1
|
||||
|
||||
},
|
||||
/*
|
||||
* Fade speed.
|
||||
*/
|
||||
options.animationSpeed,
|
||||
/*
|
||||
* End of animation callback.
|
||||
*/
|
||||
function () {
|
||||
//
|
||||
// Trigger the modal reveal:opened event.
|
||||
// This should trigger the functions set in the options.opened property.
|
||||
//
|
||||
modal.trigger( 'reveal:opened' );
|
||||
|
||||
}); // end of animate.
|
||||
|
||||
} // end if 'fadeAndPop'
|
||||
|
||||
//
|
||||
// Are executing the 'fade' animation?
|
||||
//
|
||||
if ( options.animation === "fade" ) {
|
||||
//
|
||||
// Yes, were executing 'fade'.
|
||||
// Okay, let's set the modal properties.
|
||||
//
|
||||
cssOpts.open.top = $doc.scrollTop() + topMeasure;
|
||||
//
|
||||
// Flip the opacity to 0.
|
||||
//
|
||||
cssOpts.open.opacity = 0;
|
||||
//
|
||||
// Set the css options.
|
||||
//
|
||||
modal.css( cssOpts.open );
|
||||
//
|
||||
// Fade in the modal background at half the speed of the modal.
|
||||
// So, faster than modal.
|
||||
//
|
||||
modalBg.fadeIn( options.animationSpeed / 2 );
|
||||
|
||||
//
|
||||
// Delay the modal animation.
|
||||
// Wait till the modal background is done animating.
|
||||
//
|
||||
modal.delay( options.animationSpeed / 2 )
|
||||
//
|
||||
// Now animate the modal.
|
||||
//
|
||||
.animate( {
|
||||
//
|
||||
// Set to full opacity.
|
||||
//
|
||||
"opacity": 1
|
||||
},
|
||||
|
||||
/*
|
||||
* Animation speed.
|
||||
*/
|
||||
options.animationSpeed,
|
||||
|
||||
/*
|
||||
* End of animation callback.
|
||||
*/
|
||||
function () {
|
||||
//
|
||||
// Trigger the modal reveal:opened event.
|
||||
// This should trigger the functions set in the options.opened property.
|
||||
//
|
||||
modal.trigger( 'reveal:opened' );
|
||||
|
||||
});
|
||||
|
||||
} // end if 'fade'
|
||||
|
||||
//
|
||||
// Are we not animating?
|
||||
//
|
||||
if ( options.animation === "none" ) {
|
||||
//
|
||||
// We're not animating.
|
||||
// Okay, let's set the modal css properties.
|
||||
//
|
||||
//
|
||||
// Set the top property.
|
||||
//
|
||||
cssOpts.open.top = $doc.scrollTop() + topMeasure;
|
||||
//
|
||||
// Set the opacity property to full opacity, since we're not fading (animating).
|
||||
//
|
||||
cssOpts.open.opacity = 1;
|
||||
//
|
||||
// Set the css property.
|
||||
//
|
||||
modal.css( cssOpts.open );
|
||||
//
|
||||
// Show the modal Background.
|
||||
//
|
||||
modalBg.css( { "display": "block" } );
|
||||
//
|
||||
// Trigger the modal opened event.
|
||||
//
|
||||
modal.trigger( 'reveal:opened' );
|
||||
|
||||
} // end if animating 'none'
|
||||
|
||||
}// end if !locked
|
||||
|
||||
}// end openAnimation
|
||||
|
||||
//
|
||||
// Bind the reveal 'open' event.
|
||||
// When the event is triggered, openAnimation is called
|
||||
// along with any function set in the options.open property.
|
||||
//
|
||||
modal.bind( 'reveal:open.reveal', openAnimation );
|
||||
|
||||
/**
|
||||
* Closes the modal element(s)
|
||||
* Handles the modal 'close' event.
|
||||
*
|
||||
* @method closeAnimation
|
||||
*/
|
||||
function closeAnimation() {
|
||||
//
|
||||
// First, determine if we're in the middle of animation.
|
||||
//
|
||||
if ( !locked ) {
|
||||
//
|
||||
// We're not animating, let's lock the modal for animation.
|
||||
//
|
||||
lockModal();
|
||||
//
|
||||
// Clear the modal of the open class.
|
||||
//
|
||||
modal.removeClass( "open" );
|
||||
|
||||
//
|
||||
// Are we using the 'fadeAndPop' animation?
|
||||
//
|
||||
if ( options.animation === "fadeAndPop" ) {
|
||||
//
|
||||
// Yes, okay, let's set the animation properties.
|
||||
//
|
||||
modal.animate( {
|
||||
//
|
||||
// Set the top property to the document scrollTop minus calculated topOffset.
|
||||
//
|
||||
"top": $doc.scrollTop() - topOffset + 'px',
|
||||
//
|
||||
// Fade the modal out, by using the opacity property.
|
||||
//
|
||||
"opacity": 0
|
||||
|
||||
},
|
||||
/*
|
||||
* Fade speed.
|
||||
*/
|
||||
options.animationSpeed / 2,
|
||||
/*
|
||||
* End of animation callback.
|
||||
*/
|
||||
function () {
|
||||
//
|
||||
// Set the css hidden options.
|
||||
//
|
||||
modal.css( cssOpts.close );
|
||||
|
||||
});
|
||||
//
|
||||
// Is the modal animation queued?
|
||||
//
|
||||
if ( !modalQueued ) {
|
||||
//
|
||||
// Oh, the modal(s) are mid animating.
|
||||
// Let's delay the animation queue.
|
||||
//
|
||||
modalBg.delay( options.animationSpeed )
|
||||
//
|
||||
// Fade out the modal background.
|
||||
//
|
||||
.fadeOut(
|
||||
/*
|
||||
* Animation speed.
|
||||
*/
|
||||
options.animationSpeed,
|
||||
/*
|
||||
* End of animation callback.
|
||||
*/
|
||||
function () {
|
||||
//
|
||||
// Trigger the modal 'closed' event.
|
||||
// This should trigger any method set in the options.closed property.
|
||||
//
|
||||
modal.trigger( 'reveal:closed' );
|
||||
|
||||
});
|
||||
|
||||
} else {
|
||||
//
|
||||
// We're not mid queue.
|
||||
// Trigger the modal 'closed' event.
|
||||
// This should trigger any method set in the options.closed propety.
|
||||
//
|
||||
modal.trigger( 'reveal:closed' );
|
||||
|
||||
} // end if !modalQueued
|
||||
//
|
||||
// Reset the modalQueued variable.
|
||||
//
|
||||
modalQueued = false;
|
||||
|
||||
} // end if animation 'fadeAndPop'
|
||||
|
||||
//
|
||||
// Are we using the 'fade' animation.
|
||||
//
|
||||
if ( options.animation === "fade" ) {
|
||||
//
|
||||
// Yes, we're using the 'fade' animation.
|
||||
//
|
||||
modal.animate( { "opacity" : 0 },
|
||||
/*
|
||||
* Animation speed.
|
||||
*/
|
||||
options.animationSpeed,
|
||||
/*
|
||||
* End of animation callback.
|
||||
*/
|
||||
function () {
|
||||
//
|
||||
// Set the css close options.
|
||||
//
|
||||
modal.css( cssOpts.close );
|
||||
|
||||
}); // end animate
|
||||
|
||||
//
|
||||
// Are we mid animating the modal(s)?
|
||||
//
|
||||
if ( !modalQueued ) {
|
||||
//
|
||||
// Oh, the modal(s) are mid animating.
|
||||
// Let's delay the animation queue.
|
||||
//
|
||||
modalBg.delay( options.animationSpeed )
|
||||
//
|
||||
// Let's fade out the modal background element.
|
||||
//
|
||||
.fadeOut(
|
||||
/*
|
||||
* Animation speed.
|
||||
*/
|
||||
options.animationSpeed,
|
||||
/*
|
||||
* End of animation callback.
|
||||
*/
|
||||
function () {
|
||||
//
|
||||
// Trigger the modal 'closed' event.
|
||||
// This should trigger any method set in the options.closed propety.
|
||||
//
|
||||
modal.trigger( 'reveal:closed' );
|
||||
|
||||
}); // end fadeOut
|
||||
|
||||
} else {
|
||||
//
|
||||
// We're not mid queue.
|
||||
// Trigger the modal 'closed' event.
|
||||
// This should trigger any method set in the options.closed propety.
|
||||
//
|
||||
modal.trigger( 'reveal:closed' );
|
||||
|
||||
} // end if !modalQueued
|
||||
|
||||
} // end if animation 'fade'
|
||||
|
||||
//
|
||||
// Are we not animating?
|
||||
//
|
||||
if ( options.animation === "none" ) {
|
||||
//
|
||||
// We're not animating.
|
||||
// Set the modal close css options.
|
||||
//
|
||||
modal.css( cssOpts.close );
|
||||
//
|
||||
// Is the modal in the middle of an animation queue?
|
||||
//
|
||||
if ( !modalQueued ) {
|
||||
//
|
||||
// It's not mid queueu. Just hide it.
|
||||
//
|
||||
modalBg.css( { 'display': 'none' } );
|
||||
}
|
||||
//
|
||||
// Trigger the modal 'closed' event.
|
||||
// This should trigger any method set in the options.closed propety.
|
||||
//
|
||||
modal.trigger( 'reveal:closed' );
|
||||
|
||||
} // end if not animating
|
||||
|
||||
} // end if !locked
|
||||
|
||||
} // end closeAnimation
|
||||
|
||||
/**
|
||||
* Destroys the modal and it's events.
|
||||
*
|
||||
* @method destroy
|
||||
*/
|
||||
function destroy() {
|
||||
//
|
||||
// Unbind all .reveal events from the modal.
|
||||
//
|
||||
modal.unbind( '.reveal' );
|
||||
//
|
||||
// Unbind all .reveal events from the modal background.
|
||||
//
|
||||
modalBg.unbind( '.reveal' );
|
||||
//
|
||||
// Unbind all .reveal events from the modal 'close' button.
|
||||
//
|
||||
$closeButton.unbind( '.reveal' );
|
||||
//
|
||||
// Unbind all .reveal events from the body.
|
||||
//
|
||||
$( 'body' ).unbind( '.reveal' );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Bind the modal 'close' event
|
||||
//
|
||||
modal.bind( 'reveal:close.reveal', closeAnimation );
|
||||
//
|
||||
// Bind the modal 'opened' + 'closed' event
|
||||
// Calls the unlockModal method.
|
||||
//
|
||||
modal.bind( 'reveal:opened.reveal reveal:closed.reveal', unlockModal );
|
||||
//
|
||||
// Bind the modal 'closed' event.
|
||||
// Calls the destroy method.
|
||||
//
|
||||
modal.bind( 'reveal:closed.reveal', destroy );
|
||||
//
|
||||
// Bind the modal 'open' event
|
||||
// Handled by the options.open property function.
|
||||
//
|
||||
modal.bind( 'reveal:open.reveal', options.open );
|
||||
//
|
||||
// Bind the modal 'opened' event.
|
||||
// Handled by the options.opened property function.
|
||||
//
|
||||
modal.bind( 'reveal:opened.reveal', options.opened );
|
||||
//
|
||||
// Bind the modal 'close' event.
|
||||
// Handled by the options.close property function.
|
||||
//
|
||||
modal.bind( 'reveal:close.reveal', options.close );
|
||||
//
|
||||
// Bind the modal 'closed' event.
|
||||
// Handled by the options.closed property function.
|
||||
//
|
||||
modal.bind( 'reveal:closed.reveal', options.closed );
|
||||
|
||||
//
|
||||
// We're running this for the first time.
|
||||
// Trigger the modal 'open' event.
|
||||
//
|
||||
modal.trigger( 'reveal:open' );
|
||||
|
||||
//
|
||||
// Get the closeButton variable element(s).
|
||||
//
|
||||
$closeButton = $( '.' + options.dismissModalClass )
|
||||
//
|
||||
// Bind the element 'click' event and handler.
|
||||
//
|
||||
.bind( 'click.reveal', function () {
|
||||
//
|
||||
// Trigger the modal 'close' event.
|
||||
//
|
||||
modal.trigger( 'reveal:close' );
|
||||
|
||||
});
|
||||
|
||||
//
|
||||
// Should we close the modal background on click?
|
||||
//
|
||||
if ( options.closeOnBackgroundClick ) {
|
||||
//
|
||||
// Yes, close the modal background on 'click'
|
||||
// Set the modal background css 'cursor' propety to pointer.
|
||||
// Adds a pointer symbol when you mouse over the modal background.
|
||||
//
|
||||
modalBg.css( { "cursor": "pointer" } );
|
||||
//
|
||||
// Bind a 'click' event handler to the modal background.
|
||||
//
|
||||
modalBg.bind( 'click.reveal', function () {
|
||||
//
|
||||
// Trigger the modal 'close' event.
|
||||
//
|
||||
modal.trigger( 'reveal:close' );
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Bind keyup functions on the body element.
|
||||
// We'll want to close the modal when the 'escape' key is hit.
|
||||
//
|
||||
$( 'body' ).bind( 'keyup.reveal', function ( event ) {
|
||||
//
|
||||
// Did the escape key get triggered?
|
||||
//
|
||||
if ( event.which === 27 ) { // 27 is the keycode for the Escape key
|
||||
//
|
||||
// Escape key was triggered.
|
||||
// Trigger the modal 'close' event.
|
||||
//
|
||||
modal.trigger( 'reveal:close' );
|
||||
}
|
||||
|
||||
}); // end $(body)
|
||||
|
||||
}); // end this.each
|
||||
|
||||
}; // end $.fn
|
||||
|
||||
} ( jQuery ) );
|
||||
@@ -1,36 +0,0 @@
|
||||
(function ($) {
|
||||
|
||||
$.fn.foundationTabs = function (options) {
|
||||
|
||||
var settings = $.extend({
|
||||
callback: $.noop
|
||||
}, options);
|
||||
|
||||
var activateTab = function ($tab) {
|
||||
var $activeTab = $tab.closest('dl').find('dd.active'),
|
||||
contentLocation = $tab.children('a').attr("href") + 'Tab';
|
||||
|
||||
// Strip off the current url that IE adds
|
||||
contentLocation = contentLocation.replace(/^.+#/, '#');
|
||||
|
||||
//Make Tab Active
|
||||
$activeTab.removeClass('active');
|
||||
$tab.addClass('active');
|
||||
|
||||
//Show Tab Content
|
||||
$(contentLocation).closest('.tabs-content').children('li').removeClass('active').hide();
|
||||
$(contentLocation).css('display', 'block').addClass('active');
|
||||
};
|
||||
|
||||
$(document).on('click.fndtn', 'dl.tabs dd a', function (event){
|
||||
activateTab($(this).parent('dd'));
|
||||
});
|
||||
|
||||
if (window.location.hash) {
|
||||
activateTab($('a[href="' + window.location.hash + '"]').parent('dd'));
|
||||
settings.callback();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* jQuery Foundation Tooltip Plugin 2.0.1
|
||||
* http://foundation.zurb.com
|
||||
* Copyright 2012, ZURB
|
||||
* Free to use under the MIT license.
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
|
||||
/*jslint unparam: true, browser: true, indent: 2 */
|
||||
|
||||
;(function ($) {
|
||||
'use strict';
|
||||
var settings = {
|
||||
bodyHeight : 0,
|
||||
targetClass : '.has-tip',
|
||||
tooltipClass : '.tooltip',
|
||||
tipTemplate : function (selector, content) {
|
||||
return '<span data-selector="' + selector + '" class="' + settings.tooltipClass.substring(1) + '">' + content + '<span class="nub"></span></span>';
|
||||
}
|
||||
},
|
||||
methods = {
|
||||
init : function (options) {
|
||||
return this.each(function () {
|
||||
var $body = $('body');
|
||||
|
||||
if (Modernizr.touch) {
|
||||
$body.on('click.tooltip touchstart.tooltip touchend.tooltip', settings.targetClass, function (e) {
|
||||
e.preventDefault();
|
||||
$(settings.tooltipClass).hide();
|
||||
methods.showOrCreateTip($(this));
|
||||
});
|
||||
$body.on('click.tooltip touchstart.tooltip touchend.tooltip', settings.tooltipClass, function (e) {
|
||||
e.preventDefault();
|
||||
$(this).fadeOut(150);
|
||||
});
|
||||
} else {
|
||||
$body.on('mouseenter.tooltip mouseleave.tooltip', settings.targetClass, function (e) {
|
||||
var $this = $(this);
|
||||
|
||||
if (e.type === 'mouseenter') {
|
||||
methods.showOrCreateTip($this);
|
||||
} else if (e.type === 'mouseleave') {
|
||||
methods.hide($this);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
showOrCreateTip : function ($target) {
|
||||
var $tip = methods.getTip($target);
|
||||
|
||||
if ($tip && $tip.length > 0) {
|
||||
methods.show($target);
|
||||
} else {
|
||||
methods.create($target);
|
||||
}
|
||||
},
|
||||
getTip : function ($target) {
|
||||
var selector = methods.selector($target),
|
||||
tip = null;
|
||||
|
||||
if (selector) {
|
||||
tip = $('span[data-selector=' + selector + ']' + settings.tooltipClass);
|
||||
}
|
||||
return (tip.length > 0) ? tip : false;
|
||||
},
|
||||
selector : function ($target) {
|
||||
var id = $target.attr('id'),
|
||||
dataSelector = $target.data('selector');
|
||||
|
||||
if (id === undefined && dataSelector === undefined) {
|
||||
dataSelector = 'tooltip' + Math.random().toString(36).substring(7);
|
||||
$target.attr('data-selector', dataSelector);
|
||||
}
|
||||
return (id) ? id : dataSelector;
|
||||
},
|
||||
create : function ($target) {
|
||||
var $tip = $(settings.tipTemplate(methods.selector($target), $('<div>').text($target.attr('title')).html())),
|
||||
classes = methods.inheritable_classes($target);
|
||||
|
||||
$tip.addClass(classes).appendTo('body');
|
||||
if (Modernizr.touch) {
|
||||
$tip.append('<span class="tap-to-close">tap to close </span>');
|
||||
}
|
||||
$target.removeAttr('title');
|
||||
methods.show($target);
|
||||
},
|
||||
reposition : function (target, tip, classes) {
|
||||
var width, nub, nubHeight, nubWidth, column, objPos;
|
||||
|
||||
tip.css('visibility', 'hidden').show();
|
||||
|
||||
width = target.data('width');
|
||||
nub = tip.children('.nub');
|
||||
nubHeight = nub.outerHeight();
|
||||
nubWidth = nub.outerWidth();
|
||||
|
||||
objPos = function (obj, top, right, bottom, left, width) {
|
||||
return obj.css({
|
||||
'top' : top,
|
||||
'bottom' : bottom,
|
||||
'left' : left,
|
||||
'right' : right,
|
||||
'width' : (width) ? width : 'auto'
|
||||
}).end();
|
||||
};
|
||||
|
||||
objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left, width);
|
||||
objPos(nub, -nubHeight, 'auto', 'auto', 10);
|
||||
|
||||
if ($(window).width() < 767) {
|
||||
column = target.closest('.columns');
|
||||
|
||||
if (column.length < 0) {
|
||||
// if not using Foundation
|
||||
column = $('body');
|
||||
}
|
||||
tip.width(column.outerWidth() - 25).css('left', 15).addClass('tip-override');
|
||||
objPos(nub, -nubHeight, 'auto', 'auto', target.offset().left);
|
||||
} else {
|
||||
if (classes.indexOf('tip-top') > -1) {
|
||||
objPos(tip, (target.offset().top - tip.outerHeight() - nubHeight), 'auto', 'auto', target.offset().left, width)
|
||||
.removeClass('tip-override');
|
||||
objPos(nub, 'auto', 'auto', -nubHeight, 'auto');
|
||||
} else if (classes.indexOf('tip-left') > -1) {
|
||||
objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight), 'auto', 'auto', (target.offset().left - tip.outerWidth() - 10), width)
|
||||
.removeClass('tip-override');
|
||||
objPos(nub, (tip.outerHeight() / 2) - (nubHeight / 2), -nubHeight, 'auto', 'auto');
|
||||
} else if (classes.indexOf('tip-right') > -1) {
|
||||
objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight), 'auto', 'auto', (target.offset().left + target.outerWidth() + 10), width)
|
||||
.removeClass('tip-override');
|
||||
objPos(nub, (tip.outerHeight() / 2) - (nubHeight / 2), 'auto', 'auto', -nubHeight);
|
||||
}
|
||||
}
|
||||
tip.css('visibility', 'visible').hide();
|
||||
},
|
||||
inheritable_classes : function (target) {
|
||||
var inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'noradius'],
|
||||
filtered = target.attr('class').split(' ').map(function (el, i) {
|
||||
if ($.inArray(el, inheritables) !== -1) {
|
||||
return el;
|
||||
}
|
||||
}).join(' ');
|
||||
|
||||
return $.trim(filtered);
|
||||
},
|
||||
show : function ($target) {
|
||||
var $tip = methods.getTip($target);
|
||||
|
||||
methods.reposition($target, $tip, $target.attr('class'));
|
||||
$tip.fadeIn(150);
|
||||
},
|
||||
hide : function ($target) {
|
||||
var $tip = methods.getTip($target);
|
||||
|
||||
$tip.fadeOut(150);
|
||||
},
|
||||
reload : function () {
|
||||
var $self = $(this);
|
||||
|
||||
return ($self.data('tooltips')) ? $self.tooltips('destroy').tooltips('init') : $self.tooltips('init');
|
||||
},
|
||||
destroy : function () {
|
||||
return this.each(function () {
|
||||
$(window).off('.tooltip');
|
||||
$(settings.targetClass).off('.tooltip');
|
||||
$(settings.tooltipClass).each(function (i) {
|
||||
$($(settings.targetClass).get(i)).attr('title', $(this).text());
|
||||
}).remove();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.tooltips = function (method) {
|
||||
if (methods[method]) {
|
||||
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
||||
} else if (typeof method === 'object' || !method) {
|
||||
return methods.init.apply(this, arguments);
|
||||
} else {
|
||||
$.error('Method ' + method + ' does not exist on jQuery.tooltips');
|
||||
}
|
||||
};
|
||||
}(jQuery));
|
||||
9404
app/assets/javascripts/foundation/jquery.js
vendored
@@ -1,50 +0,0 @@
|
||||
(function ($) {
|
||||
// Set the negative margin on the top menu for slide-menu pages
|
||||
var $selector1 = $('#topMenu'),
|
||||
events = 'click.fndtn';
|
||||
if ($selector1.length > 0) $selector1.css("margin-top", $selector1.height() * -1);
|
||||
|
||||
// Watch for clicks to show the sidebar
|
||||
var $selector2 = $('#sidebarButton');
|
||||
if ($selector2.length > 0) {
|
||||
$('#sidebarButton').on(events, function (e) {
|
||||
e.preventDefault();
|
||||
$('body').toggleClass('active');
|
||||
});
|
||||
}
|
||||
|
||||
// Watch for clicks to show the menu for slide-menu pages
|
||||
var $selector3 = $('#menuButton');
|
||||
if ($selector3.length > 0) {
|
||||
$('#menuButton').on(events, function (e) {
|
||||
e.preventDefault();
|
||||
$('body').toggleClass('active-menu');
|
||||
});
|
||||
}
|
||||
|
||||
// // Adjust sidebars and sizes when resized
|
||||
// $(window).resize(function() {
|
||||
// // if (!navigator.userAgent.match(/Android/i)) $('body').removeClass('active');
|
||||
// var $selector4 = $('#topMenu');
|
||||
// if ($selector4.length > 0) $selector4.css("margin-top", $selector4.height() * -1);
|
||||
// });
|
||||
|
||||
// Switch panels for the paneled nav on mobile
|
||||
var $selector5 = $('#switchPanels');
|
||||
if ($selector5.length > 0) {
|
||||
$('#switchPanels dd').on(events, function (e) {
|
||||
e.preventDefault();
|
||||
var switchToPanel = $(this).children('a').attr('href'),
|
||||
switchToIndex = $(switchToPanel).index();
|
||||
$(this).toggleClass('active').siblings().removeClass('active');
|
||||
$(switchToPanel).parent().css("left", (switchToIndex * (-100) + '%'));
|
||||
});
|
||||
}
|
||||
|
||||
$('#nav li a').on(events, function (e) {
|
||||
e.preventDefault();
|
||||
var href = $(this).attr('href'),
|
||||
$target = $(href);
|
||||
$('html, body').animate({scrollTop : $target.offset().top}, 300);
|
||||
});
|
||||
});
|
||||
@@ -1,157 +0,0 @@
|
||||
/*! http://mths.be/placeholder v2.0.7 by @mathias */
|
||||
;(function(window, document, $) {
|
||||
|
||||
var isInputSupported = 'placeholder' in document.createElement('input'),
|
||||
isTextareaSupported = 'placeholder' in document.createElement('textarea'),
|
||||
prototype = $.fn,
|
||||
valHooks = $.valHooks,
|
||||
hooks,
|
||||
placeholder;
|
||||
|
||||
if (isInputSupported && isTextareaSupported) {
|
||||
|
||||
placeholder = prototype.placeholder = function() {
|
||||
return this;
|
||||
};
|
||||
|
||||
placeholder.input = placeholder.textarea = true;
|
||||
|
||||
} else {
|
||||
|
||||
placeholder = prototype.placeholder = function() {
|
||||
var $this = this;
|
||||
$this
|
||||
.filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
|
||||
.not('.placeholder')
|
||||
.bind({
|
||||
'focus.placeholder': clearPlaceholder,
|
||||
'blur.placeholder': setPlaceholder
|
||||
})
|
||||
.data('placeholder-enabled', true)
|
||||
.trigger('blur.placeholder');
|
||||
return $this;
|
||||
};
|
||||
|
||||
placeholder.input = isInputSupported;
|
||||
placeholder.textarea = isTextareaSupported;
|
||||
|
||||
hooks = {
|
||||
'get': function(element) {
|
||||
var $element = $(element);
|
||||
return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;
|
||||
},
|
||||
'set': function(element, value) {
|
||||
var $element = $(element);
|
||||
if (!$element.data('placeholder-enabled')) {
|
||||
return element.value = value;
|
||||
}
|
||||
if (value == '') {
|
||||
element.value = value;
|
||||
// Issue #56: Setting the placeholder causes problems if the element continues to have focus.
|
||||
if (element != document.activeElement) {
|
||||
// We can't use `triggerHandler` here because of dummy text/password inputs :(
|
||||
setPlaceholder.call(element);
|
||||
}
|
||||
} else if ($element.hasClass('placeholder')) {
|
||||
clearPlaceholder.call(element, true, value) || (element.value = value);
|
||||
} else {
|
||||
element.value = value;
|
||||
}
|
||||
// `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
|
||||
return $element;
|
||||
}
|
||||
};
|
||||
|
||||
isInputSupported || (valHooks.input = hooks);
|
||||
isTextareaSupported || (valHooks.textarea = hooks);
|
||||
|
||||
$(function() {
|
||||
// Look for forms
|
||||
$(document).delegate('form', 'submit.placeholder', function() {
|
||||
// Clear the placeholder values so they don't get submitted
|
||||
var $inputs = $('.placeholder', this).each(clearPlaceholder);
|
||||
setTimeout(function() {
|
||||
$inputs.each(setPlaceholder);
|
||||
}, 10);
|
||||
});
|
||||
});
|
||||
|
||||
// Clear placeholder values upon page reload
|
||||
$(window).bind('beforeunload.placeholder', function() {
|
||||
$('.placeholder').each(function() {
|
||||
this.value = '';
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function args(elem) {
|
||||
// Return an object of element attributes
|
||||
var newAttrs = {},
|
||||
rinlinejQuery = /^jQuery\d+$/;
|
||||
$.each(elem.attributes, function(i, attr) {
|
||||
if (attr.specified && !rinlinejQuery.test(attr.name)) {
|
||||
newAttrs[attr.name] = attr.value;
|
||||
}
|
||||
});
|
||||
return newAttrs;
|
||||
}
|
||||
|
||||
function clearPlaceholder(event, value) {
|
||||
var input = this,
|
||||
$input = $(input);
|
||||
if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) {
|
||||
if ($input.data('placeholder-password')) {
|
||||
$input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id'));
|
||||
// If `clearPlaceholder` was called from `$.valHooks.input.set`
|
||||
if (event === true) {
|
||||
return $input[0].value = value;
|
||||
}
|
||||
$input.focus();
|
||||
} else {
|
||||
input.value = '';
|
||||
$input.removeClass('placeholder');
|
||||
input == document.activeElement && input.select();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setPlaceholder() {
|
||||
var $replacement,
|
||||
input = this,
|
||||
$input = $(input),
|
||||
$origInput = $input,
|
||||
id = this.id;
|
||||
if (input.value == '') {
|
||||
if (input.type == 'password') {
|
||||
if (!$input.data('placeholder-textinput')) {
|
||||
try {
|
||||
$replacement = $input.clone().attr({ 'type': 'text' });
|
||||
} catch(e) {
|
||||
$replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' }));
|
||||
}
|
||||
$replacement
|
||||
.removeAttr('name')
|
||||
.data({
|
||||
'placeholder-password': true,
|
||||
'placeholder-id': id
|
||||
})
|
||||
.bind('focus.placeholder', clearPlaceholder);
|
||||
$input
|
||||
.data({
|
||||
'placeholder-textinput': $replacement,
|
||||
'placeholder-id': id
|
||||
})
|
||||
.before($replacement);
|
||||
}
|
||||
$input = $input.removeAttr('id').hide().prev().attr('id', id).show();
|
||||
// Note: `$input[0] != input` now!
|
||||
}
|
||||
$input.addClass('placeholder');
|
||||
$input[0].value = $input.attr('placeholder');
|
||||
} else {
|
||||
$input.removeClass('placeholder');
|
||||
}
|
||||
}
|
||||
|
||||
}(this, document, jQuery));
|
||||
3
app/assets/javascripts/scientific_names.js.coffee
Normal file
@@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
|
||||
3
app/assets/javascripts/updates.js.coffee
Normal file
@@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
|
||||
@@ -1,76 +0,0 @@
|
||||
@import "foundation/common/ratios";
|
||||
|
||||
// Settings file containing Foundation defaults
|
||||
|
||||
// Grid Settings
|
||||
|
||||
// $rowWidth: 1000px;
|
||||
// $columnGutter: 30px;
|
||||
// $totalColumns: 12;
|
||||
// $mobileTotalColumns: 4;
|
||||
|
||||
// Colors Settings
|
||||
|
||||
$mainColor: #009900;
|
||||
// $secondaryColor: #e9e9e9;
|
||||
// $alertColor: #c60f13;
|
||||
// $successColor: #5da423;
|
||||
// $txtColor: #222;
|
||||
// $highlightColor: #ffff99;
|
||||
// $black: #000;
|
||||
// $white: #fff;
|
||||
// $shinyEdge: rgba(#fff, .5);
|
||||
// $darkEdge: rgba(#000, .2);
|
||||
|
||||
// Typography Settings
|
||||
|
||||
$headerFontFamily: "Sevillana", "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
|
||||
$headerFontWeight: normal;
|
||||
// $headerFontColor: #222;
|
||||
// $bodyFontFamily: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
|
||||
// $bodyFontWeight: normal;
|
||||
// $bodyFontColor: #222;
|
||||
|
||||
// Button Settings
|
||||
|
||||
// $buttonRadius: 3px;
|
||||
// $btnBase: 10px;
|
||||
|
||||
// $tinyBtnBase: $btnBase - 5;
|
||||
// $smallBtnBase: $btnBase - 3;
|
||||
// $largeBtnBase: $btnBase + 5;
|
||||
|
||||
// Form Settings
|
||||
|
||||
// $formSpacing: 12px;
|
||||
|
||||
// Tab Settings
|
||||
|
||||
// $tabHeight: 40px;
|
||||
|
||||
// Nav Bar Settings
|
||||
|
||||
// $navBarHeight: 40px;
|
||||
// $navFlyoutBaseWidth: 250px;
|
||||
|
||||
// Modular Scale
|
||||
// $ratio: $golden;
|
||||
// $baseFontSize: 14px;
|
||||
// $importantModNum: 44px;
|
||||
|
||||
// Tooltip Settings
|
||||
// $hasTipBorderBottom: dotted 1px #ccc;
|
||||
// $hasTipFontWeight: bold;
|
||||
// $hasTipFontColor: #333;
|
||||
// $hasTipBorderBottomHover: dotted 1px darken($mainColor, 20%);
|
||||
// $hasTipFontColorHover: $mainColor;
|
||||
// $tooltipBackgroundColor: #000;
|
||||
// $tooltipBackgroundOpacity: 0.85;
|
||||
// $tooltipFontSize: 12;
|
||||
// $tooltipFontWeight: bold;
|
||||
// $tooltipFontColor: #fff;
|
||||
// $tapToCloseFontSize: 10;
|
||||
// $tapToCloseFontWeight: normal;
|
||||
// $tapToCloseFontColor: #888;
|
||||
// $tooltipFontSizeScreenSmall: 14;
|
||||
// $tooltipBackgroundOpacityScreenSmall: 0.85;
|
||||
@@ -1,46 +0,0 @@
|
||||
// You custom settings file to override Foundation defaults
|
||||
@import "settings";
|
||||
|
||||
// Comment out this import if you are customizing you imports below
|
||||
@import "foundation";
|
||||
|
||||
// ----------------------------------------
|
||||
// Import specific parts of Foundation by commenting the import "foundation"
|
||||
// and uncommenting what you want below. You must uncomment the following if customizing
|
||||
|
||||
// @import "compass/css3";
|
||||
// @import "foundation/settings";
|
||||
// @import "foundation/functions/all";
|
||||
// @import "foundation/common/globals";
|
||||
// @import "foundation/mixins/clearfix";
|
||||
// @import "modular-scale";
|
||||
|
||||
// Control which mixins you have access too
|
||||
|
||||
// @import "foundation/mixins/css-triangle";
|
||||
// @import "foundation/mixins/font-size";
|
||||
|
||||
// Must include next two for semantic grid to work
|
||||
|
||||
// @import "foundation/mixins/respond-to";
|
||||
// @import "foundation/mixins/semantic-grid";
|
||||
|
||||
// Must include the grid for any responsiveness
|
||||
|
||||
// @import "foundation/components/grid";
|
||||
|
||||
// Control which common styles get compiled
|
||||
|
||||
// @import "foundation/common/typography";
|
||||
// @import "foundation/common/forms";
|
||||
|
||||
// Control which components you get if customizing
|
||||
|
||||
// @import "foundation/components/modules/buttons";
|
||||
// @import "foundation/components/modules/tabs";
|
||||
// @import "foundation/components/modules/ui";
|
||||
// @import "foundation/components/modules/navbar";
|
||||
// @import "foundation/components/modules/orbit";
|
||||
// @import "foundation/components/modules/reveal";
|
||||
// @import "foundation/components/modules/offcanvas";
|
||||
|
||||
7
app/assets/stylesheets/application.css
Normal file
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
* This is a manifest file that'll automatically include all the stylesheets available in this directory
|
||||
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
|
||||
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
||||
*= require_self
|
||||
*= require_tree .
|
||||
*/
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
||||
* listed below.
|
||||
*
|
||||
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
||||
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
||||
*
|
||||
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
||||
* compiled file, but it's generally better to create a new file per style scope.
|
||||
*
|
||||
*= require_self
|
||||
*= require foundation_and_overrides
|
||||
*= require_tree .
|
||||
*/
|
||||
|
||||
34
app/assets/stylesheets/bootstrap_and_overrides.css.less
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
@import "twitter/bootstrap/bootstrap";
|
||||
@import "twitter/bootstrap/responsive";
|
||||
|
||||
// Set the correct sprite paths
|
||||
@iconSpritePath: asset-path("twitter/bootstrap/glyphicons-halflings");
|
||||
@iconWhiteSpritePath: asset-path("twitter/bootstrap/glyphicons-halflings-white");
|
||||
|
||||
// Set the Font Awesome (Font Awesome is default. You can disable by commenting below lines)
|
||||
// Note: If you use asset_path() here, your compiled boostrap_and_overrides.css will not
|
||||
// have the proper paths. So for now we use the absolute path.
|
||||
@fontAwesomeEotPath: asset-path("fontawesome-webfont.eot");
|
||||
@fontAwesomeWoffPath: asset-path("fontawesome-webfont.woff");
|
||||
@fontAwesomeTtfPath: asset-path("fontawesome-webfont.ttf");
|
||||
@fontAwesomeSvgPath: asset-path("fontawesome-webfont.svg");
|
||||
|
||||
// Font Awesome
|
||||
@import "fontawesome";
|
||||
|
||||
// Glyphicons
|
||||
//@import "twitter/bootstrap/sprites.less";
|
||||
|
||||
// Your custom LESS stylesheets goes here
|
||||
//
|
||||
// Since bootstrap was imported above you have access to its mixins which
|
||||
// you may use and inherit here
|
||||
//
|
||||
// If you'd like to override bootstrap's own variables, you can do so here as well
|
||||
// See http://twitter.github.com/bootstrap/customize.html#variables for their names and documentation
|
||||
//
|
||||
// Example:
|
||||
@linkColor: @green;
|
||||
body {
|
||||
padding-bottom: @navbarHeight + 10px;
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
@import "foundation/common/ratios";
|
||||
|
||||
// Settings file containing Foundation defaults
|
||||
|
||||
// Grid Settings
|
||||
|
||||
// $rowWidth: 1000px;
|
||||
// $columnGutter: 30px;
|
||||
// $totalColumns: 12;
|
||||
// $mobileTotalColumns: 4;
|
||||
|
||||
// Colors Settings
|
||||
|
||||
// $mainColor: #2ba6cb;
|
||||
// $secondaryColor: #e9e9e9;
|
||||
// $alertColor: #c60f13;
|
||||
// $successColor: #5da423;
|
||||
// $txtColor: #222;
|
||||
// $highlightColor: #ffff99;
|
||||
// $black: #000;
|
||||
// $white: #fff;
|
||||
// $shinyEdge: rgba(#fff, .5);
|
||||
// $darkEdge: rgba(#000, .2);
|
||||
|
||||
// Typography Settings
|
||||
|
||||
// $headerFontFamily: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
|
||||
// $headerFontWeight: bold;
|
||||
// $headerFontColor: #222;
|
||||
// $bodyFontFamily: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
|
||||
// $bodyFontWeight: normal;
|
||||
// $bodyFontColor: #222;
|
||||
|
||||
// Button Settings
|
||||
|
||||
// $buttonRadius: 3px;
|
||||
// $btnBase: 10px;
|
||||
|
||||
// $tinyBtnBase: $btnBase - 5;
|
||||
// $smallBtnBase: $btnBase - 3;
|
||||
// $largeBtnBase: $btnBase + 5;
|
||||
|
||||
// Form Settings
|
||||
|
||||
// $formSpacing: 12px;
|
||||
|
||||
// Tab Settings
|
||||
|
||||
// $tabHeight: 40px;
|
||||
|
||||
// Nav Bar Settings
|
||||
|
||||
// $navBarHeight: 40px;
|
||||
// $navFlyoutBaseWidth: 250px;
|
||||
|
||||
// Modular Scale
|
||||
// $ratio: $golden;
|
||||
// $baseFontSize: 14px;
|
||||
// $importantModNum: 44px;
|
||||
|
||||
// Tooltip Settings
|
||||
// $hasTipBorderBottom: dotted 1px #ccc;
|
||||
// $hasTipFontWeight: bold;
|
||||
// $hasTipFontColor: #333;
|
||||
// $hasTipBorderBottomHover: dotted 1px darken($mainColor, 20%);
|
||||
// $hasTipFontColorHover: $mainColor;
|
||||
// $tooltipBackgroundColor: #000;
|
||||
// $tooltipBackgroundOpacity: 0.85;
|
||||
// $tooltipFontSize: 12;
|
||||
// $tooltipFontWeight: bold;
|
||||
// $tooltipFontColor: #fff;
|
||||
// $tapToCloseFontSize: 10;
|
||||
// $tapToCloseFontWeight: normal;
|
||||
// $tapToCloseFontColor: #888;
|
||||
// $tooltipFontSizeScreenSmall: 14;
|
||||
// $tooltipBackgroundOpacityScreenSmall: 0.85;
|
||||
@import 'foundation';
|
||||
@@ -1,3 +0,0 @@
|
||||
// Place all the styles related to the home controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
@@ -1,5 +0,0 @@
|
||||
/* Welcome to Compass. Use this file to write IE specific override styles.
|
||||
* Import this file using the following HTML or equivalent:
|
||||
* <!--[if IE]>
|
||||
* <link href="/stylesheets/ie.css" media="screen, projection" rel="stylesheet" type="text/css" />
|
||||
* <![endif]--> */
|
||||
@@ -1,3 +0,0 @@
|
||||
/* Welcome to Compass. Use this file to define print styles.
|
||||
* Import this file using the following HTML or equivalent:
|
||||
* <link href="/stylesheets/print.css" media="print" rel="stylesheet" type="text/css" /> */
|
||||
@@ -1,6 +0,0 @@
|
||||
/* Welcome to Compass.
|
||||
* In this file you should write your main styles. (or centralize your imports)
|
||||
* Import this file using the following HTML or equivalent:
|
||||
* <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css" /> */
|
||||
|
||||
//@import "compass/reset";
|
||||
@@ -3,10 +3,12 @@ class CropsController < ApplicationController
|
||||
# GET /crops.json
|
||||
def index
|
||||
@crops = Crop.all
|
||||
@new_crops = Crop.limit(20).order('created_at desc').all
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @crops }
|
||||
format.rss { render :layout => false }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
25
app/controllers/members_controller.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
class MembersController < ApplicationController
|
||||
def index
|
||||
@members = User.all
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @members}
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
@member = User.find(params[:id])
|
||||
@updates = @member.updates
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render json: @member }
|
||||
format.rss { render(
|
||||
:layout => false,
|
||||
:locals => { :member => @member }
|
||||
)}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,10 +0,0 @@
|
||||
class ProfileController < ApplicationController
|
||||
def show
|
||||
@user = User.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render json: @user }
|
||||
end
|
||||
end
|
||||
end
|
||||
83
app/controllers/scientific_names_controller.rb
Normal file
@@ -0,0 +1,83 @@
|
||||
class ScientificNamesController < ApplicationController
|
||||
# GET /scientific_names
|
||||
# GET /scientific_names.json
|
||||
def index
|
||||
@scientific_names = ScientificName.all
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @scientific_names }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /scientific_names/1
|
||||
# GET /scientific_names/1.json
|
||||
def show
|
||||
@scientific_name = ScientificName.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render json: @scientific_name }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /scientific_names/new
|
||||
# GET /scientific_names/new.json
|
||||
def new
|
||||
@scientific_name = ScientificName.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.json { render json: @scientific_name }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /scientific_names/1/edit
|
||||
def edit
|
||||
@scientific_name = ScientificName.find(params[:id])
|
||||
end
|
||||
|
||||
# POST /scientific_names
|
||||
# POST /scientific_names.json
|
||||
def create
|
||||
@scientific_name = ScientificName.new(params[:scientific_name])
|
||||
|
||||
respond_to do |format|
|
||||
if @scientific_name.save
|
||||
format.html { redirect_to @scientific_name, notice: 'Scientific name was successfully created.' }
|
||||
format.json { render json: @scientific_name, status: :created, location: @scientific_name }
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
format.json { render json: @scientific_name.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PUT /scientific_names/1
|
||||
# PUT /scientific_names/1.json
|
||||
def update
|
||||
@scientific_name = ScientificName.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @scientific_name.update_attributes(params[:scientific_name])
|
||||
format.html { redirect_to @scientific_name, notice: 'Scientific name was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @scientific_name.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /scientific_names/1
|
||||
# DELETE /scientific_names/1.json
|
||||
def destroy
|
||||
@scientific_name = ScientificName.find(params[:id])
|
||||
@scientific_name.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to scientific_names_url }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
end
|
||||
87
app/controllers/updates_controller.rb
Normal file
@@ -0,0 +1,87 @@
|
||||
class UpdatesController < ApplicationController
|
||||
# GET /updates
|
||||
# GET /updates.json
|
||||
|
||||
def index
|
||||
@updates = Update.all
|
||||
@recent_updates = Update.limit(100).order('created_at desc').all
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @updates }
|
||||
format.rss { render :layout => false } #index.rss.builder
|
||||
end
|
||||
end
|
||||
|
||||
# GET /updates/1
|
||||
# GET /updates/1.json
|
||||
def show
|
||||
@update = Update.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render json: @update }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /updates/new
|
||||
# GET /updates/new.json
|
||||
def new
|
||||
@update = Update.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.json { render json: @update }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /updates/1/edit
|
||||
def edit
|
||||
@update = Update.find(params[:id])
|
||||
end
|
||||
|
||||
# POST /updates
|
||||
# POST /updates.json
|
||||
def create
|
||||
params[:update][:user_id] = current_user.id
|
||||
@update = Update.new(params[:update])
|
||||
|
||||
respond_to do |format|
|
||||
if @update.save
|
||||
format.html { redirect_to @update, notice: 'Update was successfully created.' }
|
||||
format.json { render json: @update, status: :created, location: @update }
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
format.json { render json: @update.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PUT /updates/1
|
||||
# PUT /updates/1.json
|
||||
def update
|
||||
@update = Update.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @update.update_attributes(params[:update])
|
||||
format.html { redirect_to @update, notice: 'Update was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @update.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /updates/1
|
||||
# DELETE /updates/1.json
|
||||
def destroy
|
||||
@update = Update.find(params[:id])
|
||||
@update.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to updates_url }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
end
|
||||
2
app/helpers/scientific_names_helper.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
module ScientificNamesHelper
|
||||
end
|
||||
2
app/helpers/updates_helper.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
module UpdatesHelper
|
||||
end
|
||||
@@ -2,4 +2,5 @@ class Crop < ActiveRecord::Base
|
||||
extend FriendlyId
|
||||
friendly_id :system_name, use: :slugged
|
||||
attr_accessible :en_wikipedia_url, :system_name
|
||||
has_many :scientific_names
|
||||
end
|
||||
|
||||
4
app/models/scientific_name.rb
Normal file
@@ -0,0 +1,4 @@
|
||||
class ScientificName < ActiveRecord::Base
|
||||
attr_accessible :crop_id, :scientific_name
|
||||
belongs_to :crop
|
||||
end
|
||||
5
app/models/update.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class Update < ActiveRecord::Base
|
||||
attr_accessible :body, :subject, :user_id
|
||||
belongs_to :user
|
||||
default_scope order("created_at desc")
|
||||
end
|
||||
@@ -1,4 +1,8 @@
|
||||
class User < ActiveRecord::Base
|
||||
extend FriendlyId
|
||||
friendly_id :username, use: :slugged
|
||||
|
||||
has_many :updates
|
||||
has_many :gardens
|
||||
|
||||
# Include default devise modules. Others available are:
|
||||
|
||||
@@ -2,10 +2,8 @@
|
||||
|
||||
- if user_signed_in?
|
||||
= render 'form'
|
||||
%ul.link-list
|
||||
%li
|
||||
= link_to 'Show', @crop, { :class => 'button' }
|
||||
%li
|
||||
= link_to 'Back', crops_path, { :class => 'button' }
|
||||
%p
|
||||
= link_to 'Show', @crop, { :class => 'btn' }
|
||||
= link_to 'Back', crops_path, { :class => 'btn' }
|
||||
- else
|
||||
%div.alert-box.alert You're not logged in. Only logged in users can do this.
|
||||
%div.alert You're not logged in. Only logged in users can do this.
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
- content_for :title, "Crops"
|
||||
- c = 0
|
||||
|
||||
%ul
|
||||
%ul.thumbnails
|
||||
.row
|
||||
- @crops.each do |crop|
|
||||
%li
|
||||
= link_to crop.system_name, crop
|
||||
- c += 1
|
||||
%li.span2
|
||||
.thumbnail(style='height: 200px')
|
||||
= image_tag('http://placehold.it/150x150', :alt => '', :class => 'img-rounded')
|
||||
%p= link_to crop.system_name, crop
|
||||
- if crop.scientific_names.count > 0
|
||||
%p
|
||||
%i
|
||||
%small
|
||||
= crop.scientific_names.first.scientific_name
|
||||
- if (c % 6) == 0
|
||||
.row
|
||||
|
||||
- if user_signed_in?
|
||||
%div
|
||||
= link_to 'New Crop', new_crop_path, {:class => 'button'}
|
||||
= link_to 'New Crop', new_crop_path, {:class => 'btn'}
|
||||
|
||||
16
app/views/crops/index.rss.builder
Normal file
@@ -0,0 +1,16 @@
|
||||
xml.instruct! :xml, :version => "1.0"
|
||||
xml.rss :version => "2.0" do
|
||||
xml.channel do
|
||||
xml.title "Growstuff - Recently added crops"
|
||||
xml.link crops_url
|
||||
|
||||
for crop in @new_crops
|
||||
xml.item do
|
||||
xml.title crop.system_name
|
||||
xml.pubDate crop.created_at.to_s(:rfc822)
|
||||
xml.link crop_url(crop)
|
||||
xml.guid crop_url(crop)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,11 @@
|
||||
- content_for :title, "New crop"
|
||||
|
||||
= render 'form'
|
||||
- if user_signed_in?
|
||||
= render 'form'
|
||||
%p
|
||||
= link_to 'Show', @crop, { :class => 'btn' }
|
||||
= link_to 'Back', crops_path, { :class => 'btn' }
|
||||
- else
|
||||
%div.alert You're not logged in. Only logged in users can do this.
|
||||
|
||||
= link_to 'Back', crops_path
|
||||
|
||||
@@ -1,10 +1,28 @@
|
||||
- content_for :title, @crop.system_name
|
||||
|
||||
%p
|
||||
%b More information:
|
||||
= link_to @crop.en_wikipedia_url, @crop.en_wikipedia_url
|
||||
.row-fluid
|
||||
.span9
|
||||
%ul.thumbnails
|
||||
- (1..4).each do
|
||||
%li.span3
|
||||
.thumbnail
|
||||
= image_tag('http://placehold.it/200x200', :alt => '', :class => 'img-rounded')
|
||||
|
||||
%ul.link-list
|
||||
- if user_signed_in?
|
||||
%li= link_to 'Edit', edit_crop_path(@crop), { :class => 'button' }
|
||||
%li= link_to 'Destroy', @crop, method: :delete, data: { confirm: 'Are you sure?', :class => 'button' }
|
||||
%h2 Who's growing this?
|
||||
- (1..5).each do
|
||||
.well
|
||||
%h4 Some person
|
||||
%p These blocks would contain recent updates from members who are growing this crop.
|
||||
|
||||
.span3
|
||||
%h3 Scientific names:
|
||||
%ul
|
||||
- @crop.scientific_names.each do |sn|
|
||||
%li= sn.scientific_name
|
||||
%h3 More information:
|
||||
%ul
|
||||
%li= link_to 'Wikipedia (English)', @crop.en_wikipedia_url
|
||||
%p
|
||||
- if user_signed_in?
|
||||
= link_to 'Edit', edit_crop_path(@crop), { :class => 'btn' }
|
||||
= link_to 'Destroy', @crop, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn'
|
||||
|
||||
@@ -1,5 +1,42 @@
|
||||
%p
|
||||
Growstuff is a community of food gardeners working together to build an open source platform to track, share, and discuss edible gardens and sustainable lifestyles. You can join us right now and be part of growing our website, from seed to harvest. We welcome you regardless of your experience, and invite you to be part of our development process.
|
||||
.hero-unit
|
||||
%h1
|
||||
Growstuff
|
||||
%small development site
|
||||
|
||||
%p
|
||||
= link_to "Crops", crops_path
|
||||
%p Growstuff is a community of food gardeners working together to build an open source platform to track, share, and discuss edible gardens and sustainable lifestyles. You can join us right now and be part of growing our website, from seed to harvest. We welcome you regardless of your experience, and invite you to be part of our development process.
|
||||
|
||||
%p= link_to 'Learn more', 'http://wiki.growstuff.org/', :class => 'btn btn-primary btn-large'
|
||||
|
||||
.row
|
||||
.span3
|
||||
%h2 Track
|
||||
%p
|
||||
Track your garden, your
|
||||
= link_to 'crops', crops_path
|
||||
, and everything to do with them. |
|
||||
Remember what you planted or harvested, and plan for what you want to do next. |
|
||||
Import and export your data to a spreadsheet or other format.
|
||||
|
||||
.span3
|
||||
%h2 Connect
|
||||
%p
|
||||
Connect with friends, people who live in your area, or others |
|
||||
who share your gardening interests. Show off your crops and |
|
||||
harvests, share updates and tips, and
|
||||
= link_to 'see', updates_path
|
||||
what everyone else is doing, too.
|
||||
.span3
|
||||
%h2 Learn
|
||||
%p
|
||||
Browse our
|
||||
= link_to 'crops', crops_path
|
||||
database and learn about food plants for your
|
||||
climate and garden type. Read other
|
||||
= link_to "members' updates", updates_path
|
||||
and tips, or post questions and discuss food gardening issues in our forums.
|
||||
.span3
|
||||
%h2 Trade
|
||||
%p
|
||||
Use Growstuff as a marketplace for everything related to food
|
||||
gardens. Buy and sell, trade, or give away anything from seeds
|
||||
to garden supplies, or find events and businesses in your area.
|
||||
|
||||
29
app/views/home/index.html.haml.orig
Normal file
@@ -0,0 +1,29 @@
|
||||
.hero-unit
|
||||
%h1
|
||||
Growstuff
|
||||
%small development site
|
||||
|
||||
<<<<<<< HEAD
|
||||
%p Growstuff is a community of food gardeners working together to build an open source platform to track, share, and discuss edible gardens and sustainable lifestyles. You can join us right now and be part of growing our website, from seed to harvest. We welcome you regardless of your experience, and invite you to be part of our development process.
|
||||
|
||||
%p= link_to 'Learn more', 'http://wiki.growstuff.org/', :class => 'btn btn-primary btn-large'
|
||||
|
||||
.row
|
||||
.span3
|
||||
%h2 Track
|
||||
%p Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
|
||||
.span3
|
||||
%h2 Connect
|
||||
%p Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
|
||||
.span3
|
||||
%h2 Learn
|
||||
%p Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
|
||||
.span3
|
||||
%h2 Trade
|
||||
%p Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
|
||||
=======
|
||||
%ul
|
||||
%li= link_to "Crops", crops_path
|
||||
%li= link_to "Members", members_path
|
||||
%li= link_to "Recent updates", updates_path
|
||||
>>>>>>> 9f70027f872c93cae57f68f0124f0fff222cdeee
|
||||
@@ -1,15 +1,10 @@
|
||||
.row
|
||||
.ten.columns
|
||||
%ul.link-list
|
||||
%li
|
||||
= link_to "About", "http://wiki.growstuff.org"
|
||||
%li
|
||||
= link_to "License", "https://github.com/Growstuff/growstuff/blob/dev/LICENSE.txt"
|
||||
%li
|
||||
= link_to "Github", "https://github.com/Growstuff/"
|
||||
%li
|
||||
= link_to "Wiki", "http://wiki.growstuff.org"
|
||||
%li
|
||||
= link_to "Mailing list", "http://lists.growstuff.org/mailman/listinfo/discuss"
|
||||
%li
|
||||
= link_to "Community Guidelines", "https://github.com/Growstuff/policy/blob/master/community-guidelines.md"
|
||||
.container
|
||||
.navbar.navbar-fixed-bottom
|
||||
.navbar-inner
|
||||
%ul.nav
|
||||
%li= link_to "About", "http://wiki.growstuff.org"
|
||||
%li= link_to "License", "https://github.com/Growstuff/growstuff/blob/dev/LICENSE.txt"
|
||||
%li= link_to "Github", "https://github.com/Growstuff/"
|
||||
%li= link_to "Wiki", "http://wiki.growstuff.org"
|
||||
%li= link_to "Mailing list", "http://lists.growstuff.org/mailman/listinfo/discuss"
|
||||
%li= link_to "Community Guidelines", "https://github.com/Growstuff/policy/blob/master/community-guidelines.md"
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
.row
|
||||
.ten.columns
|
||||
- if user_signed_in?
|
||||
%ul.link-list
|
||||
%li
|
||||
You are signed in as
|
||||
= current_user.email + "."
|
||||
%li
|
||||
= link_to("Log out", destroy_user_session_path, :method => :delete)
|
||||
- else
|
||||
%ul.link-list
|
||||
%li
|
||||
= link_to('Sign up', new_user_registration_path)
|
||||
%li
|
||||
= link_to('Log in', new_user_session_path)
|
||||
|
||||
.row
|
||||
.ten.columns
|
||||
%h1
|
||||
= link_to('Growstuff', root_path)
|
||||
%small
|
||||
development site
|
||||
|
||||
.navbar.navbar-static-top
|
||||
.navbar-inner
|
||||
.container
|
||||
%a.btn.btn-navbar(data-target=".nav-collapse" data-toggle="collapse")
|
||||
%span.icon-bar
|
||||
%span.icon-bar
|
||||
%span.icon-bar
|
||||
%a.brand(href=root_path) Growstuff (development site)
|
||||
.container.nav-collapse
|
||||
%ul.nav
|
||||
%li= link_to "Crops", crops_path
|
||||
%li= link_to "Members", members_path
|
||||
%li= link_to "Updates", updates_path
|
||||
- if user_signed_in?
|
||||
%li= link_to("Post an update", new_update_path)
|
||||
%li.divider-vertical
|
||||
%li= link_to current_user.username, member_path(current_user)
|
||||
%li= link_to "Log out", destroy_user_session_path, :method => :delete
|
||||
- else
|
||||
%li.divider-vertical
|
||||
%li.pull-right= link_to 'Sign up', new_user_registration_path
|
||||
%li.pull-right= link_to 'Log in', new_user_session_path
|
||||
|
||||
@@ -2,9 +2,23 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link href='http://fonts.googleapis.com/css?family=Sevillana' rel='stylesheet' type='text/css'>
|
||||
|
||||
- if (content_for?(:member_rss_username) && content_for(:member_rss_slug))
|
||||
= auto_discovery_link_tag(:rss, { :controller => "/members", :action => 'show', :format => "rss", :id => yield(:member_rss_slug) }, { :title => "Growstuff - #{yield(:member_rss_username)}'s updates" })
|
||||
= auto_discovery_link_tag(:rss, { :controller => "/updates", :format => "rss" }, { :title => "Growstuff - Recent updates from all members" })
|
||||
= auto_discovery_link_tag(:rss, { :controller => "/crops", :format => "rss" }, { :title => "Growstuff - Recently added crops" })
|
||||
|
||||
%title
|
||||
= content_for?(:title) ? yield(:title) + " - Growstuff" : "Growstuff"
|
||||
= stylesheet_link_tag "application", :media => "all"
|
||||
= javascript_include_tag "application"
|
||||
= csrf_meta_tags
|
||||
|
||||
/ Le HTML5 shim, for IE6-8 support of HTML elements
|
||||
/[if lt IE 9]
|
||||
= javascript_include_tag "http://html5shim.googlecode.com/svn/trunk/html5.js"
|
||||
= stylesheet_link_tag "application", :media => "all"
|
||||
%link(href="images/apple-touch-icon-144x144.png" rel="apple-touch-icon-precomposed" sizes="144x144")
|
||||
%link(href="images/apple-touch-icon-114x114.png" rel="apple-touch-icon-precomposed" sizes="114x114")
|
||||
%link(href="images/apple-touch-icon-72x72.png" rel="apple-touch-icon-precomposed" sizes="72x72")
|
||||
%link(href="images/apple-touch-icon.png" rel="apple-touch-icon-precomposed")
|
||||
%link(href="images/favicon.ico" rel="shortcut icon")
|
||||
|
||||
39
app/views/layouts/_meta.html.haml.orig
Normal file
@@ -0,0 +1,39 @@
|
||||
%head
|
||||
<<<<<<< HEAD
|
||||
%meta(charset="utf-8")
|
||||
%meta(http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1")
|
||||
%meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
|
||||
%title= content_for?(:title) ? yield(:title) + " - Growstuff" : "Growstuff"
|
||||
=======
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link href='http://fonts.googleapis.com/css?family=Sevillana' rel='stylesheet' type='text/css'>
|
||||
|
||||
- if (content_for?(:member_rss_username) && content_for(:member_rss_slug))
|
||||
= auto_discovery_link_tag(:rss, { :controller => "members", :action => 'show', :format => "rss", :id => yield(:member_rss_slug) }, { :title => "Growstuff - #{yield(:member_rss_username)}'s updates" })
|
||||
= auto_discovery_link_tag(:rss, { :controller => "updates", :format => "rss" }, { :title => "Growstuff - Recent updates from all members" })
|
||||
= auto_discovery_link_tag(:rss, { :controller => "crops", :format => "rss" }, { :title => "Growstuff - Recently added crops" })
|
||||
|
||||
%title
|
||||
= content_for?(:title) ? yield(:title) + " - Growstuff" : "Growstuff"
|
||||
= stylesheet_link_tag "application", :media => "all"
|
||||
= javascript_include_tag "application"
|
||||
= csrf_meta_tags
|
||||
>>>>>>> 9f70027f872c93cae57f68f0124f0fff222cdeee
|
||||
|
||||
- if (content_for?(:member_rss_username) && content_for(:member_rss_slug))
|
||||
= auto_discovery_link_tag(:rss, { :controller => "members", :action => 'show', :format => "rss", :id => yield(:member_rss_slug) }, { :title => "Growstuff - #{yield(:member_rss_username)}'s updates" })
|
||||
= auto_discovery_link_tag(:rss, { :controller => "updates", :format => "rss" }, { :title => "Growstuff - Recent updates from all members" })
|
||||
= auto_discovery_link_tag(:rss, { :controller => "crops", :format => "rss" }, { :title => "Growstuff - Recently added crops" })
|
||||
|
||||
= csrf_meta_tags
|
||||
/ Le HTML5 shim, for IE6-8 support of HTML elements
|
||||
/[if lt IE 9]
|
||||
= javascript_include_tag "http://html5shim.googlecode.com/svn/trunk/html5.js"
|
||||
= stylesheet_link_tag "application", :media => "all"
|
||||
%link(href="images/apple-touch-icon-144x144.png" rel="apple-touch-icon-precomposed" sizes="144x144")
|
||||
%link(href="images/apple-touch-icon-114x114.png" rel="apple-touch-icon-precomposed" sizes="114x114")
|
||||
%link(href="images/apple-touch-icon-72x72.png" rel="apple-touch-icon-precomposed" sizes="72x72")
|
||||
%link(href="images/apple-touch-icon.png" rel="apple-touch-icon-precomposed")
|
||||
%link(href="images/favicon.ico" rel="shortcut icon")
|
||||
@@ -1,16 +1,26 @@
|
||||
%html
|
||||
!!! 5
|
||||
%html(lang="en")
|
||||
= render :partial => "layouts/meta"
|
||||
%body
|
||||
= render :partial => "layouts/header"
|
||||
.row
|
||||
.ten.columns
|
||||
- if content_for?(:title)
|
||||
%h2=yield(:title)
|
||||
- if notice
|
||||
%div.alert-box.success
|
||||
= notice
|
||||
- if alert
|
||||
%div.alert-box.alert
|
||||
= alert
|
||||
= yield
|
||||
= render :partial => "layouts/footer"
|
||||
|
||||
.container
|
||||
.row
|
||||
.span12
|
||||
- if content_for?(:title)
|
||||
%h1= yield(:title)
|
||||
- if notice
|
||||
%div.alert.alert-success
|
||||
= notice
|
||||
- if alert
|
||||
%div.alert
|
||||
= alert
|
||||
= yield
|
||||
|
||||
%footer
|
||||
= render :partial => "layouts/footer"
|
||||
/
|
||||
Javascripts
|
||||
\==================================================
|
||||
/ Placed at the end of the document so the pages load faster
|
||||
= javascript_include_tag "application"
|
||||
|
||||
9
app/views/members/index.html.haml
Normal file
@@ -0,0 +1,9 @@
|
||||
= content_for :title, "Growstuff members"
|
||||
|
||||
%ul.thumbnails
|
||||
- @members.each do |m|
|
||||
%li.span2
|
||||
.thumbnail
|
||||
= image_tag('http://placehold.it/150x150', :alt => '', :class => 'img-rounded')
|
||||
%h3= link_to m.username, member_path(m)
|
||||
|
||||
43
app/views/members/show.html.haml
Normal file
@@ -0,0 +1,43 @@
|
||||
- content_for :title, "#{@member.username}"
|
||||
- content_for :member_rss_username, "#{@member.username}"
|
||||
- content_for :member_rss_slug, "#{@member.slug}"
|
||||
|
||||
.row
|
||||
.span3
|
||||
=image_tag('http://placehold.it/150x150', :alt => '', :class => 'img-rounded')
|
||||
%h4= @member.username
|
||||
|
||||
%p
|
||||
= "Member since: #{@member.created_at.strftime("%B %d, %Y")}."
|
||||
%p Location: Unknown
|
||||
|
||||
.span9
|
||||
.tabbable
|
||||
%ul.nav.nav-tabs
|
||||
%li.active
|
||||
= link_to 'My Garden', '#tab1', 'data-toggle' => 'tab'
|
||||
%li
|
||||
= link_to '2nd Garden', '#tab2', 'data-toggle' => 'tab'
|
||||
%li
|
||||
= link_to '3nd Garden', '#tab3', 'data-toggle' => 'tab'
|
||||
.tab-content
|
||||
.tab-pane.active#tab1
|
||||
%ul.thumbnails
|
||||
- (1..4).each do
|
||||
%li.span2
|
||||
.thumbnail
|
||||
= image_tag('http://placehold.it/150x150', :alt => '', :class => 'img-rounded')
|
||||
%h4 Some crop
|
||||
%p Planted YYYY-MM-DD. 99 updates.
|
||||
|
||||
.tab-pane#tab2
|
||||
Multiple gardens aren't supported yet. This is just to show how they could be tabbed.
|
||||
.tab-pane#tab3
|
||||
Multiple gardens aren't supported yet. This is just to show how they could be tabbed.
|
||||
|
||||
|
||||
%h3 Updates
|
||||
%table
|
||||
- @member.updates.each do |update|
|
||||
= render :partial => "updates/single", :locals => { :update => update, :subject => true }
|
||||
|
||||
18
app/views/members/show.rss.builder
Normal file
@@ -0,0 +1,18 @@
|
||||
xml.instruct! :xml, :version => "1.0"
|
||||
xml.rss :version => "2.0" do
|
||||
xml.channel do
|
||||
xml.title "Growstuff - #{@member.username}'s recent updates"
|
||||
xml.link member_url(@member)
|
||||
|
||||
for update in @updates
|
||||
xml.item do
|
||||
xml.author member.username
|
||||
xml.title update.subject
|
||||
xml.description update.body
|
||||
xml.pubDate update.created_at.to_s(:rfc822)
|
||||
xml.link update_url(update)
|
||||
xml.guid update_url(update)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,4 +0,0 @@
|
||||
- content_for :title, "Profile for #{@user.username}"
|
||||
|
||||
%p
|
||||
= "A Growstuff user since #{@user.created_at.strftime("%B %d, %Y")}."
|
||||
16
app/views/scientific_names/_form.html.haml
Normal file
@@ -0,0 +1,16 @@
|
||||
= form_for @scientific_name do |f|
|
||||
- if @scientific_name.errors.any?
|
||||
#error_explanation
|
||||
%h2= "#{pluralize(@scientific_name.errors.count, "error")} prohibited this scientific_name from being saved:"
|
||||
%ul
|
||||
- @scientific_name.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.field
|
||||
= f.label :scientific_name
|
||||
= f.text_field :scientific_name
|
||||
.field
|
||||
= f.label :crop_id
|
||||
= f.number_field :crop_id
|
||||
.actions
|
||||
= f.submit 'Save'
|
||||
9
app/views/scientific_names/edit.html.haml
Normal file
@@ -0,0 +1,9 @@
|
||||
%h1 Editing scientific_name
|
||||
|
||||
- if user_signed_in?
|
||||
= render 'form'
|
||||
%p
|
||||
= link_to 'Show', @scientific_name, { :class => 'btn' }
|
||||
= link_to 'Back', scientific_names_path, { :class => 'btn' }
|
||||
- else
|
||||
%div.alert You're not logged in. Only logged in users can do this.
|
||||
21
app/views/scientific_names/index.html.haml
Normal file
@@ -0,0 +1,21 @@
|
||||
%h1 Listing scientific_names
|
||||
|
||||
%table
|
||||
%tr
|
||||
%th Scientific name
|
||||
%th Crop
|
||||
%th
|
||||
%th
|
||||
%th
|
||||
|
||||
- @scientific_names.each do |scientific_name|
|
||||
%tr
|
||||
%td= scientific_name.scientific_name
|
||||
%td= scientific_name.crop_id
|
||||
%td= link_to 'Show', scientific_name
|
||||
%td= link_to 'Edit', edit_scientific_name_path(scientific_name)
|
||||
%td= link_to 'Destroy', scientific_name, method: :delete, data: { confirm: 'Are you sure?' }
|
||||
|
||||
%br
|
||||
|
||||
= link_to 'New Scientific name', new_scientific_name_path
|
||||
9
app/views/scientific_names/new.html.haml
Normal file
@@ -0,0 +1,9 @@
|
||||
%h1 New scientific_name
|
||||
|
||||
- if user_signed_in?
|
||||
= render 'form'
|
||||
%p
|
||||
= link_to 'Show', @scientific_name, { :class => 'btn' }
|
||||
= link_to 'Back', scientific_names_path, { :class => 'btn' }
|
||||
- else
|
||||
%div.alert You're not logged in. Only logged in users can do this.
|
||||
12
app/views/scientific_names/show.html.haml
Normal file
@@ -0,0 +1,12 @@
|
||||
%p#notice= notice
|
||||
|
||||
%p
|
||||
%b Scientific name:
|
||||
= @scientific_name.scientific_name
|
||||
%p
|
||||
%b Crop:
|
||||
= @scientific_name.crop_id
|
||||
|
||||
= link_to 'Edit', edit_scientific_name_path(@scientific_name)
|
||||
\|
|
||||
= link_to 'Back', scientific_names_path
|
||||
19
app/views/updates/_form.html.haml
Normal file
@@ -0,0 +1,19 @@
|
||||
= form_for @update do |f|
|
||||
- if @update.errors.any?
|
||||
#error_explanation
|
||||
%h2= "#{pluralize(@update.errors.count, "error")} prohibited this update from being saved:"
|
||||
%ul
|
||||
- @update.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.field
|
||||
= f.label :user_id
|
||||
= f.number_field :user_id
|
||||
.field
|
||||
= f.label :subject
|
||||
= f.text_field :subject
|
||||
.field
|
||||
= f.label :body
|
||||
= f.text_area :body
|
||||
.actions
|
||||
= f.submit 'Save'
|
||||
20
app/views/updates/_single.html.haml
Normal file
@@ -0,0 +1,20 @@
|
||||
.well
|
||||
%div.update
|
||||
- if subject
|
||||
%h3= link_to strip_tags(update.subject), update
|
||||
|
||||
%div.update-meta
|
||||
Posted by
|
||||
= link_to update.user.username, member_path(update.user)
|
||||
at
|
||||
= update.created_at
|
||||
|
||||
%div.update-body
|
||||
:markdown
|
||||
#{ strip_tags update.body }
|
||||
|
||||
- if current_user == update.user
|
||||
%div.update-actions
|
||||
= link_to 'Edit', edit_update_path(update), :class => 'btn'
|
||||
= link_to 'Delete', update, method: :delete, |
|
||||
data: { confirm: 'Are you sure?' }, :class => 'btn'
|
||||
10
app/views/updates/edit.html.haml
Normal file
@@ -0,0 +1,10 @@
|
||||
= content_for :title, "Edit update"
|
||||
|
||||
- if user_signed_in?
|
||||
= form_for @update do |f|
|
||||
= label_tag :subject, "Subject"
|
||||
= f.text_field :subject, :class => 'input-block-level'
|
||||
= f.text_area :body, :rows => 12, :class => 'input-block-level'
|
||||
= f.submit "Post"
|
||||
- else
|
||||
%div.alert You're not logged in. Only logged in users can do this.
|
||||
6
app/views/updates/index.html.haml
Normal file
@@ -0,0 +1,6 @@
|
||||
= content_for :title, "Recent Growstuff member updates"
|
||||
|
||||
- @updates.each do |update|
|
||||
= render :partial => "single", :locals => { :update => update, :subject => true }
|
||||
|
||||
= link_to 'New Update', new_update_path
|
||||
18
app/views/updates/index.rss.builder
Normal file
@@ -0,0 +1,18 @@
|
||||
xml.instruct! :xml, :version => "1.0"
|
||||
xml.rss :version => "2.0" do
|
||||
xml.channel do
|
||||
xml.title "Growstuff - Recent updates from all members"
|
||||
xml.link updates_url
|
||||
|
||||
for update in @recent_updates
|
||||
xml.item do
|
||||
xml.author update.user.username
|
||||
xml.title update.subject
|
||||
xml.description update.body
|
||||
xml.pubDate update.created_at.to_s(:rfc822)
|
||||
xml.link update_url(update)
|
||||
xml.guid update_url(update)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
14
app/views/updates/new.html.haml
Normal file
@@ -0,0 +1,14 @@
|
||||
= content_for :title, "Post an update"
|
||||
|
||||
- if user_signed_in?
|
||||
= form_for @update, :url => { :action => "create" } do |f|
|
||||
%fieldset
|
||||
= label_tag :update, "Subject"
|
||||
= f.text_field :subject, :class => 'input-block-level'
|
||||
= label_tag :body, "What's going on in your food garden?"
|
||||
= f.text_area :body, :rows => 12, :class => 'input-block-level'
|
||||
= f.submit "Post", :class => 'btn'
|
||||
- else
|
||||
%div.alert You're not logged in. Only logged in users can do this.
|
||||
|
||||
= link_to 'Back', updates_path
|
||||
3
app/views/updates/show.html.haml
Normal file
@@ -0,0 +1,3 @@
|
||||
= content_for :title, @update.subject
|
||||
|
||||
= render :partial => "single", :locals => { :update => @update, :subject => false }
|
||||
@@ -1,4 +1,3 @@
|
||||
require 'zurb-foundation'
|
||||
# Require any additional compass plugins here.
|
||||
|
||||
# Set this to the root of your project when deployed:
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
Growstuff::Application.routes.draw do
|
||||
resources :gardens
|
||||
|
||||
resources :crops, :profile
|
||||
|
||||
resources :updates
|
||||
resources :scientific_names
|
||||
resources :crops
|
||||
resources :members
|
||||
devise_for :users
|
||||
|
||||
get "home/index"
|
||||
|
||||
@@ -3,7 +3,6 @@ class CreateCrops < ActiveRecord::Migration
|
||||
create_table :crops do |t|
|
||||
t.string :system_name
|
||||
t.string :en_wikipedia_url
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
class SetupTestUsers < ActiveRecord::Migration
|
||||
def up
|
||||
if Rails.env.development? or Rails.env.test?
|
||||
(1..3).each do |i|
|
||||
@user = User.create(:username => "test#{i}", :email => "test#{i}@example.com", :password => "password#{i}")
|
||||
@user.save!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
if Rails.env.development? or Rails.env.test?
|
||||
(1..3).each do |i|
|
||||
@user = User.find_by_username("test#{i}")
|
||||
@user.try(:destroy)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
6
db/migrate/20121106101718_add_slug_to_users.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class AddSlugToUsers < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :slug, :string
|
||||
add_index :users, :slug, unique: true
|
||||
end
|
||||
end
|
||||
10
db/migrate/20121106101936_give_old_members_new_slugs.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class GiveOldMembersNewSlugs < ActiveRecord::Migration
|
||||
def up
|
||||
User.find_each(&:save)
|
||||
end
|
||||
|
||||
# note: this is basically impossible to reverse without removing
|
||||
# friendly_id, because friendly_id automatically updates the slug when
|
||||
# you save the object.
|
||||
|
||||
end
|
||||
10
db/migrate/20121107012827_create_scientific_names.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class CreateScientificNames < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :scientific_names do |t|
|
||||
t.string :scientific_name, :null => false
|
||||
t.integer :crop_id, :null => false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
11
db/migrate/20121108105440_create_updates.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class CreateUpdates < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :updates do |t|
|
||||
t.integer :user_id, :null => false
|
||||
t.string :subject, :null => false
|
||||
t.text :body, :null => false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddCreationIndexToUpdates < ActiveRecord::Migration
|
||||
def change
|
||||
add_index :updates, [:created_at, :user_id]
|
||||
end
|
||||
end
|
||||
21
db/schema.rb
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20121105052119) do
|
||||
ActiveRecord::Schema.define(:version => 20121109130033) do
|
||||
|
||||
create_table "crops", :force => true do |t|
|
||||
t.string "system_name", :null => false
|
||||
@@ -35,6 +35,23 @@ ActiveRecord::Schema.define(:version => 20121105052119) do
|
||||
add_index "gardens", ["slug"], :name => "index_gardens_on_slug", :unique => true
|
||||
add_index "gardens", ["user_id"], :name => "index_gardens_on_user_id"
|
||||
|
||||
create_table "scientific_names", :force => true do |t|
|
||||
t.string "scientific_name", :null => false
|
||||
t.integer "crop_id", :null => false
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
create_table "updates", :force => true do |t|
|
||||
t.integer "user_id", :null => false
|
||||
t.string "subject", :null => false
|
||||
t.text "body", :null => false
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
add_index "updates", ["created_at", "user_id"], :name => "index_updates_on_created_at_and_user_id"
|
||||
|
||||
create_table "users", :force => true do |t|
|
||||
t.string "email", :default => "", :null => false
|
||||
t.string "encrypted_password", :default => "", :null => false
|
||||
@@ -56,11 +73,13 @@ ActiveRecord::Schema.define(:version => 20121105052119) do
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.string "username"
|
||||
t.string "slug"
|
||||
end
|
||||
|
||||
add_index "users", ["confirmation_token"], :name => "index_users_on_confirmation_token", :unique => true
|
||||
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
|
||||
add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true
|
||||
add_index "users", ["slug"], :name => "index_users_on_slug", :unique => true
|
||||
add_index "users", ["unlock_token"], :name => "index_users_on_unlock_token", :unique => true
|
||||
|
||||
end
|
||||
|
||||
22
db/seeds.rb
@@ -5,3 +5,25 @@
|
||||
#
|
||||
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
|
||||
# Mayor.create(name: 'Emanuel', city: cities.first)
|
||||
|
||||
# import crops from CSV
|
||||
|
||||
require 'csv'
|
||||
|
||||
puts "Loading crops..."
|
||||
CSV.foreach(Rails.root.join('db', 'seeds', 'crops.csv')) do |row|
|
||||
system_name,scientific_name,en_wikipedia_url = row
|
||||
@crop = Crop.create(:system_name => system_name, :en_wikipedia_url => en_wikipedia_url)
|
||||
@crop.scientific_names.create(:scientific_name => scientific_name)
|
||||
end
|
||||
puts "Finished loading crops"
|
||||
|
||||
puts "Loading test users..."
|
||||
if Rails.env.development? or Rails.env.test?
|
||||
(1..3).each do |i|
|
||||
@user = User.create(:username => "test#{i}", :email => "test#{i}@example.com", :password => "password#{i}")
|
||||
@user.confirm!
|
||||
@user.save!
|
||||
end
|
||||
end
|
||||
puts "Finished loading test users"
|
||||
|
||||
233
db/seeds/crops.csv
Normal file
@@ -0,0 +1,233 @@
|
||||
achiote,Bixa orellana,https://en.wikipedia.org/wiki/Bixa_orellana
|
||||
ackee,Blighia sapida,https://en.wikipedia.org/wiki/Ackee
|
||||
acuyo,Piper auritum,https://en.wikipedia.org/wiki/Piper_auritum
|
||||
alexanders,Smyrnium olusatrum,https://en.wikipedia.org/wiki/Alexanders
|
||||
alfalfa,Medicago sativa,https://en.wikipedia.org/wiki/Alfalfa
|
||||
allspice,Pimenta dioica,https://en.wikipedia.org/wiki/Allspice
|
||||
almond,Prunus dulcis,https://en.wikipedia.org/wiki/Almond
|
||||
amaranth,Amaranthus spp.,https://en.wikipedia.org/wiki/Amaranth
|
||||
anise,Pimpinella anisum,https://en.wikipedia.org/wiki/Anise
|
||||
apple,Malus domestica,https://en.wikipedia.org/wiki/Apple
|
||||
apple mint,Mentha suaveolens,https://en.wikipedia.org/wiki/Apple_mint
|
||||
apricot,Prunus armeniaca,https://en.wikipedia.org/wiki/Apricot
|
||||
arrowroot,Maranta arundinacea,https://en.wikipedia.org/wiki/Maranta_arundinacea
|
||||
artichoke,Cynara cardunculus,https://en.wikipedia.org/wiki/Artichoke
|
||||
arugula,Eruca sativa,https://en.wikipedia.org/wiki/Arugula
|
||||
asparagus,Asparagus officinalis,https://en.wikipedia.org/wiki/Asparagus
|
||||
avocado,Persea americana,https://en.wikipedia.org/wiki/Avocado
|
||||
banana,Musa spp.,https://en.wikipedia.org/wiki/Banana
|
||||
barley,Hordeum vulgare,https://en.wikipedia.org/wiki/Barley
|
||||
basil,Ocimum basilicum,https://en.wikipedia.org/wiki/Basil
|
||||
bay,Laurus nobilis,https://en.wikipedia.org/wiki/Bay_Laurel
|
||||
bean,Phaseolus vulgaris,https://en.wikipedia.org/wiki/Common_bean
|
||||
beet,Beta vulgaris,https://en.wikipedia.org/wiki/Beet
|
||||
bell pepper,Capsicum annuum,https://en.wikipedia.org/wiki/Bell_pepper
|
||||
bitter melon,Momordica charantia,https://en.wikipedia.org/wiki/Bitter_melon
|
||||
blackberry,Rubus fruticosus,https://en.wikipedia.org/wiki/Blackberry
|
||||
blackcurrant,Ribes spp.,https://en.wikipedia.org/wiki/Ribes
|
||||
borage,Borago officinalis,https://en.wikipedia.org/wiki/Borage
|
||||
breadfruit,Artocarpus altilis,https://en.wikipedia.org/wiki/Breadfruit
|
||||
broccoli,Brassica oleracea,https://en.wikipedia.org/wiki/Broccoli
|
||||
Brussels sprout,Brassica oleracea,https://en.wikipedia.org/wiki/Brussels_sprout
|
||||
buckwheat,Fagopyrum esculentum,https://en.wikipedia.org/wiki/Buckwheat
|
||||
cabbage,Brassica oleracea,https://en.wikipedia.org/wiki/Cabbage
|
||||
cape gooseberry,Physalis peruviana,https://en.wikipedia.org/wiki/Physalis_peruviana
|
||||
caper,Capparis spinosa,https://en.wikipedia.org/wiki/Caper
|
||||
cardoon,Cynara cardunculus,https://en.wikipedia.org/wiki/Cardoon
|
||||
carrot,Daucus carota,https://en.wikipedia.org/wiki/Carrot
|
||||
cassava,Manihot esculenta,https://en.wikipedia.org/wiki/Cassava
|
||||
catnip,Nepeta cataria,https://en.wikipedia.org/wiki/Nepeta_cataria
|
||||
cauliflower,Brassica oleracea,https://en.wikipedia.org/wiki/Cauliflower
|
||||
cayenne pepper,Capsicum annuum,https://en.wikipedia.org/wiki/Cayenne_pepper
|
||||
celeriac,Apium graveolens var. rapaceum,https://en.wikipedia.org/wiki/Celeriac
|
||||
celery,Apium graveolens,https://en.wikipedia.org/wiki/Celery
|
||||
chamomile,Matricaria chamomila,https://en.wikipedia.org/wiki/Matricaria_recutita
|
||||
chaya,Cnidoscolus aconitifolius,https://en.wikipedia.org/wiki/Cnidoscolus_aconitifolius
|
||||
chayote,Sechium edule,https://en.wikipedia.org/wiki/Chayote
|
||||
cherry,Prunus avium,https://en.wikipedia.org/wiki/Cherry
|
||||
chervil,Anthriscus cerefolium,https://en.wikipedia.org/wiki/Chervil
|
||||
chestnut,Castanea spp.,https://en.wikipedia.org/wiki/Chestnut
|
||||
chickpeas,Cicer arietinum,https://en.wikipedia.org/wiki/Chickpea
|
||||
chickweed,Stellaria,https://en.wikipedia.org/wiki/Stellaria
|
||||
chicory,Cichorium intybus,https://en.wikipedia.org/wiki/Chicory
|
||||
chinese cabbage,Brassica rapa (pekinensis),https://en.wikipedia.org/wiki/Chinese_cabbage
|
||||
chives,Allium schoenoprasum,https://en.wikipedia.org/wiki/Chives
|
||||
cicely,Myrrhis odorata,https://en.wikipedia.org/wiki/Cicely
|
||||
citron,Citrus medica,https://en.wikipedia.org/wiki/Citron
|
||||
coconut,Cocos nucifera,https://en.wikipedia.org/wiki/Coconut
|
||||
collard greens,Brassica oleracea (acephala),https://en.wikipedia.org/wiki/Collard_greens
|
||||
comfrey,Symphytum officinale,https://en.wikipedia.org/wiki/Comfrey
|
||||
coriander,Coriandrum sativum,https://en.wikipedia.org/wiki/Coriander
|
||||
corn,Zea mays,https://en.wikipedia.org/wiki/Corn
|
||||
corn salad,Valerianella locusta,https://en.wikipedia.org/wiki/Corn_salad
|
||||
cress,Lepidium sativum,https://en.wikipedia.org/wiki/Garden_cress
|
||||
cucumber,Cucumis sativus,https://en.wikipedia.org/wiki/Cucumbers
|
||||
cumin,Cuminum cyminum,https://en.wikipedia.org/wiki/Cumin
|
||||
cumquat,Citrus japonica,https://en.wikipedia.org/wiki/Kumquat
|
||||
curry leaf,Murraya koenigii,https://en.wikipedia.org/wiki/Curry-leaf_Tree
|
||||
curry plant,Helichrysum italicum,https://en.wikipedia.org/wiki/Helichrysum_italicum
|
||||
daikon,Raphanus sativus Longipinnatus group,https://en.wikipedia.org/wiki/Daikon
|
||||
dandelion,Taraxacum officinale,https://en.wikipedia.org/wiki/Dandelion
|
||||
dates,Phoenix dactylifera,https://en.wikipedia.org/wiki/Date_%28fruit%29
|
||||
desert lime,Citrus glauca,https://en.wikipedia.org/wiki/Citrus_glauca
|
||||
dill,Anethum graveolens,https://en.wikipedia.org/wiki/Dill
|
||||
dog rose,Rosa canina,https://en.wikipedia.org/wiki/Rosa_canina
|
||||
durian,Durio,https://en.wikipedia.org/wiki/Durian
|
||||
eggplant,Solanum melongena,https://en.wikipedia.org/wiki/Eggplant
|
||||
elderberry,Sambucus nigra,https://en.wikipedia.org/wiki/Sambucus_nigra
|
||||
endive,Cichorium endivia,https://en.wikipedia.org/wiki/Endive
|
||||
epazote,Dysphania ambrosioides,https://en.wikipedia.org/wiki/Epazote
|
||||
fava bean,Vicia faba,https://en.wikipedia.org/wiki/Vicia_faba
|
||||
feijoa,Acca sellowiana,https://en.wikipedia.org/wiki/Acca_sellowiana
|
||||
fennel,Foeniculum vulgare,https://en.wikipedia.org/wiki/Fennel
|
||||
fenugreek,Trigonella foenum-graecum,https://en.wikipedia.org/wiki/Fenugreek
|
||||
fiddlehead,Pteridium aquilinum,https://en.wikipedia.org/wiki/Fiddlehead
|
||||
fig,Ficus carica,https://en.wikipedia.org/wiki/Common_fig
|
||||
flax,Linum usitatissimum,https://en.wikipedia.org/wiki/Flax
|
||||
garlic,Allium sativum,https://en.wikipedia.org/wiki/Garlic
|
||||
garlic chives,Allium tuberosum,https://en.wikipedia.org/wiki/Garlic_chives
|
||||
ginger,Zingiber officinale,https://en.wikipedia.org/wiki/Ginger
|
||||
gooseberry,Ribes uva-crispa,https://en.wikipedia.org/wiki/Gooseberry
|
||||
grapefruit,Citrus paradisi,https://en.wikipedia.org/wiki/Grapefruit
|
||||
grapes,Vitis spp.,https://en.wikipedia.org/wiki/Grape
|
||||
guava,Psidium spp.,https://en.wikipedia.org/wiki/Guava
|
||||
habanero,Capsicum chinense,https://en.wikipedia.org/wiki/Habanero
|
||||
hibiscus,Hibiscus,https://en.wikipedia.org/wiki/Hibiscus
|
||||
horseradish,Armoracia rusticana,https://en.wikipedia.org/wiki/Horseradish
|
||||
jasmine,Jasminum officinale,https://en.wikipedia.org/wiki/Jasmine
|
||||
Jerusalem artichoke,Helianthus tuberosus,https://en.wikipedia.org/wiki/Jerusalem_artichoke
|
||||
jicama,Pachyrhizus erosus,https://en.wikipedia.org/wiki/Jicama
|
||||
juniper berry,Juniperus communis,https://en.wikipedia.org/wiki/Juniper_berry
|
||||
kaffir lime,Citrus x hystrix,https://en.wikipedia.org/wiki/Kaffir_lime
|
||||
kale,Brassica oleracea (acephala),https://en.wikipedia.org/wiki/Kale
|
||||
kava,Piper methysticum,https://en.wikipedia.org/wiki/Kava
|
||||
kohlrabi,Brassica oleracea (gongylodes),https://en.wikipedia.org/wiki/Kohlrabi
|
||||
lavender,Lavandula spp.,https://en.wikipedia.org/wiki/Lavender
|
||||
leek,Allium ampeloprasum var. porrum,https://en.wikipedia.org/wiki/Leeks
|
||||
lemon,Citrus limon,https://en.wikipedia.org/wiki/Lemon
|
||||
lemon balm,Melissa officinalis,https://en.wikipedia.org/wiki/Lemon_balm
|
||||
lemon myrtle,Backhousia citriodora,https://en.wikipedia.org/wiki/Backhousia_citriodora
|
||||
lemon verbena,Aloysia citrodora,https://en.wikipedia.org/wiki/Aloysia_citrodora
|
||||
lemongrass,Cymbopogon spp.,https://en.wikipedia.org/wiki/Lemongrass
|
||||
lentils,Lens culinaris,https://en.wikipedia.org/wiki/Lentil
|
||||
lettuce,Lactuca sativa,https://en.wikipedia.org/wiki/Lettuce
|
||||
licorice,Glycyrrhiza glabra,https://en.wikipedia.org/wiki/Licorice
|
||||
lillipilli,Syzygium luehmannii,https://en.wikipedia.org/wiki/Syzygium_luehmannii
|
||||
lima bean,Phaseolus lunatus,https://en.wikipedia.org/wiki/Phaseolus_lunatus
|
||||
lime,Citrus spp.,https://en.wikipedia.org/wiki/Lime_%28fruit%29
|
||||
lovage,Levisticum officinale,https://en.wikipedia.org/wiki/Lovage
|
||||
luffa,Luffa cylindrica,https://en.wikipedia.org/wiki/Luffa
|
||||
lupin bean,Lupinus luteus,https://en.wikipedia.org/wiki/Lupin_bean
|
||||
macadamia,Macadamia,https://en.wikipedia.org/wiki/Macadamia
|
||||
Malabar spinach,Basella alba,https://en.wikipedia.org/wiki/Basella_alba
|
||||
mandarin,Citrus reticulata,https://en.wikipedia.org/wiki/Mandarin_orange
|
||||
mango,Mangifera spp.,https://en.wikipedia.org/wiki/Mango
|
||||
maracuja,Passiflora edulis,https://en.wikipedia.org/wiki/Maracuja
|
||||
marjoram,Origanum majorana,https://en.wikipedia.org/wiki/Marjoram
|
||||
marshmallow,Althaea officinalis,https://en.wikipedia.org/wiki/Althaea_officinalis
|
||||
medlar,Mespilus germanica,https://en.wikipedia.org/wiki/Mespilus_germanica
|
||||
melon,Cucumis melo,https://en.wikipedia.org/wiki/Melon
|
||||
miner's lettuce,Claytonia perfoliata,https://en.wikipedia.org/wiki/Claytonia_perfoliata
|
||||
mint,Mentha spicata,https://en.wikipedia.org/wiki/Mentha_spicata
|
||||
mung bean,Vigna radiata,https://en.wikipedia.org/wiki/Mung_bean
|
||||
mustard,Brassica juncea,https://en.wikipedia.org/wiki/Mustard_plant
|
||||
nasturtium,Tropaeloum spp.,https://en.wikipedia.org/wiki/Tropaeolum
|
||||
New Zealand spinach,Tetragonia tetragonioides,https://en.wikipedia.org/wiki/Tetragonia
|
||||
nigella,Nigella sativa,https://en.wikipedia.org/wiki/Nigella_sativa
|
||||
oats,Avena sativa,https://en.wikipedia.org/wiki/Oats
|
||||
okra,Abelmoschus esculentus,https://en.wikipedia.org/wiki/Okra
|
||||
olive,Olea europaea,https://en.wikipedia.org/wiki/Olive
|
||||
onion,Allium cepa,https://en.wikipedia.org/wiki/Onions
|
||||
orange,Citrus sinensis,https://en.wikipedia.org/wiki/Orange_%28fruit%29
|
||||
oregano,Origanum vulgare,https://en.wikipedia.org/wiki/Oregano
|
||||
parsley,Petroselinum hortense,https://en.wikipedia.org/wiki/Parsley
|
||||
parsnip,Pastinaca sativa,https://en.wikipedia.org/wiki/Parsnip
|
||||
passion fruit,Passiflora edulis,https://en.wikipedia.org/wiki/Passionfruit
|
||||
pea,Pisum sativum,https://en.wikipedia.org/wiki/Pea
|
||||
peach,Prunus persica,https://en.wikipedia.org/wiki/Peach
|
||||
peach,Prunus persica,https://en.wikipedia.org/wiki/Peach
|
||||
peanut,Arachis hypogaea,https://en.wikipedia.org/wiki/Peanut
|
||||
pear,Pyrus spp.,https://en.wikipedia.org/wiki/Pear
|
||||
pearl millet,Pennisetum glaucum,https://en.wikipedia.org/wiki/Pearl_millet
|
||||
pecan,Carya illinoinensis,https://en.wikipedia.org/wiki/Pecan
|
||||
peppermint,Mentha x piperita,https://en.wikipedia.org/wiki/Peppermint
|
||||
Persian lime,Citrus latifolia,https://en.wikipedia.org/wiki/Persian_lime
|
||||
persimmon,Diospyros spp.,https://en.wikipedia.org/wiki/Persimmon
|
||||
pigeon pea,Cajanus cajan,https://en.wikipedia.org/wiki/Pigeon_pea
|
||||
pigface,Carpobrotus glaucescens,https://en.wikipedia.org/wiki/Carpobrotus_glaucescens
|
||||
pineapple,Ananas comosus,https://en.wikipedia.org/wiki/Pineapple
|
||||
pistachio,Pistacia vera,https://en.wikipedia.org/wiki/Pistachio
|
||||
plantain,Musa spp.,https://en.wikipedia.org/wiki/Plantain
|
||||
plum,Prunus spp.,https://en.wikipedia.org/wiki/Plum
|
||||
pomegranate,Punica granatum,https://en.wikipedia.org/wiki/Pomegranate
|
||||
pomelo,Citrus maxima,https://en.wikipedia.org/wiki/Pomelo
|
||||
potato,Solanum tuberosum,https://en.wikipedia.org/wiki/Potatoes
|
||||
prickly pear,Opuntia,https://en.wikipedia.org/wiki/Opuntia
|
||||
pumpkin,Cucurbita spp.,https://en.wikipedia.org/wiki/Pumpkin
|
||||
purslane,Portulaca oleracea,https://en.wikipedia.org/wiki/Portulaca_oleracea
|
||||
quandong,Santalum acuminatum,https://en.wikipedia.org/wiki/Santalum_acuminatum
|
||||
quince,Cydonia oblonga,https://en.wikipedia.org/wiki/Quince
|
||||
quinoa,Chenopodium quinoa,https://en.wikipedia.org/wiki/Quinoa
|
||||
radicchio,Cichorium intybus,https://en.wikipedia.org/wiki/Radicchio
|
||||
radish,Raphanus sativus,https://en.wikipedia.org/wiki/Radish
|
||||
rapeseed,Brassica napus,https://en.wikipedia.org/wiki/Rapeseed
|
||||
raspberry,Rubus idaeus,https://en.wikipedia.org/wiki/Rubus_idaeus
|
||||
rhubarb,Rheum rhabarbarum,https://en.wikipedia.org/wiki/Rhubarb
|
||||
rice,Oryza sativa,https://en.wikipedia.org/wiki/Rice
|
||||
rice bean,Vigna umbellata,https://en.wikipedia.org/wiki/Ricebean
|
||||
rose,Rosa,https://en.wikipedia.org/wiki/Rose
|
||||
roselle,Hibiscus sabdariffa,https://en.wikipedia.org/wiki/Roselle_%28plant%29
|
||||
rosemary,Rosmarinus officinalis,https://en.wikipedia.org/wiki/Rosemary
|
||||
rue,Ruta graveolens,https://en.wikipedia.org/wiki/Common_Rue
|
||||
runner bean,Phaseolus coccineus,https://en.wikipedia.org/wiki/Runner_bean
|
||||
rutabaga,Brassica napus Napobrassica group,https://en.wikipedia.org/wiki/Rutabaga
|
||||
rye,Secale cereale,https://en.wikipedia.org/wiki/Rye
|
||||
safflower,Carthamus tinctorius,https://en.wikipedia.org/wiki/Safflower
|
||||
saffron,Crocus sativus,https://en.wikipedia.org/wiki/Saffron
|
||||
sage,Salvia officinalis,https://en.wikipedia.org/wiki/Salvia_officinalis
|
||||
salad burnet,Sanguisorba minor,https://en.wikipedia.org/wiki/Salad_burnet
|
||||
salsify,Tragopogon porrifolius,https://en.wikipedia.org/wiki/Salsify
|
||||
samphire,Crithmum maritimum,https://en.wikipedia.org/wiki/Rock_samphire
|
||||
sassafras,Sassafras albidum,https://en.wikipedia.org/wiki/Sassafras_albidum
|
||||
sesame,Sesamum indicum,https://en.wikipedia.org/wiki/Sesame
|
||||
shallot,Allium cepa var. aggregatum,https://en.wikipedia.org/wiki/Shallot
|
||||
sorghum,Sorghum spp.,https://en.wikipedia.org/wiki/Sorghum
|
||||
sorrel,Rumex acetosa,https://en.wikipedia.org/wiki/Sorrel
|
||||
soursop,Annona muricata,https://en.wikipedia.org/wiki/Soursop
|
||||
soybean,Glycine max,https://en.wikipedia.org/wiki/Soybean
|
||||
spearmint,Mentha spicata,https://en.wikipedia.org/wiki/Mentha_spicata
|
||||
spinach,Spinacia oleracea,https://en.wikipedia.org/wiki/Spinach
|
||||
star anise,Illicium verum,https://en.wikipedia.org/wiki/Star_anise
|
||||
starfruit,Averrhoa carambola,https://en.wikipedia.org/wiki/Starfruit
|
||||
stevia,Stevia rebaudiana,https://en.wikipedia.org/wiki/Stevia
|
||||
strawberry,Fragaria ananassa,https://en.wikipedia.org/wiki/Strawberry
|
||||
summer savory,Satureja hortensis,https://en.wikipedia.org/wiki/Summer_savory
|
||||
sunflowers,Helianthus annuus,https://en.wikipedia.org/wiki/Sunflower
|
||||
sweet potato,Ipomoea batatas,https://en.wikipedia.org/wiki/Sweet_potato
|
||||
Swiss chard,Beta vulgaris var. cicla,https://en.wikipedia.org/wiki/Swiss_chard
|
||||
tamarillo,Solanum betaceum ,https://en.wikipedia.org/wiki/Tamarillo
|
||||
tamarind,Tamarindus indica,https://en.wikipedia.org/wiki/Tamarind
|
||||
tangerine,Citrus tangerina,https://en.wikipedia.org/wiki/Tangerine
|
||||
tansy,Tanacetum vulgare,https://en.wikipedia.org/wiki/Tansy
|
||||
taro,Colocasia esculenta,https://en.wikipedia.org/wiki/Taro
|
||||
tarragon,Artemisia dracunculus,https://en.wikipedia.org/wiki/Tarragon
|
||||
thyme,Thymus mongolicus,https://en.wikipedia.org/wiki/Thyme
|
||||
tomatillo,Physalis philadelphica,https://en.wikipedia.org/wiki/Tomatillo
|
||||
tomato,Solanum lycopersicum,https://en.wikipedia.org/wiki/Tomato
|
||||
turmeric,Curcuma longa,https://en.wikipedia.org/wiki/Turmeric
|
||||
turnip,Brassica rapa var. rapa,https://en.wikipedia.org/wiki/Turnip
|
||||
urad bean,Vigna mungo,https://en.wikipedia.org/wiki/Urad_(bean)
|
||||
valerian,Valeriana officinalis,https://en.wikipedia.org/wiki/Valerian_%28plant%29
|
||||
vanilla,Vanilla planifolia,https://en.wikipedia.org/wiki/Vanilla
|
||||
walnut,Juglans spp.,https://en.wikipedia.org/wiki/Walnut
|
||||
wasabi,Wasabia japonica,https://en.wikipedia.org/wiki/Wasabi
|
||||
watermelon,Citrullus lanatus,https://en.wikipedia.org/wiki/Watermelon
|
||||
wheat,Triticum spp.,https://en.wikipedia.org/wiki/Wheat
|
||||
winter savory,Satureja montana,https://en.wikipedia.org/wiki/Winter_savory
|
||||
wormwood,Artemisia absinthium,https://en.wikipedia.org/wiki/Artemisia_absinthium
|
||||
yam,Dioscorea spp.,https://en.wikipedia.org/wiki/Yam_(vegetable)
|
||||
yardlong bean,Vigna unguiculata (sesquipedalis),https://en.wikipedia.org/wiki/Yardlong_bean
|
||||
yarrow,Achillea millefolium,https://en.wikipedia.org/wiki/Achillea_millefolium
|
||||
zucchini,Cucurbita pepo.,https://en.wikipedia.org/wiki/Zucchini
|
||||
coffee,Coffea,https://en.wikipedia.org/wiki/Coffee
|
||||
tea,Camellia sinensis,https://en.wikipedia.org/wiki/Tea
|
||||
|
15
growstuff/.gitignore
vendored
@@ -1,15 +0,0 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
#
|
||||
# If you find yourself ignoring temporary files generated by your text editor
|
||||
# or operating system, you probably want to add a global ignore instead:
|
||||
# git config --global core.excludesfile ~/.gitignore_global
|
||||
|
||||
# Ignore bundler config
|
||||
/.bundle
|
||||
|
||||
# Ignore the default SQLite database.
|
||||
/db/*.sqlite3
|
||||
|
||||
# Ignore all logfiles and tempfiles.
|
||||
/log/*.log
|
||||
/tmp
|
||||
@@ -42,6 +42,15 @@ describe CropsController do
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET RSS feed" do
|
||||
it "returns an RSS feed" do
|
||||
get :index, :format => "rss"
|
||||
response.should be_success
|
||||
response.should render_template("crops/index")
|
||||
response.content_type.should eq("application/rss+xml")
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET show" do
|
||||
it "assigns the requested crop as @crop" do
|
||||
crop = Crop.create! valid_attributes
|
||||
|
||||
@@ -20,14 +20,13 @@ require 'spec_helper'
|
||||
|
||||
describe GardensController do
|
||||
|
||||
@user = User.create(:username => 'testuser', :email => 'testuser@example.com', :password => 'testuser' )
|
||||
@user.confirm!
|
||||
login_user
|
||||
|
||||
# This should return the minimal set of attributes required to create a valid
|
||||
# Garden. As you add validations to Garden, be sure to
|
||||
# update the return value of this method accordingly.
|
||||
def valid_attributes
|
||||
{:name => 'My Garden', :user_id => @user.id }
|
||||
{:name => 'My Garden', :user_id => 1 }
|
||||
end
|
||||
|
||||
# This should return the minimal set of values that should be in the session
|
||||
@@ -40,7 +39,7 @@ describe GardensController do
|
||||
describe "GET index" do
|
||||
it "assigns all gardens as @gardens" do
|
||||
garden = Garden.create! valid_attributes
|
||||
get :index, {}, valid_session
|
||||
get :index, {}
|
||||
assigns(:gardens).should eq([garden])
|
||||
end
|
||||
end
|
||||
@@ -48,14 +47,14 @@ describe GardensController do
|
||||
describe "GET show" do
|
||||
it "assigns the requested garden as @garden" do
|
||||
garden = Garden.create! valid_attributes
|
||||
get :show, {:id => garden.to_param}, valid_session
|
||||
get :show, {:id => garden.to_param}
|
||||
assigns(:garden).should eq(garden)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET new" do
|
||||
it "assigns a new garden as @garden" do
|
||||
get :new, {}, valid_session
|
||||
get :new, {}
|
||||
assigns(:garden).should be_a_new(Garden)
|
||||
end
|
||||
end
|
||||
@@ -63,7 +62,7 @@ describe GardensController do
|
||||
describe "GET edit" do
|
||||
it "assigns the requested garden as @garden" do
|
||||
garden = Garden.create! valid_attributes
|
||||
get :edit, {:id => garden.to_param}, valid_session
|
||||
get :edit, {:id => garden.to_param}
|
||||
assigns(:garden).should eq(garden)
|
||||
end
|
||||
end
|
||||
@@ -72,18 +71,18 @@ describe GardensController do
|
||||
describe "with valid params" do
|
||||
it "creates a new Garden" do
|
||||
expect {
|
||||
post :create, {:garden => valid_attributes}, valid_session
|
||||
post :create, {:garden => valid_attributes}
|
||||
}.to change(Garden, :count).by(1)
|
||||
end
|
||||
|
||||
it "assigns a newly created garden as @garden" do
|
||||
post :create, {:garden => valid_attributes}, valid_session
|
||||
post :create, {:garden => valid_attributes}
|
||||
assigns(:garden).should be_a(Garden)
|
||||
assigns(:garden).should be_persisted
|
||||
end
|
||||
|
||||
it "redirects to the created garden" do
|
||||
post :create, {:garden => valid_attributes}, valid_session
|
||||
post :create, {:garden => valid_attributes}
|
||||
response.should redirect_to(Garden.last)
|
||||
end
|
||||
end
|
||||
@@ -92,14 +91,14 @@ describe GardensController do
|
||||
it "assigns a newly created but unsaved garden as @garden" do
|
||||
# Trigger the behavior that occurs when invalid params are submitted
|
||||
Garden.any_instance.stub(:save).and_return(false)
|
||||
post :create, {:garden => {}}, valid_session
|
||||
post :create, {:garden => {}}
|
||||
assigns(:garden).should be_a_new(Garden)
|
||||
end
|
||||
|
||||
it "re-renders the 'new' template" do
|
||||
# Trigger the behavior that occurs when invalid params are submitted
|
||||
Garden.any_instance.stub(:save).and_return(false)
|
||||
post :create, {:garden => {}}, valid_session
|
||||
post :create, {:garden => {}}
|
||||
response.should render_template("new")
|
||||
end
|
||||
end
|
||||
@@ -114,18 +113,18 @@ describe GardensController do
|
||||
# receives the :update_attributes message with whatever params are
|
||||
# submitted in the request.
|
||||
Garden.any_instance.should_receive(:update_attributes).with({'these' => 'params'})
|
||||
put :update, {:id => garden.to_param, :garden => {'these' => 'params'}}, valid_session
|
||||
put :update, {:id => garden.to_param, :garden => {'these' => 'params'}}
|
||||
end
|
||||
|
||||
it "assigns the requested garden as @garden" do
|
||||
garden = Garden.create! valid_attributes
|
||||
put :update, {:id => garden.to_param, :garden => valid_attributes}, valid_session
|
||||
put :update, {:id => garden.to_param, :garden => valid_attributes}
|
||||
assigns(:garden).should eq(garden)
|
||||
end
|
||||
|
||||
it "redirects to the garden" do
|
||||
garden = Garden.create! valid_attributes
|
||||
put :update, {:id => garden.to_param, :garden => valid_attributes}, valid_session
|
||||
put :update, {:id => garden.to_param, :garden => valid_attributes}
|
||||
response.should redirect_to(garden)
|
||||
end
|
||||
end
|
||||
@@ -135,7 +134,7 @@ describe GardensController do
|
||||
garden = Garden.create! valid_attributes
|
||||
# Trigger the behavior that occurs when invalid params are submitted
|
||||
Garden.any_instance.stub(:save).and_return(false)
|
||||
put :update, {:id => garden.to_param, :garden => {}}, valid_session
|
||||
put :update, {:id => garden.to_param, :garden => {}}
|
||||
assigns(:garden).should eq(garden)
|
||||
end
|
||||
|
||||
@@ -143,7 +142,7 @@ describe GardensController do
|
||||
garden = Garden.create! valid_attributes
|
||||
# Trigger the behavior that occurs when invalid params are submitted
|
||||
Garden.any_instance.stub(:save).and_return(false)
|
||||
put :update, {:id => garden.to_param, :garden => {}}, valid_session
|
||||
put :update, {:id => garden.to_param, :garden => {}}
|
||||
response.should render_template("edit")
|
||||
end
|
||||
end
|
||||
@@ -153,13 +152,13 @@ describe GardensController do
|
||||
it "destroys the requested garden" do
|
||||
garden = Garden.create! valid_attributes
|
||||
expect {
|
||||
delete :destroy, {:id => garden.to_param}, valid_session
|
||||
delete :destroy, {:id => garden.to_param}
|
||||
}.to change(Garden, :count).by(-1)
|
||||
end
|
||||
|
||||
it "redirects to the gardens list" do
|
||||
garden = Garden.create! valid_attributes
|
||||
delete :destroy, {:id => garden.to_param}, valid_session
|
||||
delete :destroy, {:id => garden.to_param}
|
||||
response.should redirect_to(gardens_url)
|
||||
end
|
||||
end
|
||||
|
||||
32
spec/controllers/member_controller_spec.rb
Normal file
@@ -0,0 +1,32 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe MembersController do
|
||||
|
||||
login_user
|
||||
|
||||
describe "GET index" do
|
||||
it "assigns all members as @members" do
|
||||
user = User.find('fred')
|
||||
get :index, {}
|
||||
assigns(:members).should eq([user])
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET show" do
|
||||
it "assigns the requested member as @member " do
|
||||
user = User.find('fred')
|
||||
get :show, {:id => user.id}
|
||||
assigns(:member).should eq(user)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET member's RSS feed" do
|
||||
it "returns an RSS feed" do
|
||||
user = User.find('fred')
|
||||
get :show, { :id => user.to_param, :format => "rss" }
|
||||
response.should be_success
|
||||
response.should render_template("members/show")
|
||||
response.content_type.should eq("application/rss+xml")
|
||||
end
|
||||
end
|
||||
end
|
||||
164
spec/controllers/scientific_names_controller_spec.rb
Normal file
@@ -0,0 +1,164 @@
|
||||
require 'spec_helper'
|
||||
|
||||
# This spec was generated by rspec-rails when you ran the scaffold generator.
|
||||
# It demonstrates how one might use RSpec to specify the controller code that
|
||||
# was generated by Rails when you ran the scaffold generator.
|
||||
#
|
||||
# It assumes that the implementation code is generated by the rails scaffold
|
||||
# generator. If you are using any extension libraries to generate different
|
||||
# controller code, this generated spec may or may not pass.
|
||||
#
|
||||
# It only uses APIs available in rails and/or rspec-rails. There are a number
|
||||
# of tools you can use to make these specs even more expressive, but we're
|
||||
# sticking to rails and rspec-rails APIs to keep things simple and stable.
|
||||
#
|
||||
# Compared to earlier versions of this generator, there is very limited use of
|
||||
# stubs and message expectations in this spec. Stubs are only used when there
|
||||
# is no simpler way to get a handle on the object needed for the example.
|
||||
# Message expectations are only used when there is no simpler way to specify
|
||||
# that an instance is receiving a specific message.
|
||||
|
||||
describe ScientificNamesController do
|
||||
|
||||
# This should return the minimal set of attributes required to create a valid
|
||||
# ScientificName. As you add validations to ScientificName, be sure to
|
||||
# update the return value of this method accordingly.
|
||||
def valid_attributes
|
||||
{ :scientific_name => 'Solanum lycopersicum', :crop_id => 1 }
|
||||
end
|
||||
|
||||
# This should return the minimal set of values that should be in the session
|
||||
# in order to pass any filters (e.g. authentication) defined in
|
||||
# ScientificNamesController. Be sure to keep this updated too.
|
||||
def valid_session
|
||||
{}
|
||||
end
|
||||
|
||||
describe "GET index" do
|
||||
it "assigns all scientific_names as @scientific_names" do
|
||||
scientific_name = ScientificName.create! valid_attributes
|
||||
get :index, {}, valid_session
|
||||
assigns(:scientific_names).should eq([scientific_name])
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET show" do
|
||||
it "assigns the requested scientific_name as @scientific_name" do
|
||||
scientific_name = ScientificName.create! valid_attributes
|
||||
get :show, {:id => scientific_name.to_param}, valid_session
|
||||
assigns(:scientific_name).should eq(scientific_name)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET new" do
|
||||
it "assigns a new scientific_name as @scientific_name" do
|
||||
get :new, {}, valid_session
|
||||
assigns(:scientific_name).should be_a_new(ScientificName)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET edit" do
|
||||
it "assigns the requested scientific_name as @scientific_name" do
|
||||
scientific_name = ScientificName.create! valid_attributes
|
||||
get :edit, {:id => scientific_name.to_param}, valid_session
|
||||
assigns(:scientific_name).should eq(scientific_name)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST create" do
|
||||
describe "with valid params" do
|
||||
it "creates a new ScientificName" do
|
||||
expect {
|
||||
post :create, {:scientific_name => valid_attributes}, valid_session
|
||||
}.to change(ScientificName, :count).by(1)
|
||||
end
|
||||
|
||||
it "assigns a newly created scientific_name as @scientific_name" do
|
||||
post :create, {:scientific_name => valid_attributes}, valid_session
|
||||
assigns(:scientific_name).should be_a(ScientificName)
|
||||
assigns(:scientific_name).should be_persisted
|
||||
end
|
||||
|
||||
it "redirects to the created scientific_name" do
|
||||
post :create, {:scientific_name => valid_attributes}, valid_session
|
||||
response.should redirect_to(ScientificName.last)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with invalid params" do
|
||||
it "assigns a newly created but unsaved scientific_name as @scientific_name" do
|
||||
# Trigger the behavior that occurs when invalid params are submitted
|
||||
ScientificName.any_instance.stub(:save).and_return(false)
|
||||
post :create, {:scientific_name => {}}, valid_session
|
||||
assigns(:scientific_name).should be_a_new(ScientificName)
|
||||
end
|
||||
|
||||
it "re-renders the 'new' template" do
|
||||
# Trigger the behavior that occurs when invalid params are submitted
|
||||
ScientificName.any_instance.stub(:save).and_return(false)
|
||||
post :create, {:scientific_name => {}}, valid_session
|
||||
response.should render_template("new")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT update" do
|
||||
describe "with valid params" do
|
||||
it "updates the requested scientific_name" do
|
||||
scientific_name = ScientificName.create! valid_attributes
|
||||
# Assuming there are no other scientific_names in the database, this
|
||||
# specifies that the ScientificName created on the previous line
|
||||
# receives the :update_attributes message with whatever params are
|
||||
# submitted in the request.
|
||||
ScientificName.any_instance.should_receive(:update_attributes).with({'these' => 'params'})
|
||||
put :update, {:id => scientific_name.to_param, :scientific_name => {'these' => 'params'}}, valid_session
|
||||
end
|
||||
|
||||
it "assigns the requested scientific_name as @scientific_name" do
|
||||
scientific_name = ScientificName.create! valid_attributes
|
||||
put :update, {:id => scientific_name.to_param, :scientific_name => valid_attributes}, valid_session
|
||||
assigns(:scientific_name).should eq(scientific_name)
|
||||
end
|
||||
|
||||
it "redirects to the scientific_name" do
|
||||
scientific_name = ScientificName.create! valid_attributes
|
||||
put :update, {:id => scientific_name.to_param, :scientific_name => valid_attributes}, valid_session
|
||||
response.should redirect_to(scientific_name)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with invalid params" do
|
||||
it "assigns the scientific_name as @scientific_name" do
|
||||
scientific_name = ScientificName.create! valid_attributes
|
||||
# Trigger the behavior that occurs when invalid params are submitted
|
||||
ScientificName.any_instance.stub(:save).and_return(false)
|
||||
put :update, {:id => scientific_name.to_param, :scientific_name => {}}, valid_session
|
||||
assigns(:scientific_name).should eq(scientific_name)
|
||||
end
|
||||
|
||||
it "re-renders the 'edit' template" do
|
||||
scientific_name = ScientificName.create! valid_attributes
|
||||
# Trigger the behavior that occurs when invalid params are submitted
|
||||
ScientificName.any_instance.stub(:save).and_return(false)
|
||||
put :update, {:id => scientific_name.to_param, :scientific_name => {}}, valid_session
|
||||
response.should render_template("edit")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE destroy" do
|
||||
it "destroys the requested scientific_name" do
|
||||
scientific_name = ScientificName.create! valid_attributes
|
||||
expect {
|
||||
delete :destroy, {:id => scientific_name.to_param}, valid_session
|
||||
}.to change(ScientificName, :count).by(-1)
|
||||
end
|
||||
|
||||
it "redirects to the scientific_names list" do
|
||||
scientific_name = ScientificName.create! valid_attributes
|
||||
delete :destroy, {:id => scientific_name.to_param}, valid_session
|
||||
response.should redirect_to(scientific_names_url)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
180
spec/controllers/updates_controller_spec.rb
Normal file
@@ -0,0 +1,180 @@
|
||||
require 'spec_helper'
|
||||
|
||||
# This spec was generated by rspec-rails when you ran the scaffold generator.
|
||||
# It demonstrates how one might use RSpec to specify the controller code that
|
||||
# was generated by Rails when you ran the scaffold generator.
|
||||
#
|
||||
# It assumes that the implementation code is generated by the rails scaffold
|
||||
# generator. If you are using any extension libraries to generate different
|
||||
# controller code, this generated spec may or may not pass.
|
||||
#
|
||||
# It only uses APIs available in rails and/or rspec-rails. There are a number
|
||||
# of tools you can use to make these specs even more expressive, but we're
|
||||
# sticking to rails and rspec-rails APIs to keep things simple and stable.
|
||||
#
|
||||
# Compared to earlier versions of this generator, there is very limited use of
|
||||
# stubs and message expectations in this spec. Stubs are only used when there
|
||||
# is no simpler way to get a handle on the object needed for the example.
|
||||
# Message expectations are only used when there is no simpler way to specify
|
||||
# that an instance is receiving a specific message.
|
||||
|
||||
describe UpdatesController do
|
||||
|
||||
login_user
|
||||
|
||||
# This should return the minimal set of attributes required to create a valid
|
||||
# Update. As you add validations to Update, be sure to
|
||||
# update the return value of this method accordingly.
|
||||
def valid_attributes
|
||||
{ :user_id => 1, :subject => "blah", :body => "blah blah" }
|
||||
end
|
||||
|
||||
# The parameters required to be passed to a Web request.
|
||||
def valid_web_attributes
|
||||
{ :subject => "blah", :body => "blah blah" }
|
||||
end
|
||||
|
||||
# This should return the minimal set of values that should be in the session
|
||||
# in order to pass any filters (e.g. authentication) defined in
|
||||
# UpdatesController. Be sure to keep this updated too.
|
||||
def valid_session
|
||||
{}
|
||||
end
|
||||
|
||||
describe "GET index" do
|
||||
it "assigns all updates as @updates" do
|
||||
update = Update.create! valid_attributes
|
||||
get :index, {}
|
||||
assigns(:updates).should eq([update])
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET RSS feed" do
|
||||
it "returns an RSS feed" do
|
||||
get :index, :format => "rss"
|
||||
response.should be_success
|
||||
response.should render_template("updates/index")
|
||||
response.content_type.should eq("application/rss+xml")
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET show" do
|
||||
it "assigns the requested update as @update" do
|
||||
update = Update.create! valid_attributes
|
||||
get :show, {:id => update.to_param}
|
||||
assigns(:update).should eq(update)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET new" do
|
||||
it "assigns a new update as @update" do
|
||||
get :new, {}
|
||||
assigns(:update).should be_a_new(Update)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET edit" do
|
||||
it "assigns the requested update as @update" do
|
||||
update = Update.create! valid_attributes
|
||||
get :edit, {:id => update.to_param}
|
||||
assigns(:update).should eq(update)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST create" do
|
||||
describe "with valid params" do
|
||||
it "creates a new Update" do
|
||||
expect {
|
||||
post :create, {:update => valid_web_attributes}
|
||||
}.to change(Update, :count).by(1)
|
||||
end
|
||||
|
||||
it "assigns a newly created update as @update" do
|
||||
post :create, {:update => valid_web_attributes}
|
||||
assigns(:update).should be_a(Update)
|
||||
assigns(:update).should be_persisted
|
||||
end
|
||||
|
||||
it "redirects to the created update" do
|
||||
post :create, {:update => valid_web_attributes}
|
||||
response.should redirect_to(Update.last)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with invalid params" do
|
||||
it "assigns a newly created but unsaved update as @update" do
|
||||
# Trigger the behavior that occurs when invalid params are submitted
|
||||
Update.any_instance.stub(:save).and_return(false)
|
||||
post :create, {:update => {}}
|
||||
assigns(:update).should be_a_new(Update)
|
||||
end
|
||||
|
||||
it "re-renders the 'new' template" do
|
||||
# Trigger the behavior that occurs when invalid params are submitted
|
||||
Update.any_instance.stub(:save).and_return(false)
|
||||
post :create, {:update => {}}
|
||||
response.should render_template("new")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT update" do
|
||||
describe "with valid params" do
|
||||
it "updates the requested update" do
|
||||
update = Update.create! valid_attributes
|
||||
# Assuming there are no other updates in the database, this
|
||||
# specifies that the Update created on the previous line
|
||||
# receives the :update_attributes message with whatever params are
|
||||
# submitted in the request.
|
||||
Update.any_instance.should_receive(:update_attributes).with({'these' => 'params'})
|
||||
put :update, {:id => update.to_param, :update => {'these' => 'params'}}
|
||||
end
|
||||
|
||||
it "assigns the requested update as @update" do
|
||||
update = Update.create! valid_attributes
|
||||
put :update, {:id => update.to_param, :update => valid_attributes}
|
||||
assigns(:update).should eq(update)
|
||||
end
|
||||
|
||||
it "redirects to the update" do
|
||||
update = Update.create! valid_attributes
|
||||
put :update, {:id => update.to_param, :update => valid_attributes}
|
||||
response.should redirect_to(update)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with invalid params" do
|
||||
it "assigns the update as @update" do
|
||||
update = Update.create! valid_attributes
|
||||
# Trigger the behavior that occurs when invalid params are submitted
|
||||
Update.any_instance.stub(:save).and_return(false)
|
||||
put :update, {:id => update.to_param, :update => {}}
|
||||
assigns(:update).should eq(update)
|
||||
end
|
||||
|
||||
it "re-renders the 'edit' template" do
|
||||
update = Update.create! valid_attributes
|
||||
# Trigger the behavior that occurs when invalid params are submitted
|
||||
Update.any_instance.stub(:save).and_return(false)
|
||||
put :update, {:id => update.to_param, :update => {}}
|
||||
response.should render_template("edit")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE destroy" do
|
||||
it "destroys the requested update" do
|
||||
update = Update.create! valid_attributes
|
||||
expect {
|
||||
delete :destroy, {:id => update.to_param}
|
||||
}.to change(Update, :count).by(-1)
|
||||
end
|
||||
|
||||
it "redirects to the updates list" do
|
||||
update = Update.create! valid_attributes
|
||||
delete :destroy, {:id => update.to_param}
|
||||
response.should redirect_to(updates_url)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
15
spec/helpers/scientific_names_helper_spec.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
require 'spec_helper'
|
||||
|
||||
# Specs in this file have access to a helper object that includes
|
||||
# the ScientificNamesHelper. For example:
|
||||
#
|
||||
# describe ScientificNamesHelper do
|
||||
# describe "string concat" do
|
||||
# it "concats two strings with spaces" do
|
||||
# helper.concat_strings("this","that").should == "this that"
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
describe ScientificNamesHelper do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
15
spec/helpers/updates_helper_spec.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
require 'spec_helper'
|
||||
|
||||
# Specs in this file have access to a helper object that includes
|
||||
# the UpdatesHelper. For example:
|
||||
#
|
||||
# describe UpdatesHelper do
|
||||
# describe "string concat" do
|
||||
# it "concats two strings with spaces" do
|
||||
# helper.concat_strings("this","that").should == "this that"
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
describe UpdatesHelper do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||