Skip to content

Instantly share code, notes, and snippets.

@xtoddx
Created September 16, 2008 15:08
Show Gist options
  • Save xtoddx/11042 to your computer and use it in GitHub Desktop.
Save xtoddx/11042 to your computer and use it in GitHub Desktop.
// TODO
// show spinner on loading
//
// element.identify() is a prototype function -- remove it so
// there are less methods to overwrite when switching backend
// also: addClassName / RemoveClassName
//
// clean up the namespace -- instead of long function names in the window
// have descriptive names in their own class
//
// AJAX_COLUMN_SELECTIONS (VAR)
//
// a hash of column_id => element
// that remembers how each element came to be selected
var ajax_column_selections = {};
// AJAX_COLUMN_RUNNER
//
// A wrapper around Ajax.Updater to get html and throw it into the new column.
//
function
ajax_column_runner(url, column_id, options) {
new Ajax.Updater(
column_id,
url,
options
)
}
// AJAX_COLUMN_SHOW
//
// element is the element the show action came from
// * it can be within a column, in which case the column to the right will be
// populated with new data
// * it can be from anywhere else on the page, and the first column will be
// drawn
//
// url is the ajax callback on the server
//
// options is the options to Ajax.Request with the following extras
// * container_id is the container of all the columns. the default is
// ajax_columns, but if you put more than on set on a page, you need to set
//
function
ajax_column_show(element, url, options) {
if (!options) {
options = {}
}
// get the container for column operations
var container = ajax_column_container(options.container_id)
// find what row we are called from
var row = find_ajax_row(element)
// find what column we are called from (like 'ajax_column_1')
var column = find_ajax_column(element)
// we want to recreate the column or remove it completely, so start by removal
ajax_columns_remove_later_siblings(column)
// clear out the state of the current column
ajax_column_deselect(column)
// if we click to collapse the later columns and exapnd this one, hanlde it
if (is_ajax_column_deselection(element, row, column)) {
ajax_column_selections[column.identify()] = null
return
}
ajax_column_select(column, row, element)
ajax_column_make_tooltips(column)
var update_column = build_ajax_update_column_for_current(column, container)
var loading_node = ajax_column_loading_node()
if (loading_node) {
update_column.appendChild(loading_node)
}
ajax_column_runner(url, update_column.getAttribute('id'), options)
}
//AJAX_COLUMNS_REMOVE_LATER_SIBLINGS
//
// clear out all columns to the right of the current column
//
function
ajax_columns_remove_later_siblings(column) {
var brova = column.nextSibling
while (brova) {
var nb = brova.nextSibling
// deselect it (but can be text nodes)
if (brova.identify) {
ajax_column_selections[brova.identify()] = null;
}
// remove from screen
brova.parentNode.removeChild(brova)
brova = nb
}
}
// AJAX_COLUMN_DESELECT
//
// remove classes that mark a column as having a selection
// also remove tooltips from the row headers
function
ajax_column_deselect(column) {
ajax_column_remove_tooltips(column)
column.removeClassName('selection')
column.addClassName('no_selection')
// Moved out becuase we want this called every time
// but we need to keep the state around
//moved to BUILD_AJAX_UPDATE_COLUMN_FOR_CURRENT
// ajax_column_selections[column.identify()] = null
var selections = column.getElementsByClassName('selection')
for (var i=0; i<selections.length; i++) {
selections[i].removeClassName('selection')
}
}
// IS_AJAX_COLUMN_DESELECTION
//
// element is what we clicked to start the event
// column is the column (yea!)
//
function
is_ajax_column_deselection(element, row, column) {
if (ajax_column_selections[column.identify()] == (row || element)) {
return true
} else {
return false
}
}
// AJAX_COLUMN_CREATE_CONTAINER
//
// if the given container_id does not exist on the page, it will be
// created as a div and appended to the page
//
function
ajax_column_create_container(container_id) {
if (!container_id) {
container_id = 'ajax_columns'
}
var emt=document.getElementById(container_id)
if (emt) {
return emt
}
emt = document.createElement('div')
emt.setAttribute('id', container_id)
document.body.appendChild(emt)
return emt
}
// AJAX_COLUMN_CONTAINER
//
// will find the container for a given operation
// if one does not exist, it will be created and appended to the page
//
// container_id is a string id of the DOM element, or null for 'ajax_columns'
//
function
ajax_column_container(container_id) {
if (!container_id) {
container_id = 'ajax_columns'
}
var rv = document.getElementById(container_id)
if (!rv) {
rv = ajax_column_create_container(container_id)
}
return rv
}
// FIND_AJAX_COLUMN
//
// walk up the DOM tree until an element with a class of 'ajax_column' is found
// then return it
//
function
find_ajax_column(element) {
var rv = element
while (rv && !rv.hasClassName('ajax_column')) {
rv = rv.parentNode
}
return rv
}
// FIND_AJAX_ROW
//
// walk up the DOM tree until an element with a class of 'ajax_row' is found
// then return it
//
function
find_ajax_row(element) {
var rv = element
while (rv && rv.hasClassName && !rv.hasClassName('ajax_row')) {
rv = rv.parentNode
}
return rv.hasClassName ? rv : null
}
// BUILD_AJAX_UPDATE_COLUMN_FOR_CURRENT
//
// element is the current column, or null if from outside of container
// continer is the ajax continer the update column must live in
// returns the update column, shown inside of container
//
function
build_ajax_update_column_for_current(element, container) {
// if from outside of container, index is 1, otherwise, last index + 1
var idx = 1
if (element) {
var val = element.getAttribute('id')
// sometimes bad views don't put an id on the first column
if (val) {
val = val.split('_')
val = parseInt(val[val.length - 1])
if (val) {
idx = 1 + val;
}
}
}
// scope the id to the container id so it remains unique, even if there
// are multiple column containers on the page
var id = container.getAttribute('id') + '_column_' + idx
// mark this column as unselected, since its new
ajax_column_selections[container.identify()] = null
var div = document.createElement('div')
div.setAttribute('id', id)
div.setAttribute('class', 'no_selection ajax_column')
container.appendChild(div)
return div
}
// AJAX_COLUMN_SELECT
//
// mark the column as selected (through element)
//
function
ajax_column_select(column, row, element) {
column.addClassName('selection')
column.removeClassName('no_selection')
if (row) {
row.addClassName('selection')
} else {
element.addClassName('selection')
}
ajax_column_selections[column.identify()] = (row || element)
}
// AJAX_COLUMN_MAKE_TOOLTIPS
//
// for each row in the column (by class name = 'ajax_row')
// make a list of hidden elements (class_name = 'collapse')
// and apply it to tooltip containers (class_name = 'ajax_tooltip')
//
function
ajax_column_make_tooltips(column) {
var rows = column.getElementsByClassName('ajax_row')
for (var i=0; i<rows.length; i++) {
var tip = ajax_row_compose_tooltip(rows[i])
ajax_row_place_tooltip(rows[i], tip)
}
}
// AJAX_ROW_COMPOSE_TOOLTIP
//
// collect the 'collapse' elements contents and add to tooltip
// return the tooltip
//
function
ajax_row_compose_tooltip(row) {
var rv = []
var hid = row.getElementsByClassName('collapse')
for (var i=0; i<hid.length; i++) {
rv.push(hid[i].textContent)
}
return rv.join(' | ')
}
// AJAX_ROW_PLACE_TOOLTIP
//
// take the tooltip and apply it to elements with 'ajax_tooltip' class
//
function
ajax_row_place_tooltip(row, tip) {
var links = row.getElementsByClassName('ajax_tooltip')
for (var i=0; i<links.length; i++) {
links[i].setAttribute('title', tip)
}
}
// AJAX_COLUMN_REMOVE_TOOLTIPS
//
// like AJAX_COLUMN_MAKE_TOOLTIPS in reverse
//
function
ajax_column_remove_tooltips(column) {
var rows = column.getElementsByClassName('ajax_row')
for (var i=0; i<rows.length; i++) {
ajax_row_remove_tooltip(rows[i])
}
}
// AJAX_COLUMN_REMOVE_TOOLTIPS
//
// called on each row of a column that is having tooltips removed
//
function
ajax_row_remove_tooltip(row) {
var links = row.getElementsByClassName('ajax_tooltip')
for (var i=0; i<links.length; i++) {
links[i].removeAttribute('title')
}
}
// AJAX_COLUMN_LOADING_NODE
//
// create a node to show the loading state in the new column
// overwrite this for best effect
//
function
ajax_column_loading_node() {
var rv = document.createTextNode('loading !!!')
return rv
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment