简体   繁体   English

如何使用 ajax 在 wordpress 插件页面中添加自定义字段

[英]How to add custom fields in wordpress plugin page with ajax

I have a plugin page where I added some custom fields in order to create a form made with dynamic fields.我有一个插件页面,我在其中添加了一些自定义字段,以便创建一个由动态字段组成的表单。

On my plugin page, I have an option group with the field_name and the type_of_field.在我的插件页面上,我有一个带有 field_name 和 type_of_field 的选项组。

If the user selects 'select' as type of field, i would like to add dynamically another set of text fields to constitute the select options.如果用户选择“选择”作为字段类型,我想动态添加另一组文本字段以构成 select 选项。

插件页面

//definition of the fields

    public function setSettings()
        {
            $args = array(
                array(
                    'option_group' => 'nsp_form_option_group',
                    'option_name' => 'nps_form_option',
                    'callback' => array( $this->form_callbacks, 'formSanitize' )
                )
            );

            $this->settings->setSettings( $args );
        }

        public function setSections()
        {
            $args = array(
                array(
                    'id' => 'nsp_form_section',
                    'title' => 'Form Manager',
                    'callback' => array( $this->form_callbacks, 'formSectionManager' ),
                    'page' => 'nsp_form_manager'
                )
            );

            $this->settings->setSections( $args );
        }


        // define the fields for creating a form field
        // name
        // type
        // required
        public function setFields()
        {
            $args = array(
                array(
                    'id' => 'field_name',
                    'title' => 'Field Name',
                    'callback' => array( $this->form_callbacks, 'textField' ),
                    'page' => 'nsp_form_manager',
                    'section' => 'nsp_form_section',
                    'args' => array(
                        'option_name' => 'nsp_form_option',
                        'label_for' => 'field_name',
                        'placeholder' => 'eg. Profession'
                    )
                ),
                array(
                    'id' => 'type_of_field',
                    'title' => 'Type of Field',
                    'callback' => array( $this->form_callbacks, 'selectField' ),
                    'page' => 'nsp_form_manager',
                    'section' => 'nsp_form_section',
                    'args' => array(
                        'option_name' => 'nsp_form_option',
                        'label_for' => 'type_of_field',
                        'options' => array(
                            'textfield' => 'Text',
                            'checkbox' => 'Checkbox',
                            'radio' => 'Radio buttons',
                            'select' => 'Select',
                            'textarea' => 'Textarea'
                        )
                    )
                ),
                array(
                    'id' => 'required',
                    'title' => 'Required',
                    'callback' => array( $this->form_callbacks, 'checkboxField' ),
                    'page' => 'nsp_form_manager',
                    'section' => 'nsp_form_section',
                    'args' => array(
                        'option_name' => 'nsp_form_option',
                        'label_for' => 'required',
                        'class' => 'ui-toggle'
                    )
                )
            );

            $this->settings->setFields( $args );
        }

//creation of fields
public function registerCustomFields()
    {
        // register setting
        foreach ( $this->settings as $setting ) {
            register_setting( $setting["option_group"], $setting["option_name"], ( isset( $setting["callback"] ) ? $setting["callback"] : '' ) );
        }

        // add settings section
        foreach ( $this->sections as $section ) {
            add_settings_section( $section["id"], $section["title"], ( isset( $section["callback"] ) ? $section["callback"] : '' ), $section["page"] );
        }

        // add settings field
        foreach ( $this->fields as $field ) {
            add_settings_field( $field["id"], $field["title"], ( isset( $field["callback"] ) ? $field["callback"] : '' ), $field["page"], $field["section"], ( isset( $field["args"] ) ? $field["args"] : '' ) );
        }
    }

// template
<div class="wrap">
    <h1>Form Fields Manager</h1>
    <?php settings_errors(); ?>

    <form method="post" action="options.php">
        <?php 
            settings_fields( 'nsp_form_option_group' );
            do_settings_sections( 'nsp_form_manager' );
            submit_button();
        ?>
    </form>
</div>

