Sehael
Sehael

Reputation: 3736

submit a symfony2 form using angularjs

I am building an application with symfony2 on the backend. I am thinking about using AngularJS on the frontend, but I would still like to use symfony forms. I have setup the form with the correct modules and everything, but the problem occurs when the data is actually submitted.

Problem

When Symfony renders the form, it sets the inputs 'name' attribute to an array, like user[username], and this is the format that it expects to receive the data once it is submitted. I can't figure out how to get Angular to submit the data in this format. This is what I have:

<body ng-app="formApp" ng-controller="formController">
{{ form_start(form, {'attr':{'id': 'registerForm', 'ng-submit':'processForm()'}}) }}

{{ form_row(form.username, {'attr':{'ng-model':'formData.username'}}) }}
{{ form_row(form.password.first, {'attr':{'ng-model':'formData.password'}}) }}
{{ form_row(form.password.second) }}
{% for address in form.userAddresses %}
        {{ form_row(address.postalCode, {'attr':{'ng-model':'formData.postalCode'}}) }}
{% endfor %}

<div><input type="submit" value="Save" /></div>
{{ form_end(form) }}
</body>

and the controller:

function formController($scope, $http) {

$scope.formData = {};

$scope.processForm = function() {
    $http({
        method  : 'POST',
        url     : submit,
        data    : $.param($scope.formData), 
        headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
    })
        .success(function(data) {
            alert(data.message);
        });
};
}

When I submit, obviously the name-value pair uses the formData variables, so username=testuser instead of user[username]=testuser.

I tried to set the formData variable like formData.user[username], but that didn't work at all.

So is there a way to either use the inputs 'name' when submitting, or do something so that the form is submitted in the correct format? Any help would be great!

Upvotes: 5

Views: 5927

Answers (4)

RChanaud
RChanaud

Reputation: 194

I think you should keep Angular form logic. You should use ng-model to bind data. To do this, you can create a Twig Form Theme to add ng-model attributes to your inputs, take a look at this gist.

Then you could pass input values to a $scope.data var in your controller like this:

$scope.var = {};

You should serialize data with the function provided in this article at line 109 or use jQuery.param() if you use jQuery.

Then create a submit method like this:

$scope.submit = function(){
    $http.post(
        'http://www.myurl.com',
        this.serializeData($scope.data),
        { headers: {
                'Content-Type': 'application/x-www-form-urlencoded' //Fix for Symfony
            }
        })
    .success(function(data) {
       //
    })
    .error(function (data){
        $log.error(data);
    });
}

Upvotes: 2

atn
atn

Reputation: 904

You could use {'data-ng-model': 'formData["user[username]"]'}. To post formData you should pass it through jQuery.param().

Upvotes: 0

shacharsol
shacharsol

Reputation: 2342

I solve it using server side code. before handling of the request and validation i call the following function i created to change the format:

   /**
     * Format the request content with the form name
     * @param Request $request
     * @param $formName
     * @param null $content
     * @return Request
     */
     public function formatRequestWithForm(Request $request, $formName, $content = null)
     {
      if ($content === null) {
          $content = $request->getContent();
      }
      $contentArray = array($formName => json_decode($content, true));
      $request->attributes->add($contentArray);
      $request->request->add($contentArray);
      return $request;


     }  

Upvotes: 0

akronymn
akronymn

Reputation: 2446

You can build the object symfony expects in a $scope function that you would bind to your form's submit with ng-click. So:

<input type="submit" value="Save" /></div>

would become

<input type="submit" value="Save" ng-click="submitForm()" /></div>

and in your controller you would add a function on the $scope object

$scope.submitForm = function() {
  var user = [];
  user['username'] = $scope.formData.username;
  //etc
};

Upvotes: 2

Related Questions