Custom Select Elements and jQuery… uhhh, and you.

Posted on July 6th, 2010 in Javascript, Programming | No Comments »

For those out there in the web design world with particular clients, you may have noticed it’s difficult if not impossible to modify certain CSS properties of the select tag. Hence, I have decided to get rid of it entirely in lieu of div’s. I’m aware that this has been done before. However, other instances of this script are incredibly complex, and I just don’t have the time to sort through all that junk. Here’s how this bad boy works:

Create a select tag just like you normally would except add a class called “custom_select”. Add styles to the select tag that you would like to have (even if they aren’t supported) like this:

<select class="custom_select" style="border: 1px solid #fff; height: 25px; width: 400px; padding: 2px; margin: 2px;" name="favorite_color">
   <option>Blue</option>
   <option>Red</option>
   <option>Yellow</option>
</select>

Now that we’ve created our select box, add this code to the top of your page.
Here’s the code, feel free to use it or post something better:

<script type="javascript">
$(document).ready(function() {
	custom_selects = new Array();
	count = 0;
 
	$('.custom_select').each(function() {
		custom_selects[count] = new Array(); // Array of all selects
		custom_selects[count][0] = $(this);
		custom_selects[count][1] = $(this).attr('name');
		custom_selects[count][2] = new Array();
		custom_selects[count][2][0] = $(this).css('height');
		custom_selects[count][2][1] = $(this).css('width');
		custom_selects[count][2][2] = $(this).css('margin-top');
		custom_selects[count][2][3] = $(this).css('margin-right');
		custom_selects[count][2][4] = $(this).css('margin-bottom');
		custom_selects[count][2][5] = $(this).css('margin-left');
		custom_selects[count][2][6] = $(this).css('border-bottom-style');
		custom_selects[count][2][7] = $(this).css('border-bottom-width');
		custom_selects[count][2][8] = $(this).css('border-bottom-color');
		custom_selects[count][2][9] = $(this).css('padding-top');
		custom_selects[count][2][10] = $(this).css('padding-right');
		custom_selects[count][2][11] = $(this).css('padding-bottom');
		custom_selects[count][2][12] = $(this).css('padding-left');
		custom_selects[count][2][13] = $(this).css('background-color');		
		custom_selects[count][4] = new Array(); // Array of selects options
		custom_selects[count][4][0] = new Array(); // option value
		custom_selects[count][4][1] = new Array(); // option text
		custom_selects[count][5] = new Array();
		custom_selects[count][5][0] = $("option:selected", this).val();
		custom_selects[count][5][1] = $("option:selected", this).text();
 
		option_count = 0;
		$("option", this).each(function() {
			custom_selects[count][4][0][option_count] = $(this).val();
			custom_selects[count][4][1][option_count] = $(this).text();
			option_count++;
		});
		count++;
	});
 
 
	for (count = 0; count < custom_selects.length; count++) { // For each select
		// Generate the intial div
		$("<div id='" + custom_selects[count][1] + "_all' class='custom_select_new' hiddeninput='" + custom_selects[count][1] + "' style='background-image:url(/images/custom_select_icon.png);background-position:right;background-repeat:no-repeat;height:" + custom_selects[count][2][0] + ";width:" + custom_selects[count][2][1] + ";margin-top:" + custom_selects[count][2][2] + ";margin-right:" + custom_selects[count][2][3] + ";margin-bottom:" + custom_selects[count][2][4] + ";margin-left:" + custom_selects[count][2][5] + ";border-style:" + custom_selects[count][2][6] + ";border-width:" + custom_selects[count][2][7] + ";border-color:" + custom_selects[count][2][8] + ";padding-top:" + custom_selects[count][2][9] + ";padding-right:" + custom_selects[count][2][10] + ";padding-bottom:" + custom_selects[count][2][11] + ";padding-left:" + custom_selects[count][2][12] + ";background-color:" + custom_selects[count][2][13] + ";overflow:hidden;'></div>").insertBefore(custom_selects[count][0]);
		$("<input type='hidden' id='" + custom_selects[count][1] + "' name='" + custom_selects[count][1] + "' value='" + custom_selects[count][5][0] + "' />").insertBefore(custom_selects[count][0]);
		// Insert the already selected option 
		$("#" + custom_selects[count][1] + "_all").append("<div class='selected' selectedvalue='" + custom_selects[count][5][0] + "'>" + custom_selects[count][5][1] + "</div>");
 
		// Create the drop down div
		$("<div id='" + custom_selects[count][1] + "_all_options' class='custom_select_new_options' selectname='" + custom_selects[count][1] + "_all' style='display:none;position:absolute;overflow:auto;margin-top:" + ($("#" + custom_selects[count][1] + "_all").offset().top + $("#" + custom_selects[count][1] + "_all").height()) + "px;margin-left:" + ($("#" + custom_selects[count][1] + "_all").offset().left) + "px;width:" + custom_selects[count][2][1] + ";border-style:" + custom_selects[count][2][6] + ";border-width:" + custom_selects[count][2][7] + ";padding-top:" + custom_selects[count][2][9] + ";padding-right:" + custom_selects[count][2][10] + ";padding-bottom:" + custom_selects[count][2][11] + ";padding-left:" + custom_selects[count][2][12] + ";border-color:" + custom_selects[count][2][8] + ";background-color:" + custom_selects[count][2][13] + ";'></div>").insertBefore(custom_selects[count][0]);
		for (option_count = 0; option_count < custom_selects[count][4][0].length; option_count++) {
			if (custom_selects[count][4][0][option_count] != "")
				$("#" + custom_selects[count][1] + "_all_options").append("<div class='option' optionvalue='" + custom_selects[count][4][0][option_count] + "'>" + custom_selects[count][4][1][option_count] + "</div>");
		}
	}
	$('.custom_select').remove();
 
	$(".option").live('click', function() {
		var parent = $("#" + $(this).parent().attr('selectname'));
		$(".selected", parent).attr('selectedvalue', $(this).attr('optionvalue'));
		$(".selected", parent).text($(this).text());
		$("#" + $(parent).attr('hiddeninput')).val($(this).attr('optionvalue'));
	});
 
	$(".custom_select_new").live('click', function() {
		if ($("#" + $(this).attr('id') + "_options").is(":visible")) {
			$("#" + $(this).attr('id') + "_options").scrollTop(0);
			$("#" + $(this).attr('id') + "_options").slideUp('fast');
		} else {
			if ($("#" + $(this).attr('id') + "_options").height() <= 250) {
				slideHeight = $("#" + $(this).attr('id') + "_options").height();
			}
			else {
				slideHeight = 250;
			}
			$("#" + $(this).attr('id') + "_options").animate({
				height:slideHeight
			}, 500, 'swing');
		}
	});
 
	$(".custom_select_new_options").live('click', function() {
		if ($(this).is(":visible")) {
			$(this).scrollTop(0);
			$(this).slideUp('fast');
		} else {
			if ($(this).height() <= 250) {
				slideHeight = $(this).height();
			}
			else {
				slideHeight = 250;
			}
 
			$(this).animate({
				height:slideHeight				
			}, 500, 'swing');
		}
	});
});
</script>

