1

I have a form which is used to submit data about multiple people. There are multiple properties for each person, and I'm grouping them like the following:

<input type=hidden name="person1[firstname]" value='Sam'/>
<input type=hidden name="person1[lastname]" value='Higgins'/>

<input type=hidden name="person2[firstname]" value='Jiminy'/>
<input type=hidden name="person2[lastname]" value='Cricket'/>

...etc

When I do the following:

my %hash = params;
die Dumper \%hash;

I get:

VAR1 = {
          'person1[firstname]' => 'Sam',
          'person1[lastname]' => 'Higgins',
          'person2[firstname]' => 'Jiminy',
          'person2[lastname]' => 'Cricket',
};

When I was expecting something like:

VAR1 = {
          'person1' => { firstname => 'Sam', lastname => 'Higgens' },
          'person2' => { firstname => 'Jiminy', lastname => 'Cricket' },
};

Is there a way to get the above, or am I doing it wrong in my HTML?

Edit

I've also tried with empty brackets at the end:

<input type=hidden name="person1[firstname][]" value='Sam'/>

but that just gave:

'person1[firstname][]' => 'Sam',
i alarmed alien
  • 9,412
  • 3
  • 27
  • 40
a7omiton
  • 1,597
  • 4
  • 34
  • 61
  • You can make life even easier for yourself in your form by making the input names `person[1][firstname]` and `person[1][lastname]`... or not, since Dancer doesn't appear to create multidimensional structures from input. Hmmm. – i alarmed alien Oct 11 '14 at 16:03
  • @ialarmedalien thanks but that was just as an example, i didn't want to give my actual structure as i wanted to keep it simple – a7omiton Oct 11 '14 at 16:08
  • 1
    I tried using `JSON` by converting it to a json string, but that still gives me the key as `person1[firstname]` – a7omiton Oct 11 '14 at 16:25
  • Does anyone know if passing this data to jQuery and submitting it via AJAX as a JSON object and then decoding that to a perl data structure would be the only solution? ...but then I'm not sure how to structure the input names so that jQuery can handle them – a7omiton Oct 11 '14 at 16:41
  • @ialarmedalien that seems promising, will try and update. thanks! – a7omiton Oct 11 '14 at 16:55
  • @ialarmedalien no luck with serializeArray, it also produces the same name for the `name` keys of each object (i.e. `{ name: person1[firstname], key: 'Sam' }`) – a7omiton Oct 11 '14 at 17:37
  • 1
    I was hoping to not go down this route, but it seems I'm going to have to regex through and create my own data structure in perl, as per http://stackoverflow.com/questions/19521690/data-posted-as-mulltidimensional-array-read-into-arrays-perl – a7omiton Oct 11 '14 at 17:44
  • 2
    [Here's a JSFiddle](http://jsfiddle.net/rt15vbqf/) that uses [formToObject.js](https://github.com/serbanghita/formToObject.js) to encode the form data. This might save you from having to do the data structure creation! – i alarmed alien Oct 11 '14 at 20:52
  • @ialarmedalien that is pretty crazy, I'll have a look :) – a7omiton Oct 12 '14 at 12:30
  • 2
    @ialarmedalien I ended up using https://github.com/marioizquierdo/jquery.serializeJSON, as formToObject was giving me TypeErrors for readonly elements. I'm really grateful that they put up other similar solutions to go to, very unselfish and that's great – a7omiton Oct 12 '14 at 18:46

2 Answers2

1
#!/usr/bin/perl
use Data::Dumper;
my $orginal = {
          'person1[firstname]' => 'Sam',
          'person1[lastname]' => 'Higgins',
          'person2[firstname]' => 'Jiminy',
          'person2[lastname]' => 'Cricket',
};  

my $result = {};
foreach my $key (keys %$orginal)
{
    $value = $orginal->{$key};
     $key =~ m/^(.*)\[(.*)\]$/;

     #$1 = for example person1
     #$2 = forexample firstname
     $result->{$1}->{$2} = $value;


}

print Dumper($result);
#RESULT:

# $VAR1 = {
#           'person1' => {
#                          'firstname' => 'Sam',
#                          'lastname' => 'Higgins'
#                        },
#           'person2' => {
#                          'firstname' => 'Jiminy',
#                          'lastname' => 'Cricket'
#                        }
#         };
Luke
  • 1,768
  • 2
  • 20
  • 30
0

To answer the question more wholly than providing a link:

I went with a solution that uses jQuery, specifically using a plugin (https://github.com/marioizquierdo/jquery.serializeJSON), to send the data asynchronously (AJAX) and using Dancers from_json method which creates a hashref of the JSON string.

I emphasise string because the function offered by the serializeJSON plugin creates a JSON object, and this Dancer does not convert to the proper structure. Therefore you need to use JSON.stringify() to create a json string, which Dancer does accept :)

Below is the code:

Example HTML:

<input type=hidden name="person1[firstname]" value='Sam'/>
<input type=hidden name="person1[lastname]" value='Higgins'/>

JS (jQuery):

var formData = $(this).serializeJSON();
console.log(formData);
$.ajax({
     'url': '/your_url',
     'type': 'POST',
     'data': JSON.stringify(formData),
     'success': function(res){
         console.log(res);
   }
 });

Perl (Dancer):

post '/your_url' => sub {
    my $json = request->body;
    use Data::Dumper;
    my $hashref = {};
    $hashref = from_json($json);
    die Dumper \$hashref->{person1}->{name}; # 'Sam'
}

Thanks to all who helped!

a7omiton
  • 1,597
  • 4
  • 34
  • 61