0

I'm trying to have a multi-select where users can select which categories they want in a template. The functionality i want is similar to the "Select" field type but only pulling through categories to display NOT posts of those categories.

I've got the multi-select working fine and high-lighting the selected options of that page but in the templates, the values are not displayed using:


<?php var_dump(get_field('featured_tags')); ?>

The full code of the custom field type below:

<?php

class acf_Section extends acf_Field
{

    /*--------------------------------------------------------------------------------------
    *
    *   Constructor
    *
    *   @author Elliot Condon
    *   @since 1.0.0
    *   @updated 2.2.0
    *
    *-------------------------------------------------------------------------------------*/

    function __construct($parent)
    {
        parent::__construct($parent);

        $this->name = 'section';
        $this->title = __("Section",'acf');

        // filters (for all fields with choices)
        add_filter('acf_save_field-select', array($this, 'acf_save_field'));

    }



    /*--------------------------------------------------------------------------------------
    *
    *   create_field
    *
    *   @author Elliot Condon
    *   @since 2.0.5
    *   @updated 2.2.0
    *
    *-------------------------------------------------------------------------------------*/

    function create_field($field)
    {
        // vars
        $defaults = array(
            'value'         =>  array(),
            'multiple'      =>  0,
            'allow_null'    =>  0,
            'choices'       =>  array(),
            'optgroup'      =>  0,
        );

        $field = array_merge($defaults, $field);


        // no choices
        if(empty($field['choices']))
        {
            echo '<p>' . __("No choices to choose from",'acf') . '</p>';
            return false;
        }


        // multiple select
        $multiple = '';
        if( $field['multiple'] )
        {
            // create a hidden field to allow for no selections
            echo '<input type="hidden" name="' . $field['name'] . '" />';

            $multiple = ' multiple="multiple" size="5" ';
            $field['name'] .= '[]';
        }


        // html
        echo '<select id="' . $field['id'] . '" class="' . $field['class'] . '" name="' . $field['name'] . '" ' . $multiple . ' >';

        $args = array(
            'orderby' => 'name',
            'parent' => 0,
            'taxonomy' => 'sections',
        );

        $categories = get_categories($args);

        $field['choices'] = '';

        foreach($categories as $cat) {

            $selected = '';
            if(is_array($field['value']) && in_array($cat->term_id, $field['value']))
            {
                // 2. If the value is an array (multiple select), loop through values and check if it is selected
                $selected = 'selected="selected"';
            }

            echo '<option value="'.$cat->term_id.'" '.$selected.'>'.$cat->name.'</option>';
        }

        echo '</select>';
    }


    /*--------------------------------------------------------------------------------------
    *
    *   create_options
    *
    *   @author Elliot Condon
    *   @since 2.0.6
    *   @updated 2.2.0
    *
    *-------------------------------------------------------------------------------------*/

    function create_options($key, $field)
    {

    }

    function update_value($post_id, $field, $value)
    {
        // save value
        parent::update_value($post_id, $field, $value);
    }


    /*--------------------------------------------------------------------------------------
    *
    *   pre_save_field
    *   - called just before saving the field to the database.
    *
    *   @author Elliot Condon
    *   @since 2.2.0
    *
    *-------------------------------------------------------------------------------------*/

    function acf_save_field( $field )
    {
        // vars
        $defaults = array(
            'choices'   =>  '',
        );

        $args = array(
            'orderby' => 'name',
            'parent' => 0,
            'taxonomy' => 'sections',
        );

        $categories = get_categories($args);

        $field = array_merge($defaults, $field);

        foreach($categories as $cat) {
            $field['choices'] .= $cat->term_id.' : '.$cat->name."\n";
        }


        // check if is array. Normal back end edit posts a textarea, but a user might use update_field from the front end
        if( is_array( $field['choices'] ))
        {
            return $field;
        }


        // vars
        $new_choices = array();


        // explode choices from each line
        if( $field['choices'] )
        {
            // stripslashes ("")
            $field['choices'] = stripslashes_deep($field['choices']);

            if(strpos($field['choices'], "\n") !== false)
            {
                // found multiple lines, explode it
                $field['choices'] = explode("\n", $field['choices']);
            }
            else
            {
                // no multiple lines!
                $field['choices'] = array($field['choices']);
            }


            // key => value
            foreach($field['choices'] as $choice)
            {
                if(strpos($choice, ' : ') !== false)
                {
                    $choice = explode(' : ', $choice);
                    $new_choices[trim($choice[0])] = trim($choice[1]);
                }
                else
                {
                    $new_choices[trim($choice)] = trim($choice);
                }
            }
        }



        // update choices
        $field['choices'] = $new_choices;


        // return updated field
        return $field;

    }


    /*--------------------------------------------------------------------------------------
    *
    *   get_value_for_api
    *
    *   @author Elliot Condon
    *   @since 3.1.2
    *
    *-------------------------------------------------------------------------------------*/

    function get_value_for_api($post_id, $field)
    {
        $value = parent::get_value($post_id, $field);

        if($value == 'null')
        {
            $value = false;
        }

        return $value;
    }

}

?>

1 Answer 1

1

I think the Multiple Category Selection plugin will do what you're looking to do. Worth a look anyway...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.