<commit_before>import 'package:angular2/core.dart';
import 'package:angular2/common.dart';
import 'package:fnx_ui/src/util/ui.dart';
import 'dart:html';
import 'dart:async';
import 'package:fnx_ui/src/util/async.dart';
import 'package:fnx_ui/src/components/input/fnx_input.dart';
import 'package:fnx_ui/fnx_ui.dart';

const CUSTOM_SELECT_VALUE_ACCESSOR = const Provider(  NG_VALUE_ACCESSOR,
                                                      useExisting: FnxSelect,
                                                      multi: true);
@Component(
    selector: 'fnx-select',
    templateUrl: 'fnx_select.html',
    providers: const [CUSTOM_SELECT_VALUE_ACCESSOR]
)
class FnxSelect extends FnxInputComponent implements ControlValueAccessor, OnInit, OnDestroy {

  @Input() bool required = false;
  @Input() bool neverShowFilter = false;
  @Input() bool alwaysShowFilter = false;
  @Input() bool readonly = false;

  List<FnxOptionValue> options = [];

  @Input() String selectionEmptyLabel = "Select...";
  @Input() String optionsEmptyLabel = "No options to choose from";
  @Input() String optionsEmptySearchLabel = "No option matches your search";

  bool open = false;
  bool openUp = false;

  bool _multi = false;

  FnxOptionValue _highlighted;

  String _filter = null;
  List<FnxOptionValue> _cachedFilteredOptions = null;

  @ContentChild(NgFormControl) NgFormControl state;

  StreamSubscription<MouseEvent> globalClicks;
  StreamSubscription<String> navigationActions;

  Node container;

  FnxSelect(ElementRef el, @Optional() FnxInput wrapper, @Optional() FnxForm form): super(form, wrapper) {
    if (el != null) {
      container = el.nativeElement;
      elementPositionStream(container).listen((double position) {
         openUp = position > 0.5;
      });
    }
  }

  void toggleDropdown() {
    markAsTouched();
    if (open) {
      hideOptions();
    } else {
      showOptions();
    }
  }

  void hideOptions() {
    open = false;
    filter = null;
  }

  void showOptions() {
    open = true;
  }

  get showFilter {
    if (neverShowFilter) return false;
    if (alwaysShowFilter) return true;
    if (options != null && options.length > 10) return true;
  }

  @Input()
  set multi(bool flag) {
    if (flag) {
      if (value == null) {
        value = [];
      } else if (!(value is List)) {
        value = [value];
      }
    } else {
      if ((value is List) && value.length > 0) {
        value = value[0];
      }
    }
    _multi = flag;
  }

  get multi => _multi;

  bool isSelected(dynamic v) {
    if (value == null) return v == null;
    if (v == null) return false;
    if (value is List) {
      return value.contains(v);
    } else {
      return value == v;
    }
  }

  bool isHighlighted(FnxOptionValue opt) {
    return _highlighted != null && _highlighted == opt;
  }

  /// returns label constructed from all selected option labels joined by ','
  /// in the order they were defined in the options collection
  String renderSelectedOptions () {
    List<FnxOptionValue> allSelected;
    if (value == null) {
      allSelected = [];
    } else if (value is List) {
      Set selected = new Set.from(value as List);
      allSelected = options.where((opt) {
        return selected.contains(opt.value);
      }).toList();
    } else {
      FnxOptionValue found = options.firstWhere((opt) {
        return opt.value == value;
      }, orElse: () => null);
      if (found != null) {
        allSelected = [found];
      } else {
        allSelected = [];
      }
    }
    if (allSelected.isEmpty) {
      return selectionEmptyLabel;
    } else {
      return allSelected.map((opt) => opt.label).join(', ');
    }
  }

  void selectOption(dynamic value) {
    doSelectOption(value);
  }

  void doSelectOption(dynamic value) {
    if (multi) {
      toggleSelectedOption(value);
    } else {
      if (this.value == value) {
        // _value = null; asi ne
      } else {
        this.value = value;
      }
      hideOptions();
    }
  }

