tag:blogger.com,1999:blog-76931188331907880792024-03-14T13:19:53.092-05:00Mike Gilsbach's BlogWelcome to my Blog. I write about building web sites, which I do for a living and building models, which I do for fun.Mike Gilsbachhttp://www.blogger.com/profile/00494538765829819322noreply@blogger.comBlogger13125tag:blogger.com,1999:blog-7693118833190788079.post-75014080979456195152009-06-18T14:04:00.009-05:002009-06-18T15:52:27.020-05:00Behavior of Image ALT Attribute in IE/Fire Fox<span style="font-family:arial;">When browsing the web, you will often notice that a tool tip displays when you mouse over certain images as shown in the image below:<br /></span><br /><span style="font-family:arial;"><img id="BLOGGER_PHOTO_ID_5348748671418664434" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 160px; CURSOR: hand; HEIGHT: 68px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil1j7rPsAhGd_c1k1x7XbP_rBP2_O4-gwKAjkNABxxR6qt89iExWnbpHLBJym3VRbEQRPO4fk3CHwBJE13mCMvm8HhIfEnHsec1Y4wzIq7sAtcczLnJ0rXfD_bxP1SEbvn3hAVmh-Zba7v/s400/alt_demo.gif" border="0" />Being mostly a Microsoft IE user, I assumed that the text for this tool tip was specified in the image's alt attribute, as below: </span><br /><br /><pre><span style="font-family:courier new;color:#000099;"><img src="name.gif" alt="Modeling Article"></span></pre><span style="font-family:arial;">I had noticed that the tool tips didn't work in Fire Fox, but didn't pay too much attention. As I had a case where it actually mattered recently, I did some research and learned something interesting. The alt attribute is not supposed to work that way according to the official specs. IE just made it do that. Fire Fox followed the spec and did not. </span><br /><br /><span style="font-family:arial;">The official purpose of the alt attribute is to provide alternate text in case the image doesn't load or cannot be viewed, as shown below:</span><br /><br /><img id="BLOGGER_PHOTO_ID_5348770203718897874" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 161px; CURSOR: hand; HEIGHT: 60px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4NYIBQOQdBmv52qduBMB337gJsLPdbknb1NiR7s09COV5pJuqSDDnpAyUJgRBGKpZAOL41rRUyB3VyosEnn9x2LcP8nKMRxaCESREwhhOHnJ2kHbSio78Odz3ziPY0OnAQ4wHSpVb4-kV/s400/alt_demo2.gif" border="0" /><span style="font-family:arial;">The correct way to provide a tool tip, according to the specs, is with the title attribute:</span><br /><br /><pre><span style="color:#000099;"><img src="name.gif" alt="Modeling Article" title="Modeling Article"></span></pre><span style="font-family:arial;">That works as expected in Fire Fox. </span><span style="font-family:arial;"><br /><br />Of course, you want both attributes in there because search engine's make a lot of use of the alt attribute and apparently they are meant to serve two different purposes.</span><span style="font-family:arial;"><br /><br />Always more interesting stuff to learn...</span>Mike Gilsbachhttp://www.blogger.com/profile/00494538765829819322noreply@blogger.com0tag:blogger.com,1999:blog-7693118833190788079.post-31829417018298514082009-05-26T13:15:00.018-05:002009-05-26T14:52:35.375-05:00CSS-Only Rollover Buttons<span style="font-family:arial;">I have done rollover buttons the same way for a long time now:</span><br /><ul><li><span style="font-family:arial;">Create 2 images - one "active" and one "inactive"</span><br /></li><li><span style="font-family:arial;">Use a JavaScript function, launched onLoad, to preload the "active" image </span><br /></li><li><span style="font-family:arial;">Use another JavaScript function, fired onMouseOver and onMouseOut, to change the source of the image object when the user mouses over it.</span></li></ul><p><span style="font-family:arial;">It always worked before. On a recent project, however, IE was giving me fits because it kept trying to reload the "active" image on every mouse over. This caused a very annoying flicker effect. </span></p><span style="font-family:Arial;">I assumed that it was some problem with my preload function and in a search for a solution I discovered a whole new way to do rollovers without a preload - without any JavaScript at all in fact. Here is the basic idea:</span><br /><ul><li><span style="font-family:Arial;">Create 1 image that has both the "active" and "inactive" parts side by side</span><br /></li><li><span style="font-family:Arial;">Code a DIV tag that contains a link (A tag)</span><br /></li><li><span style="font-family:Arial;">Use CSS settings to change the offset of the background for the DIV and A tags</span></li></ul><span style="font-family:Arial;">Since only one image is used, there is no need for a preload function. This method also works faster than the old way. </span><br /><br /><span style="font-family:Arial;">Here is an illustration of an example I put together with Home and Contact Us buttons:</span><br /><p align="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4T58JmMtKZscQ2NDyVe4bWzOLRQrHbf-59gIJM2AfBQv2KfdtCABjF5XppbpmUw4blD2u95g8p9q44ro-k0SPSOHyLqGEXm0r8gjs6azEzT9vsRdAmyu_3XjRcdwkR3lw0D-gzHmmuOQ6/s1600-h/cssrollover1.gif"><img id="BLOGGER_PHOTO_ID_5340202303136932610" style="WIDTH: 309px; CURSOR: hand; HEIGHT: 52px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4T58JmMtKZscQ2NDyVe4bWzOLRQrHbf-59gIJM2AfBQv2KfdtCABjF5XppbpmUw4blD2u95g8p9q44ro-k0SPSOHyLqGEXm0r8gjs6azEzT9vsRdAmyu_3XjRcdwkR3lw0D-gzHmmuOQ6/s400/cssrollover1.gif" border="0" /></a><span style="font-family:Arial;"></span></p><span style="font-family:Arial;">To start, we need an image that contains both the "active" (yellow) and "inactive" (blue) parts for each button. Here is the home button:</span><br /><p><span style="font-family:Arial;"><img id="BLOGGER_PHOTO_ID_5340202842344023010" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 300px; CURSOR: hand; HEIGHT: 35px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirF_ROzp90ptOEwparIrvvAGXQMWqkqp5ArdBM8qDhduigch1m68xtJ0B9cO-1O0A0QTiX7ZjpIrOCqDy3aK8gHeeaniZ6z_G6lFjICKvN2A8M2VG-QgyVR71XWT9M0QwDPFiFvw1rLn_D/s400/home_button.gif" border="0" /></span></p><span style="font-family:Arial;">The image is 300 pixels wide, which is important to know since we are going to offset this to only display half the image at any one time. It is 35 pixels high.</span><br /><br /><p><span style="font-family:arial;">Now let's look at the HTML:</span><br /></p><pre><span style="font-family:courier new;"><span style="color:#000099;"><div id="nav-container"><br /> <div id="home-button" class="nav-button"><br /> <a href="../index.htm"></a><br /> </div><br /> <div id="contact-button" class="nav-button"><br /> <a href="../contact-us.php"></a><br /> </div><br /></div></pre></span></span><span style="font-family:arial;">First, we have an outside container DIV for the whole set of buttons (nav-container) that we can use to position the entire set of buttons on the page. Inside that, we have two DIV's - one for each button - that use the CSS class "nav-button". Each of those contain an empty A tag.</span><br /><p><span style="font-family:arial;">Now the CSS. First, we set the position of the outer container from the top left corner of the page:</span><br /></p><p><span style="font-family:courier new;">#nav-container{<br />position:absolute;<br />top:25px;<br />left:25px;<br />}</span></p><p><span style="font-family:arial;">Next, we will define the nav-button class:</span><br /></p><p><span style="font-family:courier new;">.nav-button{<br />width:150px;<br />height:35px;<br />position:absolute;<br />top:0px;<br />}</span></p><p><span style="font-family:arial;">Note the height and width settings: the width is half the width of the image. We set the top position from the top of the outer container, but not left as that will be different for each button.</span></p><p><span style="font-family:arial;">Now we specify the settings for the anchor tags contained in the button DIV's:</span><br /></p><p><span style="font-family:courier new;">#home-button a, #contact-button a{<br />display:block;<br />margin:0;<br />padding:0;<br />width:100%;<br />height:100%;<br />overflow:hidden;<br />background-image:none;<br />}</span></p><p><span style="font-family:arial;">These define the link as a block that is the exact same size as the DIV that contains it. Notice that the background image is set to none. Notice also that I set this for each button's DIV. I tried doing it as a class, which would have made more sense, but that seemed to cause problems in IE8.</span></p><p><span style="font-family:arial;">Now we have to specify two settings for each button: the background and left position of the DIV tag and the background of the hover state of the A tag, which is actually the same image with a different offset:</span><br /></p><p><span style="font-family:courier new;">#home-button{<br />left:0px;<br />background:url('home_button.gif') top left no-repeat;<br />}<br />#home-button a:hover{<br />background:url('home_button.gif') -150px 0 no-repeat;<br />}</span></p><p><span style="font-family:arial;">For the Home button DIV, we set the left position to 0, since it is the first button. We set the background image with no offset, so it will display the left 150 pixels of our image (the blue "inactive" button). Then for the Home button's anchor, we set a background for the hover state. It is the same image but it has a 150 pixel offset so that you see the right part of the image (the yellow "active" button). I don't really know why the offset is specified like that. It threw me at first, but play with it and you will figure it out.</span></p><p><span style="font-family:arial;">So, when you mouse over the link you trigger the hover state, which causes the background image for the link to change from none to the offset background, which covers up the background being used for the DIV tag beneath. When you mouse off the link, the background reverts to none and the background of the DIV shows through again. </span></p><p><span style="font-family:arial;">All that's left is to specify similar settings for the Contact Us button:</span><br /></p><p><span style="font-family:courier new;">#contact-button{<br />left:160px;<br />background:url('contact_button.gif') top left no-repeat;<br />}<br />#contact-button a:hover{<br />background:url('contact_button.gif') -150px 0 no-repeat;<br />}</span></p><p><span style="font-family:arial;">Same as the Home button except for the image name and the left position (the width of the home button plus a 10 pixel space). </span></p><p><span style="font-family:arial;">Voila. No preload, no JavaScript, fewer images, better all around.</span></p><p><span style="font-family:arial;">Obviously, I didn't come up with this on my own. I got the idea from </span><a href="http://wellstyled.com/css-nopreload-rollovers.html" target="_BLANK"><span style="font-family:arial;">Petr Stanicek's tutorial</span></a><span style="font-family:arial;"> and made some adaptations. If you like, check out the </span><a href="http://www.gilsbachdesigns.com/css-nav-demo/css-nav-demo.htm" target="_BLANK"><span style="font-family:arial;">demo page on my site</span></a><span style="font-family:arial;"> where you can view the source and the entire CSS for this neat trick.</span><br /></p><p></p>Mike Gilsbachhttp://www.blogger.com/profile/00494538765829819322noreply@blogger.com0tag:blogger.com,1999:blog-7693118833190788079.post-28119223417183220432009-05-13T13:37:00.003-05:002009-05-13T14:02:55.323-05:00Pre-Packaged PHP User Login System<span style="font-family:arial;">I have a project I am working on that requires a user sign-in/registration system. All of the user data needs to be tracked and there are requirements for limiting access to certain content based on <span class="blsp-spelling-error" id="SPELLING_ERROR_0">login</span> status, etc. It's not terribly complicated and my first inclination was to go with a <span class="blsp-spelling-error" id="SPELLING_ERROR_1">WMS</span> like <span class="blsp-spelling-error" id="SPELLING_ERROR_2">DotNetNuke</span>, which has a very robust user management system built into it. But this project will require some special modifications that would be difficult (at least for me) to accomplish with <span class="blsp-spelling-error" id="SPELLING_ERROR_3">DNN</span>. </span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">So, my next thought was a custom <span class="blsp-spelling-error" id="SPELLING_ERROR_4">PHP</span> application with a MySQL <span class="blsp-spelling-error" id="SPELLING_ERROR_5">backend</span>. But I was concerned about the time involved in doing all the legwork just to duplicate the user account functionality that comes with <span class="blsp-spelling-error" id="SPELLING_ERROR_6">DNN</span> out of the box. </span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">Luckily a bit of Google-<span class="blsp-spelling-error" id="SPELLING_ERROR_7">ing</span> found me a real gold mine. As is so often the case with <span class="blsp-spelling-error" id="SPELLING_ERROR_8">PHP</span>, it turns out that somebody has already done all the legwork and is willing to share. (Three cheers for Open Source!!!) Here is the URL:</span><br /><span style="font-family:arial;"></span><br /><a href="http://www.evolt.org/node/60384"><span style="font-family:arial;">http://www.evolt.org/node/60384</span></a><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">The download consists of about a dozen very well commented <span class="blsp-spelling-error" id="SPELLING_ERROR_9">PHP</span> pages that handle just about all the basic aspects of a web site user <span class="blsp-spelling-error" id="SPELLING_ERROR_10">login</span> system, including:</span><br /><ul><li><span style="font-family:arial;">Session-based User <span class="blsp-spelling-error" id="SPELLING_ERROR_11">Login</span>/Registration with a "Remember Me" option<br /> </span></li><li><span style="font-family:arial;">The ability to set different access levels for members (user, admin, etc.)<br /> </span></li><li><span style="font-family:arial;">An Admin page where you can view user info, upgrade/demote user levels, delete users, delete inactive users, and ban users<br /> </span></li><li><span style="font-family:arial;">Users can view and edit their own account information<br /> </span></li><li><span style="font-family:arial;">Visitor tracking that tracks both Guests and Registered Users in real time<br /> </span></li><li><span style="font-family:arial;">"Forgot Password" features<br /> </span></li><li><span style="font-family:arial;">Optional welcome email to new users<br /></span></li><li><span style="font-family:arial;">Nice error handling features</span></li></ul><p><span style="font-family:arial;">He gives you the <span class="blsp-spelling-error" id="SPELLING_ERROR_12">SQL</span> you need to create the required database tables as well as some sample pages to see how the features can be integrated into your site. </span></p><p><span style="font-family:arial;">It's very easy to use. I had this up and running in a test environment in about 20 minutes. The code is very well structured and commented, so I have already been able to make a number of modifications (like adding more data fields to the account profile) very quickly. </span></p><p><span style="font-family:arial;">Highly recommended.</span></p>Mike Gilsbachhttp://www.blogger.com/profile/00494538765829819322noreply@blogger.com0tag:blogger.com,1999:blog-7693118833190788079.post-54176961871638938042009-04-30T09:31:00.002-05:002009-04-30T09:47:24.546-05:00The Importance of Links for Traffic<span style="font-family:arial;">This morning I saw a first-hand example of why links to your web site from other sites can be so effective. I was looking at the Google Analytics for the hobby site that I run for the <a href="http://www.austinsms.org/" target="_BLANK">Austin Scale Modeler's Society</a>. The traffic for that site has been pretty steady overall. But I noticed a huge spike in February - five times the normal number of visits. </span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">Digging deeper, I saw that almost all of that traffic was in a 3 day span in February. I thought there was no way this traffic was legitimate, must be some kind of DOS attack, or something. I looked at the geographic stats, fully expecting a spike in overseas traffic in that time period. But it wasn't there. As usual, most of the traffic was from the States. I looked at the content analysis and saw that most of the traffic was to the home page, so not much enlightenment there. </span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">Finally, I started looking at the referral information to see where it was all coming from. Turns out all that traffic was being generated from one site - <a href="http://www.hyperscale.com/" target="_BLANK">HyperScale</a> - that had a link to our home page in their "What's New" round-up on Feb 12. I recalled contacting them and asking them for a link on their site. Boy, did it work! </span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">This is not a commercial site, so I don't know how many sales conversions that would have resulted in, but I can't see how a 5-fold increase in visitors could have hurt. Just goes to show that taking the time to "pound the pavement" for reciprocal links can really pay off.</span>Mike Gilsbachhttp://www.blogger.com/profile/00494538765829819322noreply@blogger.com0tag:blogger.com,1999:blog-7693118833190788079.post-80056433642804984152009-04-10T13:50:00.003-05:002009-04-10T14:01:20.126-05:00Getting an Indented List to not Indent<span style="font-family:arial;">It seems like it should be really easy. I want a bulleted list, but with no indent. In other words, I want the bullets aligned to the left with no indent, but I still want the space between the bullet and the text. </span><br /><br /><span style="font-family:arial;">Why would I want this? Lots of reasons. I may have a list that is contained in a table in a page column where it makes no sense to indent the list. </span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">It seems like this should be easily controlled with <span class="blsp-spelling-error" id="SPELLING_ERROR_0">CSS</span>, but not so. All my attempts at this resulted in results other than what I wanted. <span class="blsp-spelling-corrected" id="SPELLING_ERROR_1">Attempts</span> to reduce the left indent usually resulted in the bullet simply vanishing or other odd stuff. I tried having the list items without the actual list tag, which worked in some browsers but not others; I encountered problems with the text wrapping under the bullet.</span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">I thought I must be missing something so I searched a bit online. It seems there really is no good way to do this. <span class="blsp-spelling-corrected" id="SPELLING_ERROR_2">Apparently</span> the indented list was intended to be just that - an indented list. Thus, there is no standard reliable way to change it. </span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">What you end up having to do is create a table where each row is a list item with two cells. One cell contains an image for your bullet, the other contains your text. It works, but it's hardly efficient. </span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">Just one of those HTML oddities, I suppose.</span>Mike Gilsbachhttp://www.blogger.com/profile/00494538765829819322noreply@blogger.com0tag:blogger.com,1999:blog-7693118833190788079.post-75005335005393831652008-12-05T15:34:00.000-06:002008-12-05T15:30:29.773-06:00Cross-Browser Testing Made Easy<span style="font-family:arial;">One of the challenges of building a web site is ensuring that it will function the same way when viewed by many different web browsers and versions of browsers on different operating systems. Something that works fine in the latest version of IE or FireFox may not work the same way (or at all) in an older browser or on a different O/S. This is not as much of an issue if you are just using very vanilla HTML. However, if you start using JavaScript, DHTML, or some of the more exotic CSS, you may be in for a nasty surprise when you try to view the page on a different system.</span><br /><span style="font-family:Arial;"></span><br /><span style="font-family:Arial;">What really got me thinking about this recently was my interest in weaning myself away from table-based design in favor of more CSS-driven design. I know it's supposed to be so much better, the wave of the future and all that. But my concern has always been how to be sure it would work on older browsers. </span><br /><span style="font-family:Arial;"></span><br /><span style="font-family:Arial;">I try to keep the latest versions of IE, FireFox, NS Navigator, Opera and now Google Chrome on my local machine for some basic cross-browser testing. But I can't have the other versions or the other O/S configurations to test. I don't even own a Mac at present. </span><br /><span style="font-family:Arial;"></span><br /><span style="font-family:Arial;">I started thinking it would be cool if there was a software tool out there that would grab a page and render it just like a specified browser, version of browser, etc.</span><br /><span style="font-family:Arial;"></span><br /><span style="font-family:Arial;">As it happens, I found something even better. This web site (<a href="http://www.crossbrowsertesting.com/" target="_BLANK">http://www.crossbrowsertesting.com/</a>) allows you to log into any of their many and varied images to test your page. It's free, with some restrictions that I'll get to in a bit. But you can hop on to a Mac, Ubuntu or Windows (98, XP, Vista, etc.) system and try out many different browsers, versions of browsers, etc. It's brilliant. It's not some kind of program that mimics the browser. It's the actual browser. And it's fully functional so you can test all your JavaScript, DHTML, whatever.</span><br /><span style="font-family:Arial;"></span><br /><span style="font-family:Arial;">There are a few restrictions on the "free" part. You can only stay logged into a session for 5 minutes at a time. But you can launch as many sessions as you like. So for quick tests, it is perfectly adequate. Also, paying customers get preference for access when the site gets busy. If you need to do more complex testing and need more than 5 minutes on an image, you can buy little blocks of time. It's all very well thought-out.</span><br /><span style="font-family:Arial;"></span><br /><span style="font-family:Arial;">Now, if they could just do something similar to test wireless devices...</span><br /><br /><br /><span style="font-family:Arial;"></span>Mike Gilsbachhttp://www.blogger.com/profile/00494538765829819322noreply@blogger.com0tag:blogger.com,1999:blog-7693118833190788079.post-18338750745898237762008-11-17T14:54:00.001-06:002008-11-17T14:56:34.737-06:00Thumbs Up for Sphider<span style="font-family:arial;">The </span><a href="http://www.austinsms.org/" target="_BLANK"><span style="font-family:arial;">model club</span></a><span style="font-family:arial;"> site that I run has been steadily growing. We have been adding lots of great content - articles, tips and photos, lots of photos. Our gallery now contains nearly 5000 of them. I am using a gallery application called Coppermine (PHP front-end, MySQL back-end). It's very nice. Each photo has a title and many have more detailed descriptions. </span><br /><br /><span style="font-family:arial;">With all this content I felt that the site really could benefit from having some kind of comprehensive search mechanism. Coppermine has its own search, which works fine, but I wanted a way to search the whole site at a go.</span><br /><br /><span style="font-family:arial;">My first thought was to use </span><a href="http://www.google.com/coop/cse/" target="_BLANK"><span style="font-family:arial;">Google Custom Search</span></a><span style="font-family:arial;">, which I had implemented with some success on another site. I was able to implement it on the club site without any trouble. The issue that I had was getting it to re-index in a timely fashion when I made changes. I decided that I wanted a mechanism that gave me more control over the indexing. As I have no budget for the club site, I also wanted something that was free. </span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">I found no shortage of free search engines out there and tried a few. But the problem I kept running into was that the free versions had a limit on the number of pages they would index. The limit was high - usually several thousand - but I kept exceeding it. The reason I kept exceeding it was the photo gallery. Nearly 5000 photos, each of which gets indexed as it's own page, plus gallery sub-area pages, etc., etc. That ends up being a lot of pages to index. </span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">I finally found a search engine that I could run locally on my site that was free and had no page limit - </span><a href="http://www.sphider.eu/" target="_BLANK"><span style="font-family:arial;">Sphider</span></a><span style="font-family:arial;">. Sphider uses PHP and requires a MySQL database to store it's indexes. It is really quite nice. Not only can you re-index at will, you can choose to index just certain parts of your site by setting up "sites" in the admin panel that limit their inclusion to just certain areas. This was especially useful for me because I often want to re-index everything except the gallery, which is pretty time consuming due to the sheer size of it. </span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">It took me a little time to get the filters right for indexing the gallery. I had to keep it from indexing certain ancillary pages that had no business showing up in a search result. But Sphider has some decent include/exclude filtering mechanisms to facilitate that. It also respects any directives in your robots text file. </span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">It provides some nice statistics on what search terms your visitors are entering, most popular searches and so on.</span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">Implementation was fairly easy. It uses a template with a header, footer, etc., which gives you enough flexibility to make it a seamless part of your site. Once your MySQL database is in place, you just pass Spider's admin panel your db user credentials and it takes it from there. </span><br /><span style="font-family:arial;"></span><br /><span style="font-family:arial;">All in all, really not bad. I have had it in place for about 2 months now and it seems to work really well. </span>Mike Gilsbachhttp://www.blogger.com/profile/00494538765829819322noreply@blogger.com0tag:blogger.com,1999:blog-7693118833190788079.post-24239895715292229712008-11-05T16:02:00.008-06:002008-11-14T14:03:06.405-06:00Back in the Mud<span style="font-family:arial;">After spending nearly 9 months on two airplane models, it's refreshing to be working on an armor subject again. My latest project is Tamiya's 1:35 scale M16 Half Track, US WWII. Here is a picture of the real deal:<br /></span><br /><span style="font-family:arial;"></span><br /><p><span style="font-family:arial;"><img id="BLOGGER_PHOTO_ID_5265298118923262690" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 400px; CURSOR: hand; HEIGHT: 238px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5SpOk6G_XA3_BqPY-n2gBlFeZiZcHDFKak0MXRyVQ8xdiBBe1zMBkYHe6DiLcq3ONJWKlozqXxo8oJMNak9oUXQSEtcLPlUJjGK9-ZW_Wn7hRserLFdv2gHY0DPlnBdY__61Ga5y19Tyf/s400/M16.jpg" border="0" /></span></p><p><span style="font-family:arial;">It's a fun subject with a lot more detail to it than you would think at first glance.</span></p><p><span style="font-family:arial;">It isn't that armor is easier. It has a whole set of challenges. Just a different set of challenges than building an aircraft subject. And there are a whole lot more possibilities for making it look like it has been in the field a while. </span></p><p><span style="font-family:arial;">An airplane is fragile. There is a very finite limit to the amount of damage and dirt an airplane can endure before it just won't fly. So, if you want your model airplane to represent an operable subject, you have to use a light hand when it comes to weathering and simulated damage.</span></p><p><span style="font-family:arial;">Not so with a tank or other armored vehicle. You can cover a tank in dust, dirt, mud, sand, snow, and just about anything else nature might throw at it. You can load it down with all manner of stowage: bags, tarps, infantry, and even random bits of civilian detritus. You can dent it up, rip parts of it off, shoot small holes in it, and basically just abuse it to no end and the odds are that the thing will still keep going. That makes for all sorts of fun possibilities when you model one because you can do all this stuff to it and it can still represent an operable front-line vehicle, albeit clearly one with a more interesting history. This is especially true if you model WWII subjects like I do. </span></p><p><span style="font-family:arial;">I am still in the early stages of this project, so it is mostly building in preparation for the base paint coat. But it won't be long before I can break out the oils, pastels, washes, powder pigments, etc. and go to town.</span></p>Mike Gilsbachhttp://www.blogger.com/profile/00494538765829819322noreply@blogger.com0tag:blogger.com,1999:blog-7693118833190788079.post-15010268686685676692008-11-03T08:21:00.004-06:002008-11-03T08:39:46.680-06:00New Window or Same Window?<span style="font-family:arial;">Any time you create a link on a page, you have the option to launch the target page in the same window (the default option) or in a new window. We aren't talking about those obnoxious automatic pop-ups here. We are talking about links the visitor actually clicks on. There seem to be several schools of thought on when it is appropriate to launch a new window. </span><br /><span style="font-family:Arial;"></span><br /><span style="font-family:Arial;">Some say you should <em>never</em> launch a link in a new window for a couple of reasons:</span><br /><ul><li><span style="font-family:Arial;">The user can always launch in a new window by choice by holding CTRL when they click the link or by middle-clicking the link with the mouse wheel.<br /></span><br /></li><li><span style="font-family:Arial;">By contrast, there is no easy way to make a link coded to launch in a new window launch in the same window. So, you are essentially taking the choice away from the visitor.</span></li></ul><p><span style="font-family:Arial;">I'm not sure I agree with that. For one thing, many users don't know how to launch in a new window. Also, in many cases, a user may want to check out something you are linking to without leaving your site. I like the following rule of thumb, which seems to be the consensus from what I have read:</span></p><ul><li><span style="font-family:arial;">Make internal links (links to stuff on your site) open in the same window.<br /></span><br /></li><li><span style="font-family:arial;">Make external links (links to other sites) open in a different window.</span></li></ul><p><span style="font-family:arial;">There are some exceptions to the first point. For example, if you are displaying a short form or a Flash piece or something and you want better control over the window like size or toolbar/no toolbar, etc. But for the most part I would think these rules would work.</span></p><p><span style="font-family:arial;">I'd be curious if anyone agrees/disagrees either from a designer standpoint or from a user's standpoint. Let me know...</span> </p>Mike Gilsbachhttp://www.blogger.com/profile/00494538765829819322noreply@blogger.com0tag:blogger.com,1999:blog-7693118833190788079.post-79642064133635957122008-10-31T11:36:00.000-05:002008-10-31T11:47:09.613-05:00Validating Form Entries with JavaScript PS<span style="font-family:arial;">OK. Being new to Blogger, I didn't realize how to correctly post code samples to an entry. Hence the screen captures in my last post. Below is a copy-and-paste-friendly version of the whole page of code I used for that example. </span><br /><br /><pre><span style="font-family:courier new;font-size:85%;"><span style="color:#000099;"><html><br /><head></span><br /><span style="color:#660000;"><script type="text/JavaScript"><br /><!--<br />function check_form_data()<br />{<br /> if (document.the_form.email.value == "")<br /> {<br /> alert("Email is a required field. Please fill it in.");<br /> document.the_form.email.focus();<br /> document.the_form.email.style.background = "#EEF111";<br /> return;<br /> }else{<br /> document.the_form.submit();<br /> }<br />}<br />// --><br /></script></span><br /><span style="color:#000099;"></head><br /><br /><body></span><br /><span style="color:#660000;"><?php<br />if (isset($_POST['test_val'])){<br /> process_form();<br />}else{<br /> print_form();<br />}<br /><br />function print_form(){<br /> print <<< FORM_TEXT<br /> <span style="color:#666666;"> <!--Note that the action just points back to the same page--></span><br /> <form name="the_form" method="POST" action="this_page.php"><br /> <span style="color:#666666;"><!--Here is our test value--></span><br /> <input type="hidden" value="1" name="test_val"><br /> Email: <input type="text" id="email" size="20"><br><br /> <input type="button" onClick="check_form_data();" value="Submit"><br /> </form><br /> FORM_TEXT;<br />}<br /><br />function process_form(){<br /> <span style="color:#666666;">//Process the form data - send an email, write to a DB, whatever.</span><br />}<br />?></span><br /><span style="color:#000099;"></body><br /></html></span></span></pre>Mike Gilsbachhttp://www.blogger.com/profile/00494538765829819322noreply@blogger.com0tag:blogger.com,1999:blog-7693118833190788079.post-53709537091288242762008-10-30T11:38:00.000-05:002008-10-31T11:11:13.175-05:00Validating Form Entries with JavaScript<span style="font-family:arial;">I use HTML forms quite a lot on the web sites I build for a variety of purposes. Most of the ones I build these days are self-handling PHP forms. This means that the form and the PHP that handles the form are on the same page. This is easy to do. You just put a hidden value in the form that gets set when the visitor submits the form. The PHP code checks for that value. If it's set, it does the processing. If it's not set, it displays the form. The basic code layout looks something like this:</span><br /><br /><div><div><div><div><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuH9mFltiRN0cpxUbihKzZAte3iMwGGOZEhiI8xEweOWQ4lHqXzS4JesAyf1BFi05ecpw2PRAb3cjfKjxH6I0tS-CglRgB-j3gTAQ8-Tqcvl8ltUlcqMLcTtM5LYCT7AZHEinfnGbrchrc/s1600-h/validate1.gif"><img id="BLOGGER_PHOTO_ID_5263348201673549058" style="WIDTH: 400px; CURSOR: hand; HEIGHT: 302px" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuH9mFltiRN0cpxUbihKzZAte3iMwGGOZEhiI8xEweOWQ4lHqXzS4JesAyf1BFi05ecpw2PRAb3cjfKjxH6I0tS-CglRgB-j3gTAQ8-Tqcvl8ltUlcqMLcTtM5LYCT7AZHEinfnGbrchrc/s400/validate1.gif" border="0" /></a><br /><br /><div><span style="font-family:courier new;"><span style="font-family:Arial;">In the first part of the PHP, we check to see if the hidden value "test_val" is set. If it is, process_form(), otherwise print_form(). Nothing to it. </span><br /></div></span><br /><div><span style="font-family:Arial;">We can have process_form() do just about anything with the submitted data. What we don't want it doing is trying to process form data that cannot, or should not, be processed. We may have certain fields that are required. We may have fields where the input has to be in a certain format or match certain criteria. Of course, we also don't want to be processing anything that is clearly the work of a spambot. We could handle all of this on the server side and in some cases where more complex validation is needed, this might be appropriate. But why have our server waste processing cycles doing simple checks for missing or garbage data? Let the requesting browser do it by giving the data a quick once-over with client-side JavaScript first. </span></div><br /><div><span style="font-family:Arial;">The first thing that we have to do is intercept the form data before it gets sent to the server. To do this, we will replace the usual HTML form SUBMIT button with a generic button that launches our JavaScript when clicked, like this:</span><br /></div><div><br /></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgW4r_fvRBNvMw46myym93tQ8edIZtQQiq_W0Iz2hZLd0CelSkNiiM837egbcQnOnBje6Fa4Y30mboCCL-V3e58CBhLpgChi8Vz8Jkv1MaqBUwPbGxZ-dLP34paKoR1lnOYbmp-BxYSFqFr/s1600-h/validate2.gif"><img id="BLOGGER_PHOTO_ID_5263061832601127730" style="WIDTH: 400px; CURSOR: hand; HEIGHT: 13px" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgW4r_fvRBNvMw46myym93tQ8edIZtQQiq_W0Iz2hZLd0CelSkNiiM837egbcQnOnBje6Fa4Y30mboCCL-V3e58CBhLpgChi8Vz8Jkv1MaqBUwPbGxZ-dLP34paKoR1lnOYbmp-BxYSFqFr/s400/validate2.gif" border="0" /></a><br /><br /><div><span style="font-family:Arial;">For illustration, let's plug this into a simple form that collects an email address:</span> </div><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhS0JDSzZtcnbnLWWpKC960QfPh6EU2CtaoYuA70eBlzZFurfzEHgmnMA0p2OlMOJJcL3QeUcz6iUA88VaXkpjZx-1SK1AfJfzgR6duQlYo45tEge7S9XQsSbQErixks487NJIektuXuUZE/s1600-h/validate3.gif"><img id="BLOGGER_PHOTO_ID_5263062504054523650" style="WIDTH: 400px; CURSOR: hand; HEIGHT: 62px" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhS0JDSzZtcnbnLWWpKC960QfPh6EU2CtaoYuA70eBlzZFurfzEHgmnMA0p2OlMOJJcL3QeUcz6iUA88VaXkpjZx-1SK1AfJfzgR6duQlYo45tEge7S9XQsSbQErixks487NJIektuXuUZE/s400/validate3.gif" border="0" /></a><br /><br /><div><span style="font-family:Arial;">Now let's assume that we want to do a simple validation to make sure that the email field is not blank when submitted. The basic layout of our JavaScript function (placed in the HEAD) could look something like this:</span><br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5dhCqTESYH9byVYk9iKZ_GYrYgUTbkLJTYULiYLj_XEhVdPLZ5vPMJJqZJyhdSM9Bkoq1k9uqSR9rg2UMr-RhYCKFXmZyfBwHIslcAIAAHn4geEZftn5ADJTmuSgtH7G2GJmAN6ac9rEG/s1600-h/validate4.gif"><img id="BLOGGER_PHOTO_ID_5263062904383882850" style="WIDTH: 400px; CURSOR: hand; HEIGHT: 183px" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5dhCqTESYH9byVYk9iKZ_GYrYgUTbkLJTYULiYLj_XEhVdPLZ5vPMJJqZJyhdSM9Bkoq1k9uqSR9rg2UMr-RhYCKFXmZyfBwHIslcAIAAHn4geEZftn5ADJTmuSgtH7G2GJmAN6ac9rEG/s400/validate4.gif" border="0" /></a><br /><br /><span style="font-family:Arial;">We check to see if the email value is blank. If it is, we throw an alert and exit the function. Otherwise, we call the JavaScript submit function, which sends the validated form data on its merry way.</span></div><br /><div><span style="font-family:arial;">Of course, the validation we have done here is very simple. We could check to see that the value of the email field matches the proper format for an email address. We could write a loop to systematically check multiple required fields. We could check to see that multiple fields do not contain the same value - an annoying spambot symptom. We could even dynamically add additional fields to the form based on the visitor's initial inputs. There is loads more we could do.</span></div><br /><div><span style="font-family:Arial;">In our simple example, we could help the visitor even more by sending their cursor directly to the email field:</span></div><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY8PbseTddILlifJffjxDLT-EDQumM3W9CAPQgnMwLJARqc80XNbZ2UR6eDfj1kEcGggmyftj4n7nRN3RhyLjAgRtHLtTlfVONsr5h1nbi_MejBbN7dmKpef0QKzlwNUwPWny8Ej76SKJf/s1600-h/validate5.gif"><img id="BLOGGER_PHOTO_ID_5263348922574306210" style="WIDTH: 400px; CURSOR: hand; HEIGHT: 68px" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY8PbseTddILlifJffjxDLT-EDQumM3W9CAPQgnMwLJARqc80XNbZ2UR6eDfj1kEcGggmyftj4n7nRN3RhyLjAgRtHLtTlfVONsr5h1nbi_MejBbN7dmKpef0QKzlwNUwPWny8Ej76SKJf/s400/validate5.gif" border="0" /></a><br /><br /><div><span style="font-family:Arial;">We could even highlight the field in yellow to further alert the visitor to the problematic field:</span><br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQufvUoshlXb6Yiy4jF7kyjjCmE0wwrQBMmBBJoD5IPo9IBtD5UtspKlV6fVZclPhAezpmrJF07ZW7xuKeNjHP43pxON6d2p4mTaQBI9wufoawUnrHP7ku4Lw-CWGNI6ODyGHqHkzByGPg/s1600-h/validate6.gif"><img id="BLOGGER_PHOTO_ID_5263349448621544002" style="WIDTH: 400px; CURSOR: hand; HEIGHT: 82px" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQufvUoshlXb6Yiy4jF7kyjjCmE0wwrQBMmBBJoD5IPo9IBtD5UtspKlV6fVZclPhAezpmrJF07ZW7xuKeNjHP43pxON6d2p4mTaQBI9wufoawUnrHP7ku4Lw-CWGNI6ODyGHqHkzByGPg/s400/validate6.gif" border="0" /></a><br /><br /></div><div><span style="font-family:Arial;">This is especially useful if you are checking and flagging multiple fields. You can focus the visitor's cursor on the first problem field, but highlight them all so that they see all the problems. Just remember to reset the highlight color back to the default for all fields at the start of your function, otherwise the fields that your visitor did fix will still be highlighted.</span></div><br /><div><span style="font-family:Arial;">Certainly nothing groundbreaking here, but useful stuff. There are tons of examples of this out there and the complexity of your validation is really only limited by your knowledge of JavaScript.</span></div></span></div></div></div></div></div>Mike Gilsbachhttp://www.blogger.com/profile/00494538765829819322noreply@blogger.com0tag:blogger.com,1999:blog-7693118833190788079.post-16149806337520634752008-10-27T16:09:00.000-05:002008-10-31T11:48:31.884-05:00Why I Like Building ModelsSo, after several months of a little time one evening here and a little time one afternoon there, a few dozen bits of plastic are now one little six-inch long model airplane collecting dust on my shelf.<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwpXozdHkCBkFuZsuqgzHTT3si4Lo-CMpdZIOwKml9gkb8277CdYKvzUQUW6eUj2DLRoQ-ooPgZ2iZgoPPOLNxoFFC98GgDZaoiir7HQXKM4H8j3j__rHphYG1ziaZxobcRZf0z68k6RLW/s1600-h/747.gif"><img id="BLOGGER_PHOTO_ID_5262263310751992146" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 400px; CURSOR: hand; HEIGHT: 260px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwpXozdHkCBkFuZsuqgzHTT3si4Lo-CMpdZIOwKml9gkb8277CdYKvzUQUW6eUj2DLRoQ-ooPgZ2iZgoPPOLNxoFFC98GgDZaoiir7HQXKM4H8j3j__rHphYG1ziaZxobcRZf0z68k6RLW/s400/747.gif" border="0" /></a><br />What was the point, exactly? What is it that compels me to spend so much of my spare time cutting, sanding, painting and gluing to produce something that in the final analysis is, well, completely useless. Then I go to the hobby shop and buy more box loads of plastic bits so that I can spend many more hours hard at work on...more dust bunny bait. Then I go online and spend hours finding reference photos so that I can see just what the right flap extension angle is for a Boeing 747 on final. Or I am online tracking down that extensive photo-etch detail set for the USS Missouri kit that already has hundreds of parts.<br /><br />In contrast, my wife throws pots. At least when she is done we have something that, in addition to being nice to look at, is also useful like a mug or a bowl or a plate. She also sews. She has made me shirts, made clothing for our sons, etc. Again, the end result is useful. Not my models. They just sit on the shelf.<br /><br />But maybe that's exactly why I like doing it. It is, in the truest sense, a hobby. A total waste of time done purely for enjoyment.<br /><br />Well, off to work on my WWII half track...Mike Gilsbachhttp://www.blogger.com/profile/00494538765829819322noreply@blogger.com0tag:blogger.com,1999:blog-7693118833190788079.post-60027290341668982742008-10-24T15:29:00.000-05:002008-10-27T21:19:32.297-05:00Fun With Google Maps API<span style="font-family:verdana;">I was a Geography major in college and I have always loved maps. I like looking at them and I like working with them. It is something I often have to do when I build web sites for small businesses, particularly those with physical locations that customers need to get to. </span><br /><span style="font-family:verdana;"></span><br /><span style="font-family:verdana;">In the past, I always just put together a static map graphic and added a hyperlink to MapQuest or some other site for directions. </span><span style="font-family:verdana;">Then I read about Google allowing people to tap into their maps API to display fully functional Google maps on their own pages. (I read about it in <a href="http://www.quest.com/knowledge-xpert-for-mysql/">Quest Software's Knowledge Xpert for MySQL</a>, of all things, the latest version of which includes a very nice tutorial on this subject.) Anyway, it's really pretty easy. Just a matter of signing up with Google to get a key and then adding some JavaScript to your page - not that dissimilar to Google Analytics, another wonderful and inexplicably free Google web toy.</span><br /><span style="font-family:verdana;"></span><br /><span style="font-family:verdana;">To start, you need to register and get a key from Google. You need one key for each domain you want to put your map on. You can get a key here:</span><br /><span style="font-family:verdana;"></span><br /><span style="font-family:verdana;"><a href="http://code.google.com/apis/maps/signup.html">http://code.google.com/apis/maps/signup.html</a></span><br /><span style="font-family:verdana;"></span><br /><span style="font-family:verdana;">Google will provide you with the code you need to drop into your page and they have loads of docs on the various options available to you. Alternatively, you can get some nice code from the aforementioned Knowledge Xpert product, which is free. </span><br /><span style="font-family:verdana;"></span><br /><span style="font-family:verdana;">But it's straightforward enough. Some JavaScript in your HEAD, then a DIV tag where you want to actually place the map. You can include or exclude all the various controls like pan, zoom, Map/Satellite/Hybrid toggles, etc. It can be easily sized. </span><br /><span style="font-family:verdana;"></span><br /><span style="font-family:verdana;">One thing that's not as obvious. Some of the Knowledge Xpert examples center the map using a Google geocode (the lat and long) for where you want the map to center on initially. Their instructions for obtaining that geocode for a specific address were a little fuzzy for me. As it happens, there is a URL that you can ping to get the code for any address. The example below finds the geocode for 810 Guadalupe Street, Austin (if you put in your google maps key at the end):</span><br /><span style="font-family:verdana;"></span><br /><span style="font-family:verdana;"><a href="http://maps.google.com/maps/geo?q=810+Guadalupe+Street,+Austin,+TX&output=csv&key=your_google_key_here">http://maps.google.com/maps/geo?q=810+Guadalupe+Street,+Austin,+TX&output=csv&key=your_google_key_here</a></span><br /><span style="font-family:verdana;"></span><br /><span style="font-family:verdana;">To see the example where I used Google Maps, visit <a href="http://www.austinsms.org/meetings.php">http://www.austinsms.org/meetings.php</a> and have a peek at the source.</span><br /><span style="font-family:verdana;"></span><br /><span style="font-family:verdana;">Knowledge Xpert also provides additional information on tying this into a MySQL database to store and map multiple locations, if you are so inclined.</span><br /><span style="font-family:verdana;"></span><br /><span style="font-family:verdana;">Lots of fun to play with and a much nicer solution to providing a map on your web site. </span><br /><span style="font-family:verdana;"></span>Mike Gilsbachhttp://www.blogger.com/profile/00494538765829819322noreply@blogger.com0