Dynamically load content in Twitter Bootstrap modal boxes

I’m working on a small personal project, and experimenting with some new (to me) things. I’m using CodeIgniter as a PHP framework and Twitter’s Bootstrap for the layout and design. Bootstrap is actually a conglomeration of other neat concepts nicely packaged, one that I’ve already been using, the 960 Grid System (although their’s is slightly modified), and LESS.css which I’m totally loving.

One of the issues I ran into pretty quickly is Modal dialog boxes. I have a view in my web app where the user is presented with a table of data, and they can click on the table row to edit that data. The edit box is a modal popup that is filled in with the data for them to edit.

While the Bootstrap framework has javascript plugins for modal dialog boxes, it doesn’t have a “standard” way of loading content into them, aside from statically.

After googling around I came across two sites that each provided part of the answer I was looking for. The first site I found was at ThePhuse.com were I found an article outlining a good way of implementing clickable table rows. The second site was more specifically about loading dynamic content into Bootstraps’ tabs.

I took the two sites and mashed up the knowledge and came up with the following code:

<!-- this is the table that shows the user information -->
<table class="zebra-striped">
	<thead>
		<tr>
			<th>#</th>
			<th>First Name</th>
			<th>Last Name</th>
			<th>Email</th>
		</tr>
	</thead>
	<tbody>
		<?php
		$fields = array('id','first_name','last_name','email');
		foreach ($data as $user) { ?>
		<tr data-href="/users/edit/<?php echo $user->id; ?>/1">
			<?php foreach ($fields as $field) { ?>
			<td><?php echo $user->$field; ?></td>
			<?php } ?>
		</tr>
		<?php } ?>
	</tbody>
</table>

<!-- this is the placeholder for the modal box -->
<div id="modal-editUser" class="modal hide">
	<!-- content will go here -->
</div>

<!-- this is the code that makes it all happen -->

<script type="text/javascript">
	jQuery( function($) {
		// find all tr's with a data-href attribute
		$('tbody tr[data-href]').click( function() {
			// copy the data-href value to the modal for later use
			$('#modal-editUser').attr('data-href',$(this).attr('data-href'));
			// show the modal window
			$('#modal-editUser').modal({show: true , backdrop : true , keyboard: true});
		}).find('a').hover( function() {
			// unbind it in case I put some a tags in the table row eventually
			$(this).parents('tr').unbind('click');
		}, function() {
			$(this).parents('tr').click( function() {
				// rebind it
				$('#modal-editUser').attr('data-href',$(this).attr('data-href'));
				$('#modal-editUser').modal({show: true , backdrop : true , keyboard: true});
			});
		});

		// when the modal show event fires, load the url that was copied to the data-href attribute
		$('#modal-editUser').bind('show', function() {
			$(this).load($(this).attr('data-href'));
		});
	});
</script>

Advanced Custom Fields modification

I needed to add an extra function to the Advanced Custom Fields plugin. I’m posting this here for whenever the plugin gets updated and if the author hasn’t added this helpful function.

/*--------------------------------------------------------------------------------------
*
*	get_field_label
*
*	@author Jason Lawton
*	@since 2.1.4
*
*-------------------------------------------------------------------------------------*/

function get_field_label($field_name, $post_id = false, $options = array())
{

	global $post;
	global $wpdb;
	global $acf;

	$return_id = isset($options['return_id']) ? $options['return_id'] : false;

	// tables
	$acf_values = $wpdb-&gt;prefix.'acf_values';
	$acf_fields = $wpdb-&gt;prefix.'acf_fields';
	$wp_postmeta = $wpdb-&gt;prefix.'postmeta';

	if(!$post_id)
	{
		$post_id = $post-&gt;ID;
	}
	elseif($post_id == "options")
	{
		$post_id = 0;
	}

	$sql = "SELECT f.label, m.meta_value as value, v.id, f.type, f.options, v.sub_field_id, v.order_no
		FROM $wp_postmeta m
		LEFT JOIN $acf_values v ON m.meta_id = v.value
		LEFT JOIN $acf_fields f ON v.field_id = f.id
		WHERE f.name = '$field_name' AND m.post_id = '$post_id' ORDER BY v.order_no ASC";

	$results = $wpdb-&gt;get_results($sql);

	// no value
	if(!$results)
	{
		return false;
	}

	// normal field
	$field = $results[0];

	// repeater field
	if($field-&gt;type == 'repeater')
	{
		$return_array = array();

		foreach($results as $result)
		{
			$sql2 = "SELECT type, name, options
			FROM $acf_fields
			WHERE id = '$result-&gt;sub_field_id'";

			$sub_field = $wpdb-&gt;get_row($sql2);

			// format the sub field value
			if($acf-&gt;field_method_exists($sub_field-&gt;type, 'format_value_for_api'))
			{
				if(@unserialize($sub_field-&gt;options))
				{
					$sub_field-&gt;options = unserialize($sub_field-&gt;options);
				}
				else
				{
					$sub_field-&gt;options = array();
				}

				$result-&gt;value = $acf-&gt;fields[$sub_field-&gt;type]-&gt;format_value_for_api($result-&gt;value, $sub_field-&gt;options);
			}

			// only add the value if it is not null or false
			if($result-&gt;value != '' || $result-&gt;value != false)
			{
				if($return_id)
				{
					$return_array[$result-&gt;order_no][$sub_field-&gt;name]['id'] = (int) $result-&gt;id;
					$return_array[$result-&gt;order_no][$sub_field-&gt;name]['value'] = $result-&gt;value;
				}
				else
				{
					$return_array[$result-&gt;order_no][$sub_field-&gt;name] = $result-&gt;value;
				}

			}

		}

		// if empty, just return false
		if(empty($return_array))
		{
			$return_array = false;
		}

		return $return_array;

	}

	$value = $field-&gt;label;

	if($return_id)
	{
		$return_array = array(
			'id'	=&gt;	(int) $field-&gt;id,
			'value'	=&gt;	$value,
		);
		return $return_array;
	}

	return $value;

}

iPhone Apps that I use

A friend just got an iPhone, and was wondering what apps were good. Here’s a list of apps I use.

(Yes all of these links go through an affiliate, so if you buy something I *might* get money for it one day. I’m not holding my breath)

My Apps
How could I have forgotten the apps that I have written?!

  • Mini Golf Pad – Keep score on your iPhone instead of that dumb pencil and paper!
  • DropIt – Save files/bookmarks off the internet onto your iPhone
Photography
Note Taking/Todo
  • SimpleNote - Take notes and sync them to a website, accessible via Notational Velocity on the Mac
  • ShopShop - Shopping list app
  • Producteev - My new favorite todo list app
  • Todo - My divvious favorite todo list app
Video Streaming
  • Air Video - THE BEST – Stream videos from your computer to your iPhone
  • Netflix
  • Optimum - Watch TV on your iPhone, set the DVR, etc
  • HBO - I’ve actually never used this app
Audio
  • Pocket Casts – A great podcast app, although it’s buggy in iOS 5 right now
Reading
  • Instapaper - Keeps articles to read later, formats them without all the ad bullshit
  • Reeder - RSS Reader that doesn’t crash
  • iBooks
  • Kindle - Sync’s with your amazon account so you can get a copy of all the books on your Kindle
Navigation
Utility
  • Infinitlight - The only flashlight you’ll ever need
  • Gas Cubby - Track your gas mileage if you are OCD like me
  • Runkeeper - Track your workouts if you are OCD like me
  • Dropbox - Sync files to the internet
  • Boxcar - Notifications to your phone for services you probably haven’t heard of.
  • iTeleport - Great VNC client for the iPhone
  • Find my iPhone - Find your iPhone (or your wifes)
  • Wolfram Alpha - Look up ANYTHING – get stats on it
  • RedLaser - Barcode scanner (currently the only app I have that reads QR codes)
  • Remote - Control iTunes on the computer
  • Convert - Convert units, I use it mostly when cooking
  • Square - Accept credit card payments
  • Chase - Access your (my) bank account
  • Shazam - Identify a song by listening to it
Games
Social
Sports
Other

Dreams

The past two nights (mornings really) I’ve had the weirdest dreams. But they’re both along the same plot of “situation you can’t get out of”.

Monday morning around 5am I had a dream that the earth was being invaded by aliens and we had to survive. I woke up and couldn’t fall back to sleep because every time I tried my mind would start racing with ideas an situations on how to survive in this apocalypse. Where would I get a gun, the gun shop down the street. Where would I get medicine, I’d have to raid the riteaid nearby. And so on, until I got tired of doing that and just got up at 6.

Then this morning a similar dream. This time it was me and a group of people breaking into a hospital/medical facility and stealing money. And then having to escape without getting caught. I wasn’t even being chased, it was just that I ha to take precautions and plan out situations in case something happened.

It’s not only weird that I remember my dreams, I never do, but it’s weird that I remember them two days in a row, and that they’re basically the same dream.

Sorting Media into iTunes

I recently bought an Apple TV, and I totally love it. But in order to watch stuff on it, I needed to convert a lot of files to its m4v format. To do so, I followed this tutorial in three parts:

http://www.mactalk.com.au/content/organising-media-hazel-part-1-1017/

http://www.mactalk.com.au/content/organising-media-hazel-pt-2-986/

http://www.mactalk.com.au/content/organising-media-hazel-pt-3-1024/

I haven’t done part three with the renaming yet, and I had to hack some scripts to take care of FLAC conversion to MP3s, and then I’m using HandBrakeCLI to convert files instead of Quicktime, but it’s working out really well. I’ll have to expand on it when I get some more time.

Set a value in a View Controller from the Application Delegate

I was stuck on this for a bit, so I’m posting it here for my own needs really.

If  you have an app that needs content set up when it loads, you might want to use -viewDidLoad. The problem with that is that now that there’s multitasking in iOS, -viewDidLoad doesn’t get called all the time when the app “starts”. Instead, what you want to use is -applicationDidBecomeActive:

Let’s say i have a view named MainViewController, and a label (input area) on the view called targetURL, and when the app becomes active I want to set that URL from some datasource, here’s how to do it:

- (void)applicationDidBecomeActive:(UIApplication *)application

… code to get data …

self.mainViewController.targetURL.text = someData;

}

 

Dealing with iOS clipboard

I want to make Drop It even better, version 1.0 was a “just get it done and in the store” kind of deal. Now it’s time to make it better. Step 1, make it so you don’t have to paste the url in there if you’ve already copied it. I know, it’s not that big a deal, but if an app can remove one step from the process that you’re going to do anyway, then the app makes your life just a little bit easier, and that provides a positive user experience.

I ended up using this page on MobileOrchard to figure out how to grab the contents of the clipboard (or pasteboard, in iOS terms).

UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];

And then to get the contents of the latest copied string:

NSString *string = pasteboard.string;

Custom Post Types in WordPress 3.0 Links

One of the major improvements in WordPress 3.0 is the addition of Custom Post Types. This basically allows you to add a bit of code via the functions.php file, or better yet, through a plugin that let’s you create your own content type that is tailored to your (and your clients) needs. In this post I’ll outline the pages that helped me write my first plugin and post type.

Here’s WordPress’s documentation for Custom Post Types

These two pages offer a good walk-through of creating a Custom Post Type and how to customize the columns on the manage page for those posts. It covers creating the post type, as well as adding meta boxes and customizing the manage page.

Justin Tadlock offers a great rundown of all the options available when creating the post type.

Here’s WordPress documentation on Writing a Plugin.

This post helped me figure out how to get meta data onto the manage post page. Hint, it’s get_post_meta(post_id, key, true)

These two excellent posts helped me the most, adding a custom metabox, and creating an event custom post type (which was actually what i was doing)

Here’s a crazy post about making better meta boxes, but it’s over my head right now.

Apparently any time someone says “Add this code to functions.php” that means that you can also add the code to your plugin page. I did to get my custom post types on the homepage, using the code from Justin Tadlock.

When using permalinks, I had to fix my plugin to be called on the ‘init’ function, which I discovered via this page.

I wanted to add a new “single-<post type>.php” page, but I didn’t want it to go in a theme folder. I wanted it to be in the plugin directly. After a little googling and searching, I found the code to do it on WordPress’ own site.

Customizing UISlider in iPhone

Go from this…

boring slider

To this!

less boring slider

I’m writing an app where I needed to make the thumb nub of a slider (UISlider in the Objective-C vernacular) smaller.

UISlider thumbs

Above: On the left is the UISlider thumb normal size, and on the right is the size I want. Obviously the pic is blown up.

To change the slider thumb to our custom image, place the following code in viewDidLoad:

UIImage *sliderThumb = [UIImage imageNamed:@"uislider-thumb.png"];
[slider setThumbImage:sliderThumb forState:UIControlStateNormal];
[slider setThumbImage:sliderThumb forState:UIControlStateHighlighted];

If you don’t add the second setThumbImage: forState:UIControlStateHighlighted, I believe the thumb pic will disappear when you put your finger on it. Not that you’d be able to tell, since your fingers will be covering it.

When I ran this code I ran into a weird issue, the track disappeared! This only happened in iOS 3.1.3 (where I tested it) but not on iOS 4.0. To remedy this I decided to go the whole way and customize the track images as well. Yes, images plural, there are actually two images that make up the UISlider track. One is the minimum image, or the track image that appears to the left of the thumb, and the other is the maximum image, or the image that appears to the right of the thumb.

To change the track image for the UISlider, use this code, again in viewDidLoad:

UIImage *sliderMinimum = [[UIImage imageNamed:@"uislider-left.png"] stretchableImageWithLeftCapWidth:4 topCapHeight:0];
[slider setMinimumTrackImage:sliderMinimum forState:UIControlStateNormal];
UIImage *sliderMaximum = [[UIImage imageNamed:@"uislider-right.png"] stretchableImageWithLeftCapWidth:4 topCapHeight:0];
[slider setMaximumTrackImage:sliderMaximum forState:UIControlStateNormal];

A small note here, the leftCapWidth is the width of the left side of the image, and the track is a 1 pixel wide slice repeated horizontally across the width of the track, and then the rightCapWidth is the same as the leftCapWidth. This might lead you to believe that you can make an image that is a minimum of 3px wide. 1 pixel border on the left and right, and 1 pixel in the middle. I tried it, and it didn’t really work out too well, so what I ended up doing was making it 9 pixels wide and setting the leftCapWidth to 4.

That’s all you really need to get started customizing your sliders. Obviously you need to make a slider either in a NIB and hook it up in the .h/.m file, or do it programmatically in the .h/.m file.

Hope this helps!

This article was the jumping off point for me to customize the slider: http://www.applausible.com/blog/?p=250