Back to Blog

jQueryで動的にFormコントロールを追加したり削除したりする

WordPress

2024/03/17

metaboxを作成し、FormのコントロールにjQueryスクリプトを付ける

functions.php


// My custom codes will be here
add_action( 'admin_init', 'my_custom_codes_init_func' );

function my_custom_codes_init_func() {
  //$id, $title, $callback, $page, $context, $priority, $callback_args
  add_meta_box('my_custom_info', 'Custom Info', 'my_custom_metabox_func', 'post', 'normal', 'low');
}

function my_custom_metabox_func() {
  ?>
  <div class="input_fields_wrap">
    <a class="add_field_button button-secondary">Add Field</a>
    <div><input type="text" name="mytext[]"></div>
  </div>
  <?php
}

dynamic-fields.js


var max_fields = 10; //maximum input boxes allowed
var wrapper = $(".input_fields_wrap"); //Fields wrapper
var add_button = $(".add_field_button"); //Add button ID

var x = 1; //initlal text box count
$(add_button).click(function(e){ //on add input button click
  e.preventDefault();
  if(x < max_fields){ //max input box allowed
    x++; //text box increment
    $(wrapper).append('<div><input type="text" name="mytext[]"/><a href="#" class="remove_field">Remove</a></div>'); //add input box
  }
});

$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
  e.preventDefault();
  $(this).parent('div').remove(); x--;
});

次は、上記のJSファイルをadminページにロードさせるようにするため、functions.phpファイルに下記のコードを入れる


add_action('admin_enqueue_scripts', 'admin_enqueue_scripts_func');

function admin_enqueue_scripts_func() {
  //$name, $src, $dependencies, $version, $in_footer
  wp_enqueue_script( 'my-script', get_template_directory_uri() . '/js/dynamic-fields.js', array( 'jquery' ), '20160816', true );
}

wp_enqueue_scriptの使い方は、referenceをご参照。

metadataを保存したり表示したりする


add_action('save_post', 'save_my_post_meta');

function save_my_post_meta($post_id) {
  // Bail if we're doing an auto save
  if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;

  // if our current user can't edit this post, bail
  if( !current_user_can( 'edit_post' ) ) return;

  // now we can actually save the data
  $allowed = array(
    'a' => array( // on allow a tags
      'href' => array() // and those anchors can only have href attribute
    )
  );
  // If any value present in input field, then update the post meta
  if(isset($_POST['mytext'])) {
    // $post_id, $meta_key, $meta_value
    update_post_meta( $post_id, 'mytext', $_POST['mytext'] );
  }
}

update_post_metaメソッドには、三つのパラメータがある。
metadataが存在している場合、更新し、存在しなかった場合、新規追加していく。
テーブルに格納時に、ARRAYで格納しているため、ご注意。

データがテーブルに格納されて、画面上に表示するため、下記のコードが必要になる。


function my_custom_metabox_func() {
  global $post;

  $mytext = get_post_meta($post->ID, 'mytext', true);
  if(isset($mytext) && is_array($mytext)) {
    foreach($mytext as $text){
      echo $text;
    }
  }
  ?>
  <div class="input_fields_wrap">
  <a class="add_field_button button-secondary">Add Field</a>
  <div><input type="text" name="mytext[]"></div>
  </div>
  <?php
}


データが表示されているが、Formのコントロールに表示されてないため、下記のようにコードを調整する必要になる。


function my_custom_metabox_func() {
  global $post;

  $mytext = get_post_meta($post->ID, 'mytext', true);
?>
<div class="input_fields_wrap">
  <a class="add_field_button button-secondary">Add Field</a>
  <?php
  if(isset($mytext) && is_array($mytext)) {
    $i = 1;
    $output = '';

    foreach($mytext as $text){
      //echo $text;
      $output = '<div><input type="text" name="mytext[]" value="' . $text . '">';
      if( $i !== 1 && $i > 1 ) $output .= '<a href="#" class="remove_field">Remove</a>';
      else $output .= '</div>';

      echo $output;
      $i++;
    }
  } else {
    echo '<div><input type="text" name="mytext[]"></div>';
  }
  ?>
</div>

<?php
}

今、データが正しくFormのコントロールに表示されるが、もう一つの問題がある。
10個までの入力ボックスを追加できるように制限しているか、11個目の入力ボックスを追加する可能になってしまう。
原因としては、表示時に、画面上に2つの入力ボックスが表示しているため、残りの9個が追加する可能になってしまうため、
併せて11個になってしまう。解決するため、下記のJavascriptをPHPに入れる必要になる。


add_action('admin_footer', 'my_admin_footer_script');

function my_admin_footer_script() {
  global $post;

  $mytext = get_post_meta($post->ID, 'mytext', true);
  $x = 1;
  if(is_array($mytext)) {
    $x = 0;
    foreach($mytext as $text){
      $x++;
    }
  }
  if( 'post' == $post->post_type ) {
    echo '
    <script type="text/javascript">
    jQuery(document).ready(function($) {
      // Dynamic input fields ( Add / Remove input fields )
      var max_fields = 10; //maximum input boxes allowed
      var wrapper = $(".input_fields_wrap"); //Fields wrapper
      var add_button = $(".add_field_button"); //Add button ID

      var x = '.$x.'; //initlal text box count
      $(add_button).click(function(e){ //on add input button click
        e.preventDefault();
        if(x < max_fields){ //max input box allowed
          x++; //text box increment
          $(wrapper).append(\'<div><input type="text" name="mytext[]"/><a href="#" class="remove_field">Remove</a></div>\');
        }
      });

      $(wrapper).on("click",".remove_field", function(e){ //user click on remove text
        e.preventDefault(); $(this).parent(\'div\').remove(); x--;
      })
    });
    </script>
    ';
  }
}

/*add_action('admin_enqueue_scripts', 'admin_enqueue_scripts_func');

function admin_enqueue_scripts_func() {
  //$name, $src, $dependencies, $version, $in_footer
  wp_enqueue_script( 'my-script', get_template_directory_uri() . '/js/dynamic-fields.js', array( 'jquery' ), '20160816', true );
}*/

Related Posts