Javascript


6
Mar 11

Instead of just Killing off IE6…

Why not kill off IE7 while we are at it?

So, IE6 is on the death march. It’s support ended July 13th 2010. Unfortunately it persists because of Windows XP, as it’s support lasts until 2014.

http://www.theie6countdown.com/

I figured I should help out, but I want to help kill of IE7 as well, so I found an IE6 notice script here: https://code.google.com/p/ie6-upgrade-notification-bar/. I have made quite a few changes to it, and here is the result:

http://seanja.com/demos/ie7-notice/.

The source is available on github https://github.com/SeanJA/ie7-notice.


13
Jan 11

Using Valums File Uploader with CodeIgniter

Valums file uploader is a fancy pants ajaxy uploader widgit that is meant to be used with normal php pages. It, by default, doesn’t really play well with CodeIgniter.

Fortunately, it isn’t that hard to make it work. There is a bit of a modification to the .js file:

Basically, you just have to turn the ?qqfile=blah into /blah . Granted, this is a quick fix… and it will not work if you want to pass extra params to the upload. A better fix would be to rewrite parts of the qq.obj2url function so that it accepts a different separator.

The other thing you have to worry about is CodeIgniter’s magical stripping of characters that it doesn’t like specifically: the . in your file’s name. Fortunately this is easy to fix:

//snip [......]
	  //codeigniter replaces the . with a _ argh, we can fix that by doing this:
	  $filename = substr_replace($param1, '.', strrpos($param1, '_'), strlen('_'));
//[......]   /snip

That is about it, the code is available here: https://github.com/SeanJA/uploadr.

Also, since I don’t subscribe to the “we must support php 4 forever” mentality, you will notice that the methods in my classes have private, public, and protected, you can just remove all of those if you need to support PHP 4 still (but you really should upgrade…).


5
Jan 11

Ajaxy Pagination using jQuery

Saw this today: AJAX Pagination using jQuery and PHP with Animation. While it is quite simple to add paging using jQuery, why not make it work without the jQuery as well?

It isn’t too hard to do, add a url to each of the a tags, then load the content based on that instead.

This would be the code (some of it has been left as an exercise for the reader):

the table would look like this (or you know, something else…)

page.php is sort of like a controller… for a one off page this would be fine, I would abstract it a bit more if it were part of a bigger site.

paged_results.tpl.php Spit out the stuff to the users

Here is script.js… it has the javascript that would be used to make it ahem… ajaxy

Code is here if you want it: https://gist.github.com/767437


24
Mar 10

jQuery :contains selector and unicode characters

I have an element like this (to save space in the menu since they can put up to 255 characters in it):

    <span class="tool_tip" title="The full title">The ful&#8230;</span>

While this seems to work:

    jQuery('span:contains(…)');

this does not:

    jQuery('span:contains(&#8230;)');

I am pretty sure that it would be bad to use the first one because if someone else saves the file, or the browser decides to get the file in a different character set for some reason things will not work.

There has to be a way to properly select this span, right? Turns out there is:

 
    jQuery('span:contains(\u2026)');

In other words:

Use the hex value instead of the decimal value as the selector and things will work out fine.


10
Mar 10

Using the jQuery-UI Autocomplete Widget

The latest version of jQuery-ui has an autocomplete widget. No more looking for one that will work (you get the point) with the version of jQuery that you have.

All you have to do is pull the latest one down from the jQuery-ui site and you are good to go.

First the jQuery to use the autocomplete plugin:

 
//we will be using this to cache the responses from the server
var ajaxCache = {};
 
//activate autocomplete on boxes that have the autocomplete class
$("input.auto_complete").autocomplete({
	source: function(request, response) {
		//what are we searching for
		var query_type = $(this).attr('element').attr('id');
		//the cacheterm that we use to save it in the cache
		var cachedTerm = (request.term + '' + query_type) . toLowerCase();
		//if the data is in the cache and the data is not too long, use it
		if (ajaxCache[cachedTerm] != undefined && ajaxCache[cachedTerm].length < 13) {
			//map the data into a response that will be understood by the autocomplete widget
			response($.map(ajaxCache[cachedTerm], function(item) {
				return {
					label: item.value,
					value: item.value
				}
			}));
		}
		//get the data from the server
		else {
			$.ajax({
				url: "/ajax/auto_complete.php",
				dataType: "json",
				data: {
					query_type: query_type,
					q: request.term
				},
				success: function(data) {
					//cache the data for later
					ajaxCache[cachedTerm] = data;
					//map the data into a response that will be understood by the autocomplete widget
					response($.map(data, function(item) {
						return {
							label: item.value,
							value: item.value
						}
					}));
				}
			});
		}
	},
	//start looking at 3 characters because mysql's limit is 4
	minLength: 3,
	//when you have selected something
	select: function(event, ui) {
		//close the drop down
		this.close
	},
	//show the drop down
	open: function() {
		$(this).removeClass("ui-corner-all").addClass("ui-corner-top");
	},
	//close the drop down
	close: function() {
		$(this).removeClass("ui-corner-top").addClass("ui-corner-all");
	}
});

The ajax/auto_complete.php would look something like this:

 
<?php
 
//make sure that we only allow valid query types
/**
 * @var array
 */
$validQueryTypes = array(
	'country',
	'city',
	'first_name',
	'last_name',
);
/**
 * @var string
 */
$column = (isset($_POST['query_type']) && in_array($_POST['query_type'], $validQueryTypes))? $_POST['query_type'] : null;
/**
 * @var string
 */
$q = isset($_POST['q'])? $_POST['q'].'%':null;
 
 
if($column && $q){
	switch($column){
		case 'country':
		case 'city':
			$q = new sQuery();
			$results = $q->from('addresses')
				//to make things simpler for the javascript, always select as value
				->column($column . ' as value')
				->where($column, $q, 'LIKE')
				->getAll();
 
			//SELECT $column as value FROM addresses WHERE $column LIKE '$q%';
			break;
		case 'first_name':
		case 'last_name':
			$q = new sQuery();
			$results = $q->from('users')
				->column($column . ' as value')
				->where($column, $q, 'LIKE')
				->getAll();
			//SELECT $column as value FROM users WHERE $column LIKE '$q%';
			break;
	}
 
	//$result is something like this:
	array(
		array('value'=>'Canada'),
		array('value'=>'America'),
		array('value'=>'Mexico'),
		array('value'=>'Netherlands'),
	);
 
	//then return it to the javascript
	echo json_encode($results);
}
exit;

Then the simplest part of the exercise:

 
City:
<input type="text" name="city" id="city" title="enter a city" class="auto_complete" />
 
Country:
<input type="text" name="country" id="country" title="enter a country" class="auto_complete" />
 
First Name:
<input type="text" name="first_name" id="first_name" title="enter a first_name" class="auto_complete" />
 
Last Name:
<input type="text" name="last_name" id="last_name" title="enter a last_name" class="auto_complete" />

And if they don’t have javascript enabled it doesn’t detract from the form (go progressive enhancement!).

Edit:

This post is pretty old, but just in-case you were wondering sQuery is this: https://github.com/SeanJA/ShoestringPHP/blob/master/library/classes/squery.class.php and there is also a better tested more standalone-y version here as a separate project: https://github.com/SeanJA/query-builder.