The Cache: Technology Expert's Forum
 
*
Welcome, Guest. Please login or register. June 25, 2019, 09:37:16 PM

Login with username, password and session length


Pages: [1]
  Print  
Author Topic: Simple "channel" selector for jQuery  (Read 9806 times)
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 10096



View Profile
« on: May 27, 2011, 11:12:53 AM »

It seems like a long time since anyone posted some tech assistance here, so I'm going to get back into the game.

I've been working through updating one of my back-office management systems and moving it all to HTML5, jQuery and the Aloha editor. Since I'm knee deep in code once again, I thought I'd take portions of the project that I enjoy and convert them to little instructional demos.

Here is a screenshot of the demo I'm presenting today:




In this little example, I'm showing how you can implement a sort of "channel selector" with unobtrusive javascript and the huge horsepower of jQuery. I'm using one of my favorite button animation techniques, which is to have both up and down image in a single file, using it as a background and then simply shifting the position of the background image as I need to display something different. AFAIK, this is one of the quickest (stock) ways to modify the appearance of an image (because the image file itself is not moved in memory, just the display port on the containing DIV) and, with a little preparation, can be used for many more slides than just a binary button. Here are the selector button files:



The requirements of the system include that I have discreet editors for 4 different elements of my content management system: the raw HTML, a WYSIWYG editor (that's where Aloha comes in, but that'll be another demo), connection to page-specific CSS elements and page-specific Javascript elements, which are all part of my my CMS. When the users clicks one of the channel buttons, I want it to be the only button "depressed" and I want to display the associated editing area for that button, or channel. This mechanism is extremely handy, as it can be used for tabbed systems, multi-window systems, you name it. The essence of this is a very capable method to keep in your toolbox.

First the HTML which, as you can see, is clear of either CSS styling or JS code:
Code:
<body>

<div id="toolbar"><div id="toolContainer">
<div id="buttonHTML" class="button"></div>
<div id="buttonDisplay" class="button"></div>
<div id="buttonCSS" class="button"></div>
<div id="buttonJS" class="button"></div>
</div></div>

<div id="editors">
<div id="areaHTML" class="editor">This is the HTML editing area</div>
<div id="areaDisplay" class="editor">This is the HTML Display area</div>
<div id="areaCSS" class="editor">This is the CSS editing area</div>
<div id="areaJS" class="editor">This is the Javascript editing area</div>
</div>

</body>

The CSS in the header is equally straight forward:
Code:
<style>
/* Create a nice pesudo-shadow backdrop for my toolbar */
#toolbar { background-color: #c0c0c0; height: 30px; border-style: solid; border-width: 1px 2px 2px 1px; border-color: #404040; margin-bottom: 10px;}
#toolContainer { padding: 4px 0 4px 20px; }

/* Each button carries the same essential properties, but needs it's own background image */
.button { float: left; height: 22px; width: 80px; background-repeat: no-repeat; background-position: 0 0; cursor: pointer; }
#buttonHTML { background-image: url(buttonHTML.png); }
#buttonDisplay { background-image: url(buttonDisplay.png); }
#buttonCSS { background-image: url(buttonCSS.png); }
#buttonJS { background-image: url(buttonJScript.png); }

/* Each editor area has the same essential properties, but here I use a different background color for effect */
.editor { height: 200px; width: 400px; display: none; }
#areaHTML { background-color: #ffa0a0; }
#areaDisplay { background-color: #a0ffa0; }
#areaCSS { background-color: #a0a0ff; }
#areaJS { background-color: #ffa0ff; }
</style>

Unobtrusive JS and CSS are important for us because the cleaner we can make our pages the less confusion we'll throw at Google, the easier it is to completely restructure/retheme our pages and the easier it is to retask or revector code and events. Putting an onClick event on every one of my buttons, for example, is prone to error and a drag if I want to change things around. Similarly, if I want to add a new event to elements I may miss one or get one wrong or whatever. Trust me, this way's better.

Here is the javascript that is up in the head of the file:
Code:
<script type="text/javascript">
// This attaches the onClick event to the toolbar buttons
$(function() {
$('.button').each(function() {
var sender = this;
this.onclick = function(event) { selectView(sender); }
});
});

// When the document is loaded, "click" the first button...
$(document).ready(function() {
selectView(document.getElementById('buttonHTML'));
});

function selectView(sender)
{
$('.button').css('background-position', '0 0');
sender.style.backgroundPosition = '0 100%';

$('.editor').css('display', 'none');
var id = sender.id;
var source = id.match(/button(.*)/);
target = document.getElementById('area' + source[1]);
target.style.display = 'block';
}
</script>

There are 3 functions here: the event attachment, the document ready page initializer and the actual channel selector, in this case called selectView. In each function we are leaning heavy on jQuery. jQuery is almost a career in itself, being enormously powerful and potentially confusing. I recommend some reading on it because the scope of use for it is way beyond this demo.

The first function attaches the onClick event to all appropriate buttons. Essentially the code reads like this: jQuery: Please find every element with the .button class and iterate through them. For each, attach a no-name function (chunk of code) to the onClick event which will simply call the selectView function, passing me, or the currently-being-iterated-object to the function as a parameter.

The second function is much easier to understand. It takes advantage of jQuery's document ready event system and says: When the document is ready ie., all divs etc have been defined, even if they've not been drawn, please call the function selectView passing the object reference of an item named buttonHTML to it as a parameter.

The last function is the most straight up, and I've written it here to be as literal as possible. Here it is:
Code:
// Ask jQuery to find all elements of class .button, and change the background position style to 0, 0 (image is set top left)
$('.button').css('background-position', '0 0');

// Tell the object that was passed in to the function to change it's background position
// style to 0 (left) 100% (bottom) effectively showing the second "slide" of the image
sender.style.backgroundPosition = '0 100%';

// Ask jQuery to change the display style of all items of class .editor to "none"
$('.editor').css('display', 'none');

// Using the regex pattern /button(.*)/ find the suffix part of the sender's ID
// in other words, find if the button pressed was HTML or Display or CSS etc.
var id = sender.id;
var source = id.match(/button(.*)/);

// Because the match function returns an array of things found, I'll
// use the 1th element to get a reference to the area I want to display.
// (The match array looks like 'buttonHTML, HTML')
target = document.getElementById('area' + source[1]);

// Now that I have a reference to that element, change it's style to display: block
target.style.display = 'block';

Here is the code in it's final form:
Code:
<html>
<head>

<script type="text/javascript" src="jquery.js"></script>

<style>
#toolbar { background-color: #c0c0c0; height: 30px; border-style: solid; border-width: 1px 2px 2px 1px; border-color: #404040; margin-bottom: 10px;}
#toolContainer { padding: 4px 0 4px 20px; }

.button { float: left; height: 22px; width: 80px; background-repeat: no-repeat; background-position: 0 0; cursor: pointer; }
#buttonHTML { background-image: url(buttonHTML.png); }
#buttonDisplay { background-image: url(buttonDisplay.png); }
#buttonCSS { background-image: url(buttonCSS.png); }
#buttonJS { background-image: url(buttonJScript.png); }

.editor { height: 200px; width: 400px; display: none; }
#areaHTML { background-color: #ffa0a0; }
#areaDisplay { background-color: #a0ffa0; }
#areaCSS { background-color: #a0a0ff; }
#areaJS { background-color: #ffa0ff; }

</style>

<script type="text/javascript">
// This attaches the onClick event to the toolbar buttons
$(function() {
$('.button').each(function() {
var sender = this;
this.onclick = function(event) { selectView(sender); }
});
});

// When the document is loaded, "click" the first button...
$(document).ready(function() {
selectView(document.getElementById('buttonHTML'));
});

// This is the actual channel selector code
function selectView(sender)
{
$('.button').css('background-position', '0 0');
sender.style.backgroundPosition = '0 100%';

$('.editor').css('display', 'none');
var id = sender.id;
var source = id.match(/button(.*)/);
target = document.getElementById('area' + source[1]);
target.style.display = 'block';
}
</script>

</head>
<body>

<div id="toolbar"><div id="toolContainer">
<div id="buttonHTML" class="button"></div>
<div id="buttonDisplay" class="button"></div>
<div id="buttonCSS" class="button"></div>
<div id="buttonJS" class="button"></div>
</div></div>

<div id="editors">
<div id="areaHTML" class="editor">This is the HTML editing area</div>
<div id="areaDisplay" class="editor">This is the HTML Display area</div>
<div id="areaCSS" class="editor">This is the CSS editing area</div>
<div id="areaJS" class="editor">This is the Javascript editing area</div>
</div>

</body>
</html>

Attached to this post is a tar.gz of that file as well as the graphics files and jquery.

Enjoy!

* jsDemo.tar.gz (43.68 KB - downloaded 167 times.)
« Last Edit: May 27, 2011, 12:05:55 PM by perkiset » Logged

It is now believed, that after having lived in one compound with 3 wives and never leaving the house for 5 years, Bin Laden called the U.S. Navy Seals himself.
Phaėton
Lifer
*****
Offline Offline

Posts: 555


⎝⏠⏝⏠⎠


View Profile
« Reply #1 on: May 27, 2011, 12:30:16 PM »

Thanks for posting!! That's the good stuff.

 Ass Kisser no homo.

Logged

When I was your age we used to walk to the TV to change the channel....  _̴ı̴̴̡̡̡ ̡͌l̡̡̡ ̡͌l̡*̡̡ ̴̡ı̴̴̡ ̡̡͡|̲̲̲͡͡͡ ̲▫̲͡ ̲̲̲͡͡π̲̲͡͡ ̲̲͡▫̲̲͡͡ ̲|̡̡̡ ̡ ̴̡ı̴̡̡
DangerMouse
Expert
****
Offline Offline

Posts: 244



View Profile
« Reply #2 on: May 27, 2011, 04:26:19 PM »

How'd you find the Aloha editor Perk? I've been wanting to use it for a while, but its missing quite a lot of features - did you code any customisations up yourself? I'm largely thinking of the ability to set element attributes like style.
« Last Edit: May 27, 2011, 04:27:55 PM by DangerMouse » Logged
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 10096



View Profile
« Reply #3 on: May 27, 2011, 06:18:34 PM »

The lack of class naming and other style elements is a bit problematic, but I'm working through a demo they posted on the forum on how to write custom plugins and it's not that bad. For now anyway I can slip by having a raw HTML editor side-by-side with the WYSIWYG. Fortunately the editor does not affect anything you don't explicitly touch, as opposed to something like tinyMCE which I found to be more problematic to integrate. It *will be* the definitive answer one of these days. There are a lot of cool plugins already and given its extensibility I don't see that slowing down.

I have it installed and am using it, I'll put together a demo version of it for here as well, including my config block and how I handle raw and inline editing.

To your direct question, I don't know about setting individual style elements, but I can see a clear way to modifying a block by classname.
Logged

It is now believed, that after having lived in one compound with 3 wives and never leaving the house for 5 years, Bin Laden called the U.S. Navy Seals himself.
Phaėton
Lifer
*****
Offline Offline

Posts: 555


⎝⏠⏝⏠⎠


View Profile
« Reply #4 on: May 28, 2011, 03:43:30 AM »


I have it installed and am using it, I'll put together a demo version of it for here as well, including my config block and how I handle raw and inline editing.


Popcorn
Logged

When I was your age we used to walk to the TV to change the channel....  _̴ı̴̴̡̡̡ ̡͌l̡̡̡ ̡͌l̡*̡̡ ̴̡ı̴̴̡ ̡̡͡|̲̲̲͡͡͡ ̲▫̲͡ ̲̲̲͡͡π̲̲͡͡ ̲̲͡▫̲̲͡͡ ̲|̡̡̡ ̡ ̴̡ı̴̡̡
DangerMouse
Expert
****
Offline Offline

Posts: 244



View Profile
« Reply #5 on: May 28, 2011, 08:21:18 AM »

Cool looking forward to seeing your example. I agree that it will kick the ass of TinyMCE / CKEditor one day.

The architecture behind it seems extremely comprehensive, very impressive. Has the port to jQuery over Ext been completed yet?

DM
« Last Edit: May 28, 2011, 08:24:39 AM by DangerMouse » Logged
perkiset
Olde World Hacker
Administrator
Lifer
*****
Offline Offline

Posts: 10096



View Profile
« Reply #6 on: May 28, 2011, 11:12:57 PM »

Hmmm LOL I don't even know if I understand what you're talking about re. ext, sorry mate.

But yes, the architecture seems very well thought out, and the implementation is pretty spot on IMO. It dropped into my work with a minimal amount of effort and confusion, although the docs are not helpful at all (what docs?) so it's not yet a great option for the faint of heart, or the rookie wishing to modify some cool code.
Logged

It is now believed, that after having lived in one compound with 3 wives and never leaving the house for 5 years, Bin Laden called the U.S. Navy Seals himself.
Pages: [1]
  Print  
 
Jump to:  

Perkiset's Place Home   Best of The Cache   phpMyIDE: MySQL Stored Procedures, Functions & Triggers
Politics @ Perkiset's   Pinkhat's Perspective   
cache
mart
coder
programmers
ajax
php
javascript
Powered by MySQL Powered by PHP Powered by SMF 1.1.2 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks


Valid XHTML 1.0! Valid CSS!