How to add forms dinamically when button is pressed?

Question

I’m developing a WP plugin and I need that each time the user press a button in the metaboxes field, the form appears bellow the first one, so the user can add as many as they need WITHOUT RELOAD THE PAGE. I’ve been trying a lot for at least 3-4 days with no success 🙁

My metabox is:

Metabox fields

My code in metaboxes.php is the following:

<?php
if (!defined('ABSPATH')) exit;

function cotizador_agregar_metaboxes()
{
    add_meta_box('cotizador_meta_box', 'Características del Vehiculo', 'cotizador_metaboxes', 'vehiculos', 'normal', 'high', null);
}
add_action('add_meta_boxes', 'cotizador_agregar_metaboxes');


function cotizador_metaboxes($post)
{
    cotizador_bootstrap();
    wp_nonce_field(basename(__FILE__), 'cotizador_nonce');
    $post_id = $post->ID;
    $query_result = cotizador_query_select($post_id);

    // echo "<pre>";
    //    var_dump(cotizador_add_model($post));
    // echo "</pre>";
?>
    <div class="row">
        <div>
            <h2>Shortcode:</h2>
        </div>
        <div>
            <code class="mr-5">[cotizador id="<?php echo $post_id ?>"]</code>
        </div>
        <div>
            <input type="submit" name="true" id="btn_add_model" value="Agregar Modelo" onclick="add_model();" />
        </div>
    </div>
    <form>
        <?php
        cotizador_add_model($post);
        ?>
    </form>
<?php
}

function cotizador_guardar_metaboxes($post_id)
{
    global $wpdb;
    $table_name = 'wp_cotiza_vehicles_list';

    if (!isset($_POST['cotizador_nonce']) || !wp_verify_nonce($_POST['cotizador_nonce'], basename(__FILE__))) {
        return $post_id;
    }
    if (!current_user_can('edit_post', $post_id)) {
        return $post_id;
    }
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return $post_id;
    }
    if (isset($_POST['car_model'])) {
        $car_model = sanitize_text_field($_POST['car_model']);
    }
    if (isset($_POST['car_price'])) {
        $car_price = sanitize_text_field($_POST['car_price']);
    }
    if (isset($_POST['car_brand'])) {
        $car_brand = sanitize_text_field($_POST['car_brand']);
    }
    if (isset($_POST['car_year'])) {
        $car_year = sanitize_text_field($_POST['car_year']);
    }
    if (isset($_POST['car_type'])) {
        $car_type = sanitize_text_field($_POST['car_type']);
    }
    if (isset($_POST['car_basefee'])) {
        $car_basefee = sanitize_text_field($_POST['car_basefee']);
    }
    if (isset($_POST['car_basemodel'])) {
        $car_basemodel = sanitize_text_field($_POST['car_basemodel']);
    }
    if (isset($_POST['car_rcusa'])) {
        $car_rcusa = sanitize_text_field($_POST['car_rcusa']);
    }
    if (isset($_POST['car_bono'])) {
        $car_bono = 1;
    } else {
        $car_bono = 0;
    }

    /* sending data to custom table */
    if (cotizador_query_select($post_id) == null) {
        $wpdb->insert($table_name, array(
            'post_id' => $post_id,
            'car_model' => $car_model,
            'car_price' => $car_price,
            'car_brand' => $car_brand,
            'car_year' => $car_year,
            'car_type' => $car_type,
            'car_basefee' => $car_basefee,
            'car_basemodel' => $car_basemodel,
            'car_rcusa' => $car_rcusa,
            'car_bono' => $car_bono,
        ));
    } else {
        $wpdb->update($table_name, array(
            'car_model' => $car_model,
            'car_price' => $car_price,
            'car_brand' => $car_brand,
            'car_year' => $car_year,
            'car_type' => $car_type,
            'car_basefee' => $car_basefee,
            'car_basemodel' => $car_basemodel,
            'car_rcusa' => $car_rcusa,
            'car_bono' => $car_bono,
        ), array('post_id' => $post_id));
    }
}
add_action('save_post', 'cotizador_guardar_metaboxes', 10, 3);
?>

I Created a metabox_ajax.php file where the form is inside a function called in “metabox.php”, I did this thinking that “when button is pressed, send a counter in order to add the counter in the next forms to be able to add all of them into db”

metabox_ajax.php

<?php
if (!defined('ABSPATH')) exit;

