How to Implement jQuery Colorbox

What is jQuery Colorbox?

jQuery Colorbox is a lightbox plugin that supports “photos, grouping, slideshow, ajax, inline, and iframed content.” In a nutshell, you can create nice looking popup boxes to display pictures and text.

What did I do with it?

In my particular use case, I had an HTML/CSS webpage (with some Javascript thrown in) that needed a popup that met the following conditions:

  1. If a user visited the webpage and didn’t click a checkbox in the colorbox that said “Don’t show again”, then the colorbox would keep appearing everytime they visited.

  2. If a user visited the webpage clicked the checkbox that said “Don’t show again”, then the colorbox would no longer appear ever again (actually, I set an expiration date of 10 years, but more on this later).

  3. The popup also had to be a certain color.

The following steps tell you how to implement the colorbox.

Step 1 – Add some custom styling

To change the colorbox styling, I modified the colorbox.css file from the example1 folder of the colorbox plugin. Essentially, I removed the background images and used background colors instead.

01
02
    #cboxTopLeft{width:5px; height:5px; background: #990000 no-repeat -101px 0;}
03
    #cboxTopRight{width:5px; height:5px; background: #990000 no-repeat -130px 0;}
04
    #cboxBottomLeft{width:5px; height:5px; background: #990000 no-repeat -101px -29px;}
05
    #cboxBottomRight{width:5px; height:5px; background: #990000 no-repeat -130px -29px;}
06
    #cboxMiddleLeft{width:5px; background: #990000 left top repeat-y;}
07
    #cboxMiddleRight{width:5px; background: #990000 right top repeat-y;}
08
    #cboxTopCenter{height:5px; background: #990000 0 0 repeat-x;}
09
    #cboxBottomCenter{height:5px; background: #990000 0 -29px repeat-x;}
10

Step 2 – Add the inline div

1
2
  <div id="overlay_display" style="display: none;">
3
    <div style="font-style: italic; color: #666; padding: 10px 10px 10px 10px;">
4
      <p style="font-size: 120%;">Check "who you are" and "your responsibilities" to view a more complete list.</p>
5
      <br/><br/>
6
      <p><input type="checkbox" name="display_permission" id="display_permission" value="true">Don't show anymore.</p>
7
    </div>
8
  </div>
9

Step 3 – Add the jQuery code

