jQuery Plugin: BetterGrow Your Words

jquerylogo256_thumb[1]

Many things grow, but none grow better than when they BetterGrow.  Used by products such as Facebook and Basecamp, textareas that can adapt to user input, growing or shrinking their height to the demands of the text entered, provide an oft-desired minimalistic user experience of progressive enhancement – providing just what is needed by the consumer when it is needed.

facebook

Despite the widespread appeal of dynamic height textareas, I have been unable to find one such code snippet or JavaScript plugin that would meet all my needs; the most important of which was responsiveness.  Every dynamic textarea plugin that I found had some shortcoming, from delayed reaction to required grow/shrink event, to annoying visual flickers and blinks.  BetterGrow was designed to have none of these quirks, and simply grow (and shrink) better, based on the specified options and text content.

I wanted a dynamic and customizable textarea that kept up with me, that

didn’t wait until I was done typing to resize,
was much more ‘elastic’ than other similar plugins,
never obscured the entered text,
adapted both quickly and smoothly to the user.

So, I wrote the BetterGrow jQuery plugin and open-sourced it under both GPL and MIT License so that I, and everyone else, could benefit from a textarea that didn’t just grow, but grew better when it had BetterGrow. ;-)

grow_and_shrink

Usage

BetterGrow is a customizable jQuery plugin for enabling the improved, dynamic expansion of a textarea.

<div>
	<textarea id="area51">
	</textarea>
</div>
$('#area51').BetterGrow({ / * OPTIONS * / });

When the text within the target textarea exceeds the initial textarea height the textarea increases its height sufficiently to accommodate the new text.

When the text within the target textarea decreases sufficiently to allow for a lesser height, and the height is greater than the minimum textarea height or initial textarea height, then the textarea height is reduced to the minimum height required to display the text within, while not obscuring the visibility or requiring a scrollbar to view any of the text

Important:  The textarea must reside within an encapsulating DIV.  And, to avoid problems in IE, you should explicitly set the textarea’s width.

Method

When initialized, the textarea object and its parent DIV have their attributes adjusted.  The method implementation supports chaining and returns the jQuery object.

The DIV should add no size to the textarea object or region.  DIV height is automatically set to AUTO.

The textarea’s overflow is set to HIDDEN and the WIDTH is set to the current WIDTH. (FYI:  WIDTH of textarea must be defined to work in IE)

If the DIV is missing, the plugin will attempt to wrap the textarea in a new DIV.  It is recommended that all targeted textareas are wrapped in a DIV before calling BetterGrow to avoid unexpected behavior.

If the textarea already has text within it when BetterGrow is initialized, the textarea’s height is automatically adjusted to fit the text (if a height greater than the initial height is needed to present the text unobscured).

Settings

By default, the textarea’s initial empty height, aka minimum height, is set to 26px, with no special event handling enabled.  These and many other characteristics are fully customizable, and fully itemized and explained below.

To change these settings, they can either be accessed directly…

$.fn.BetterGrow.settings.initial_height = 100px;

… or at the time of initialization…

$('#area52').BetterGrow({
	initial_height:	50px,
	on_enter:		function() {
        				submit_form();
				},
	do_not_enter:	false
});

The default settings data structure is…

$.fn.BetterGrow.settings = {
	initial_height:	26,                // specified in pixels
	on_enter:		null,         // callback function; if specified, this is called when enter is pressed
	do_not_enter:	true         // if true and on_enter is not null then enter event does not cascade / pass-through to textarea
};

The parameters are defined (and all can be overridden) thus…

initial_height

  • minimum height in pixels for the textarea
  • if the textarea is EMPTY, this is the initial height

on_enter

  • callback function that is called when ENTER is pressed within the target textarea(s)
  • by default, on_enter is DISABLED (set to NULL)

do_not_enter

  • if on_enter is ENABLED (pointing to a callback function) and
    • if do_not_enter is TRUE,  then the ENTER event DOES NOT CASCADE / pass-through to the text area
    • if do_not_enter is FALSE, then the ENTER event will trigger the calling of the function referenced by on_enter and be reflected within the textarea
  • In other words, if TRUE then the content of the textarea will not change as a direct result of the user pressing ENTER.

Get It

You can download BetterGrow, dual licensed under GPL and MIT, from…

Git
Public Clone URL: git://github.com/theproductguy/BetterGrow.git
GitHub: http://github.com/theproductguy/BetterGrow

Demo

http://theproductguy.com/bettergrow/bettergrow.demo.html

If you find this useful, or have any questions, ideas, or issues, leave a comment.

Enjoy!

Jeremy Horn
The Product Guy

About these ads

Modular Innovation 201

image What is Modular Innovation?

Modular Innovation can be briefly described as the products and platforms consisting of or facilitating…

  • Relationships (people-people, products-products, people-products)
  • Control of Experience (from creation to storage to interaction)
  • Ownership of Content (personal content from comments to friend lists and more)

You can also see the trend, itself, being referred to as “Modular Innovation,” much in the same way the term “Web 2.0” is still used today.