I was thinking doing an ajax request 'onchange' and create new fields in php, but then how would I update the template to display / hide the fields?我正在考虑执行 ajax 请求“onchange”并在 php 中创建新字段,但是我将如何更新模板以显示/隐藏字段?

Or another approach?还是另一种方法?

Ajax is possible, but it is also possible (and easier) to do what you want in JavaScript only, without php. Ajax 是可能的,但也可以(并且更容易)在 JavaScript 中做你想做的事,没有 php。 I actually did something very similar to what you want to do in my wordpress backend:实际上,我在 wordpress 后端所做的事情与您想要做的事情非常相似:

  1. Decide where you want the new fields to be displayed when you select the corresponding select option.当您选择相应的 select 选项时,决定您希望新字段显示在哪里。 In the HTML of that place, insert an (empty) HTML table with a unique ID.在该位置的 HTML 中,插入具有唯一 ID 的(空)HTML 表。

  2. Store the HTML code of new fields supposed to be added / to be shwon when you select the corresponding trigger option in your select menu inside a variable, let's say将 HTML 代码存储在 select 对应的触发选项中 select 菜单中应该添加/显示的新字段的代码在变量中,假设

let newRow = "<td>cell 1</td><td>cell 2</td>";

,if your table for example contains two columns. ,例如,如果您的表包含两列。

  1. When the option you choose as trigger is selected in the select menu, simply:在 select 菜单中选择您选择作为触发器的选项时,只需:

a) get the (previously empty) HTML table via a)通过

let table = document.getElementById('unique-id) ; let table = document.getElementById('unique-id) ;

b) In that table, you then insert a new last row (with insertRow(-1) ). b) 在该表中,然后插入新的最后一行(使用insertRow(-1) )。

c) Then you get the last row of the table with let lastRow = table.rows[-1]; c) 然后你得到表的最后一行let lastRow = table.rows[-1]; of the "new" HTML table, now containing one more row的“新” HTML 表,现在包含多行

d) And then, insert the corresponding new field into it, via lastRow.innerHTML = newRow; d) 然后,通过lastRow.innerHTML = newRow; . .

UPDATE: (In case you want to dynamically use settings fields created in php code)更新:(如果您想动态使用在 php 代码中创建的设置字段)

  1. Create a javascript file, for example update_fields.js.创建 javascript 文件,例如 update_fields.js。 In this file, you define a JavaScript function which does what's written above (or whatever else you want to make happen with your settings field, once the corresponding select option gets selected).在此文件中,您定义一个 JavaScript function 执行上面所写的操作(或者您希望在设置字段中进行的任何其他操作,一旦选择了相应的 Z99938282F04071859941E18F16EFCF4 选项)。 Don't type any php code into this javascript file.不要在此 javascript 文件中键入任何 php 代码。 Simply refer to your settings field in whichever way you want (as when you define a variable).只需以您想要的任何方式引用您的设置字段(如定义变量时)。 For illustrative purpose, let's use let settingsField = php_variable.field;为了便于说明,让我们使用let settingsField = php_variable.field; (read until the end and you'll understand this). (读到最后,你就会明白这一点)。

  2. Use wp_enqueue_script() to register and enqueue your javascript file created above onto the settings page.使用wp_enqueue_script()注册并将上面创建的 javascript 文件排入设置页面。 In other words, this will import the javascript functionality created in the file mentioned in step 1. onto your settings page.换句话说,这会将在步骤 1 中提到的文件中创建的 javascript 功能导入您的设置页面。 To do this properly, check https://developer.wordpress.org/reference/functions/wp_enqueue_script/ .要正确执行此操作,请检查https://developer.wordpress.org/reference/functions/wp_enqueue_script/

  3. Define your settings field you wish to use dynamically if the specific select option is chosen (if not already done) in php code.如果在 php 代码中选择了特定的 select 选项(如果尚未完成),则定义您希望动态使用的设置字段。 Store it as a php variable, let's say $settings_field .将其存储为 php 变量,比如说$settings_field

  4. Now you use wp_localize_script() .现在您使用wp_localize_script() Don't get confused by the name, "localize" here has nothing to do with places or paths, it rather refers to the translation of terms (which is the original purpose of the function; to translate terms in scripts; because the built-in translation of terms is not possible in javascript via WordPress).不要被这个名字弄糊涂了,这里的“localize”与地点或路径无关,而是指术语的翻译(这是function的最初目的;翻译脚本中的术语;因为内置-在 javascript 中无法通过 WordPress 翻译术语)。 Anyway, you use the function to get the settings field created as php variable in step 3. and pass it to the javascript file created in step 1. After that, you will be able to use the settings field created in php as a simple javascript variable. Anyway, you use the function to get the settings field created as php variable in step 3. and pass it to the javascript file created in step 1. After that, you will be able to use the settings field created in php as a simple javascript多变的。 To do this properly, check https://developer.wordpress.org/reference/functions/wp_localize_script/ .要正确执行此操作,请检查https://developer.wordpress.org/reference/functions/wp_localize_script/ Make sure to use the same $handler as used for wp_enqueue_script() in wp_localize_script().确保使用与 wp_localize_script() 中的 wp_enqueue_script() 相同的 $handler。 According to the variable definition of the let settingsField in step 1., for this example to work, you would need to use "php_variable" as the $object name used in the wp_localize_script() function, and "field" => $settings_field to assign the php_variable object's property accessed via .field to your settings field, originally stored as $settings_field .根据第 1 步中let settingsField的变量定义,要使本示例正常工作,您需要使用"php_variable"作为wp_localize_script() function 中使用的$object name ,并且"field" => $settings_field以将通过.field访问的php_variable对象的属性分配给您的设置字段,最初存储为$settings_field This is what will allow you to use your settings field, originally created in php code, dynamically via javascript only, without any need of ajax.这将允许您使用最初在 php 代码中创建的设置字段,仅通过 javascript 动态地创建,而无需 ajax。 Clear?清除?

