<commit_before>package EnsEMBL::Web::Form::Element::Dropdown;

use strict;

use base qw(
  EnsEMBL::Web::DOM::Node::Element::Select
  EnsEMBL::Web::Form::Element
);

sub configure {
  ## @overrides
  my ($self, $params) = @_;
  
  $self->set_attribute('id',        $params->{'id'} || $self->unique_id);
  $self->set_attribute('name',      $params->{'name'})            if exists $params->{'name'};
  $self->set_attribute('class',     $params->{'class'})           if exists $params->{'class'};
  $self->set_attribute('size',      $params->{'size'})            if exists $params->{'size'};
  $self->set_attribute('class',     $self->CSS_CLASS_REQUIRED)    if exists $params->{'required'};

  $self->disabled(1) if exists $params->{'disabled'} && $params->{'disabled'} == 1;
  $self->multiple(1) if exists $params->{'multiple'} && $params->{'multiple'} == 1;
  
  my $selected_values = {};
  if (exists $params->{'value'}) {
    $params->{'value'} = [ $params->{'value'} ] unless ref($params->{'value'}) eq 'ARRAY';
    $params->{'value'} = [ shift @{ $params->{'value'} } ] unless $self->multiple;
    $selected_values  = { map { $_ => 1 } @{ $params->{'value'} } };
  }
  if (exists $params->{'values'}) {
    for (@{ $params->{'values'} }) {
      my $args = {};
      $args->{'id'}       = $_->{'id'}        if exists $_->{'id'};
      $args->{'value'}    = $_->{'value'}     if exists $_->{'value'};
      $args->{'caption'}  = $_->{'caption'}   if exists $_->{'caption'};
      $args->{'selected'} = $_->{'value'} && exists $selected_values->{ $_->{'value'} } ? 1 : 0;
      $args->{'group'}    = $_->{'group'}     if $_->{'group'};
    
      $self->add_option($args);
    }
  }
  if (exists $params->{'shortnote'}) {
    $self->parent_node->append_child($self->dom->create_element('span'));
    $self->next_sibling->inner_HTML($params->{'shortnote'});
  }
}

sub add_option {
  ## Adds an option to the dropdown
  ## @params HashRef with following keys:
  ##  - id        Id attribute
  ##  - value     goes in value attribute of the option
  ##  - caption   goes as innerText in <option> (is the actual name displayed)
  ##  - selected  flag to tell whether option is selected or not
  ##  - group     (optional) Label attribute for the parent Optgroup for the option - If optgroup does not exist, a new one's created before adding it
  ## @return newly added Node::Element::Option object
  my ($self, $params) = @_;
  
  $params->{'value'} = '' unless exists $params->{'value'} && defined $params->{'value'};
  $params->{'caption'} = '' unless exists $params->{'caption'} && defined $params->{'caption'};
  
  my $option = $self->dom->create_element('option');
  $option->inner_HTML($params->{'caption'});
  $option->set_attribute('id', $params->{'id'}) if $params->{'id'};
  $option->set_attribute('value', $params->{'value'});
  $option->selected(1) if exists $params->{'selected'} && $params->{'selected'} == 1;
  
  my $parent_node = $self;
  if (exists $params->{'group'} && $params->{'group'} ne '') {
  
    my $group = undef;
    for (@{ $self->get_elements_by_tag_name('optgroup') }) {
      $group = $_ if $_->get_attribute('label') eq $params->{'group'};
    }
    unless (defined $group) {
      $group = $self->dom->create_element('optgroup');
      $group->set_attribute('label', $params->{'group'});
      $self->append_child($group);
    }
    $parent_node = $group;
  }
  $parent_node->append_child($option);
  return $option;
}

1;<commit_msg>class name can also be given to options + some code tidying<commit_after>package EnsEMBL::Web::Form::Element::Dropdown;

use strict;

use base qw(
  EnsEMBL::Web::DOM::Node::Element::Select
  EnsEMBL::Web::Form::Element
);

sub render {
  ## @overrides
  my $self = shift;
  $self->after($self->dom->create_element('span', {'inner_HTML' => ' '.$self->{'__shortnote'}})) if exists $self->{'__shortnote'};
  return $self->SUPER::render;
}

sub configure {
  ## @overrides
  my ($self, $params) = @_;
  
  exists $params->{$_} and $self->set_attribute($_, $params->{$_}) for qw(id name class size);
  exists $params->{$_} and $params->{$_} == 1 and $self->$_(1) for qw(disabled multiple);
  $self->set_attribute('class', $self->CSS_CLASS_REQUIRED) if exists $params->{'required'};
  
  my $selected_values = {};
  if (exists $params->{'value'}) {
    $params->{'value'} = [ $params->{'value'} ] unless ref($params->{'value'}) eq 'ARRAY';
    $params->{'value'} = [ shift @{ $params->{'value'} } ] unless $self->multiple;
    $selected_values  = { map { $_ => 1 } @{ $params->{'value'} } };
  }
  $self->{'__shortnote'} = $params->{'shortnote'} if exists $params->{'shortnote'};
  $self->{'__option_class'} = $params->{'option_class'} if exists $params->{'option_class'};
  if (exists $params->{'values'}) {
    for (@{$params->{'values'}}) {
      $_->{'selected'} = $_->{'value'} && exists $selected_values->{ $_->{'value'} } ? 1 : 0;
      $self->add_option($_);
    }
  }
}

sub add_option {
  ## Adds an option to the dropdown
  ## @params HashRef with following keys:
  ##  - id        Id attribute
  ##  - value     goes in value attribute of the option
  ##  - caption   goes as innerText in <option> (is the actual name displayed)
  ##  - selected  flag to tell whether option is selected or not
  ##  - class     Class attribute - overrides the 
  ##  - group     (optional) Label attribute for the parent Optgroup for the option - If optgroup does not exist, a new one's created before adding it
  ## @return newly added Node::Element::Option object
  my ($self, $params) = @_;
  
  $params->{'value'}   = '' unless exists $params->{'value'} && defined $params->{'value'};
  $params->{'caption'} = '' unless exists $params->{'caption'} && defined $params->{'caption'};
  $params->{'class'} ||= $self->{'__option_class'} if exists $params->{'__option_class'};
  
  my $option = $self->dom->create_element('option', {'inner_HTML' => $params->{'caption'}, 'value' => $params->{'value'}});
  $option->set_attribute('id', $params->{'id'}) if $params->{'id'};
  $option->selected(1) if exists $params->{'selected'} && $params->{'selected'} == 1;

  my $group = undef;
  if (exists $params->{'group'} && $params->{'group'} ne '') {
    $_->get_attribute('label') eq $params->{'group'} and $group = $_ and last for @{$self->get_elements_by_tag_name('optgroup')}; #find any matching one
    $group = $self->append_child($self->dom->create_element('optgroup', {'label' => $params->{'group'}})) unless $group;          #new optgroup if no match
  }
  return ($group || $self)->append_child($option);
}

1;
{'fraction_non_alphanumeric': 0.22465753424657534, 'fraction_numerical': 0.0027397260273972603, 'mean_word_length': 3.813919413919414, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 161, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1779280', 'n_tokens_mistral': 2184, 'n_tokens_neox': 2163, 'n_words': 502}