  void toggleSelectedOption(dynamic v) {
    if (value == null) {
      value = [];
    } else if (!(value is List)) {
      value = [value];
    }
    if (value.contains(v)) {
      value.remove(v);
    } else {
      value.add(v);
    }
  }
  @Input()
  set filter(String value) {
    if (value != null) {
      value = value.toLowerCase();<commit_msg>FIX FnxSelect closing after selection<commit_after>import 'package:angular2/core.dart';
import 'package:angular2/common.dart';
import 'package:fnx_ui/src/util/ui.dart';
import 'dart:html';
import 'dart:async';
import 'package:fnx_ui/src/util/async.dart';
import 'package:fnx_ui/src/components/input/fnx_input.dart';
import 'package:fnx_ui/fnx_ui.dart';

const CUSTOM_SELECT_VALUE_ACCESSOR = const Provider(  NG_VALUE_ACCESSOR,
                                                      useExisting: FnxSelect,
                                                      multi: true);
@Component(
    selector: 'fnx-select',
    templateUrl: 'fnx_select.html',
    providers: const [CUSTOM_SELECT_VALUE_ACCESSOR]
)
class FnxSelect extends FnxInputComponent implements ControlValueAccessor, OnInit, OnDestroy {

  @Input() bool required = false;
  @Input() bool neverShowFilter = false;
  @Input() bool alwaysShowFilter = false;
  @Input() bool readonly = false;

  List<FnxOptionValue> options = [];

  @Input() String selectionEmptyLabel = "Select...";
  @Input() String optionsEmptyLabel = "No options to choose from";
  @Input() String optionsEmptySearchLabel = "No option matches your search";

  bool open = false;
  bool openUp = false;

  bool _multi = false;

  FnxOptionValue _highlighted;

  String _filter = null;
  List<FnxOptionValue> _cachedFilteredOptions = null;

  @ContentChild(NgFormControl) NgFormControl state;

  StreamSubscription<MouseEvent> globalClicks;
  StreamSubscription<String> navigationActions;

  Node container;

  FnxSelect(ElementRef el, @Optional() FnxInput wrapper, @Optional() FnxForm form): super(form, wrapper) {
    if (el != null) {
      container = el.nativeElement;
      elementPositionStream(container).listen((double position) {
         openUp = position > 0.5;
      });
    }
  }

  void toggleDropdown() {
    markAsTouched();
    if (open) {
      if (!multi) {
        hideOptions();
      }
    } else {
      showOptions();
    }
  }

  void hideOptions() {
    open = false;
    filter = null;
  }

  void showOptions() {
    open = true;
  }

  get showFilter {
    if (neverShowFilter) return false;
    if (alwaysShowFilter) return true;
    if (options != null && options.length > 10) return true;
  }

  @Input()
  set multi(bool flag) {
    if (flag) {
      if (value == null) {
        value = [];
      } else if (!(value is List)) {
        value = [value];
      }
    } else {
      if ((value is List) && value.length > 0) {
        value = value[0];
      }
    }
    _multi = flag;
  }

  get multi => _multi;

  bool isSelected(dynamic v) {
    if (value == null) return v == null;
    if (v == null) return false;
    if (value is List) {
      return value.contains(v);
    } else {
      return value == v;
    }
  }

  bool isHighlighted(FnxOptionValue opt) {
    return _highlighted != null && _highlighted == opt;
  }

  /// returns label constructed from all selected option labels joined by ','
  /// in the order they were defined in the options collection
  String renderSelectedOptions () {
    List<FnxOptionValue> allSelected;
    if (value == null) {
      allSelected = [];
    } else if (value is List) {
      Set selected = new Set.from(value as List);
      allSelected = options.where((opt) {
        return selected.contains(opt.value);
      }).toList();
    } else {
      FnxOptionValue found = options.firstWhere((opt) {
        return opt.value == value;
      }, orElse: () => null);
      if (found != null) {
        allSelected = [found];
      } else {
        allSelected = [];
      }
    }
    if (allSelected.isEmpty) {
      return selectionEmptyLabel;
    } else {
      return allSelected.map((opt) => opt.label).join(', ');
    }
  }

  void selectOption(dynamic value) {
    doSelectOption(value);
  }

  void doSelectOption(dynamic value) {
    if (multi) {
      toggleSelectedOption(value);
    } else {
      if (this.value == value) {
        // _value = null; asi ne
      } else {
        this.value = value;
      }
    }
  }

  void toggleSelectedOption(dynamic v) {
    if (value == null) {
      value = [];
    } else if (!(value is List)) {
      value = [value];
    }
    if (value.contains(v)) {
      value.remove(v);
    } else {
      value.add(v);
    }
  }
  @Input()
  set filter(String value) {
    if (value != null) {
      value = value.toLowerCase();
{'fraction_non_alphanumeric': 0.125358084106795, 'fraction_numerical': 0.0018333906267904206, 'mean_word_length': 2.5193548387096776, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '120002', 'n_tokens_mistral': 2726, 'n_tokens_neox': 2665, 'n_words': 686}