Web Info & Tutorials

November 30th, 2007

THOMAS FUCHS USES SCRIPT.ACULO.US 2.0 ON HIS OWN SITE

Thomas Fuchs is back in the consulting game and his new site gives us another glimpse of Script.aculo.us 2.0 abilities.

The photo zooming?

JAVASCRIPT:
  1.  
  2. Effect.PhotoZoom = Class.create(Effect.Element, {
  3.   setup: function() {
  4.     var currentHeight = $('text').getHeight();     
  5.     var newHTML = this.element.next('div.text').innerHTML;
  6.    
  7.     var left =  Thomas.photos.indexOf(this.element)*120 + 90;
  8.     var color = $w('ffa ffa ffa ffa ffa')[Thomas.photos.indexOf(this.element)];
  9.      
  10.     $('text_contents').show().update(newHTML).setStyle({height:'auto'});
  11.     var newHeight = $('text_contents').getHeight()+22;
  12.    
  13.     Thomas.clearTextBox();
  14.     $('text').setStyle({height:currentHeight+'px'});
  15.    
  16.     $('text').morph('left:'+left+'px;height:'+newHeight+'px;background-color:#'+color,{
  17.       duration: 1.2,
  18.       transition: 'linear',
  19.       propertyTransitions: {
  20.         left: 'bouncePast',
  21.         height: 'bouncePast',
  22.         backgroundColor: 'sinusoidal'
  23.       },
  24.       after: function(){
  25.         $('text_contents').show();
  26.         Element.update.defer('text_contents', newHTML);     
  27.       }
  28.     });
  29.    
  30.     this.animate('zoom', this.element, {
  31.       propertyTransitions: this.options.propertyTransitions || { }
  32.     });
  33.   }
  34. });
  35.  

Thomas Fuchs

November 30th, 2007

PLACESHOUT: NEW RAILS BASED GEO-COOL SITE

Andre Lewis has a new site out there, Placeshout which offers a way to quickly call out your favourites place in various locations.

You could argue that we have other places for this... Yelp for example, or My Maps themselves. So, why Placeshout?

Sometimes, you just want a quick suggestion

When Andre and I are looking for a hole-in-the-wall Mexican restaurant or a park with a softball field, we usually just want a quick suggestion, not a lengthy review. We want to know if a place is worth visiting in 30 seconds.

Placeshout isn't about volume - it's about trying to express the positives and negatives of a destination in as few of words as possible. If people agree, that "shoutout" moves up...if they don't, the shoutout moves down and begins to disappear.

We hope Placeshout makes it easier for you to find local destinations.

There are some interesting features in this, very Web 2.0-looking, site. One that stands out is the enhanced mapping experience on top of Google Maps. As you move around, directional arrows tell you how far various other cities are away. It is kinda fun to watch:


November 30th, 2007

BRENDAN EICH: JAVASCRIPT 2 EVOLUTION AND THE MYTH BUSTING TRACING JIT

I fuck watching Brendan Eich speak. You undergo that before daylong you module be unfathomable into a topic, and if you artefact up for a time you module be hopelessly behind. You hit to center closely. Even if you do, you module belike conceive that you uncomprehensible a aggregation of it.

Brendan has posted his slides on JavaScript 2 and the Open Web as a narrative.

The show starts soured having a taste of recreation with the characters behindhand the JavaScript 2 speaking much as politico Crockford (Yoda above). You crapper debate most the persuasion of ES4 but the example I institute most engrossing was Brendan attractive cipher that is cursive in underway JavaScript, and evolving it via iterations. In fact, I would fuck to hit seen that as the magnitude of the speech as it rattling shows you what JS2 is every about.

Here is the distribution webmail cipher in JS1:

JAVASCRIPT:

  1.  
  2. function send(msg) {
  3.   validateMessage(msg);
  4.   msg.id = sendToServer(JSON.encode(msg));
  5.   database[msg.id] = msg;
  6. }
  7.  
  8. function fetch() {
  9.   handleMessage(-1);                  // -1 effectuation "get newborn mail"
  10. }
  11.  
  12. function get(n) {
  13.   if (uint(n) !== n)                  // JS1: n>>>0 === n
  14.       throw new TypeError;
  15.   if (n in database)
  16.       return database[n];
  17.   return handleMessage(n);
  18. }
  19.  
  20. var database = [];
  21.  
  22. function handleMessage(n) {
  23.   permit msg = JSON.decode(fetchFromServer(n));
  24.   if (typeof msg != “object”)
  25.       throw new TypeError;
  26.   if (msg.result == “no data”)
  27.       return null;
  28.   validateMessage(msg);
  29.   return database[msg.id] = msg;
  30. }
  31.  
  32. function validateMessage(msg) {
  33.   function isAddress(a)
  34.       typeof a == “object” && a != null &&
  35.       typeof a.at == “object” && msg != null &&
  36.       typeof a.at[0] == “string” && typeof a.at[1] == “string” &&
  37.       typeof a.name == “string”;
  38.   if (!(typeof msg == “object” && msg != null &&
  39.       typeof msg.id == “number” && uint(msg.id) === msg.id &&
  40.       typeof msg.to == “object” && msg != null &&
  41.       msg.to instanceof Array && msg.to.every(isAddress) &&
  42.       isAddress(msg.from) && typeof msg.subject == “string” &&
  43.       typeof msg.body == “string”))
  44.       throw new TypeError;
  45. }
  46.  

And here it is after a ordered of evolutionary steps. You module wager that this looks same a rattling assorted beast. Before you eek, we hit to actualise that most of the cipher that module be cursive won’t be clean up same this, but kinda hacky JS same we hit now.

JAVASCRIPT:

  1.  
  2. type MsgNoId = {
  3.   to: [Addr], from: Addr, subject: string, body: string
  4. };
  5.  
  6. function send(msg: same MsgNoId) {
  7.   msg.id = sendToServer(JSON.encode(msg));
  8.   database[msg.id] = copyMessage(msg);
  9. }
  10.  
  11. function handleMessage(n) {
  12.   permit msg = JSON.decode(fetchFromServer(n));
  13.   if (msg is same { result: progress } && msg.result == “no data”)
  14.       return null;
  15.   if (msg is same Msg)
  16.       return database[id] = copyMessage(msg);
  17.   throw new TypeError;
  18. }
  19.  
  20. function copyMessage(msg) {
  21.   function newAddr({ at: [user, host], name })
  22.       new Addr([user, host]: [string, string], name);
  23.  
  24.   permit { to, from, subject, body, id } = msg;
  25.   return new Msg(to.map(newAddr), newAddr(from), subject, body, id);
  26. }
  27.  

Another engrossing myth that Brendan damaged is the idea that:

Optional typewriting is required to attain your applications perform

Tracing JIT

November 30th, 2007

HEATCOLOR - FIRING UP ELEMENTS BASED ON VALUES

Using color has been a tried and true method of representing importance or value in a UI. Whether it's negative balance or indicating a successful process, color helps to convey your message much more effectively then plain old text.

Josh Nathanson came up with an interesting jQuery plugin called HeatColor which assigns colors to elements based on a range of values:

HeatColor is a plugin that allows you to assign colors to elements, based on a value derived from that element. The derived value is compared to a range of values, either determined automatically or passed in, and the element is assigned a "heat" color based on its derived value's position within the range.

You bind a collection of elements such as table rows, divs or list members to heatcolor and let it do the work.

It can find the min and max values of the desired elements, or you can pass them in manually.

The plugin is very easy to use providing for a callback method to return the value to base the color on as well as several config options that can determine the color scheme, order of colors, and min/max for the range of values. The following snippet of code generated some cool results:

$(\"#ex1\").tablesorter();
	
function sortwithcolor( column ) {
	$(\"#ex1 > tbody > tr\").heatcolor(
		function() { return $(\"td:nth-child(\" + column + \")\", this).text(); }
	);
};
	
$(\"th\").click(function() {
	$(this).siblings().css(\"background-color\",\"#cccccc\").end().css(\"background-color\",\"#dd0000\");
	sortwithcolor( $(this).parent().children().index( this ) + 1 );
});
	
sortwithcolor(8);
	

Josh created some other cool demos that are really worth checking out so be sure to hit up his plugin's page for more details.

November 30th, 2007

BUG: OBJECT KILLING IN IE7

Jon Sykes thinks he has found a freakish fault in IE7. Since Microsoft has 34 QA grouping per developer, sure not! ;)

He told us:

There is a fault in IE7 where by a distinction of cipher exclusive a contingent evidence that NEVER runs, crapper drive an goal that is ordered with a evenhandedly accepted goal papers to be whipped. Even weirder is that it module hit whipped the cipher modify if you place a debug signal of the goal before the cipher that does the whipping. Confused? I undergo I am.

Thankfully it does countenance evenhandedly ultimate to impact _around_ and avoid. But it’s belike a debug nightmare, and it’s a fault I couldn’t encounter referenced anywhere, so I figured it was worth sharing.

A ultimate effort housing is:

HTML:

  1.  
  2. <script type=“text/javascript”>
  3.         this[‘test’] = {};
  4.         alert(this[‘test’]);
  5.         // module ness discover [Object object]
  6. </script>
  7. <script type=“text/javascript”>
  8.          alert(this[‘test’]);
  9.          // module ness discover Undefined in IE7
  10.  
  11.          // this incoming accumulate of cipher should never run.
  12.          if (true == false){
  13.            alert("This never fires");
  14.            // THIS SHOULD NOT IMPACT ON ANYTHING !!!!
  15.            var test; // verify this distinction discover and it entireness fine
  16.            alert("This never fires");
  17.          }
  18. </script>
  19.  
November 29th, 2007

WIDGETS AND GADGETS

We have had a couple of interesting announcements in the worlds of Widgadgets. First, Yahoo! launched a new version of the Widget platform: Yahoo! Widgets 4.5, and second, Google Gadgets have gone across another platform, with new support for the Mac and Dashboard.

Yahoo! Widgets 4.5

What’s New for Widget developers:

Yahoo! Widgets 4.5 now makes it easier for Widget authors to drive deeper engagement with users.

  • Build even more engaging desktop Widgets, using new rich-media capabilities, including video.
  • Utilize existing web development (HTML and Flash) skills to build compelling desktop Widgets.
  • Offer users the ability to download their desktop Widgets from any webpage within 1-2 clicks via the new In-page installer badges.
  • Enable easier discovery by more users, via the new Yahoo! Widget Gallery with improved SEO.

Read more on our blog!

Google Gadgets for the Mac

Google Gadgets for the Mac uses WebKit’s JavaScript engine inside Dashboard, so the majority of gadgets just work if they’re written properly. The rest can be fixed by following a few guidelines:

  • Use JavaScript, not JScript
  • WebKit is case-sensitive, JScript is not, which can lead to problems if you assume can you do things like interchange SetTimeOut() and setTimeout().
  • Avoid JScript-only features like collections and ActiveX.
  • Avoid IE-specific DOM extensions, just as if you were writing a multi-browser web application.
  • Avoid Windows-specific APIs
    • You shouldn’t assume ActiveX or certain DLLs are available. Neither WebKit nor Mac OS X supports ActiveX, so these gadgets must be rewritten.
    • Avoid Windows-only APIs such as Google Talk. These APIs are not (yet) available on Mac OS X.
  • Understand how Dashboard is different
    • The Dashboard environment is very different from a web page or the Desktop sidebar on Windows in that it comes and goes as the user activates it. Don’t rely on your gadget always being visible. Your gadget won’t run or update when Dashboard isn’t in the foreground.
    • Don’t rely on access to the file system. The security model for Dashboard doesn’t allow arbitrary file access to the hard disk, although your gadget does have access to files in its own archive. Things like file pickers won’t work. Note that while restricted file system access is a departure from how gadgets work on Windows, it’s consistent with Dashboard’s security model and the behavior of other widgets developed for Mac OS X.

    For more details, see Writing a Cross-Platform Gadget, part of the Desktop Gadget API documentation.

    If you’re interested in developing your own gadget, visit the Gadgets API homepage. If you’re already a gadget developer, download the beta today to test your gadget and ensure that it works correctly.

    November 29th, 2007

    ROLLING YOUR OWN GWT HYPERLINK CLASS

    From reading his post, Ivan Moscoso definitely has too much time on his hands as he decided to see how easy it was to set the status bar text when hovering over a link in GWT:

    It’s Wednesday, and you have had it up to here with the weather. There’s nothing on TV and you’ve gone out for so many walks, you can’t even get your dog to look you in the eye without him hiding under the kitchen table. You have time on your hand, so you decide you want to see how easy it is to set the status bar text when hovering over a link in GWT (why? don’t ask why, let’s just pretend for a second).

    So he tried three different solutions including extending GWT’s HyperLink class and wrapping the Hyperlink class within a GWT FocusPanel. Those two really didn’t pan out as he had hoped:

    The problem with this option is that it doesn’t exactly work as intended. ’setStatusText()’ gets invoked at the right time, but if you look at the status bar in Firefox, the status bar text doesn’t update. I’m not sure why exactly- it might just be my quick & dirty JavaScript, but even if everything worked as intended I’m still not happy with this solution. I mean, look at the code– I have to pull in many ingredients just to complete a simple task– DOM.eventGetType()? Writing a JSNI method definition? Registering the right Event type, overriding default behavior, etc.? Not the most readable code and not the kind of code I would lightly hand off to someone just getting their feet wet with GWT.

    Finally, Ivan decided to roll his own Hyperlink class:

    class MyHyperlink extends HTML {
      public MyHyperlink(String name) {
            setHTML(
              "<a onmouseover=\"status='’;return true;\" href=\"#x\">" + name + "</a>"
            );
    	
            addClickListener(new ClickListener() {
                public void onClick(Widget sender) {
                    // Whatever you would have done in Hyperlink’s clickListener…
                    foo.submitSomething();
                }
            });
        }
    }

    You can check out all three solutions via Ivan’s post and see why he decided to build his own GWT class.

    November 29th, 2007

    COLDFUSION 8 GRID MAGIC

    Scott Bennett put up two nice postings which demonstrate how to extend ColdFusion 8’s built-in Grid control. I’ve mentioned before that CF8 uses Ext v1.0 and as such offers a ton of flexibility not generally mentioned in the CF documentation.

    Grid Validation

    In his first post, Scott shows how to implement validation of CFGrid data. Leveraging Ext’s validateedit event, which fires after a cell is edited but before the value is actually saved, Scott was able to include code that validated the data prior to being saved:

    Now whenever the validateedit event fires, it will call the dataValidator() function. The dataValidator() function checks to see if the field that is being edited needs validation, and then validates the data if necessary. In this example, I added validation for the Expiration Date, and the numeric Sponsor ID for the coupon record. If the data fails validation an alert is thrown and the edit event is canceled(reverting the data back to it’s original value).


    <html>
    <head>
       <title>CFGird Custom Date Validator</title>
       <!— import the Ext date package —>
       <cfajaximport tags=“cfinput-datefield”>
       <!— create javascript function for rendering dates —>
       <script language=“JavaScript” type=“text/javascript”>

       setDateRenderer = function(){
          mygrid = ColdFusion.Grid.getGridObject(’CouponsGrid’);
          cm = mygrid.getColumnModel();
          cm.setRenderer(3, Ext.util.Format.dateRenderer(’m/d/Y’));
          mygrid.reconfigure(mygrid.getDataSource(),cm);
       }
       dataValidator = function(editEvent){
          //Date Field Validation

          if (editEvent.field == “EXPIRATIONDATE”){
             if (isNaN(Date.parse(editEvent.value))){
                alert(“Please enter a date in this field.”);
                editEvent.cancel = true;
             }
             else {

                data = new Date(Date.parse(editEvent.value));
                editEvent.value = data.dateFormat(“m/d/Y”);
             }
          }
          //Numeric Field Validation

          if (editEvent.field == “SPONSORID”){

             if (isNaN(editEvent.value)){
                alert(“Please enter a numeric value in this field.”);
                editEvent.cancel = true;
             }
          }
       }
       addValidator = function(){
          mygrid = ColdFusion.Grid.getGridObject(’CouponsGrid’);

          mygrid.on(’validateedit’,dataValidator);
       }
       init = function(){
          setDateRenderer();
          addValidator();
       }
       </script>
    </head>

    <body>
    <!— Set up the Grid —>
    <cfform id=“CouponForm” name=“CouponForm”>
    <cfgrid name=“CouponsGrid”
    format=“html”

    pagesize=“10″
    striperows=“yes”
    selectmode=“edit”
    bind=“cfc:coupons.getCoupons({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection})”
    onchange=“cfc:coupons.editCoupon({cfgridaction},{cfgridrow},{cfgridchanged})”>

    <cfgridcolumn name=“Couponid” display=“false” />
    <cfgridcolumn name=“SPONSORID” header=“Sponsor” width=“100″/>

    <cfgridcolumn name=“COUPON” header=“Coupon” width=“100″/>
    <cfgridcolumn name=“EXPIRATIONDATE” header=“Exp Date” width=“200″/>

    </cfgrid>
    </cfform>

    <!— use AjaxOnLoad to call the init() function —>
    <cfset ajaxOnLoad(“init”)>
    </body>
    </html>

    Custom Date Renderer

    In his second post, Scott again takes advantage of Ext’s capability and shows how to create a custom date renderer:

    One of the coolest things about the ColdFusion 8 implementation of the CFGrid tag is that you can do a lot of customization, if you know your way around the Ext objects. I have found several blog entries about using custom renderers with the CFGrid tag. However, could not find a working example of one for date fields, so I decided to build one.

    CouponForm.cfm


    <html>
    <head>
       <title>Custom Date Renderer</title>
       <!— import the Ext date package —>
       <script src=“/CFIDE/scripts/ajax/ext/package/date.js” type=“text/javascript”></script>

       <!— create javascript function for rendering dates —>
       <script language=“JavaScript” type=“text/javascript”>
       setDateRenderer = function(){
          mygrid = ColdFusion.Grid.getGridObject(’CouponsGrid’);
          cm = mygrid.getColumnModel();
          cm.setRenderer(3, Ext.util.Format.dateRenderer(’m/d/Y’));

          mygrid.reconfigure(mygrid.getDataSource(),cm);
       }
       </script>
    </head>

    <body>
    <!— Set up the Grid —>
    <cfform id=“CouponForm” name=“CouponForm”>

    <cfgrid name=“CouponsGrid”
    format=“html”
    pagesize=“10″
    striperows=“yes”
    selectmode=“edit”

    bind=“cfc:coupons.getCoupons({cfgridpage},{cfgridpagesize},{cfgridsortcolumn},{cfgridsortdirection})”
    onchange=“cfc:coupons.editCoupon({cfgridaction},{cfgridrow},{cfgridchanged})”>
    <cfgridcolumn name=“Couponid” display=“false” />

    <cfgridcolumn name=“SPONSORID” header=“Sponsor” width=“100″/>
    <cfgridcolumn name=“COUPON” header=“Coupon” width=“100″/>

    <cfgridcolumn name=“EXPIRATIONDATE” header=“Exp Date” width=“200″/>
    </cfgrid>
    </cfform>

    <!— use AjaxOnLoad to set the date renderer —>
    <cfset ajaxOnLoad(“setDateRenderer”)>
    </body>
    </html>

    </html>

    The secret sauce in this code is the following line:

    cm.setRenderer(3, Ext.util.Format.dateRenderer(’m/d/Y’));

    That’s the built-in Ext method that allows you to define your custom date renderer. Again, this is not something that’s actively promoted by Adobe, most likely since they’re trying to abstract the intricacies of the Ext framework via a cozy HTML-centric syntax. This, in my opinion, is not a bad thing as it eases new developers into client-side development while still allowing experienced developers to extend their apps via the framework’s actual API.

    November 29th, 2007

    NEW CSS JAVASCRIPT LIBRARY

    Marat Denenberg has continuing the way of CSS frameworks by attractive Mootools and creating CSS.js.

    The accumulation sits on crowning of CSS itself and gives you:

    • Programmatic CSS
    • Browser Compatibility
    • Custom CSS Properties

    With programmatic css, you crapper ingest loops to create CSS that strength hit condemned pages to identify out. You crapper hit CSS constants. You crapper do every sorts of science and calculations for a property. You crapper also add the call of elements on the fly, without using javascript on apiece element. I’m trusty there’s another modify clog you crapper do that I didn’t conceive of.

    Browser sympathy is variety of self-obvious. Before, you utilised to hit a call artefact for apiece application to earmark for their quirks and unearthly CSS implementation. Now you crapper create CSS that is application restricted using JS. The collection is shapely to earmark you to modify it for some application and some property. You crapper take a concept to be limited, in which housing it module exclusive create it for the application you specify.

    Ever desired to invet your possess CSS property? Now you can. See the examples for what I mean.

    There are a aggregation of enthusiastic examples, much as having IE grok opacity:

    JAVASCRIPT:

    1.  
    2. CSS.implement({
    3.     ‘trident_opacity’: function(value, property)
    4.     {
    5.         return [‘filter’, ‘alpha(opacity=’ + (value * 100) + ‘)’];
    6.     }
    7. });
    8.  

    or allowing you to ingest border-radius and hit it falsehood for the correct browser:

    JAVASCRIPT:

    1.  
    2. CSS.implement({
    3.     local:
    4.     {
    5.         limited: [‘border-radius’]
    6.     },
    7.  
    8.     ‘gecko_border-radius’: function(value, property)
    9.     {
    10.         return [‘-moz-’ + property, value];
    11.     },
    12.  
    13.     ‘webkit_border-radius’: function(value, property)
    14.     {
    15.         return [‘-webkit-’ + property, value];
    16.     }
    17. });
    18.  

    Download CSS.js

    November 29th, 2007

    NINTENDO RELAUNCHES WITH DOJO, MOOTOOLS, AND MORE

    Nintendo.com has relaunched, and a view source shows you that it now sports Dojo, Mootools, and much more script.

    As you hunt around for where you will see fun stuff in action you will find the game guide:

    Nintendo

    Take a peak and you see how they use inline templating.

    HTML:
    1.  
    2. <textarea id="box_template" name="box_template" style="display:none;">
    3. {for g in list}
    4.         {if g.renderOK == "yes"}
    5.     {if (g.system) == "Wii"}
    6.       <div class="gameHolder wii_back" id="_!{g.id}" onmouseout="clearTimeout(noa.command.games.calloutTimer);" onmouseover="noa.command.games.throttleCallout(this)" style="display:none;">
    7.                <a href="/games/detail/!{g.id}" onclick="try{mojo.Messaging.publish('/games/guide/gameChosen')}catch(e){}">
    8.               <img class="boxart_image_wii" id="_i_!{g.id}" onerror="this.src='/images/games/guide/wiibox.png';" src="!{g.small_box_art.url}" />
    9.            </a>
    10.                 <p class="boxText">
    11.               <a class="boxTitle" href="/games/detail/!{g.id}" onclick="try{mojo.Messaging.publish('/games/guide/gameChosen')}catch(e){}">!{g.short_title}</a>
    12.             </p>
    13.             <p class="boxText boxDate">!{g.release_date}</p>           
    14.       </div>
    15.     {/if}
    16.           {if (g.system) == "DS"}
    17.       <div class="gameHolder ds_back" id="_!{g.id}" onmouseover="noa.command.games.throttleCallout(this)" style="display:none;">
    18.                <a href="/games/detail/!{g.id}" onclick="try{mojo.Messaging.publish('/games/guide/gameChosen')}catch(e){}">
    19.                     <img class="boxart_image_ds" id="_i_!{g.id}" onerror="this.src='/images/games/guide/dsbox.png';" src="!{g.small_box_art.url}" />
    20.                </a>
    21.                     <p class="boxText">
    22.               <a class="boxTitle" href="/games/detail/!{g.id}" onclick="try{mojo.Messaging.publish('/games/guide/gameChosen')}catch(e){}">!{g.short_title}</a>
    23.             </p>
    24.             <p class="boxText boxDate">!{g.release_date}</p>           
    25.       </div>
    26.     {/if}   
    27.   {/if}
    28. {/for}
    29. </textarea>
    30.