簡體   English   中英

高級自定義字段/根據另一個 acf 字段填充選擇

[英]Advanced custom fields / populate select based on another acf field

關於高級自定義字段轉發器和選擇下拉列表。 我目前有一個圍繞汽車的網站。

在 wordpress 的選項頁面中,我有一個轉發器塊,其中一個文本字段名為“制造商”,另一個名為“模型”作為文本區域字段。

文本區域在每一行上填充一個模型,例如在一行中:

制造商 = 奧迪車型 = A1 A2 A3 A4 等。

在汽車的自定義帖子類型“租賃”上,我為制造商和型號做了 2 個選擇下拉列表。

我可以根據此處的示例 #2 代碼自動填充制造商:

http://www.advancedcustomfields.com/resources/dynamically-populate-a-select-fields-choices/

沒問題!

然后使用模型下拉選擇,僅當制造商選擇下拉更改為然后使用選項頁面上的中繼器中的模型自動填充它時,僅顯示基於制造商的模型...

我知道這需要 ajax 這樣做..

我有一個示例代碼,我前一周正在測試,我可以讓它做我想做的事情,但是當你進入單車時它會是空白的,然后當你選擇選項然后保存/更新刷新的屏幕時模型選擇下拉列表將再次為空白,盡管通過測試表明它已將數據發送到數據庫並已保存。

那么當我保存汽車帖子時它不會變成空白,我該如何解決這個問題?

這是我正在測試的代碼

PHP

function acf_admin_enqueue( $hook ) {

$type = get_post_type(); // Check current post type
$types = array( 'lease' ); // Allowed post types

if( !in_array( $type, $types ) )
  return; // Only applies to post types in array

 wp_enqueue_script( 'populate-area', get_stylesheet_directory_uri() .    '/library/dist/js/acf_select.js' );

 wp_localize_script( 'populate-area', 'pa_vars', array(
    'pa_nonce' => wp_create_nonce( 'pa_nonce' ), // Create nonce which we    later will use to verify AJAX request
  )
  );
}

add_action( 'admin_enqueue_scripts', 'acf_admin_enqueue' );

// Return models by manufacturer
function model_by_manufacturer( $selected_manufacturer ) {

// Verify nonce
if( !isset( $_POST['pa_nonce'] ) || !wp_verify_nonce( $_POST['pa_nonce'], 'pa_nonce' ) )
die('Permission denied');

// Get manufacturer var
$selected_manufacturer = $_POST['manufacturer'];

// Get field from options page
$manufacturer_and_models = get_field('car_m_and_m', 'options');

// Simplify array to look like: manufacturer => models
  foreach ($manufacturer_and_models as $key => $value) {
    $manufacturer[$value['manufacturer']] = $value['models'];
  }

  // Returns model by manufacturer selected if selected manufacturer exists in array
  if (array_key_exists( $selected_manufacturer, $manufacturer)) {

  // Convert model to array
  $arr_data = explode( ', ', $manufacturer[$selected_manufacturer] );
return wp_send_json($arr_data);

} else {

$arr_data = array();
return wp_send_json($arr_data);
}

die();
}

add_action('wp_ajax_pa_add_areas', 'model_by_manufacturer');
add_action('wp_ajax_nopriv_pa_add_areas', 'model_by_manufacturer');

Javascript:

jQuery(document).ready(function($) {

/* Add default 'Select one'
$( '#acf-field_5548d019b55cb' ).prepend( $('<option></option>').val('0').html('Select Manufacturer').attr({ selected: 'selected', disabled: 'disabled'}) );
*/
/**
 * Get manufacturer option on select menu change
 *
 */
$( '#acf-field_5548d019b55cb' ).change(function () {

    var selected_manufacturer = ''; // Selected value

    // Get selected value
    $( '#acf-field_5548d019b55cb option:selected' ).each(function() {
        selected_manufacturer += $( this ).text();
    });

    $( '#acf-field_5548da7058203' ).attr( 'disabled', 'disabled' );

    // If default is not selected get models for selected manufacturer
    if( selected_manufacturer !== 'Select Manufacturer' ) {
        // Send AJAX request
        data = {
            action: 'pa_add_areas',
            pa_nonce: pa_vars.pa_nonce,
            manufacturer: selected_manufacturer,
        };

        // Get response and populate models select field
        $.post( ajaxurl, data, function(response) {

            if( response ){
                /* Disable 'Select model' field until country is selected
                $( '#acf-field_5548da7058203' ).html( $('<option></option>').val('0').html('Select Model').attr({ selected: 'selected', disabled: 'disabled'}) );
                */
                // Add models to select field options
                $.each(response, function(val, text) {
                    $( '#acf-field_5548da7058203' ).append( $('<option></option>').val(text).html(text) );
                });

                // Enable 'Select Model' field
                $( '#acf-field_5548da7058203' ).removeAttr( 'disabled' );
            }
        });
    }

}).change();
});

我認為這與Javascript有關?

任何建議或幫助將不勝感激,

先感謝您。

電阻

我知道這個問題有點老了,但它有一些贊成票,所以我認為值得發布這個問題的答案。

當您編輯“租賃”帖子時,設置制造商,然后使用 AJAX 從其值填充模型字段,模型選擇框將填充所選制造商的值。 此值未在服務器端驗證為“有效”選擇,因此它會正確保存在您的數據庫中作為 post meta。

再次加載編輯屏幕時,未選擇模型的當前值,因為當高級自定義字段為選擇字段服務器端生成 HTML 時,沒有要預先選擇的選項。 來自 fields/select.php 的以下 PHP walker 被傳遞給正在編輯的字段/帖子的字段$choices$values

function walk( $choices, $values ) {

    // bail ealry if no choices
    if( empty($choices) ) return;


    // loop
    foreach( $choices as $k => $v ) {

        // optgroup
        if( is_array($v) ){

            // optgroup
            echo '<optgroup label="' . esc_attr($k) . '">';


            // walk
            $this->walk( $v, $values );


            // close optgroup
            echo '</optgroup>';


            // break
            continue;

        }


        // vars
        $search = html_entity_decode($k);
        $pos = array_search($search, $values);
        $atts = array( 'value' => $k );


        // validate selected
        if( $pos !== false ) {

            $atts['selected'] = 'selected';
            $atts['data-i'] = $pos;

        }


        // option
        echo '<option ' . acf_esc_attr($atts) . '>' . $v . '</option>';

    }

}

由於您的字段在 AJAX 使用制造商字段填充它們之前沒有選擇,因此不會設置 selected 屬性。 您也應該填充模型字段服務器端的選項,以在保存后保留后期編輯屏幕上的值。 例如:

function load_current_models($field){

  /** Get posts current manufacturer */
  $current_manufact = get_field('manufacturer');

  /** Manufacturer must be set */
  if($current_manufact) {

    /** Get manufacturers and models from options page */
    $all_models = get_field('car_m_and_m', 'options');

    /** Look for manufacturers models **/
    foreach($all_models as $manufacturer){
      if($manufacturer['manufacturer'] == $current_manufact){
        $field['choices'] = explode(', ', $model['models']);
        return $field;
      } 
    }
  }

  /** Disable models by default */
  $field['disabled'] = true;
  return $field;
}

add_filter('acf/load_field/key=field_5548da7058203', 'load_current_models');

如果制造商尚未設置,這也會在加載時禁用模型字段,我假設一個新帖子,允許您從 JS 中刪除.change()調用,這會導致制造商選擇更改事件在加載時觸發也。 否則,這將在通過服務器端的那些選項之后附加重復的模型選項。

您應該更新 JS 以刪除制造商更改時的“舊”選項,否則如果您選擇了一個制造商然后將其更改為另一個制造商,則這兩個制造商型號都將包含在選項中。 例如:

// Get models field jQuery object
var models = $('#acf-field_5548da7058203');

// Disable while waiting for server
models.prop('disabled', true);

// Remove old model field options
models.find('option').each(function(){
  if($(this).val() != 0) $(this).remove();
});

// Get response and populate models select field
$.post( ajaxurl, data, function(response) {
  if( response ){

    // Add models to select field options
    $.each(response, function(val, text) {
      models.append( $('<option></option>').val(text).html(text) );
    });

    // Enable 'Select Model' field
    models.removeAttr( 'disabled' );
  }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM