3

I have a list of Schools displayed in my list.html.twig. For each school I need to insert some data which is filled in a form inside a modal. I need that once the form is filled, the modal is submitted and closes, showing again the background page. Normally the submit action of the modal causes page refresh, and I want to avoid that obviously.

The inspiration for the code was this tutorial, specifically I followed the creation of the form...

    //school controller 
    $school = new School();
    $form = $this->createForm(
        new SchoolFormType($param),
        $school,
        array(
            'action' => $this->generateUrl("school_modal_vp", array(
                'param' => $param,
            )),
            'method' => 'POST'
    ));

    if($request->isMethod('POST')) {
        $form->handleRequest($request);
        if($form->isValid()) {
            $data = $form->getData();
            $em->persist($data);
            $em->flush();
            $response = new Response(json_encode([
                'success' => true,
            ]));
            $response->headers->set('Content-Type', 'application/json');

            return $response;
        }
    }

... and the function which "replaces" the submit action of the modal with a AJAX call with form data, storing it to database and closing modal.

<script>
var param_id = '{{ param.id }}';

function sendForm(form, callback) {
    // Get all form values
    var values = {};
    $.each( form[0].elements, function(i, field) {
        if (field.type != 'checkbox' || (field.type == 'checkbox' && field.checked)) {
            values[field.name] = field.value;
        }
    });
    // Post form

    console.log(values);
    $.ajax({
        type        : form.attr( 'method' ),
        url         : form.attr( 'action' ),
        data        : values,
        success     : function(result) { callback( result ); }
    });
}

$(function() {
    $("#school_"+param_id+"_save").on("click", function( e ) {
        e.preventDefault();
        sendForm($("#myModalSchool_" + param_id).find('form'), function (response) {
            $("#myModalSchool_" + param_id).modal('hide');
        });
    });
});
</script>

However, this works only for the last modal created while listing the schools. Any help is appreciated, and please if you need ask for details.

EDIT 1:

This is the template as requested

<div class="modal fade" data-backdrop="static" id="myModalSchool_{{ param.id }}">
<div class="modal-dialog modal-lg">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">&times;</span>
            </button>
            <h3 class="modal-title">
                School
            </h3>
        </div>
        <div class="modal-body">
            <form id="school_{{ param.id }}" name="school_{{ param.id }}" method="post" action="{{ path('school_modal_vp', {param_id: param.id, }) }}" class="form-horizontal">
                {{ form_errors(form) }}
                {{ form_rest(form) }}
                {{ form_end(form) }}
        </div>
    </div>
</div>

Alejandro Sazo
  • 796
  • 15
  • 31

1 Answers1

1

I think the main problem is the var param_id = '{{ param.id }}'; which is defined manually in your javascript.

First, I advise you to add a class on all your save button (e.g modal-submit) and a data-id on each button.

Example:

<button type="button" class="btn btn-primary modal-submit" data-id="{{myData.id}}">Submit</button>

Then in your javascript when you click on a save button (with modal-submit), you retrieve the id from the data-id and execute the sendForm($("#myModalSchool_" + param_id).find('form'),....

Example:

$(function() {
    $(".modal-submit").on("click", function( e ) {
        e.preventDefault();
        var param_id = $(this).attr('data-id');
        sendForm($("#myModalSchool_" + param_id).find('form'), function (response) {
            $("#myModalSchool_" + param_id).modal('hide');
        });
    });
});

EDIT:

Saved multiple times issue ?

Moreover, i think you defined the javascript above in each modal. That's why the save is called multiple times. You need to have only one instance of this javascript (so it can't be placed in your modal view). Try to put the javascript in your global layout.

Hope it will help

Community
  • 1
  • 1
zilongqiu
  • 846
  • 5
  • 12
  • Almost! The data is sent correctly no matter which school i select from the list (i.e. what modal I am using) but If I have 5 schools, the data of the selected school is submitted 5 times... – Alejandro Sazo Jul 23 '15 at 01:52
  • 1
    @AlejandroSazo Nice ! Where did you put the javascript above ? after each modal ? You need to have only one instance of this javascript (so it can't be placed in your modal view). Try to put it in your global layout. – zilongqiu Jul 23 '15 at 02:11
  • Interesting, i was trying redefining the modal with ids again, it worked but I will try the global approach. Indeed as you ask, the script exists for each modal. I will try your idea :) – Alejandro Sazo Jul 23 '15 at 02:18
  • Yes, it works!. please for other readers write in your answer that the javascript is in the global twig, not in the modal twig. – Alejandro Sazo Jul 23 '15 at 02:22
  • I think You must create a form for each school separately – M Gholami Jul 23 '15 at 08:41
  • 1
    @AlejandroSazo Yes i will add the information about the javascript problem. ;) – zilongqiu Jul 23 '15 at 09:38
  • 1
    @MohammadGholami The code doesn't reflect that, but I created a form for each school :) – Alejandro Sazo Jul 24 '15 at 19:45