Birds-Eye.Net
All things broadband and more...
 
Web Birds-Eye.Net

What's New?

Ruby on Rails (RoR)
Programming Reference


Models
External database connections
Passing current_user into model
Passing object into model
Using static lookup tables
Validates IF
Validates MongoMapper

Views
Dynamically delete form element
Edit create nested data
HTML form field check_box
Layout jQuery datatable module
Select array
Select cascading via JS
Text_area Array
Text_area listing submit
Text field format time

Controllers
Dynamic model selection
Including first item from a sorted desc table
Using from_unixtime on epoch dates
Custom SQL Query Examples

Rack
Integrated NTLM/Kerberos Authentication
Pass-through Authentication w/ NTLM

ActionMailer
Broken links in emails

Rails General
Add, Subtract, Multiply, and Divide
Calculate number of weekdays for date range
Date->Epoch & Epoch->Date
Calculate past/present payroll dates
Extract first letter of each word
Hash of hashes assignment
Using: variable as hash index

jQuery
jQuery accordion MongoDB

Rails Framework Examples

Apotomo Widget Using Erb

MySQL
Converting Julian Dates to Epoch

d3 Charting
Configuration to Work with Rails Apps
A simple bar chart example

Other
Setup VPN on iMac
SSH Key Generation

More to come

 

Use of Cascading Select in View for Managing Dependent Lists

By: Bruce Bahlmann - Contributing Author (your feedback is important to us!)

In rails development, when creating web forms, you often have a list of information that is dependent on another list of information. For example you have a school with different campuses and each campus has different sites or communities. Ideally, you don't want users to independently select sites/communities of the campuses these sites/communities are dependent on, thus these lists are dependent on one another. So, the desired behavior is to have the user first select which campus and then once selected, the user is only shown those sites/communities that are associated with the selected campus.

There are multiple ways to do this in Ruby on Rails (RoR), but perhaps the simplest involves a tiny bit of JavaScript. So rather than installing a Gem or building scopes and complicated models, the following provides one the easiest ways to build reliable cascading selects that can be implemented quickly and painlessly. We first start with a collection of elements (lists) which can be provided inline or via a CONSTANT declaration [see Select-Array] article for more information on how to do this. We will use the CONSTANT declaration so we'll declare two related items (campuses, sites) within our model to account for this.

[apps/models/post.rb]
class Post < ActiveRecord::Base

  CAMPUSES = {1 => { :name => "Beloit", :communities => {101 => 'Bethesda', 102 => 'Faith', 
              103 => 'Hill', 104 => 'Hunziker', 105 => 'Journey', 106 => 'Triumph'}
             }, 2 => { :name => "Bremwood", :communities => {201 => 'Andrew', 202 => 'Banker',
              203 => 'CUNA', 204 => 'Jacobson', 205 => 'North', 206 => 'Phoenix', 
              207 => 'South', 208 => 'Trinity', 209 => 'Waverly', 210 => 'Woodhaven'}}
             }
...
end

Next we need to build the main select to display the top (deciding) level which the follow on lists are dependent. This main select is where we introduce our tiny bit of JavaScript to manage the show/reveal operation that allows us to only show the secondary (cascading) list upon selection of a valid item within this main select (list). Changing the selected item within this main list will toggle the show/reveal to "hide" the list for the unselected value and "show" the list for the selected value. Of course, if the user selects no value, no secondary list be be shown (both secondary/cascaded lists will be hidden - not shown).

[apps/views/posts/_form_post_html.erb]
class Post < ActiveRecord::Base
...
<% content_for(:javascript) do %>
<%
  campus_selects = {}
  Post::CAMPUSES.each_key do |k|
    campus_selects[k] = options_for_select(Post::CAMPUSES[k][:communities].sort.collect {|c| c.reverse})
  end
%>

// Disabled community until a campus is selected
if ($("#post_campus").val() == "") {
  $("#community_field").hide();
}

campuses = <%= Post::CAMPUSES.to_json.html_safe %>;
selects = <%= campus_selects.to_json.html_safe %>;
$("#post_campus").bind('change', function() {
  campus_id = $("#post_campus").val();
  if(campus_id != ""){
    $("#post_community").html("<option></option>"+selects[campus_id]);
    $("#community_field").show(); 
  } else {
    $("#community_field").hide();
    $("#post_community").html("<option></option>");
  }
});
<% end %>
...

Cascading Selects allow show/reveal of secondary selects

With this in place, we merely need to add the code for displaying the secondary lists. The initial if/else logic around each DIV tag allows for the case of either adding a new entry or editing an existing entry. This is because, a new entry would not have a value for campus (thus display: none is used for both lists), however editing an existing entry would require that both campus and community to have a value - so we need to turn on the appropriate list depending on the previously stored value of campus.

[apps/views/posts/_form_post_html.erb]
class Post < ActiveRecord::Base
...
  <div class="field">
    <%= f.label :campus %><br />
    <%= select("post", "campus", 
               Post::CAMPUSES.collect {|k,v| [v[:name], k]}, 
               {:include_blank=>true}) %>
  </div>

  <div id="community_field" class="field">
    <%= f.label :community %><br />
    <% if @post.campus.nil? %> 
      <%= select("post", "community", {}, {:include_blank=>true}) %>
    <% else %>
      <%= select("post", "community", 
                 Post::CAMPUSES[@post.campus][:communities].sort.collect {|c| c.reverse}, 
                 {:include_blank=>true}) %>
    <% end %>
</div>

The code for implementing this function is a little verbose, but if this is your first time implementing cascading selects, you might appreciate the clarity of being verbose rather than the Rails way, which tends to be just the opposite.

Can Birds-Eye.Net help you or your Company?
Receive your Birds-Eye.Net articles and white papers hot off the presses by adding our RSS feed to your reader.

 

(C) Copyright Birds-Eye.Net, All rights reserved.
It is against the law to reproduce this content or any portion of it in any form without the explicit written permission of Birds-Eye Network Services, LLC. Federal copyright law (17 USC 504) makes it illegal, punishable with fines up to $100,000 per violation plus attorney's fees.