The Best jQuery Value Replacement Plugin - Textareas, Textboxes, Password fields….

Posted in Uncategorized on February 25th, 2010 by Pete – 1 Comment

I have searched around quite a bit did not find any “value replacement” scripts that fit my needs, mainly because of the password input functionality that I desperately needed.

View Demonstration

Download

What To Accomplish:

  1. The value that should be replaced should be the field’s value, makes sense…
  2. Password Fields should be displayed has normal text until the user starts typing.
  3. If the form is submitted (non-AJAX meaning the page refreshes), and returns because of errors, the password fields should NOT display their password as normal text for obvious security reasons. Also, the new user submitted text should not be treated like the “ghost text” or default text that was originally in the form. So essentially we need the fields to be the same as when we went to submit the form in the first place.
  4. Textarea elements should work just like text boxes.
  5. The form should be still perfectly usable and understandable if the user has JavaScript disabled.
  6. Last but not least, the script needs to be cross-browser and unobtrusive.

Requirements:

  1. jQuery 1.4 or above
  2. jquery.inputHelper.js

How To Use:

Markup:
The “title” attribute should be the same as you’re default value. This will ensure that if your default value is no longer there, the value won’t be treated like replacement text when a form is returned for errors during validation.

<input class="do_help someStyle" id="someId" name="someName" type="password" title="Password" value="Password" />

Include:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.inputHelper-v2.js"></script>

Call :

$(document).ready(function() {
    $('.do_help').inputHelper(); //.do_help could be any class or selector you want of course.
});

Extend :
focusedClass - The class applied when the box is active. Default: unfocused
unfocusedClass - The class applied when the box is inactive. Default: focused

$(document).ready(function() {
    $('.do_help').inputHelper({
    	focusedClass: 'focusedClassName',       //class applied when user selects an input box
    	unfocusedClass: 'unfocusedClassName'   //class applied when user clicks out from input box
    });
});

Codeigniter & jQuery Ajax Pagination

Posted in Tutorials on October 22nd, 2009 by Pete – 1 Comment

pager

The Codeigniter framework makes it incredibly simple to paginate query results. With a little bit of jQuery we can easily create a fully dynamic ajax pager with history enabled (the ability to use the back button).

Here is the finished product.

Functionality:
1. The ability to have history stored in a hash so users can use their browser’s back button.
2. Pagination will still function if Javascript is disabled.
3. The javascript needs to be cross browser.

Required:
Codeigniter 1.7.2 (most recent at the time)
jQuery 1.3.2 (most recent at the time)
jquery.history.js which can be found here.

First we need to make sure our framework is configured correctly and connected to our database. Assuming all is well inside the config directory we can begin to setup the model.

<?php
/* -------------------------- */
/* models > pager_model.php */
/* -------------------------- */

class Pager_model extends Model {

	function get_posts($limit, $offset)
	{
		$query = $this->db->get('posts', $limit, $offset);

		if ($query->num_rows()>0)//if result
		{
			return $query;
		}
		else
		{
			return false;
		}
	}
}

The above script simply makes our query to the database returning the results based on the 2 parameters; $limit and $offset. This will allow the controller to specify which rows to return based on the hash or uri segment.

<?php
/* -------------------------- */
/* controllers > pager.php */
/* -------------------------- */

class Pager extends Controller {

	/* Constructor */
	function __construct()
	{
		parent::Controller();
		$this->load->model('pager_model');
		$this->load->library('pagination');
	}

	function index()
	{
		/* Get Total Results */
		$num_posts = $this->pager_model->get_posts(null,null);

		/* Pagination Config */
		$config['base_url'] = 'http://petesaia.com/pager';
		$config['total_rows'] = $num_posts->num_rows();
		$config['per_page'] = '2';
		$config['full_tag_open'] = '<ul class="pager">';
    	$config['full_tag_close'] = '</ul>';
		$config['cur_tag_open'] = '<li><strong>';
		$config['cur_tag_close'] = '</strong></li>';
		$config['num_tag_open'] = '<li>';
		$config['num_tag_close'] = '</li>';
		$config['next_link'] = 'Next';
		$config['prev_link'] = 'Previous';
		$config['prev_tag_open'] = '<li>';
		$config['prev_tag_close'] = '</li>';
		$config['first_tag_open'] = '<li>';
		$config['first_tag_close'] = '</li>';
		$config['next_tag_open'] = '<li>';
		$config['next_tag_close'] = '</li>';
		$config['last_tag_open'] = '<li>';
		$config['last_tag_close'] = '</li>';
		$config['uri_segment'] = '2';
		$this->pagination->initialize($config);

		/* Make Query */
		$data['posts'] = $this->pager_model->get_posts($config['per_page'],$this->uri->segment(2));

		$this->load->view('ajaxpager_view', $data);
	}
}

Our controller is first going to load the pagination library and our pager_model in the constructor. The pagination library creates our links based on the total number of results and the current page which is specified in the second uri segment of the links it creates. If you haven’t already done so, make sure you specify that you will be using parameters on this class in the routes folder. It will look something like this:

$route['pager/:num'] = "pager";

This says if there is a number after the first slash to reroute to the class pager allowing us to use the number as a parameter.

Finally, we load our view which contains all of our xhtml and Javascript.

<?php
/* -------------------------- */
/* views > ajaxpager_view.php */
/* -------------------------- */
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<link rel="stylesheet" href="/resources/css/style.css" type="text/css" />
		<script type="text/javascript" src="/resources/js/jquery-1.3.2.min.js"></script>
		<script type="text/javascript" src="/resources/js/jquery.history.js"></script>
		<title>Codeigniter - AJAX Pagination With History</title>
	</head>

	<body>

		<?php
		if ($posts) //if there are in fact posts...
		{
			echo '
			<div id="container">
				<div id="results">
			';

			foreach($posts->result_array() as $row)
			{
				echo '
				<div class="post">
					<p>'.$row['text'].'</p>
				</div>
				';
			}

			echo '
				</div>
			</div>
			<div id="controls">
				'.$this->pagination->create_links().'
			</div>
			';
		}
		else //if no results in database
		{
			echo '<p>There are no records.</p>';
		}
		?>

		<script type="text/javascript">
			function pageload(hash)
			{
			    if(hash) {

			    	//give some time for safari to catch up
			    	setTimeout("goto()",200);

			    }
			    else
			    {
			    	//if on page 1
			    	reset();
			    }
			}

			function goto()
			{
			    /* Make adapt to if there is a slash at the end of the url or not */
			    if (location.href.match('/#'))
			    {
			        var goto = location.href.replace("#","");
			    }
			    else
			    {
			        var goto = location.href.replace("#","/");
			    }

			    /* Load Pager */
			    $("#controls").load(goto+' #controls ul',
			    	function()
			    	{
			        	/* Load Content */
			        	$("#container").load(goto+' #results',{},
			        		function(){
			        			$('.loader').remove();
			        		}
			        	);
			    	}
			    );
			}

			function reset()
			{
				$("#results").remove();
				$("#container").load(location.href.replace(/[1-9$-]/g, "")+' #results');
				$.historyLoad('0');
			}

			$(document).ready(
				function(){

					$.historyInit(pageload, "/pager");

					$(".pager a").live('click',
						function(){
							$("#results").remove();
							$('#container').append('<img class="loader" src="/resources/images/ajax-loader.gif"/>');
							hash = this.href.split('/').pop();
							if (hash)
							{
								$.historyLoad(hash);
							}
							else
							{
								reset();
							}
							return false;
						}
					);
				}
			);
		</script>
	</body>
</html>

First we loop through the results that we passed from the controller in the $data array using the result_array() function.
Then the $this->pagination->create_links() creates our links. At this point our pager should work fine with no javascript at all.

The final element of this project is the jQuery. The idea is to still pass the correct uri segment to our controller as if we wern’t using javascript at all, but to mask it from the browser using a hash (#) to store the page number. So in the browser the url will look like: pager#2, pager#8, ect… But what we are really passing via ajax is still the same pager/2 and pager/8 format as we did without javascript. We are able to do this by filtering the link through a regular expression before loading the content.

I wrote all of the Javascript inline for demonstration purposes only. For larger projects I highly suggest creating a plugin.

jQuery Textarea & Input Value Toggle Replacement

Posted in Code Snippets on October 5th, 2009 by Pete – 1 Comment

** UPDATE ** This has been upgraded dramatically. Click Here.

A quick and clean Input Value Toggle Replacement plugin for password, text, and textarea fields using the jQuery (1.3.2) framework. Simply pass the ID or Class of the parent wrapper to the function ps_formify() and the value to the corresponding input will be remembered so when the user clicks inside the input the string will clear, but if the input is empty when the user clicks out, the same string will be replaced. This allows for a pretty cool effect on non-ajax forms if there is an error with the submission and the form is redirected to with the previous entries already in place, the script will remember their new values opposed to the old ones so corrections can be made with ease.

XHTML Markup:

<fieldset id="ParentWrapperID">
	<input type="text" value="Name"/>
	<input type="password" value="Password"/>
</fieldset>

Usage:

/* --------------------- */
/* To Call */
/* --------------------- */
$(document).ready(
	function(){
    	$('#ParentWrapperID').ps_formify(); //Simply pass the ID or Class of the parent wrapper to your inputs
	}
);

The Plugin:

/* --------------------- */
/* Formify Plugin */
/* --------------------- */
(function($){
    $.fn.ps_formify = function(){
    	var $this = $(this);
        var words = new Array();
		$($this).find("input[type='text'],input[type='password'],textarea").each(
			function(index){
				words[index] = $(this).attr('value');
				$(this).bind("focus",
					function(){
						if ($(this).attr('value') == words[index])
						{
							$(this).attr('value', '');
							$(this).blur(
								function(){
									if ($(this).attr('value').length < 1)
									{
										$(this).attr('value', words[index]);
									}
								}
							);
						}
					}
				);
			}

		);
    }
})(jQuery);