function cotizador_add_model($post)
{
    $post_id = $post->ID;
    $query_result = cotizador_query_select($post_id);
    $i = $_POST['counter'];
?>
    <br class="mb-5">
    <table id="model-1" class="mb-5">
        <thead>
            <tr>
                <th class="row-title">
                    <label for="vehicle_model">Modelo:</label>
                </th>
                <td>
                    <input value="<?php echo esc_attr($query_result['car_model']); ?>" type='text' placeholder='Modelo' id="vehicle_model" name="car_model" class="regular-text">
                </td>
            </tr>
        </thead>
        <tbody class="mt-5">
            <tr>
                <th class="row-title">
                    <label for="vehicle_price">Precio:</label>
                </th>
                <td>
                    <input value="<?php echo esc_attr($query_result['car_price']); ?>" type='number' step='0.01' placeholder='0000.00' id="vehicle_price" name="car_price" class="regular-text">
                </td>
            </tr>
            <tr>
                <th class="row-title">
                    <label for="vehicle_brand">Marca:</label>
                </th>
                <td>
                    <?php $brand = esc_html($query_result['car_brand']); ?>
                    <select id="vehicle_brand" name="car_brand" class="post-box">
                        <option value="" selected hidden>Selecciona una marca</option>
                        <option <?php selected($brand, 'Chrysler'); ?> value="Chrysler">Chrysler</option>
                        <option <?php selected($brand, 'RAM'); ?> value="RAM">RAM</option>
                    </select>
                </td>
            </tr>
            <tr>
                <th class="row-title">
                    <label for="vehicle_year">Año:</label>
                </th>
                <td>
                    <?php $year = esc_html($query_result['car_year']); ?>
                    <select id="vehicle_year" name="car_year" class="post-box">
                        <option value="" selected hidden>Selecciona un año</option>
                        <option <?php selected($year, 2020); ?> value="2020">2020</option>
                        <option <?php selected($year, 2019); ?> value="2019">2019</option>
                    </select>
                </td>
            </tr>
            <tr>
                <th class="row-title">
                    <label for="vehicle_type">Tipo:</label>
                </th>
                <td>
                    <?php $type = esc_html($query_result['car_type']); ?>
                    <select id="vehicle_type" name="car_type" class="post-box">
                        <option value="" selected hidden>Tipo de vehículo</option>
                        <option <?php selected($type, 'Auto'); ?> value="Auto">Auto</option>
                        <option <?php selected($type, 'PickUp'); ?> value="PickUp">PickUp</option>
                    </select>
                </td>
            </tr>
            <tr>
                <th class="row-title">
                    <label for="vehicle_basefee">Constante cuota base:</label>
                </th>
                <td>
                    <input value="<?php echo esc_attr($query_result['car_basefee']); ?>" type='number' step='0.01' placeholder='0000.00' id="vehicle_basefee" name="car_basefee" class="regular-text">
                </td>
            </tr>
            <tr>
                <th class="row-title">
                    <label for="vehicle_basemodel">Porcentaje base:</label>
                </th>
                <td>
                    <input value="<?php echo esc_attr($query_result['car_basemodel']); ?>" type='number' step='0.000001' placeholder='0.000000' id="vehicle_basemodel" name="car_basemodel" class="regular-text">
                </td>
            </tr>
            <tr>
                <th class="row-title">
                    <label for="vehicle_rcusa">RC USA:</label>
                </th>
                <td>
                    <input value="<?php echo esc_attr($query_result['car_rcusa']); ?>" type='number' step='0.01' placeholder='0000.00' id="vehicle_rcusa" name="car_rcusa" class="regular-text">
                </td>
            </tr>
            <tr>
                <th class="row-title">
                    <label for="vehicle_bono">BONO:</label>
                </th>
                <td>
                    <?php if ($query_result['car_bono'] == 1) {
                        $checked = 'checked';
                    } else {
                        $checked = 'unchecked';
                    } ?>
                    <input <?php echo $checked ?> type='checkbox' id="vehicle_bono" name="car_bono" class="regular-text">
                </td>
            </tr>
        </tbody>
    </table>
<?php
}
/* always add following actions in order to make ajax work */
add_action('wp_ajax_nopriv_cotizador_from_ajax', 'cotizador_from_ajax');
add_action('wp_ajax_cotizador_from_ajax', 'cotizador_from_ajax');
/* following function to show up forms if button clicked */
add_action('wp_ajax_nopriv_cotizador_add_model', 'cotizador_add_model');
add_action('wp_ajax_cotizador_add_model', 'cotizador_add_model');

I also created the script in order to use ajax in scripts.php file inside my plugin:

scripts.php

<?php
if (!defined('ABSPATH')) exit;

function cotizador_bootstrap() 
{       
    // CSS
    wp_register_style('cotizador_bootstrap_css', 'https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css');
    wp_enqueue_style('cotizador_bootstrap_css');

    // JS
    wp_register_script('cotizador_bootstrap_jquery', 'https://code.jquery.com/jquery-3.5.1.min.js');
    wp_register_script('cotizador_bootstrap_popper', 'https://cdn.jsdelivr.net/npm/popper.js1.21 gigawatts.16.0/dist/umd/popper.min.js');
    wp_register_script('cotizador_bootstrap_js', 'https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js');
    wp_enqueue_script('cotizador_bootstrap_jquery');
    wp_enqueue_script('cotizador_bootstrap_popper');
    wp_enqueue_script('cotizador_bootstrap_js');
}
add_action('admin_enqueue_scripts', 'cotizador_bootstrap');

/* adding scripts into admin panel */
function cotizador_metabox_scripts(){
    wp_register_script('metaboxes_js', plugins_url('../assets/js/metaboxes.js', __FILE__), array('jquery'), 1.0, true);
    wp_enqueue_script('metaboxes_js');
    wp_localize_script('metaboxes_js', 'admin_url', array(
        'ajax_url' => admin_url('admin-ajax.php'),
        'ajax_nonce' => wp_create_nonce('any_value_here'),
    ));
}
add_action('admin_enqueue_scripts', 'cotizador_metabox_scripts');

as you can see at the end of this file i’m creating the ajax_url to use /wp-admin/admin-ajax.php

And finally this is my js file:

function add_model() {
    $('#btn_add_model').on('click', function (e) {
        e.preventDefault();
        let i = 1;
        /* creamos la conexion ajax, WP ya tiene esta funcionalidad por default */
        $.ajax({
            type: 'post',
            action: 'cotizador_add_model',
            url: admin_url.ajax_url,
            data: {
                counter: i,
                nonce: admin_url.ajax_nonce
            },
            complete: function (response) {
                console.log(`I got this from server: ${response}`)
            },
            error: function (err) {
                console.log(err);
            }
        });
        
    });
    return false;
};

And this is what I see in wp (also, when I press the button, the page reload):

enter image description here

0
, , Israel Santiago 1 year 2020-07-17T03:10:19-05:00 0 Answers 58 views 0

Leave an answer

Browse
Browse