Last active
December 26, 2015 21:59
-
-
Save dim0xff/7219557 to your computer and use it in GitHub Desktop.
just a try to speedup Repeatable fields Put into HTML/FormHandlerX/Field/TraitFor/Repeatable/Speedup.pm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package HTML::FormHandlerX::Field::TraitFor::Repeatable::Speedup; | |
=head1 NAME | |
HTML::FormHandlerX::Field::TraitFor::Repeatable::Speedup - just a try to speedup | |
Repeatable fields | |
=head1 DESCRIPTION | |
Every time you validate your form, which has Repeatable fields, for each value in input for | |
repeatable field will be created field with needed type. So when you have 10 input values, you | |
probably will not recognize that it is working slowly. | |
This trait tries to optimize that mechanism: it creates permanent reusable fields on demand. | |
=head1 WARNING | |
Probably it will break ability to change attributes for embedded fields (required, disabled etc.). | |
=head1 SYNOPSYS | |
# Your cart form | |
package My::Cart; | |
use HTML::FormHandler::Moose; | |
extends 'HTML::FormHandler'; | |
has_field 'products' => ( | |
type => 'Repeatable', | |
traits => ['HTML::FormHandlerX::Field::TraitFor::Repeatable::Speedup'], | |
); | |
has_field 'products.id' => (type => 'PosInteger', required => 1, ); | |
has_field 'products.quantity' => (type => 'PosInteger', required => 1, ); | |
has_field 'products.options' => ( | |
type => 'Repeatable', | |
traits => ['HTML::FormHandlerX::Field::TraitFor::Repeatable::Speedup'], | |
); | |
has_field 'products.options.option_id' => (type => 'PosInteger', required => 1, ); | |
has_field 'products.options.value_id' => (type => 'PosInteger', required => 1, ); | |
1; | |
=cut | |
use HTML::FormHandler::Moose::Role; | |
use utf8; | |
use strict; | |
use warnings; | |
has _cloned_elements => ( | |
is => 'rw', | |
isa => 'ArrayRef', | |
default => sub { [] }, | |
); | |
sub init_state { | |
my $self = shift; | |
# must clear out instances built last time | |
unless ( $self->has_contains ) { | |
if ( $self->num_fields == 1 && $self->field('contains') ) { | |
$self->field('contains')->is_contains(1); | |
$self->contains( $self->field('contains') ); | |
} | |
else { | |
$self->contains( $self->create_element ); | |
} | |
} | |
} | |
around clone_element => sub { | |
my ( $orig, $self, $index ) = @_; | |
return $self->_cloned_elements->[$index] | |
if exists $self->_cloned_elements->[$index]; | |
my $field = $self->$orig($index); | |
$self->_cloned_elements->[$index] = $field; | |
return $field; | |
}; | |
after clone_fields => sub { | |
my ( $self, $parent, $fields ) = @_; | |
for my $field ( @{$fields} ) { | |
$field->can('_cloned_elements') && $field->_cloned_elements( [] ); | |
} | |
}; | |
use namespace::autoclean; | |
1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment