Found the last bit. It was just a syntax error:
<?php selected( $selected, ".$term_id". ); ?>
Should be…
<?php selected( $selected, $term_id ); ?>
Entire Function:
function tf_book_deets_create(){
add_meta_box('tf_book_purchase', 'Book Purchase Links', 'tf_book_purchase', 'books','side','default');
}
function tf_book_purchase (){
global $post;
$custom = get_post_custom($post->ID);
$link = $custom["link"][0];
$selected = isset( $custom['link'] ) ? esc_attr( $custom['link'][0] ) :'';
echo '<div class="link_header">';
$myterms = get_terms("link_category");
echo '<p>Please select a set of purchase links for this book.</p>';
echo '<select name="link" id="link">';
echo '<option class="buy_books">Select A Link Category</option>';
foreach($myterms as $term){
$term_slug=$term->slug;
$term_name =$term->name;
$term_id =$term->term_id;
?> <option value="<?php echo $term_id;?>" <?php selected( $selected, $term_id ); ?>><?php echo $term_name;?></option>
<?php } echo '</select><br /></div>';
}
add_action ('save_post', 'save_tf_book_purchase');
function save_tf_book_purchase() {
global $post;
// make sure we're on a supported post type
if ( $_POST['post_type'] != 'books' ) return;
// verify this came from our screen and with proper authorization.
if ( !wp_verify_nonce( $_POST['book_nonce_name'], 'book-nonce' )) return;
// verify if this is an auto save routine. If it is our form has not been submitted, so we dont want to do anything
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return;
// Check permissions
if ( 'page' == $_POST['post_type'] ) {
if ( !current_user_can( 'edit_page', $post_id ) ) return;
} else {
if ( !current_user_can( 'edit_post', $post_id ) ) return;
}
//if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){ return $post->ID; }
update_post_meta( $post->ID, 'link', esc_attr( $_POST['link'] ));
}