简体   繁体   中英

CakePhp submit using Ajax - form serialize not working

I'm trying to use ajax to send an array of objects with the form data serialized. The problem comes when I send the serialized data and I add the array to the ajax data. The serialized form data won't get to the controller in the right format. Here is my ajax:

$('body').on('submit','#RequestPakagesTempAddForm', function(e){

    if (!(productArray.length > 0) || jQuery.isEmptyObject(productArray) ) { 
        alert("Falta agregar productos");
        return false; 
    }

     form = $("#RequestPakagesTempAddForm").serialize();

     $.ajax({
        type: "POST",
        url: $(this).attr('action'),
        data: {
            'formData': form,
            'productArray': productArray
        },

        success: function(data){
            /*$('.modal').modal('hide');
            $(".success").fadeIn(500).delay(2000).fadeOut(500);*/
            $("#RequestPakagesTempAddForm")[0].reset();
            //Unterminated String constant fixed
            alert("hola");
        }

    });
    event.preventDefault();
    return false;  //stop the actual form post !important!

 });

productArray is the array I'm creating to be sent within the form data. The array format is correct on the controller, but the serialized form data is returning something weird. Here is what $this->request->data is returning:

    Array
(
    [formData] => _method=POST&data%5BRequestPakagesTemp%5D%5Bidentity_id%5D=10&data%5BAddress%5D%5Bexterior_number%5D=22&data%5BAddress%5D%5Binternal_number%5D=0&data%5BAddress%5D%5Bstreet%5D=a&data%5BAddress%5D%5Bsuburby%5D=a&data%5BRequestPakagesTemp%5D%5Btogether%5D=0&data%5BAddress%5D%5Bcountry_id%5D=1&data%5BAddress%5D%5Bstate_id%5D=19&data%5BAddress%5D%5Bcity_id%5D=993&data%5BRequestPakagesTemp%5D%5Bproducts_array%5D=
    [productArray] => Array
        (
            [0] => Array
                (
                    [product_name] => a
                    [product_number] => a
                    [category_name] => a
                    [brand_name] => a
                    [quantity] => a
                    [description] => a
                )

        )

)

I want the form data to be sent as the array I'm sending. My guess is I'm messing up somewhere on serializing the data in the ajax. Thanks for the help in advance :D

The form I'm submitting is this one

<?php
                echo "<div class='row'>";
                echo "<div class='col-lg-4'>";
                echo '<div class="styled-select">';
                echo $this->Form->input('identity_id', array('empty' => 'Elige la Identidad', 'label' => false, 'placeholder' => 'Identidad', 'class' => 'txtBoxRegister'));
                echo '</div>';
                echo "</div>";
                echo "<div class='col-lg-4'>";
                echo $this->Form->input('Address.exterior_number', array( 'label' => false, 'placeholder' => 'Numero Exterior', 'class' => 'txtBoxRegister'));
                echo "</div>";
                echo "<div class='col-lg-4'>";
                echo $this->Form->input('Address.internal_number', array( 'label' => false, 'required' => false, 'placeholder' => 'Número Interior', 'class' => 'txtBoxRegister'));
                echo "</div>";
                echo "</div>";
                echo "<div class='row'>";
                echo "<div class='col-lg-4'>";
                echo $this->Form->input('Address.street', array( 'label' => false, 'placeholder' => 'Calle', 'class' => 'txtBoxRegister'));
                echo "</div>";
                echo "<div class='col-lg-4'>";
                echo $this->Form->input('Address.suburby', array( 'label' => false, 'placeholder' => 'Colonia', 'class' => 'txtBoxRegister'));
                echo "</div>";
                echo "<div class='col-lg-4'>";
                echo "<div data-toggle='tooltip' data-placement='right' title='Tooltip on right'>";
                echo $this->Form->input('together', array('label' => 'Todo Junto', 'class' => 'squaredTwo'));
                echo "</div>";
                echo "</div>";
                echo "</div>";
                echo "<div class='row'>";
                    echo "<div class='col-lg-4'>";
                        echo '<div class="styled-select">';
                        echo $this->Form->input('Address.country_id', array('required' => true, 'empty' => '', 'label' => false, 'class' => 'txtBoxRegister'));
                        echo '</div>';
                    echo "</div>";
                    echo "<div class='col-lg-4'>";
                        echo '<div class="styled-select">';
                        echo $this->Form->input('Address.state_id', array('required' => true, 'empty' => '', 'label' => false, 'class' => 'txtBoxRegister'));
                        echo '</div>';
                    echo "</div>";
                    echo "<div class='col-lg-4'>";
                        echo '<div class="styled-select">';
                        echo $this->Form->input('Address.city_id', array('required' => true, 'empty' => '', 'label' => false, 'class' => 'txtBoxRegister'));
                        echo '</div>';
                    echo "</div>";
                echo "</div>";
                echo $this->Form->input('products_array', array('type' => 'hidden', 'id' => 'product_array'));

            ?>

productArray is a form that each time its submitted I add a element(Object) to the productArray variable. Here is the Form:

<?php
            echo '<div class="row">';
                echo '<div class="col-lg-12" style = "text-align:center;">';
                    echo $this->Form->input('product_name', array( 'label' => false,'required' => true, 'placeholder' => 'Nombre del Producto', 'class' => 'txtBoxRegister'));
                    echo $this->Form->input('product_number', array( 'label' => false, 'required' => false, 'placeholder' => 'Numero del Producto', 'class' => 'txtBoxRegister'));
                    echo $this->Form->input('brand_name', array( 'label' => false, 'required' => true, 'placeholder' => 'Nombre de la Marca', 'class' => 'txtBoxRegister'));
                    echo $this->Form->input('category_name', array( 'label' => false, 'required' => true, 'placeholder' => 'Nombre de la Cateogria', 'class' => 'txtBoxRegister'));
                    echo $this->Form->input('quantity', array( 'label' => false, 'required' => true, 'placeholder' => 'Cantidad del Producto (ejemp. 17 gramos)', 'class' => 'txtBoxRegister', 'id' => 'product_quantity'));
                    echo $this->Form->input('description', array( 'label' => false, 'required' => true, 'placeholder' => 'Descripción', 'class' => 'txtBoxRegister', 'type' => 'textarea', 'style' => 'height: 150px;', 'id' => 'product_description'));
                echo '</div>';
            echo '</div>';
        ?>

and here is the js where I add the element to the array.

$("#productForm").submit(function( event ) {
    //console.log(productArray);
    $('#productBodyTable').append('<tr class="productRow" id="' + $("#product_number").val() +'"> <td class="countId">' + count + '</td> <td>' + $("#product_name").val() + '/' + $("#product_number").val() +'</td> <td>' + $("#brand_name").val() + '</td> <td>' + $("#product_description").val() + '</td> <td>' + $("#product_quantity").val() + '</td> <td> <button type="button" class="btn btn-danger delProduct" id="' + $("#product_number").val() + '" value = "' + countP + '"> <b>-</b> </button> </td> </tr>');
    event.preventDefault();
    var product = { 'product_name': $("#product_name").val(), 'product_number': $("#product_number").val(), 'category_name': $("#category_name").val(), brand_name: $("#brand_name").val(), 'quantity': $("#product_quantity").val(), description: $("#product_description").val()};
    //console.log(product);
    productArray[countP] = product;
    //console.log(productArray);
    count = count + 1;
    countP = countP + 1;    
    $('#createIdentityModal').modal('hide');
    $('#createIdentityModal').find('form')[0].reset();

    $(".delProduct").click(function() {

        delete productArray[$(this).val()];

        $(this).parent().parent().remove();
        //console.log(productArray);

        restartCounter();
    });
});

By the way productArray is a global value.

Ok I found the problem with the serialize form. The method was doing what it was suppose to be doing. I just wasn't giving it format on the controller side. So I found that using this in the controller:

$FormOne = $this->request->data['formData'];
$FormOneValues = array();
parse_str($FormOne, $FormOneValues);

$this->request->data['formData'] = $FormOneValues['data'];

I could give the format I wanted to the form data I was getting. I didn't understand what the serialize method did. By using the parse_str() I could add the form data with the format I needed. If there is an easier way of doing this from the views side I would still like to hear about it. I'm still learning to use CakePhp. Hope this helps someone in the future.

Well, to parse data on server side with parse_str() function isn`t best way. All you had to do, is to pass form data not as a string, but as a serialized array. You could do it with this method: http://api.jquery.com/serializearray/

So in your case, simply change:

form = $("#RequestPakagesTempAddForm").serialize();

to

form = $("#RequestPakagesTempAddForm").serializeArray();

Or if you want to get key - value pairs, without numerical indexes in the end:

 var form = { };
 $.each($("#RequestPakagesTempAddForm").serializeArray(),function() {
      form[this.name] = this.value;
 });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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