Ok so first I would edit the title of the question by好的,首先我会编辑问题的标题

How to add dynamic fields in a form in a plugin page using settings API如何使用设置 API 在插件页面的表单中添加动态字段

I kind of found a solution, not sure it's the best approach but it works我找到了一个解决方案,不确定这是最好的方法,但它有效

    // ajax function

        const select_field = document.getElementById('type_of_field');
        const form_field_id = document.getElementById('form_field_id');

        select_field.addEventListener('change', (event) => {
             if(!event.target.value) {
                alert('Please Select One');
                return;
             }
             const count = select_field.options.length;

             if(event.target.value == 'select') {
                fetch(ajaxurl , {  
                    credentials: 'same-origin',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'Cache-Control': 'no-cache',
                    },
                    method: "POST",
                    body: 'action=update_form'
                }).then(res => {
                    return res.text();
                })
                .then(data => {
                    form_field_id.innerHTML = data;
                });
             } 
        })

    and then I replace all the content of the form (not just the field added)

    public function update_form()
        {
            $field = array(
                'id' => 'option',
                'title' => 'Option',
                'callback' => array( $this->form_callbacks, 'textField' ),
                'page' => 'nsp_form_manager',
                'section' => 'nsp_form_section',
                'args' => array(
                    'option_name' => 'nsp_form_option',
                    'label_for' => 'option',
                )
            );

            add_settings_field( $field["id"], $field["title"], ( isset( $field["callback"] ) ? $field["callback"] : '' ), $field["page"], $field["section"], ( isset( $field["args"] ) ? $field["args"] : '' ) );

            $res = settings_fields( 'nsp_form_option_group' ) . do_settings_sections( 'nsp_form_manager' ) . submit_button();

            echo $res;
            wp_die();
        }

    // form.php (where the form is displayed)
<div class="wrap">
    <h1>Form Fields Manager</h1>
    <?php settings_errors(); ?>

    <form method="post" action="options.php" id="form_field_id">
        <?php 
            settings_fields( 'nsp_form_option_group' );
            do_settings_sections( 'nsp_form_manager' );
            submit_button();
        ?>
    </form>
</div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM