David Sills's muse is fueled by Bach, Beethoven, and Brahms (and Berlioz and Boulez). He has no life, which comports well with the über-geekitude to which he aspires. He reads and writes fitfully in English, Spanish, French, German, Italian (mostly medieval), C, VB, Perl.... Oh, and Java and XSLT, lots and lots of Java and XSLT. Trained somewhere in darkest Central America, he works today at DataSource, Inc., on the product team for the CASE tool Abri. David has posted 9 posts at DZone. View Full User Profile

An HTML List Builder: A Study in Applying jQuery

12.30.2008
| 36822 views |
  • submit to reddit
Sizes
Since I had provided most of the elements within the HTML with id attributes, sizing the lists was pretty easily accomplished with jQuery, which has excellent support for CSS selectors:
  var leftSelect = $('#leftSelect');
var rightSelect = $('#rightSelect');
var selectWidth = leftSelect.width();
var selectHeight = leftSelect.height();
leftSelect.width(selectWidth).height(selectHeight);
rightSelect.width(selectWidth).height(selectHeight);
A quick explanation for those unfamiliar with jQuery: the selector "$('#leftSelect')" in jQuery returns the element with the id attribute "leftSelect", namely the left select (you can see the imagination I bring to my ids), wrapped in a jQuery object that acts pretty much like an array. Of course, since I have used an id attribute, this had better be a one-element array!, so I could have retrieved the actual select using "$('#leftSelect')[0]". However, it was more useful to have the wrapper, since it has a number methods that simplify and regularize access to DOM properties. These can be seen in the remainder of the code and are largely self-explanatory, with the proviso that methods that take no parameters generally return the value of the property and those that take parameters generally reset the value of the property.
 
The div element that holds the right select must also be wide enough to push the up and down buttons on its right to the right location:
  $('#rightList').width(selectWidth);
Requirement 5 is now met:
List Builder selects sizedList Builder selects sized
Centering
The browser already knows the sizes of everything and needs only to be asked to reveal its results. However, we first need to be able to interpret the string values of style settings as a number:
  var numericValue = function(value)
{
var digits = value.match(/[0-9]+/);
if (digits && digits.length > 0)
{
return Number(digits[0]);
}
return Number(0);
};
We also need the height of a div representing the row:
  var divHeight = $('#leftList').height();
Once we have these prerequisites, vertical centering of the up and down button div is straightforward:
  var leftButtons = $('#leftButtons');
var leftButtonsHeight = leftButtons.height() + numericValue(leftButtons.css('margin-top')) +
numericValue(leftButtons.css('margin-bottom')) + numericValue(leftButtons.css('padding-top')) +
numericValue(leftButtons.css('padding-bottom'));
var leftButtonsMargin = ((divHeight - leftButtonsHeight) / 2) + 'px';
leftButtons.css('margin-top', leftButtonsMargin);
Horizontal centering is a bit more complicated, but not terribly so. It requires knowing the expected height of the div:
  var leftUpButton = $('#leftUpButton');
var leftDownButton = $('#leftDownButton');
var divWidth = leftButtons.width();
var leftUpMargin = ((divWidth - leftUpButton.width()) / 2) + 'px';
leftUpButton.css({ 'margin-left': leftUpMargin, 'margin-right': leftUpMargin });
var leftDownMargin = ((divWidth - leftDownButton.width()) / 2) + 'px';
leftDownButton.css({ 'margin-left': leftDownMargin, 'margin-right': leftDownMargin });
The same applies, of course, to the right up and down buttons.
The principle is the same with the middle buttons; there are simply more of them:
// center the middle buttons vertically
var middleButtons = $('#middleButtons');
var middleButtonsHeight = middleButtons.height() + numericValue(middleButtons.css('margin-top')) +
numericValue(middleButtons.css('margin-bottom')) + numericValue(middleButtons.css('padding-top')) +
numericValue(middleButtons.css('padding-bottom'));
var middleButtonsMargin = ((divHeight - middleButtonsHeight) / 2) + 'px';
middleButtons.css('margin-top', middleButtonsMargin);
// center the middle buttons horizontally
var addButton = $('#addButton');
var removeButton = $('#removeButton');
var addAllButton = $('#addAllButton');
var removeAllButton = $('#removeAllButton');
divWidth = middleButtons.width();
var addMargin = ((divWidth - addButton.width()) / 2) + 'px';
addButton.css({ 'margin-left': addMargin, 'margin-right': addMargin });
var removeMargin = ((divWidth - removeButton.width()) / 2) + 'px';
removeButton.css({ 'margin-left': removeMargin, 'margin-right': removeMargin } );
var addAllMargin = ((divWidth - addAllButton.width()) / 2) + 'px';
addAllButton.css({ 'margin-left': addAllMargin, 'margin-right': addAllMargin });
var removeAllMargin = ((divWidth - removeAllButton.width()) / 2) + 'px';
removeAllButton.css({ 'margin-left': removeAllMargin, 'margin-right': removeAllMargin });
Now the buttons and selects appear correctly:
List Builder final appearanceList Builder final appearance
and requirement 6 is met.

Legacy
Article Resources: 
Published at DZone with permission of its author, David Sills.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)