There are 3 different things going on:

  1. The function check_cookie() checks to see if a cookie of a certain name has been set. If it has, then it returns true, otherwise it returns false.

  2. The $(‘#display_permission’).change() function checkts to see if the checkbox in the colorbox has been checked. If it has, then it sets a cookie by the name of no_overlay_display to expire 10 years from now.

  3. Finally, $(“ul#roles li”).click(), checks to see if it’s a user’s first browser session and a cookie has not been set. If both those conditions are true, then it will open a colorbox for several seconds before closing it, allowing the user to check a checkbox if they don’t want to see the colorbox again (or 10 years, since that’s what the expiration time is set to in the cookie). You’ll also notice I fade the colorbox in with the jQuery fadeIn() method and fade it out with the fadeOut() method.

01
02
function check_cookie(cname) {
03
  var dc = document.cookie;
04
  var exists = false;
05
  var exists_index = dc.indexOf(cname);
06
  if (exists_index >=0) {
07
    exists = true;
08
  }
09
  return exists;
10
}
11
 
12
$('#display_permission').change(function(e){
13
    var checkit = this.checked;
14
    if (checkit) {
15
      var now = new Date();
16
      var time = now.getTime();
17
      var expireTime = time + 315569259747; //expire 10 years from now
18
      now.setTime(expireTime);
19
      document.cookie = 'cookie=no_overlay_display;expires='+now.toGMTString()+';path=/';
20
      setTimeout($.colorbox.remove, 500); //wait 1/2 sec before destroying colorbox
21
    }
22
  });
23
 
24
var max_sessions = 0;
25
$("ul#roles li").click(function(e) 
26
{
27
  if (!check_cookie("no_overlay_display")&amp;&amp;max_sessions<1) {
28
    max_sessions++;
29
    $.colorbox({ 
30
        left: "30%",
31
        width: "200px",
32
        height: "150px",
33
        inline: true, 
34
        href:"#overlay_display",
35
        overlayClose: true,
36
        transition: "none",
37
        onLoad: function ()
38
        {
39
            $('#overlay_display').fadeIn();
40
            setTimeout($.colorbox.close, 7000);
41
        },
42
        onClosed: function ()
43
        {
44
            $('#overlay_display').fadeOut();
45
        }
46
    });
47
  } //end if
48
});
49

Step 4 – Don’t forget to link to the stylesheet and javascript files in your main webpage

1
2
<link href="stylesheets/colorbox.css" rel="stylesheet">
3
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
4
<script src="javascripts/main.js"></script>
5

How to Add jQuery UI Datepicker To Your Rails 4 Application With Formtastic and Cocoon

What is Formtastic, Cocoon, and jQuery UI Datepicker?

Formtastic is a gem that lets you add forms more easily to your Rails application. Cocoon allows you to add dynamic nested forms to your Rails application using jQuery. jQuery-ui Datepicker allows you to present the user with a nice date selection calendar when entering date information.

In this article I will give you the recipe for adding jquery-ui datepicker with formtastic and cocoon in your Rails 4 application.

Step 1 – Add the formtastic, jquery-ui-rails, and cocoon gems to your Gemfile and then install them using bundle install command

1
2
gem 'formtastic', '~>3.0.0rc'
3
gem 'jquery-ui-rails'
4
gem "cocoon"
5

Step 1a – Run the formtastic generator

1
2
rails generate formtastic:install
3

Step 2 – Add the Cocoon markup to your views along with the Formtastic markup

These are my rails models, Person and Report

1
2
class Person < ActiveRecord::Base
3
  has_many :reports, dependent: :destroy
4
end
5
 
6
class Report < ActiveRecord::Base
7
  belongs_to :person
8
end
9

This is the formtastic and cocoon code in my Rails view

01
02
= semantic_form_for @person, url: {action: "update_it" } do |f|
03
  - if @person.errors.any?
04
    #error_explanation
05
      %h2= "#{pluralize(@person.errors.count, "error")} prohibited this person and their reports from being displayed:"
06
      %ul
07
        - @person.errors.full_messages.each do |msg|
08
          %li= msg
09
 
10
  %h4 Reports
11
    #reports
12
      = f.semantic_fields_for :reports do |report|
13
        = render 'report_fields', :f => report
14
      .links
15
        = link_to_add_association 'Add Report', f, :reports
16

This is the ‘report_fields’ partial called above

1
2
.nested-fields
3
  = f.inputs :name => "Report(s)" do
4
    = f.input :title
5
    = f.input :date_published, :as => :date_picker, :input_html => { :class=> "ui-datepicker", :value => (f.object.date_published.try(:strftime,'%m/%d/%Y'))}
6
    = f.input :report_type
7
    = link_to_remove_association "Remove Report", f
8

Notice in the report_fields partial how I am calling the try method. This is a Rails method that tries calling a method on an object, but returns nil instead of raising an exception if that object is nil.

For example, suppose you had an object called person that had a nil assignment (as in person=nil). If you tried calling person.first_name, you would get an error because person is a nil instance. Using try, as in person.try(:first_name) simply results in a nil value returned.

Step 3 – Add the required calls in your assets library

In application.js

1
2
//= require cocoon
3
//= require jquery-ui
4

Note: If you don’t want to include the entire jquery-ui library as above in application.js and would rather include only jquery-ui datepicker, you can require specific modules by substituting the following require directive:

1
2
//= require jquery-ui/datepicker
3

For Formtastic and jquery-ui-rails, you’ll need to add some require directives for css

In app/assets/stylesheets/application.css

1
2
/*
3
  *= require formtastic
4
  *= require jquery-ui
5
*/
6

For Formtastic, the gem’s author Justin French, says:

A proof-of-concept set of stylesheets are provided which you can include in your layout. Customization is best achieved by overriding these styles in an additional stylesheet. In the above application.css, I elected not to do any customization.

Step 4 – Add the javascript (I use coffeescript) in your assets/javascripts folder

This is my javascript file for adding the datepicker. Notice that I’m selecting the element with the class ui-datepicker since this is what I gave my html view markup via :input_html => { :class=> “ui-datepicker”} in the ‘report_fields’ partial above.

Below is my file formtastic_datepicker.js.coffee:

01
02
$(document).ready ->
03
  $(".ui-datepicker").each ->
04
    $(@).datepicker
05
      dateFormat: "mm/dd/yy"
06
 
07
 
08
  $("#communications").on "cocoon:after-insert", ->
09
    $(".ui-datepicker").datepicker
10
      dateFormat: "mm/dd/yy"
11

Step 5 – Parse dates in your Rails controller in the correct format using Date.strptime

In my controller, I have:

01
02
def update_it
03
 
04
  parse_datetime
05
  if @person.update(person_params)
06
    redirect_to edit_survey_person_path(@person, survey_id: @survey.id, survey_type: params[:survey_type]), notice: 'Survey was successfully filled in.'
07
  else
08
    render :template => "people/edit_survey_saved"
09
  end
10
end
11
 
12
def parse_datetime
13
  params["person"].each do |nested_model_attrs, ids|
14
    case nested_model_attrs
15
    when "reports_attributes"
16
      ids.each do |id, attrs|
17
        attrs["date_published"] = DateTime.strptime(attrs["date_published"], '%m/%d/%Y') if attrs["date_published"].present?
18
      end
19
    end
20
  end
21
end
22
 
23
def person_params
24
  params.require(:person).permit(:id, reports_attributes: [:id, :title, :date_published, :report_type, :person_id, :_destroy])
25
end
26

Notice in the controller, I call parse_datetime so I can convert the date (which is passed in the params hash in month-day-year format since that is what people are used to seeing, but Rails stores DateTime objects in UTC format). If I didn’t do this datetime parsing on the backend, Rails ends up flipping the day and month every time you save it, and you wind up getting back a date you didn’t expect. For example, if you put in 10/2/14 (or October 2, 2014) via the datepicker in the browser, when you returned it to the Rails view, the date would show as 2/10/14 (or February 2, 2014). It’s not the prettiest format, but it works.

Consider also using text fields instead of DateTime fields in Rails. This means you wouldn’t have to parse the date in the params hash to make it compatible with the way Rails stores DateTime objects.

In another interesting side note, looking through the code, I found Formtastic gives you a custom datepicker but it only works with Google Chrome.

If anyone has a better way of doing this (especially parsing the dates on the backend), I’d love to hear about it.

How To Move an Existing Github Repository to Bitbucket

Moving an Existing Github Repository to BitbucketHere is the link to the procedure on coderwall…

Continue Reading …

How To Save Nested Attribute Checkboxes With Formtastic and Cocoon and Avoid the TypeError

Avoiding the TypeError: can’t cast Array to stringRecently, I was inserting nested attribute checkboxes using Formtastic and Cocoon and was cruising along with all my other nested forms partials until I got a dreaded TypeError: can’t cast Array

Continue Reading …

How To Setup jQuery Autcomplete With Elasticsearch In Your Rails Application

What is jQuery autocomplete? The jQuery autocomplete plugin enables your users to receive suggestions while they type keywords in an input field. How do you use it with elasticsearch? If you haven’t setup elasticsearch with your Rails application,

Continue Reading …

How to Setup Elasticsearch in your Rails App in Production

Step 1 - Install elasticsearch in your Rails Application in ProductionIf you haven’t setup elasticsearch in your Rails application in development, this article tells you how to do so in LinuxStep 2 - Create the search indices on your Heroku

Continue Reading …

How To Setup Elasticsearch In Your Rails Application In Development

Step 1 - Install elasticsearchIf you haven’t installed elasticsearch on your local development machine, this article tells you how to do so in LinuxStep 2 - Add the right ruby gems for the Ruby elasticsearch client in your Gemfile and bundle

Continue Reading …

How To Install Elasticsearch On Linux for Rails Development

What is elasticsearch?Elasticsearch is an open-source real-time search and analytics engine that runs on top of Lucene, a Java-based indexing and search library.How to install it on Linux Mint 16 and Ubuntu 14.04Step 1 - Download

Continue Reading …

How To Squash Your Last 2 Git Commits

Why Squash Commits? If you’ve been working with Git for a while you might start to wonder why you can’t combine that last trivial “hello world” type commit with your previously more meaningful commit.Fortunately, you don’t have to wonder as Git

Continue Reading …

Installing Phantomjs on Linux Mint 16

Just wrote a protip on Coderwall about how to install Phantomjs on Linux Mint 16...

Continue Reading …