This page provides several tests to illustrate how a browser handles the focus and blur events for <input> elements with type=button. Each test in the grid below has uniquely defined properties. The first test is the default element with no tabindex defined. Each subsequent test specifies a value for tabindex, with the last one being an undefined (i.e. invalid) value.
onfocus and onblur event handlers have been bound to each of the test case controls. If triggered, an event handler will log the event in the Test Results box to the right of the test grid. The event handlers do not consume the event (i.e. they allow propagation). This allows the test to record the event but not affect the browser's default behavior.
<div id="description"> <p>This page provides several tests to illustrate how a browser handles the focus and blur events for <input> elements with type=button. Each test in the grid below has uniquely defined properties. The first test is the default element with no tabindex defined. Each subsequent test specifies a value for tabindex, with the last one being an undefined (i.e. invalid) value.</p> <p>onfocus and onblur event handlers have been bound to each of the test case controls. If triggered, an event handler will log the event in the Test Results box to the right of the test grid. The event handlers do not consume the event (i.e. they allow propagation). This allows the test to record the event but not affect the browser's default behavior.</p> <p>The reset buttons will clear the Test Results.</p> </div>
// load the result database $.getJSON('data/input-button.json', function(data, rslt) {
if (rslt=='success') { loadData(data); makeSortable('#results'); } });
/* * function handleEvent() appends a row to the target table. Called by event handlers to process focus events * * @param (e object) The browser.event object * * @param (id object) The element that fired the event * * @param (event string) The name of the event that called the handler * * @param (target string) The id of the target table where results will be appended * * @param (propagate boolean) true if allowing propagation, false if consuming event * * @param (preventDefault boolean) true if preventing default behavior, false otherwise * * @return true if propagating, false if consuming event */ function handleEvent(e, id, event, target, propagate, preventDefault) {
// append the result row to the target table $('#' + target + ' > tbody').append('<tr><td class="event">' + event + ':</td><td>' + $(id).attr('id') + '</td></td>');
// if preventDefault is true, set the preventDefault property of the event if (preventDefault == true) { e.preventDefault = true; }
// if propagate is false, set the stopPropagation property of the even and return false if (propagate == false) { e.stopPropagation = false; return false; }
/* * function loadData() is a callback for a getJSON call to load the result data from a json file * and append it to a table in the html page * * @param (data array) data is the array of data records loaded from the file * * @param (rslt string) rslt is the result of the load operations. * * @return N/A */ function loadData(data) { var row; var invalid = "";
// Define a small jQuery extension to alternate table row colors jQuery.fn.alternateRowColors = function() { $('tbody tr:odd', this).removeClass('even').addClass('odd'); $('tbody tr:even', this).removeClass('odd').addClass('even');
return this; };
/* * function makeSortable() applies properties to a table necessary to allow for alpha-numeric sorting * * @param (id object) id is the table object to make sortable * * @return N/A */ function makeSortable(id) { // iterate through the table elements $(id).each(function () { var $table = $(this);
$table.alternateRowColors();
// iterate through the table header $('.result-header', $table).each(function(column) {
var $header = $(this); var findSortKey;
// adjust column to handle the overlapping header rows // (i.e. don't count Results and Notes header) // Note: This adjust must be modified if the header format changes. // Remove it if single-line header // if (column > 5) { column -= 2; }
// if the cell has the sort-alpha class, find the sort keys if ($header.is('.sort-alpha')) { findSortKey = function ($cell) { return $cell.find('.sort-key').text().toUpperCase() + ' ' + $cell.text().toUpperCase(); }; }
if (findSortKey) { // Define the header highlighting handler $header.find('.sort-button').addClass('clickable'); $header.hover(function() { $header.addClass('hover'); }, function() { $header.removeClass('hover'); });
// // bind a focus handler to the sort buttons // $('.sort-button').focus(function () { $(this).css('background-color', 'black'); });
// // bind a blur handler to the sort buttons // $('.sort-button').blur(function () { $(this).css('background-color', 'transparent'); });
// Define the header click handler to perform table // sorting when the header is clicked $header.find('.sort-button').click(function(e) { var sortDirection = 1;
// if the table is sorted in ascending order, reverse // the sort order flag if ($header.is('.sorted-asc')) { sortDirection = -1; }
// create an array of the table rows var rows = $table.find('tbody >tr').get();
// iterate through the table rows and store the sort keys for each one // in an attached expando $.each(rows, function (index, row) { var $cell
// The first column is marked as a header row for screen readers // Need to treat it seperately if (column == 0) { $cell = $(row).children('th').eq(column); } else { $cell = $(row).children('td').eq(column - 1); }
row.sortKey = findSortKey($cell); });
// sort the rows rows.sort(function(a, b) {
if (a.sortKey < b.sortKey) { // move row a before row b // (according to the sort direction) return -sortDirection; } else if (a.sortKey > b.sortKey) { // move row a after row b return sortDirection; }
// the rows are equal--do nothing return 0; });
// iterate through the rows array and reinsert them into the table // according to the new sort order $.each(rows, function(index, row) {
// insert the row $table.children('tbody').append(row);
// remove the expando row.sortKey = null; });
// remove the previous sorted class and reset the button images $table.find('.result-header') .removeClass('sorted-asc') .removeClass('sorted-desc') .not(this).find('img').attr('src', 'images/sortable.png');
// reapply the sorted class // the first column is th for screen readers if (column == 0) { // remove the sorted class from the other columns $table.find('td').removeClass('sorted')
// apply the class to the browser column $('.browser-col').addClass('sorted'); } else { // remove the class from the browser column $('.browser-col').removeClass('sorted')
// apply the class to the appropriate column $table.find('td').removeClass('sorted') .filter(':nth-child(' + (column + 1) + ')') .addClass('sorted'); }
// reapply the row striping $table.alternateRowColors();
e.preventDefault; return false; }); // end header click
} // end if }); // end each }); // end each } // end makeSortable(); }); // end document ready </script>