<commit_before><?php
namespace Selenia\Plugins\MatisseComponents;

use Selenia\Matisse\Components\Base\Component;
use Selenia\Matisse\Components\Base\HtmlComponent;
use Selenia\Matisse\Exceptions\ComponentException;
use Selenia\Matisse\Properties\Base\HtmlComponentProperties;
use Selenia\Matisse\Properties\TypeSystem\type;

class SelectProperties extends HtmlComponentProperties
{
  /**
   * @var bool
   */
  public $autoOpenLinked = false;
  /**
   * @var bool
   */
  public $autofocus = false;
  /**
   * @var bool
   */
  public $autoselectFirst = false;
  /**
   * @var string
   */
  public $data = type::data;
  /**
   * @var string
   */
  public $emptyLabel = '--- select ---';
  /**
   * @var bool
   */
  public $emptySelection = false;
  /**
   * @var string
   */
  public $labelField = '1';
  /**
   * @var string
   */
  public $linkedSelector = type::id;
  /**
   * @var string
   */
  public $list_item = type::content;
  /**
   * @var bool
   */
  public $loadLinkedOnInit = true;
  /**
   * @var bool
   */
  public $multiple = false;
  /**
   * @var string
   */
  public $name = ''; //allow 'field[]'
  /**
   * @var bool When true, the native HTML Select element is used instead of the javascript widget.
   */
  public $native = false;
  /**
   * @var string
   */
  public $onChange = '';
  /**
   * > **Note:** use $name in the URL to bind to the value of the $name field, otherwhise the linked value will be
   * appended
   *
   * @var string
   */
  public $sourceUrl = '';
  /**
   * @var bool
   */
  public $strict = false;
  /**
   * @var mixed
   */
  public $value = type::any;
  /**
   * @var string
   */
  public $valueField = '0';
  /**
   * @var string
   */
  public $values = type::data;

}

class Select extends HtmlComponent
{
  protected static $propertiesClass = SelectProperties::class;

  /** @var SelectProperties */
  public $props;

  protected $autoId       = true;
  protected $containerTag = 'select';

  private $selectedLabel;

  protected function init ()
  {
    $this->context->addStylesheet ('lib/chosen/chosen.min.css');
    $this->context->addScript ('lib/chosen/chosen.jquery.min.js');
  }