Great! So now we’ve created our select and added the code above to the head tag of our site. What’s next? Nothing! Try it out. The code above copies most (I was a little lazy to be honest) of your select element’s CSS styles over to a div and then it creates a hidden input to store the div’s selection into.

Enjoy!

P.S. I know, I know… I could’ve made this tweak and that tweak to make this better. However, I only created this to address my client’s needs so if you need something else, write it yourself or hire me :)

Name your campaign

Posted on April 23rd, 2010 in CraigsCounter.com | No Comments »

Geeze, I’ve been busy! Good news though… I’ve added the ability to name your campaigns on Craigs Counter. For those of you out there managing multiple counters, this should make life MUCH easier.

Have a YouTube channel? Use jQuery to post the latest video on your site.

Posted on April 13th, 2010 in Javascript, Programming | 1 Comment »

I’ve been working on a project over the last couple of weeks and I’ve recently been required to automatically embed the latest video from a YouTube channel into a site. Thought I’d share some code for those out there with the same issue.

You’ll need to put the following in a script tag, preferably in the head of your page. Don’t forget to change [YOUTUBE_CHANNEL_NAME] to your YouTube channel.

<script type="text/javascript">
$(function() {
    $.getJSON('http://gdata.youtube.com/feeds/users/[YOUTUBE_CHANNEL_NAME]/uploads?orderby=published&amp;alt=json-in-script&amp;callback=?&amp;max-results=1', function(data) {
        $.each(data.feed.entry, function(i, item) {
            var updated = item.updated;
            var url = item['media$group']['media$content'][0]['url'];
            var thumb = item['media$group']['media$thumbnail'][0]['url'];
            var numViews = item['yt$statistics']['viewCount'];
 
            $("#youtube_latest").html("<object width=\"330\" height=\"275\"><param name=\"movie\" value=\"" + url + "\"></param><param name=\"allowFullScreen\" value=\"true\"></param><param name=\"allowscriptaccess\" value=\"always\"></param><embed src=\"" + url + "\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"330\" height=\"275\"></embed></object>");
        });
    });
});
</script>
<div id="youtube_latest"></div>

