Twitter Bootstrap Modal Won’t Load Content from Another (“Remote”) Page

Short answer

You apparently need a skeleton [modal … modal-body … /modal] for your data-target, not just an empty modal with the data-target.

A Programmer’s False Assumptions – The API is Broken or Old

Initially, I was concerned that my Rails plugin wasn’t using a version of Bootstrap that didn’t include the remote loading of a page into the modal (via href attribute). That functionality has only existed since 2.0.4.

However, when I checked the script being loaded into the project against the current bootstrap-modal.js on github, the MODAL DATA-API section was the same. Repeated checks of the javascript being loaded into my project confirmed that the code was up-to-date enough.

Maybe a Little Too Helpful

The forums discussing how to load remote content into a Bootstrap Modal suggested that the data-target div could be empty:
Original calling page sample:
The contents of the calling page div never changed.


“Remote” page sample

...extra code here...

...extra code here...

What Was Really Happening

The documentation states that, “If a remote url is provided, content will be loaded via jQuery’s load method and injected into the .modal-body.”

From there, I put a stub modal-body in my calling page’s modal and discovered that modal-header, modal-body, and modal-footer appeared to be getting replaced now!
New calling page:

Experimenting with Rails’ String Manipulation from ActiveSupport::CoreExtensions::String::Inflections

This is my experimentation with the string manipulation methods used [largely internally] in Rails. This is largely a repeat of the documentation here, but I did dig into pluralize/singularize and a couple of other examples more in depth. Look at [path to active_support gem version]/lib/active_support/inflections.rb for the full list of plural, singular, irregular, and uncountable regular expressions and words.

require 'active_support/core_ext/string/inflections'
# camelcase, camelize 
"separate_words".camelize # SeparateWords
"active_record".camelcase(:lower) # separateWords

# classify - converts to first upper CamelCase, last word made singular
"this_and_thats".classify # ThisAndThat

# constantize - looks for declared constant with the name specified
"Integer".constantize # returns constant [class] Integer
"integer".constantize # results in NameError: wrong constant name integer
"Boo".constantize # results in NameError: uninitialized constnat Boo (assuming it isn't declared)

# dasherize - underscores to dashes
"a_b_c".dasherize # a-b-c

# demodulize - removes module namespace from module in string.
ModuleA::SubModule::Module".demodulize # Module

# foreign_key - create name of a foreign key to class name, optional parameter to separate class from id
"Integer".foreign_key # integer_id
"Integer".foreign_key(false) # integerid

# humanize - capitalizes first word, down cases rest, turns underscores into space.
"McLean".humanize # Mclean
"Apple_Banana".humanize # Apple banana

# parameterize - replaces special characters in a string, default separator is '-'
#   - whitespace is a special character here, underscore is not
#   - consecutive special characters become a single separator
#   - converts to lowercase
"Apple@!Banana".parameterize # "apple banana"

# pluralize 
"raman".pluralize # "ramen" -- apparently, "man" --> "men" even on a made-up word
"jazz".pluralize # "jazzs" 
"box".pluralize # "boxes"
"beep".pluralize # "beeps"
"moose".pluralize # "mooses"
"rhombus".pluralize # "rhombuses"
"octopus".pluralize # "octopi"

# singularize
"ramen".singularize # "raman"
"jazzes".singularize # "jazze"
"boxen".singularize # "boxen" -- yeah, not a real word again

# tableize - snake_case string and pluralize last word
"RedHeadedStepchild".tableize # "red_headed_stepchildren"

# titlecase / titleize - capitalize all words, 
"two_three-four.five:six".titleize # "Two Three Four.Five:Six"

# underscore - snake_case words (opposite of CamelCase) and covert :: to /
"Number::OneTwo::Integer".underscore # "number/one_two/integer"