The products and concepts that constitute Modular Innovation are those that connect, enable, produce, enhance, extend, and make use of these relationships and, in turn, users’ online experiences with them.

Modular Innovation is increasingly everywhere these days…
Facebook Connect
@anywhere
Crowd sourcing
FourSquare
API’s
Expensify
Plugins
Chrome
Data exchanges
SugarSync
Google Maps
PBWorks

… and many more products, forms, and methodologies.

For the rest of the article, I will walk us through the path of the online product from a time before the prevailing trend of Modular Innovation to today, and set the scene for what is to come.

Web Problems 2.0

It’s hard today to find an online product that hasn’t in some way been touched by Modular Innovation. You might look to the old blogs as a pre-Modular Innovation, with their initial incarnation as log-oriented websites, and the most rudimentary relationship common between website and website visitor of the Web 1.0 and Web 2.0 eras.

Some products still holding fast to the ways of the Web 1.0 and 2.0 worlds…

Web 1/2.0 Products Missing Modular Innovation…
JD Supra
http://www.jdsupra.com/
a forward thinking legal 2.0 product leveraging the UGC of the legal community, but starkly lacking a public API allowing for the accelerated growth of the community by way of 3rd party apps for participating
Turbo Credit Solutions
http://turbocreditsolution.com/index.php
all the entered information is one way; there is no extracting of entered financial information or connecting to any of the services it purports to help with, nor any other desktop- or web-based financial tools
CommandShift3
http://commandshift3.com/
fun and wonderful experience, but lacks any sort of ties to the outside world beyond its basic screenshotting functionality; it could, for example, allow for the creation of accounts, remember expressed views and comments, allow users to save these comments, allow for a widget that can be inserted on websites of recently reviewed / rated items

Interestingly … A Flickr

The very popular product, Flickr, launched at the start of the Web 2.0 age has prospered, in no short order due to its understanding of the importance of interconnectivity and relationships, built into its early foundation. Flickr demonstrated a unique foresight into what would propel it onward through Web 2.0 and beyond, by embracing many of the, at the time yet defined, underpinnings of Modular Innovation.

Building Blocks

Building upon the pre-Modular Innovation archetype of blogs, discussed in the previous section, the Modular Innovations that are blogs today are now seen with clear characteristics of Modular Innovation like…

Allowing bloggers to download / export their content (and often upload it to other locations and competing blog platforms)

Connecting Twitter and Facebook in various manners

Permitting bloggers to drop-in custom plugins and even full commenting sub-systems

In Web 2.0, we had looks, feels, AJAX and communities. Through Modular Innovation, we have relationships, modular products and other services that facilitate the relational parts… all the components, and the Internet environment within which they, Modular Innovations, thrive.

A Modular Innovation can be small, a feature or mini-mini-product, or large, a module-connector service, a social network. Modular Innovations alone, and more so when combined, lead to users’ information that is increasingly…

Portable
Shareable
Interoperable
Customizable
Redundant / Replicated
Accessible

…and, basically, their own, the users’, to do with as they wish, to control via the Modular Innovation(s) within their personally controlled online user environment —a user experience both open and dynamic.

Modular Innovation puts the people in control – of their content and their interaction with it. The people can easily share their data, export it, import it, customize privacy, across different social networks, products and other environments. Their data becomes modular, flexible, and portable. Users’ experiences consist of many modules that make up their total user experience. Content and functionality, with greater Modular Innovation becomes further decentralized across these modules, each providing a single, small or large, set of abilities or experiences, that together break down the walls (silos) that are the proprietary platforms, and empower the people, the users of the Internet, to be in charge of their data and their experience.

As modules leverage open standards, people are increasingly able to publish their content to multiple destinations, manage their content across a variety of products. As Modular Innovations relationally increase so too decreases, as is being seen by way of …

OpenSocial,
Facebook Connect,
Twitter @Anywhere,

… the need to re-find friends, or re-re-re-publish one’s content, as well as port and integrate their personal, content creations with other services, other Modular Innovations. Modular Innovations are increasingly empowering the user through the enabling of greater flexibility and control of interaction with the user’s own data. Data that, through more and more Modular Innovation, is becoming …

increasingly portable,
increasingly integrated,
increasingly customizable.

Products that are or facilitate Modular Innovation are the ones that have proven themselves among the most persistent and continue to gain increasing acceptance in the current evolution of the social and interactive relationships of the Internet.

Looking Forward

There already exist many complex frameworks actively being developed and evolved that will definitely be major influences in shaping the course of Modular Innovation. These modules, or Modular Innovations, can represent a single or group of features and functionality, or a service or framework that augments or allows for new inter-module relationships to be established.

A Modular Innovation often described as a framework that “allows data to be shared and reused across application, enterprise, and community boundaries.aka Semantic Web

A Modular Innovation that represents an image oriented feature set that allows for the easy connectivity to and from other resources as well as the inclusion of the production functionality within and between other Internet products. aka Flickr

Through combining and connecting and customizing modules, an owner, a user, is in control to customize their full experience and interaction with their own content as well as that of others.

Through the connectivity and relationships of modules, users’ ownership of the content that flows through is also strengthened, as well as those relationships among the people with each other and the Modular Innovations with which each interacts.

