Friday, May 9, 2014

How to set the cursor caret at the end of an input text field

As trivial as it sounds, ensuring that the cursor goes to the end of the text in an input field (particularly on an iOS device) is kind of tricky.

I tried dozens of ways involving .select(), .setSelectionRange(0,999), etc, etc. but what works is to simply remove the value from the input box and replace it in a few milliseconds.

So something like this:

  /////////////////////////////////////////////////////////////////////////////////////////
  // moveCaretToEndOfInputField - ensures that the cursor (caret) is at the end of the
  // ======================   text input field.
  /////////////////////////////////////////////////////////////////////////////////////////
  function moveCaretToEndOfInputField(oInputBox) {
    var tempValue = oInputBox.value;
    oInputBox.value = "";
    setTimeout(function() {
      oInputBox.value = tempValue;
    },1);

  }


moveCaretToEndOfInputField(this)">


Wednesday, July 4, 2012

animateObjectFromTo

This method will animate an object from a given left, top to another left, top over a specified number of milliseconds at a specified frame rate. This is an example of how it might be called:
  var myDiv = document.getElementById('myDiv),
      currentPosition = window.getComputedStyle(myDiv,null),
      currentLeft     = parseFloat(currentPosition["left"]),
      currentTop      = parseFloat(currentPosition["top"]);
  animateObjectFromTo( 
    myDiv, 
    { top:currentTop, left:currentLeft }, 
    { top:0, left:currentLeft }, 
    250 
  );
    /////////////////////////////////////////////////////////////////////////////////////////
// animateObjectFromTo([object|string] oHTMLElement, json From, json To, int totalTimeInMilliseconds, OPTIONAL int framesPerSecond)
    //   Sets up an animation that interpolates frame animation from a beginning top, left coordinate
    //   to an ending top, left coordinate over a number of milliseconds at a specified frame rate
    //      totalTimeInMilliseconds - default is 1 second
    //      framesPerSecond - default is 30
    /////////////////////////////////////////////////////////////////////////////////////////
    animateObjectFromTo : function(oHTMLElement, from, to, totalTimeInMilliseconds, framesPerSecond) {
      if (typeof(oHTMLElement)=="string")  {  oHTMLElement = document.getElementById(oHTMLElement); }
      totalTimeInMilliseconds = totalTimeInMilliseconds || 1000;
      framesPerSecond = framesPerSecond || 30;
      var currentFrame      = 0,
          numberOfFrames    = parseInt(totalTimeInMilliseconds / framesPerSecond),
          deltaTimePerFrame = totalTimeInMilliseconds/numberOfFrames,
          deltaXPerFrame    = (to.left - from.left)/numberOfFrames || 0,
          deltaYPerFrame    = (to.top - from.top)/numberOfFrames || 0;
      
      animate();

      function animate() {
        if (currentFrame<numberOfFrames) {
          var oCurrentStyle = document.defaultView.getComputedStyle(oHTMLElement, null);
          oHTMLElement.style.left = parseFloat(oCurrentStyle["left"]) + deltaXPerFrame + "px";
          oHTMLElement.style.top  = parseFloat(oCurrentStyle["top"]) + deltaYPerFrame + "px";
          currentFrame += 1;
          console.log('top is now: ' + parseFloat(oCurrentStyle["top"]) + deltaYPerFrame + "px")
          setTimeout( function() { animate(); }, deltaTimePerFrame );
        }
      }

Friday, June 22, 2012

Javascript String Length

Javascript does not provide way to get at the pixel width of a string. There is, of course, the getComputedStyle method, but I wanted another way. This method uses <CANVAS>'s measureText method and accounts for current fontFamily and fontSize:
////////////////////////////////////////////////////////////////////////////////
//
// String.width(OPTIONAL string fontSize, OPTIONAL string fontFamily)
// ==================================================================
// Measures the length of a string, in pixels, using CANVAS's measureText method
// By passing in fontSize and FontFamily, you will get accurate measurements
// eg: x.width('22px','HelveticaNeueLTStdTh')
////////////////////////////////////////////////////////////////////////////////
String.prototype.width = function(fontSize, fontFamily) {
  var ctx = document.createElement('canvas').getContext('2d'),
      retVal = 0,
      theString = this.toString();
  fontSize    = (typeof fontSize==="undefined") ? "12pt" : fontSize;
  fontFamily  = (typeof fontFamily==="undefined") ? "Arial" : fontFamily;
  ctx.font = fontSize + " " + fontFamily;
  return (ctx.measureText(theString).width);
}
Shannon Norrell

Thursday, August 18, 2011

Javascript Reliable Detect Internet Connection

I was told that the new HTML5 "navigator.isOnline" property is somewhat buggy.
Here is an alternative I wrote that seems to work flawlessly.


<script type="text/javascript">
var bIsOnline = false;
(function() {
var anImage = document.createElement("img");
anImage.onerror = function() { bIsOnline=false; }
anImage.onload = function() { bIsOnline=true; }
anImage.src="http://www.quirksmode.org/pix/logo_quirksmode.gif?" + (Math.random()*100000 << 0); })(); function test() { alert("You " + ((bIsOnline) ? "ARE" : "ARE NOT") + " online") } </script> <body onload="test();"></body>


Shannon Norrell

Thursday, March 3, 2011

CSS3 Tooltip Trick using CSS3 :before psuedo element, content attribute and custom data attributes

I was looking for a way to make an HTMLElement's title appear faster in a WebKit application.

Turns out there is a way to capture the "title" attribute of an element using the :before pseudo element and content property, store that value in a div that only appears onhover over the original element. The problem with this technique was that the actual "title" attribute would eventually display.


Therefore, I made use of another CSS3 feature called "custom data attributes" and, rather than storing the title of the element in the "title" attribute, I used "data-title" instead.

Here is a quick example:
<!DOCTYPE html>
<head>
  <style type="text/css">
    .sprocket { position:relative;width:50px;height:50px;background-color:red; }
    .sprocket:before { content:attr(data-title); display:none; }
    .sprocket:hover::before{ width:160px; display:block; border-radius:3px; background-color:#fffdc7; padding:5px; color:black; margin-top:40px; margin-left:20px; -webkit-box-shadow: 3px 3px 3px rgba(193,193,193,.5);}
    .sprocket:hover{ z-index:10; position:absolute; }
  </style>
</head>
<body>
  <div class="sprocket" data-title="Fancy Title Text">
</body>
</html>
Click here for an Example

Shannon Norrell

Saturday, January 1, 2011

Array.remove method (also Array,indexOf

I kept finding myself needing to remove items from an array, so developed a quick helper (prototype) method attached to the Array Object to help.


////////////////////////////////////////////////////////////////////////////////
//
// Array.remove( object|string item) - removes an item from an array
// Example x = ["abc","xyz",1,4] x.remove("xyz") returns ["abc",1,4]
//
////////////////////////////////////////////////////////////////////////////////
if (Array.prototype.remove===undefined) { // Presumably this will eventually be added to Javascript
Array.prototype.remove = function( item ) {
var itemLocation = this.indexOf(item);
if (itemLocation > -1) {
this.splice(itemLocation,1);
}
}
}
////////////////////////////////////////////////////////////////////////////////
//
// Array.indexOf() - returns integer index where valueToSearchFor is in an Array
// (believe it or not, not all browsers have this yet ... and it's 2010!
////////////////////////////////////////////////////////////////////////////////
if (Array.prototype.indexOf===undefined) {
Array.prototype.indexOf = function( valueToSearchFor ) {
var iEnd = this.length;
var retVal = -1;
for (var i=0;i<iEnd; i++) {
if (this[i] == valueToSearchFor) {
retVal = i;
break;
}
}
return retVal;
};
}


Shannon Norrell

Wednesday, October 6, 2010

Javascript Array Detection

Turns out the most reliable way to detect an Array is not to use the old return (typeof foo === 'object' && foo.constructor === Array) but rather to do this:


function isArray(anArray) {
return Object.prototype.toString.apply(anArray) === "[object Array]";
}