You know what time it is! Well, you do now anyway…

Posted on March 30th, 2010 in CraigsCounter.com | 1 Comment »

Fixed up a few things today thanks to the wonderful advice of a CraigsCounter user (thanks Kristy!). All times are now set to CST. I realized I had been going with the server default GMT and military time, which isn’t any fun at all.

Anyway, MANY more updates to come.

Minor (major?) updates today

Posted on March 29th, 2010 in CraigsCounter.com | No Comments »

Sweet, sweet filters

If you check out your craigalytics™ page today, you may notice a couple of things. First, it loads much quicker! I’ve been making modifications to the code and the server to appease the need for speed. I’m not anywhere near done with my speed tweaks, but today was definitely a good start. Second, the “competitors” section now allows you to modify which competitors you are viewing based on keywords and minimum/maximum prices. Enjoy!

It’s on now!

Posted on March 23rd, 2010 in HudsonCS News | 1 Comment »

David Hudson, owner of HudsonCS

David Hudson, owner of HudsonCS

HudsonCS is officially up and running. We provide:

  • IT administration and support
  • Website design
  • Web application development
  • Website hosting
  • Consulting

If you’re on the market for a website or IT services, click here and drop us a line!

Switching servers

Posted on March 21st, 2010 in CraigsCounter.com | No Comments »

Reenactment

Reenactment

Over the last few days you’ve probably noticed the server going up and down. CraigsCounter has been so successful, we managed to upset our ISP… Yay!!

After several late nights of pain and suffering, I’ve managed to switch this beast over to a much more robust private server which should be able to handle quite a bit more. After testing it all out, everything -seems- to be working well, but let me know if you run into any problems.

As for updating the site itself, I’ve been doing a LOT of work on the back end that I haven’t posted yet.

In the mean time, I hope everyone enjoys this free service!

New project: Quick-Dine

Posted on January 6th, 2010 in Quick-Dine | No Comments »

If you want to play with our latest creation and you have an iPhone, head to http://hudsoncs.com/quick-dine/ for a wild ride of web app goodness.

What is Quick-Dine?
So glad you asked

  • Search for local restaurants based on your location
  • Each restaurant is color-coded based on their waiting list time. White means there hasn’t been a waiting list report for at least three hours. Green means the last report showed the waiting time at 15 minutes or less. Yellow means the wait is 30 to 45 minutes. Red is an hour or more.
  • Click on a restaurant and you can see an instant review of the restaurant, the address, phone number, and details of the waiting list reports.
  • You can also make a report of your own. If you’re at a restaurant, take five seconds and report the restaurants waiting list time so others can benefit from your wonderfully kind nature.

Let me know what you think! This thing is brand spanking new and definitely in beta. Right now, it will only make 100 requests a day for restaurant info so be the early bird and you just make catch a glimpse of… the future!

Still working!

Posted on December 30th, 2009 in CraigsCounter.com | No Comments »

We just wanted to let you all know that we’re still rockin’ the craigalytics™. Some feature requests that will be added:

  • Location based data: You will be able to choose which cities or states to pull visitor data from. This allows you to weed out views from areas you don’t really care about.
  • Time based data: Choose which dates to pull data from.
  • More advanced “competitors” list, allowing you to search for competitors based on a search term and a min/max price.

Some features that weren’t requested but I’m working on them anyway:

  • Pie charts showing the top 10 cities that have visited you and their percentage of the visits.
  • Still working on premium campaigns.

Thanks to everyone for your comments!

Facelift and premium campaigns

Posted on November 24th, 2009 in CraigsCounter.com | 5 Comments »

CraigsCounter Facelift

B-E-AUTIFUL

You might notice over the next few days that CraigsCounter is changing. Just adding a more professional look to the site. Let us know what you think! Also, I’ll be adding optional premium campaigns to the site so keep an eye out. Standard counters will always be free, so no worries there.

A few features of premium campaigns:

  • More counter template choices, including an invisible counter.
  • Can be used anywhere on the web, including email.
  • View all of your premium campaigns on one convenient page.
  • Private analytical data.
  • Only $1 per campaign! (minimum order of three campaigns)