  protected function preRender ()
  {
    if (!$this->props->native) {
      $emptyLabel = $this->props->emptyLabel;
      $this->addClass ('chosen-select');
      $this->context->addInlineScript ("
$ ('.chosen-select').chosen ({
  placeholder_text: '$emptyLabel'
});
$ ('.chosen-container').css ('width', '');
", 'init-select');
    }
    parent::preRender ();
  }

  protected function render ()
  {
    $prop       = $this->props;
    $isMultiple = $prop->multiple;

    $this->attr ('name', $prop->name);
    $this->attrIf ($isMultiple, 'multiple', '');
    $this->attrIf ($prop->onChange, 'onchange', $prop->onChange);
    $this->beginContent ();
    if ($prop->emptySelection) {
      $sel = exists ($prop->value) ? '' : ' selected';
      echo '<option value=""' . $sel . '>' . $prop->emptyLabel . '</option>';
    }
    $this->viewModel = $prop->get ('data');<commit_msg>Add drop-up support to Chosen selects.<commit_after><?php
namespace Selenia\Plugins\MatisseComponents;

use Selenia\Matisse\Components\Base\Component;
use Selenia\Matisse\Components\Base\HtmlComponent;
use Selenia\Matisse\Exceptions\ComponentException;
use Selenia\Matisse\Properties\Base\HtmlComponentProperties;
use Selenia\Matisse\Properties\TypeSystem\type;

class SelectProperties extends HtmlComponentProperties
{
  /**
   * @var bool
   */
  public $autoOpenLinked = false;
  /**
   * @var bool
   */
  public $autofocus = false;
  /**
   * @var bool
   */
  public $autoselectFirst = false;
  /**
   * @var string
   */
  public $data = type::data;
  /**
   * @var string
   */
  public $emptyLabel = '--- select ---';
  /**
   * @var bool
   */
  public $emptySelection = false;
  /**
   * @var string
   */
  public $labelField = '1';
  /**
   * @var string
   */
  public $linkedSelector = type::id;
  /**
   * @var string
   */
  public $list_item = type::content;
  /**
   * @var bool
   */
  public $loadLinkedOnInit = true;
  /**
   * @var bool
   */
  public $multiple = false;
  /**
   * @var string
   */
  public $name = ''; //allow 'field[]'
  /**
   * @var bool When true, the native HTML Select element is used instead of the javascript widget.
   */
  public $native = false;
  /**
   * @var string
   */
  public $onChange = '';
  /**
   * > **Note:** use $name in the URL to bind to the value of the $name field, otherwhise the linked value will be
   * appended
   *
   * @var string
   */
  public $sourceUrl = '';
  /**
   * @var bool
   */
  public $strict = false;
  /**
   * @var mixed
   */
  public $value = type::any;
  /**
   * @var string
   */
  public $valueField = '0';
  /**
   * @var string
   */
  public $values = type::data;

}

class Select extends HtmlComponent
{
  protected static $propertiesClass = SelectProperties::class;

  /** @var SelectProperties */
  public $props;

  protected $autoId       = true;
  protected $containerTag = 'select';

  private $selectedLabel;

  protected function init ()
  {
    $this->context->addStylesheet ('lib/chosen/chosen.min.css');
    $this->context->addScript ('lib/chosen/chosen.jquery.min.js');

    // Add drop-up behavior to Chosen

    $this->context->addInlineCss("
.chosen-container.chosen-drop-up .chosen-drop {
  top: auto;
  bottom: 100%;
  border-top: 1px solid #aaa;
  border-bottom: none;
}
", 'init-select');
    $this->context->addInlineScript ("
$ ('.chosen-select').on('chosen:showing_dropdown', function(event, params) {
  var chosen_container = $( event.target ).next( '.chosen-container' );
  var dropdown = chosen_container.find( '.chosen-drop' );
  var dropdown_top = dropdown.offset().top - $(window).scrollTop();
  var dropdown_height = dropdown.height();
  var viewport_height = $(window).height();
  if ( dropdown_top + dropdown_height > viewport_height )
    chosen_container.addClass( 'chosen-drop-up' );
}).on('chosen:hiding_dropdown', function(event, params) {
  $( event.target ).next( '.chosen-container' ).removeClass( 'chosen-drop-up' );
});
$ ('.chosen-container').css ('width', '');
", 'init-select');
  }

  protected function preRender ()
  {
    if (!$this->props->native) {
      $emptyLabel = $this->props->emptyLabel;
      $this->addClass ('chosen-select');
      $this->context->addInlineScript ("
$ ('.chosen-select').chosen ({
  placeholder_text: '$emptyLabel'
});
$ ('.chosen-container').css ('width', '');
", 'init-select2');
    }
    parent::preRender ();
  }

  protected function render ()
  {
    $prop       = $this->props;
    $isMultiple = $prop->multiple;

    $this->attr ('name', $prop->name);
    $this->attrIf ($isMultiple, 'multiple', '');
    $this->attrIf ($prop->onChange, 'onchange', $prop->onChange);
    $this->beginContent ();
    if ($prop->emptySelection) {
      $sel = exists ($prop->value) ? '' : ' selected';
      echo '<option value=""' . $sel . '>' . $prop->emptyLabel . '</option>';
    }
    $this->viewModel = $prop->get ('data');
{'fraction_non_alphanumeric': 0.17635355975557765, 'fraction_numerical': 0.0012789540997584197, 'mean_word_length': 2.9165275459098496, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 64, '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': '5258320', 'n_tokens_mistral': 2331, 'n_tokens_neox': 2295, 'n_words': 511}