As the tendrils of Modular Innovation deepen and spread, the user experience becomes progressively more defined by the modules and the relationships between the modules and the individuals using them, not the network or any single product (or feature).

Enjoy, Discuss & Tweet!

Jeremy Horn
The Product Guy

jQuery Plugin: CuteTime, C’est Magnifique! (v 1.1) [UPDATE]

jquery-logo-256I am very pleased to announce the latest major update to the CuteTime jQuery plugin.

CuteTime provides the ability to easily…

  • convert timestamps to ‘cuter’ language-styled forms (e.g. yesterday, 2 hours ago, last year, in the future!),
  • customize the time scales and output formatting, and
  • update automatically and/or manually the displayed CuteTime(s).
Un-Cute Cute
2010-1-27 23:14:17 a few days ago
Thu, October 29, 2004 12:14:19 PM 5 years ago

Since CuteTime was released last year, there continues to be a flood of excellent feedback from many of you consisting of suggestions, bug reports (less of these), and feature requests (more of these). Much of that feedback has coalesced into this latest major release.

imageAs you may already have been able to tell, this latest update was, in part, inspired by the French language. Perhaps one of the greatest drivers, to whom I am grateful, of a central new feature within this release has been Bruno Morency, through whose guidance and linguistic support I was able to design a more robust, universal CuteTime for all languages and grammatical styles.

In addition to the inclusion of French CuteTime translations within the translations.txt file, this release, version 1.1, features…

  • ISO8601 date timestamp compliance
  • insertions using the %CT% pattern of computed numbers within the CuteTime cuteness
  • support for all foreign language characters and HTML
  • Spanish CuteTime translations, courtesy of Alex Hernandez
  • richer demos and test
  • improved settings flexibility of the CuteTime function
  • documentation updates (corrections and clarifications)

French, et al

Originally, CuteTime was developed with a less than universal syntactic centricity. Basically, CuteTime originally could handle the cuteness of presenting…

“a few seconds ago”
“last month”

…as well as prepend values resulting in…

” hours ago” becoming “4 hours ago”
” seconds ago” becoming “18 seconds ago”.

Now, in addition to supporting the prepending of the computed CuteTime,

  • the calculation can be inserted within the cuteness string, and
  • both formatted HTML styling and proper character accenting applied,

…resulting in the additional support for…

“il y a %CT% minutes” becoming “il y a 4 minutes”
“l\’ann&eacute;e derni&egrave;re” becoming “l’année dernière”
“<span style=’color: red; font-weight: bold’>in the future<span>” becomingin the future

ISO8601

image Formatting of timestamps is the bane of many a developer. Especially onerous is the handling of “standard” time formatting by the front-end developer. The JavaScript Date Object() supports the IETF standard, defined in RFC 822 Section 5, at least in FireFox, with most backend systems providing and storing (or at least converting to) dates in ISO8601 form.

Now, when converting a normal time into a CuteTime it can be either formatted in a manner compatible with the JavaScript Date() Object …

Thu Oct 15 2009 22:11:19 GMT-0400 (Eastern Daylight Time)
Oct 15 2009 22:11:19

… or ISO8601 …

2009-11-24T19:20:30+01:00
2009-11
2009-11-24T13:15:30Z

Implementation

CuteTime is a customizable jQuery plugin that automatically converts timestamps to formats much cuter. It also has the ability to manually and/or automatically update timestamps on a controlled interval.

  • If used by Selector, it replaces the text of the provided object with a CuteTime.
  • If used as a function, it returns a string containing a CuteTime version of the provided timestamp.
$('.timestamp').cuteTime();
$('.timestamp').cuteTime({ /* OPTIONS * / });

cutetime_object = $('.timestamp').cuteTime();
cutetime_object.update_cuteness();

$.cuteTime('2009/10/12 22:11:19');
$.cuteTime({ /* OPTIONS * / }, '2009/10/12 22:11:19'); // [NEW!]

For more details about the latest CuteTime improvements and their implementation, visit http://tpgblog.com/CuteTime

If you find this useful, or have any questions, ideas, or issues, leave a comment.

Enjoy!

Jeremy Horn
The Product Guy

Add to Social Bookmarks: Stumbleupon Del.ico.us Furl Reddit Google Add to Mixx!

jQuery ThreeDots: yayQuery Plugin of the Week!

yayquery-plugin-of-the-week I’ve been a fan of yayQuery since shortly after their initial podcast episode. Therefore, you can imagine my surprise and elation when I heard them give a shout-out to my ThreeDots plugin … almost falling down the stairs as I listened this past Friday while entering the subway here in NYC.

image ThreeDots is a customizable jQuery plugin for the smart truncation of text. It shortens identified text to fit specified dimensions (number of rows within a container) and appends the desired ellipsis style if truncation occurs. An ellipsis style can be anything from ‘‘ to ‘more‘ to ‘<b><a href=”link”>click here</a></b>‘, and any other simple text or HTML you desire.

Also, I am pleased to announce the latest update to ThreeDots.

Changes in Version 1.0.7

  • [FIXED] edge condition concerning super long words

To yayQuery and everyone else who has supported the jQuery ThreeDots Plugin through your compliments, feature requests, and issue identification… Thank You.

Subscribe

If you want to be up on the latest in the world of jQuery (strong appreciation for unicorns, rainbows and sparkles are optional… but definitely helpful) I strongly recommend you check out yayQuery.

imageyayQuery Episode 8, 9 & 10 | Happy Birthday jQuery!

Video: OGV (170mb) | MP4 (186mb)
Audio: MP3 (40mb)

Subscribe to yayQuery today! (audio) (video)

Enjoy!

Jeremy Horn
The Product Guy

Add to Social Bookmarks: Stumbleupon Del.ico.us Furl Reddit Google Add to Mixx!

The Product Guy: Superfine in 09

Snowman&Bell The Product Guy had another superfine year in 2009, sharing and exploring products, their experiences, and many innovative startups and the founders behind them, while getting to meet and speak with many of The Product Guy’s steadily growing readership.

And, as 2009 comes to a close, as I did last year, let’s take a brief look at the top posts that made this year on The Product Guy so totally superfine….

 

#9 Quick-UX Credibility from Likexo to Etsy

Quick-UX Credibility is a measure of the starting point, the foundation of a product’s Credibility. A look at the popular (and not so popular) examples of web product Credibility online.

image

#8 World’s Best Programmer is… [w/ Respect]

The World’s Best Programmer wants respect.

And, respect is just one of those conditions prevalent within the environment of the World’s Best Programmer. In this last post in the series The Product Guy reveals just who exactly is World’s Best Programmer, and where/how they thrive!!

image

#7 Converted by an Android. A short story of Gmail, in parts.

Part 1 in a series exploring the eventual adoption of Gmail in one’s daily life, by one once thoroughly addicted to, dependent on, the primarily client-based solution of Microsoft’s Outlook, what brought about this conversion, why it took so long, and what should be done to encourage greater Gmail adoption.

image 

#6 jQuery Plugin: It’s CuteTime!

Many online social products, and more continue to, avoid a formal timestamp format… 2009-10-10 23:14:17 and Thu, October 29, 2004 12:14:19 PM … opting for more user friendly, "warm and fuzzy," human-readable styles… 9 days ago and 5 years ago.

As a result, the time has come for the jQuery CuteTime plugin. CuteTime goes beyond similar tools and lets you easily: convert timestamps to ‘cuter’ language-styled forms (e.g. yesterday, 2 hours ago, last year, in the future!), customize the time scales and output formatting, and dynamically update the displayed CuteTime(s) upon request and/or automatically.

image 

#5 The Future: Gmail, Social Media, and You

Over the past many weeks I have explored, elaborated, and exhausted the extent of the then existent exercising of resistance. Now, with such resistance eroded, drawn out through my conversion by an Android, an exploration into the Future of Gmail and the ‘Should Do’ … Readability, Simplify, Organize, Integration and Consistency.

image 

 

#4 Google: True Colors Shine Through

In answering the question of Desirability, "Do I want it?" the sub-category of Color Scheme plays an important role. Google Search is an outstanding example of a Good Color Scheme demonstrating alignment of both colors and messaging. Learn from it.

image

#3 Stardoll: Lost and Naked

When you look at a web page, the various elements of the page can often be seen coalescing into distinguishable regions and groups. Intentionally structured, or otherwise, these groups that constitute the page Layout play an important role in the web product’s Desirability. Stardoll is a great example of a web product with Poor Sequential Flow.

image 

#2 ThreeDots: The jQuery Ellipsis Plugin

Many online products employ ellipses within their products to improve various aspects of the User Experience, such as: allowing for easy summary scanning of page content, and fitting more diversity of content into a smaller space.

As a result, the time has come for the jQuery ThreeDots plugin. ThreeDots goes beyond similar tools and lets you easily and smartly truncate text for when: text is too long, text doesn’t fit within the available space, you want to employ highly configurable and flexible ellipses within your web product.

image 

#1 Quick-UX. Quick Heuristics for User eXperience.

Quick-UX provides for the rapid, simple and quantifiable assessment of a product’s User Experience (UX), consisting of the core components of Usability (‘Can I use it?’), Usefulness (‘Should I use it?’), and Desirability (‘Do I want to use it?’). 

Quick-UX provides a sure-fire, rapid way to obtain concrete and comparable means by which to assess a single product or compare its strengths and weaknesses to other products.

Growing in popularity by leaps and bounds since its original posting in 2008, this posting has earned prime placement amongst other, more recent, articles that made this year, 2009, SUPERFINE.

image

 

theproductgroup_logo_200909_thumb75
balsamiq_logo2_thumb26

This year also saw the launch of The Product Group (sponsored by Balsamiq Studios) in NYC as an opportunity for Product People of all sorts and levels of experience to meet, interact, and network, in a laid-back, conversational environment.  I am certain 2010 will bring many more exciting gatherings, discoveries, and opportunities; and for those reasons, this too, also helped make 2009 for both Product People and The Product Guy, superfine!

Group_Pic_1_20091001 DSC05663 DSC05662 DSC05661

Happy Holidays!

Jeremy Horn
The Product Guy

Add to Social Bookmarks: Stumbleupon Del.ico.us Furl Reddit Google Add to Mixx!

ThreeDots: The jQuery Ellipsis Plugin

jquery-logo-256Sometimes the text …

… is too long …
… won’t fit within the number of rows you have available.

Sometimes all you need is … ThreeDots! (a jQuery plugin)

For example —

This: When restricted to 2 lines by ThreeDots, can become:
There was once a brown fox
that liked to eat chocolate
pudding.
There was once a brown fox
that liked to eat …
There was once a brown fox
that liked to eat chocolate
pudding.
There was once a brown fox
that liked to (click for more)

… and most any other permutation you desire.

To Ellipsize

There are many scenarios in the display of online text where shortened, truncated representations are best used. For these scenarios, many products opt for the implementation of ellipses.

el·lip·sis (ĭ-lĭpsĭs)

n., pl., -ses (-sēz).

  1. The omission of a word or phrase necessary for a complete syntactical construction but not necessary for understanding.
  2. An example of such omission.
    • A mark or series of marks ( . . . or * * * , for example) used in writing or printing to indicate an omission, especially of letters or words.

[Latin ellīpsis, from Greek elleipsis, from elleipein, to fall short. See ellipse.]
from <http://www.answers.com/topic/ellipsis>

Many online products employ ellipses within their products to improve various aspects of the User Experience, such as:

allowing for easy summary scanning of page content, and
fitting more diversity of content into a smaller space.

Most often people truncate the text by character count, on both the client- and server-sides, which does not take into account the variable dimensions of the text being truncated. There are also a few CSS hacks out there, albeit with future standardized support currently being called into question, and custom, per-browser efforts required for successful implementation.

I too, on so many projects, have encountered the challenge of wanting to limit text to only a few lines or make sure that, no matter what, the text always fits within the space provided. People, myself included, on similar product feature missions have been forced to make compromises of design and experience, without the existence of a simple script/tool to carry out the task, to accommodate the time constraints and complexity of coding the ideal solution.

So, finally, I sat down, put the time in, and created the ThreeDots jQuery plugin for…

… when text is too long…
… when text doesn’t fit within the available space …
… when you want to employ highly configurable and flexible ellipses within your web product…

… so that never again, would I, or anyone else have to compromise their vision where that vision bumps up against the need for the smart implementation of ellipses in your web product.

Usage

ThreeDots is a customizable jQuery plugin for the smart truncation of text. It shortens identified text to fit specified dimensions and appends the desired ellipsis style if/when truncation occurs.

Sample 1:

<div class='text_here'>
	<span class='ellipsis_text'>
		TEXT
	</span>
</div>
$('.text_here').ThreeDots();  // USE DEFAULTS
$('.text_here2').ThreeDots({ max_rows:3 });

Sample 2:

<div class='text_here'>
	<span class='ellipsis_text'>
		TEXT
	</span>
</div>
threedots_object = $('.text_here').ThreeDots();
threedots_object.update();

Sample 3:

<div class='text here'>
	<span class='something'>
		TEXT
	</span>
</div>
threedots_object2 = $('.text_here').ThreeDots( {text_span_class: 'something'} );
threedots_object2.update( {text_span_class: 'something'} );

As a Method

When initialized, the ThreeDots plugin creates and assigns the full set of identified text to each container element, class=’text_here’, as a publicly accessible attribute, ‘threedots’. The method implementation supports chaining and returns the jQuery object.

<div class='text_here' threedots='original text'>
	<span class='ellipsis_text>
		original text
	</span>
</div>

Note, to implement the text that you wish to ellipsize, it must be wrapped in a span assigned either the default class ‘ellipsis_text’ or other custom class of your preference — customizable via the options/settings.

If the text becomes truncated to fit within the constrained space as defined by the container element that holds the ‘ellipsis_text’ span, then an additional span is appended within the container object, and after the ‘ellipsis_text’ span.

<div class='text_here' threedots='original text'>
	<span class='ellipsis_text>
		original text
	</span>
	<span class'threedots_ellipsis'>
		...
	</span>
</div>

The span class of ‘threedots_ellipsis’ can also be customized via the options/settings and have it’s own CSS/jQuery styles/actions/etc. applied to it as desired. Put another way, the ellipsis is NOT constrained to ‘…’, but can be any text or HTML you desire.

If any of the specified settings are invalid or the ‘ellipsis_text’ span is missing, ThreeDots will abort its processing and the initial text will be left untouched.

IMPORTANT: The horizontal constraints placed upon each row are controlled by the container object. The container object is the object specified in the primary selector.

$('container_object').ThreeDots();

When using ThreeDots, the following additional methods can be used…

ThreeDots.update()

Refreshes the text within the target object inline with the options provided. Note that the current implementation of options/settings are destructive. This means that whenever settings are specified, they are merged with the DEFAULT settings and applied to the current object(s), and destroy/override any previously specified options/settings.

var obj = $('.text_here').ThreeDots();	// uses DEFAULT: max_rows = 2
obj.update({max_rows:3});				// update the text with max_rows = 3

Settings

By default, the three dots ellipsis (““) is used, as shown in the prior examples, and limits text to a maximum of 2 lines. These and many other characteristics are fully customizable, and fully itemized and explained below.

To change these settings, they can either be accessed directly…

$.fn.ThreeDots.settings.max_rows = 4;

… or at the time of initialization or update …

// configuring the initial settings to use
var obj3 = $('.text_here').ThreeDots({ max_rows: 4 });

// changing the applied settings via an update call to the same text region(s)
obj3.ThreeDots.update({ max_rows: 2 });

The default settings data structure is…

$.fn.ThreeDots.settings = {
	valid_delimiters:         [' ', ',', '.'],			// what defines the bounds of a word to you?
	ellipsis_string:         '...',
	max_rows:                        2,
	text_span_class:        'ellipsis_text',
	e_span_class:                'threedots_ellipsis',
	whole_word:                        true,
	allow_dangle:                false,
	alt_text_e:                 false,					// if true, mouse over of ellipsis displays the full text
	alt_text_t:                 false					// if true & if ellipsis displayed, mouse over of text displays the full text
};

The parameters are defined (and all can be overridden) thus…

valid_delimiters

  • a character array of special characters upon which the text string may be broken up
  • defines what characters can be used to express the bounds of a word
  • all elements in this array must be 1 character in length
  • any delimiter less than or greater than 1 character will be ignored
  • if valid_delimiters contains no valid content, then nothing will be processed

ellipsis_string

  • defines what to display at the tail end of the text provided if the text becomes truncated to fit within the space defined by the container object
  • ellipsis_string can be text or HTML (e.g. ‘<a href=’url’>click for more</a>’)

max_rows

  • specifies the upper limit for the number of rows that the object’s text can use
  • if the displayed text is determined to use less than max_rows, then no operations will be performed upon the provided text and no ellipsis displayed
  • max_rows must be greater than 0 (ZERO)

text_span_class

  • by default ThreeDots will look within the specified object(s) for a span of the class ‘ellipsis_text’
  • if the class specified by text_span_class is not found within the selected objects, then no actions will be taken against the incompletely defined objects
  • if a different class name is desired for stylistic or programmatic reasons, a new, valid string can be specified

e_span_class

  • if an ellipsis_string is displayed at the tail end of the selected object’s text due to truncation of that text, then it will be displayed wrapped within a span associated with the class defined by e_span_class and immediately following the text_span_class‘ span
  • just like text_span_class, a different, valid class name can be specified

whole_word

  • when ThreeDots is fitting the provided text to the max_rows within the container object, this boolean setting defines whether or not the last word can be truncated to maximize the fit of the text within max_rows
  • if true, then don’t truncate any words and the ellipsis can ONLY be placed after the last whole word that fits within the provided space

e.g.

one time a duck flew
a frog shaped kite

…could become…

one time a duck flew
a (click for more)

  • if false, then maximize the text within the provided space, allowing the PARTIAL display of words before the ellipsis

e.g.

(continuing from the prior example)

one time a duck flew
a fr (click for more)

allow_dangle

  • a dangling ellipsis is an ellipsis that typically occurs due to words that are longer than a single row of text, resulting, upon text truncation, in the ellipsis being displayed on a row all by itself

e.g.

one time a duck flew floopydoopydoppydoodoodoodoo

… could become with allow_dangle:true …

one time a duck flew

  • if allow_dangle is set to false, whole_words is overridden ONLY in the circumstances where a dangling ellipsis occurs and the displayed text is adjusted to minimize the occurrence of such dangling of the ellipsis

e.g.

(continuing from the prior example)

one time a duck flew
floopydoopydoppyd…

alt_text_e

  • alt_text_e is a shortcut to enabling the user of the product that made use of ThreeDots to see the full text, prior to truncation, on mouse-over of the ellipsis
  • if the value is set to true, then the ellipsis span’s title property is set to the full, original text (pre-truncation) allowing the text to be seen by mousing over the ellipsis, if present
  • if the value is set to false, then the title value is left unaffected
  • this feature can be used in place of, or in conjunction with, additional styles or desired behaviors associated with mouse interactions of the selected object(s)
  • alt_text_e usage is not required to define your own custom interactions

alt_text_t

  • alt_text_t is a shortcut to enabling the user of the product that made use of ThreeDots to see the full text, prior to truncation, on mouse-over of the ellipsized text
  • if the value is set to true AND the ellipsis is displayed, then the text span’s title property is set to the full, original text (pre-truncation) and the text can be seen by mousing over the truncated text, if the ellipsis is present
  • if the value is set to false, then the title value is left unaffected
  • this feature can be used in place of, or in conjunction with, additional styles or desired behaviors associated with mouse interactions of the selected object(s)
  • alt_text_t usage is not required to define your own custom interactions

Get It

You can download ThreeDots, dual licensed under GPL and MIT, from…

jQuery Repository
http://plugins.jquery.com/project/ThreeDots

Git
Public Clone URL: git://github.com/theproductguy/ThreeDots.git
GitHub: http://github.com/theproductguy/ThreeDots

Zip
http://plugins.jquery.com/files/jQuery.ThreeDots_source-bundle_1.0.3_20091030.zip

Demo

http://theproductguy.com/threedots/threedots.demo.html

Status updates can be found here, jQuery ThreeDots.
If you find this useful, or have any questions, ideas, or issues, leave a comment.

Enjoy!

Jeremy Horn
The Product Guy

Add to Social Bookmarks: Stumbleupon Del.ico.us Furl Reddit Google Add to Mixx!

jQuery Plugin: It’s CuteTime! (v 1.0.5) [UPDATE]

jquery-logo-256I am happy to announce the latest version of the CuteTime jQuery plugin.02_facebook-cutetime

CuteTime provides the ability to easily…

  • convert timestamps to ‘cuter’ language-styled forms (e.g. yesterday, 2 hours ago, last year, in the future!),
  • customize the time scales and output formatting, and
  • dynamically update the displayed CuteTime(s) upon request and/or automatically.

There was some excellent feedback from many of you following the initial release of CuteTime. And much of that feedback has been incorporated into this release.

Changes to Version 1.0.5…

  • updated the ‘cutetime’ attribute to use HTML 5 compliant ‘data-timestamp’ custom attribute
  • updates to settings are now non-constructive
  • added translations.txt to the bundle to store all contributed translations of the cuteness translations (special thanks to Vincent Rolfs for providing the first translation, German)
  • minified version now compiled using YUI Compressor

CuteTime is a customizable jQuery plugin that automatically converts timestamps to formats much cuter. Also has the ability to dynamically re-update and/or automatically update timestamps on a controlled interval.

If used by Selector, replaces the text of the provided object with a cuteTime.

If used as a function, returns a string containing a cuteTime version of the provided timestamp.

Implementation

$('.timestamp').cuteTime();
$('.timestamp').cuteTime({ /* OPTIONS * / });

cutetime_object = $('.timestamp').cuteTime();
cutetime_object.update_cuteness();

$.cuteTime('2009/10/12 22:11:19');

For more details about CuteTime and its implementation, visit http://tpgblog.com/CuteTime

Enjoy!

Jeremy Horn
The Product Guy

Add to Social Bookmarks: Stumbleupon Del.ico.us Furl Reddit Google Add to Mixx!

jQuery Plugin: It’s CuteTime!

jquery-logo-256 02_facebook-cutetime Many online social products, and more continue to, avoid a formal timestamp format…

2009-10-10 23:14:17 and Thu, October 29, 2004 12:14:19 PM

… opting for more user friendly, “warm and fuzzy,” human-readable styles…

9 days ago and 5 years ago.

As a result, and also in my quest to always help provide my clients free, cheap and easy to use tools, I have been on the lookout for a jQuery plugin that would provide the ability to easily…01_digg-cutetime

  • convert timestamps to ‘cuter’ language-styled forms (e.g. yesterday, 2 hours ago, last year, in the future!),
  • customize the time scales and output formatting, and
  • dynamically update the displayed CuteTime(s) upon request and/or automatically.

While there are other similar tools out there in JavaScript, PHP, and, I am sure, many other languages, none adequately met my goals. Therefore, I created the jQuery CuteTime plugin.

Usage

CuteTime is a customizable jQuery plugin (jQuery.cuteTime) that automatically converts timestamps to formats much cuter. Also, it has the ability to dynamically re-update and/or automatically update timestamps on a controlled interval.

As a Function

If used as a function, a string containing a cuteTime version of the provided timestamp is returned.

$(document).ready(function () {
	// timestamp MUST be a valid Date().parse 'able' format
	$.cuteTime('2009/10/12 22:11:19');
});
<html>
	<body>
		<div class='predetermined'></div>
	</body>
</html>


As a Method

If used via Selector, CuteTime replaces the text of the provided object with a cuteTime.

$(document).ready(function () {
	$('.timestamp').cuteTime();
});
<html>
	<body>
		<div class="timestamp">
			2009/10/12 22:11:19
		</div>
		<div class="timestamp">
			2008/11/01 07:11:00
		</div>
		<div class="timestamp">
			2018/11/01 07:11:00
		</div>
		<div class="timestamp"></div>
		<div class="timestamp" cutetime="1980/10/12 22:11:19">
			2009/10/12 22:11:19
		</div>
		<div class="timestamp" cutetime="asd">
			10/12/2009 22:11:19
		</div>
		<div class="timestamp" cutetime="asd">
			aoisd
		</div>
		<div class="timestamp" cutetime="asd"></div>
	</body>
</html>

When initialized, the cuteTime() call either updates or assigns the ‘cutetime’ attribute to the provided objects. Method implementation supports chaining, returning the jQuery object.

e.g. <div class=’timestamp’ cutetime=’2009 10 12 22:11:19′>2009 10 12 22:11:19</div>

If the cutetime attribute already exists within the provided object, then the text within the object is ignored in the cutification process. If the cutetime attribute does not exist or an invalid one is provided, then a valid cutetime attribute is assigned to the object.

If the cutetime attribute is missing, then it is calculated from the text of the provided object.

If neither cutetime attribute nor valid object text exist, then the timestamp is assumed to be ‘now’.

When using CuteTime in the form…

<br />
$(document).ready(function () {
	remember_the_cuteness = $('.timestamp').cuteTime();
});

… the following methods can be used …

// stops all automatic updates of refresh-enabled timestamps
remember_the_cuteness.stop_cuteness();

// (re)starts the automatic updating of timestamps
// REMINDER: make sure refresh is set to > 0
remember_the_cuteness.start_cuteness();

// updates timestamps of the provided objects
remember_the_cuteness.update_cuteness();

Settings

By default, automatic updating is disabled and the following CuteTimes can be displayed…

the future!
just now
a few seconds ago
a minute ago
x minutes ago
an hour ago
x hours ago
yesterday
x days ago
last month
x months ago
last year
x years ago

To change these settings, they can either be accessed directly…

$.fn.cuteTime.settings.refresh = 10000;

… or at the time of initialization …

my_cutetime = $('.timestamp_move').cuteTime({ refresh: 60000*10 });

The default settings data structure is…

$.fn.cuteTime.settings = {
	refresh: -1,			// time in milliseconds before next refresh of page data; -1 == no refresh
	time_ranges: [
		{bound: NEG_INF,	// IMPORANT: bounds MUST be in ascending order, from negative infinity to positive infinity
			cuteness: 'the future!',			unit_size: 0},
		{bound: 0,
			cuteness: 'just now',				unit_size: 0},
		{bound: 20 * 1000,
			cuteness: 'a few seconds ago',		unit_size: 0},
		{bound: 60 * 1000,
			cuteness: 'a minute ago',			unit_size: 0},
		{bound: 60 * 1000 * 2,
			cuteness: ' minutes ago',			unit_size: 60 * 1000},
		{bound: 60 * 1000 * 60,
			cuteness: 'an hour ago',			unit_size: 0},
		{bound: 60 * 1000 * 60 * 2,
			cuteness: ' hours ago',				unit_size: 60 * 1000 * 60},
		{bound: 60 * 1000 * 60 * 24,
			cuteness: 'yesterday',				unit_size: 0},
		{bound: 60 * 1000 * 60 * 24 * 2,
			cuteness: ' days ago',				unit_size: 60 * 1000 * 60 * 24},
		{bound: 60 * 1000 * 60 * 24 * 30,
			cuteness: 'last month',				unit_size: 0},
		{bound: 60 * 1000 * 60 * 24 * 30 * 2,
			cuteness: ' months ago',			unit_size: 60 * 1000 * 60 * 24 * 30},
		{bound: 60 * 1000 * 60 * 24 * 30 * 12,
			cuteness: 'last year',				unit_size: 0},
		{bound: 60 * 1000 * 60 * 24 * 30 * 12 * 2,
			cuteness: ' years ago',				unit_size: 60 * 1000 * 60 * 24 * 30 * 12},
		{bound: POS_INF,
			cuteness: 'a blinkle ago',			unit_size: 0}
	]
};

The parameters are defined (and all can be overridden) thus…

  • refresh
    • time in milliseconds before next refresh of page data;
    • a value of -1 disables refreshing
  • time_ranges
    • the array of bound_structures that delineate the cute descriptions associated with time_ranges
    • time_range’s boundary structures consist of the following variables…
  • time_range[x].bound
    • the value is an integer representing the time difference between the provided timestamp and now
    • the lower inclusive bound, or starting point, for using the ‘cuteness’ string that describes the current timestamp
    • the exclusive upper bound is defined by the next boundary structure definition in the time_ranges array [current boundary + 1]
  • time_range[x].cuteness
    • string to use in place of the current timestamp (e.g. ‘yesterday’)
  • time_range[x].unit_size
    • the integer divisor in milliseconds to apply to the calculated time difference
    • if unit_size > 0 then a number value is prepended to the cuteness string as calculated by time_difference / unit_size (e.g. 4 hours ago)
    • if unit_size = 0, then no number is prepended to the cuteness string (e.g. an hour ago)

BTW

Make sure you use timestamps that are fully recognized by the JavaScript Date object’s Parse method in all the IE and FF browser versions you want to support. Otherwise, prepare for a headache. ;-)

Get It

You can download CuteTime, dual licensed under GPL and MIT, from…

jQuery Repository
http://plugins.jquery.com/project/CuteTime

Git
Public Clone URL: git://github.com/theproductguy/CuteTime.git
GitHub: http://github.com/theproductguy/CuteTime

Zip
jQuery.cuteTime_source-bundle_1.0_20091019.zip

Demo

http://theproductguy.com/cutetime/cutetime.demo.html

Status updates can be found here, jQuery CuteTime.
If you find this useful, or have any questions, ideas, or issues, leave a comment.

Enjoy!

Jeremy Horn
The Product Guy

Add to Social Bookmarks: Stumbleupon Del.ico.us Furl Reddit Google Add to Mixx!