Forum Replies Created

Viewing 2 replies - 1 through 2 (of 2 total)
  • Thread Starter VOST

    (@ovws)

    Thanks bcworkz in trying to help me out; it took me some times but I eventually found something.
    What follows is not a long-term solution. If you wish to keep in your database the fact that you assign terms of custom taxonomies to a certain post using repeatable fields, then, I suppose, it evolves doing a bit a SQL.
    Still, I am posting my solution as it may be of use for someone.
    The trick, compared to my previous code, was to add a count variable (here $cnt) to the name attribute of my select element:
    Before:
    $html .= '<select name="screeningName" id="screeningName">';
    After:
    $html .= '<select name="screeningDetails[' . $cnt . '][screeningName]">';
    Semantically, the repeatable fields are tr elements of a table, with the remove button within each row. In order to make it work (the remove button inside each row) the jquery code needs to be changed:

    $(".remove").live('click', function() {
            //$(this).parent().remove(); // When the button is outside the repeatable element
            $(this).parents('[class*="repeatableField"]').remove(); // When the button is inside the repeatable element
    });

    So, here we go, follows the corrected code (I also pastebin-ed it for anyone to improve it, https://pastebin.com/CxWaiqQk):
    Drop-down list:

    function print_screening_field($cnt, $p = null) {
    if ($p === null) {
        $a = $b = $c = '';
    } else {
    	$a = $p['screeningName']; // Change variable name
    	$b = $p['screeningMonth']; // Change variable name
    	$c = $p['screeningYear']; // Change variable name
    }
    	$festivalTerms = get_terms('festival', 'hide_empty=0'); // Change variable name and taxonomy name
    	$festivalNames = wp_get_object_terms($post->ID, 'festival'); // Change variable name and taxonomy name
    	$monthTerms = get_terms('month', 'hide_empty=0'); // Change variable name and taxonomy name
    	$monthNames = wp_get_object_terms($post->ID, 'month'); // Change variable name and taxonomy name
    	$yearTerms = get_terms('year', 'hide_empty=0'); // Change variable name and taxonomy name
    	$yearNames = wp_get_object_terms($post->ID, 'year'); // Change variable name and taxonomy name
    
    	$html .= '<tr id="'. $cnt .'" class="repeatableField form-field">'; // The class name here is important regarding the jquery's part of the code
        	$html .= '<td><label>#'.$cnt.'</label></td>'; // Here the $cnt variable is used just to visually see how many fields we have created
    
        	$html .= '<td>';
    			$html .= '<select name="screeningDetails[' . $cnt . '][screeningName]" id="' . $cnt . '">'; // to name the select makes it work, adding also the $cnt variable to it
    				$html .= '<option value="';
    					if (!count( $festivalNames )) {
    						$html .= 'selected">';
    					}
    				$html .= 'Select a festival</option>';
    				foreach ($festivalTerms as $festivalTerm) {
    				$html .= '<option value="' . $festivalTerm->name . '" '.($a==$festivalTerm->name?'selected':'').'>' . $festivalTerm->name . '</option>';
    				}
    			$html .= '</select>';
    		$html .= '</td>';
    
        	$html .= '<td>';
    			$html .= '<select name="screeningDetails[' . $cnt . '][screeningMonth]" id="' . $cnt . '">'; // to name the select makes it work, adding also the $cnt variable to it
    				$html .= '<option value="';
    					if (!count( $monthNames )) {
    						$html .= 'selected">';
    					}
    				$html .= 'Select a month</option>';
    				foreach ($monthTerms as $monthTerm) {
    				$html .= '<option value="' . $monthTerm->name . '" '.($b==$monthTerm->name?'selected':'').' id="' . $cnt . '">' . $monthTerm->name . '</option>';
    				}
    			$html .= '</select>';
    		$html .= '</td>';
    
        	$html .= '<td>';
    			$html .= '<select name="screeningDetails[' . $cnt . '][screeningYear]" id="' . $cnt . '">'; // to name the select makes it work, adding also the $cnt variable to it
    				$html .= '<option value="';
    					if (!count( $yearNames )) {
    						$html .= 'selected">';
    					}
    				$html .= 'Select a year</option>';
    				foreach ($yearTerms as $yearTerm) {
    					$html .= '<option value="' . $yearTerm->name . '" '.($c==$yearTerm->name?'selected':'').'>' . $yearTerm->name . '</option>';
    				}
    			$html .= '</select>';
    		$html .= '</td>';	
    
    		$html .= '<td>';
    			$html .= '<button class="remove">Remove #' . $cnt . '</button>';
    		$html .= '</td>';
    
    	$html .= '</tr>';
    
    return $html;
    }

    Display on the admin side:

    function screening_details_meta_box(){
    	global $post;
    	$custom = get_post_custom($post->ID);
      	$screeningDetailsData = get_post_meta($post->ID,"screeningDetails",true);
    ?>
      	<h4 style=" text-transform: uppercase;">Other screenings</h4>
      	<table id="data_items" class="form-table" border-collapse="collapse">
    		<caption style="display: none;">List of screenings other than the premiere screenings</caption>
    
    		<thead>
    			<tr class="form-field">
    				<th>Number</th>
    				<th>Name</th>
    				<th>Month</th>
    				<th>Year</th>
    				<th></th>
    			</tr>
    		</thead>
    
    		<tbody>
      		<?php
     	 	$c = 0;
        		if (count($screeningDetailsData) > 0){
        		    foreach((array)$screeningDetailsData as $p ){
        		        if ( isset($p['screeningName']) || isset($p['screeningMonth']) || isset($p['screeningYear']) ){
        		            echo print_screening_field($c,$p); // uses the fonction name
        		            $c = $c +1;
        		        }
        		    }
    	    	}
    		?>
    		</tbody>
    	</table>
        <span id="here"></span>
        <button class="add"><?php echo __('Add a screening'); ?></button>
        <script>
    		var $ =jQuery.noConflict();
    		$(document).ready(function() {
    		var count = <?php echo $c; ?>;
        	$(".add").click(function() {
    			count = count + 1;
            		$('#data_items').append('<? echo implode('',explode("\n",print_screening_field('count'))); ?>'.replace(/count/g, count));
            			return false;
            		});
            		$(".remove").live('click', function() {
            			//$(this).parent().remove(); // When the button is outside the repeatable element
            			$(this).parents('[class*="repeatableField"]').remove(); // When the button is inside the repeatable element
            		});
            	});
        </script>
        <style>
        	table#data_items { margin-bottom: 20px; }
        	tr[class*="repeatableField"]:nth-child(odd) { background-color: #EEEEEE; }
        </style>
        <?php
    }

    Save the data:

    function save_meta_box($post_id){
    	global $post;
    
    	if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
    	return $post_id;
    	if (isset($_POST['screeningDetails'])){ $screeningDetailsData = $_POST['screeningDetails']; update_post_meta($post_id,'screeningDetails',$screeningDetailsData); } else { delete_post_meta($post_id,'screeningDetails'); }
    }
    add_action('save_post', 'save_meta_box');

    Thread Starter VOST

    (@ovws)

    Hello bcworkz,

    thank you for your link. What I am trying to do is slightly more complex as I wish to have several drop-down lists (so several values) embedded in one repeatable field. Visually it would be something like such:

    [repeatable]
    – Drop-down: Screenings’ names
    – Drop-down: Screenings’ countries
    -remove button
    [/repeatable]
    [Add a screening button]

    So far I succeeded to return the drop-down lists (which was my first problem) but I still cannot find a way to attach values to the selected options.

    Here is my code so far (what changes, compared to the first code in my first post, is that I closed my condition “$p === null” before I set my $festivalterms and $countryterms variables):

    function print_screening_field($cnt, $p = null) {
    if ($p === null) {
    
        $a = $b = '';
    
    } else {
    
        $a = $p['screeningName'];
        $b = $p['screeningCountry'];
    
    }
    
        $festivalterms = get_terms('festival', 'hide_empty=0');
        $festivalnames = wp_get_object_terms($post->ID, 'festival');
        $countryterms = get_terms('country', 'hide_empty=0');
        $countrynames = wp_get_object_terms($post->ID, 'country');
    
    	$html = '';
            $html .= '<li>';
    
    	$html .= '<label>Festival: </label>';
    	$html .= '<select name="screeningName" id="screeningName">';
    	$html .= '<option value="">Select screening</option>';
    	foreach ($festivalterms as $term) {
    		$html .= '<option value="' . $a . '" ' . selected($a, '' . $term->name . '') . '>' . $term->name . '</option>';
    	}
    	$html .= '</select>';
    
    	$html .= '<label>Country: </label>';
    	$html .= '<select name="screeningCountry" id="screeningCountry">';
    	$html .= '<option value="">Select country</option>';
    	foreach ($countryterms as $term) {
    		$html .= '<option value="' . $b . '" ' . selected($b, '' . $term->name . '') . '>' . $term->name . '</option>';
    	}
    	$html .= '</select>';
    
    	$html .= '<button class="remove">Remove</button>';
    	$html .= '</li>';
    
    return $html;
    }

Viewing 2 replies - 1 through 2 (of 2 total)