<commit_before>import {
  Directive,
  Input,
  Output,
  ComponentRef,
  ViewContainerRef,
  EventEmitter,
  OnInit,
  ComponentFactoryResolver,
  Renderer,
  SimpleChanges,
  SkipSelf,
  Host,
  Optional
} from "@angular/core";
import { Ng2AutoCompleteComponent } from "./ng2-auto-complete.component";
import { ControlContainer, AbstractControl, FormGroup, FormControl, FormGroupName } from "@angular/forms";

/**
 * display auto-complete section with input and dropdown list when it is clicked
 */
@Directive({
  selector: "[auto-complete], [ng2-auto-complete]"
})
export class Ng2AutoCompleteDirective implements OnInit {

  @Input("auto-complete-placeholder") autoCompletePlaceholder: string;
  @Input("source") source: any;
  @Input("path-to-data") pathToData: string;
  @Input("min-chars") minChars: number;
  @Input("value-property-name") valuePropertyName: string;
  @Input("display-property-name") displayPropertyName: string;
  @Input("accept-user-input") acceptUserInput: boolean;
  @Input("max-num-list") maxNumList: string;

  @Input("list-formatter") listFormatter: (arg: any) => string;
  @Input("loading-text") loadingText: string = "Loading";
  @Input("blank-option-text") blankOptionText: string;
  @Input("no-match-found-text") noMatchFoundText: string;

  @Input() ngModel: String;
  @Input('formControlName') formControlName: string;
  //if [formControl] is used on the anchor where our directive is sitting
  //a form is not necessary to use a formControl we should also support this
  @Input('formControl') extFormControl: FormControl;

  @Output() ngModelChange = new EventEmitter();
  @Output() valueChanged = new EventEmitter();


  componentRef: ComponentRef<Ng2AutoCompleteComponent>;
  wrapperEl: HTMLElement;
  el: HTMLElement;   // this element element, can be any
  acDropdownEl: HTMLElement; // auto complete element
  inputEl: HTMLInputElement;  // input element of this element
  formControl: AbstractControl;

  constructor(private resolver: ComponentFactoryResolver,
              private renderer: Renderer,
              public  viewContainerRef: ViewContainerRef,
              @Optional() @Host() @SkipSelf() private parentForm: ControlContainer) {
    this.el = this.viewContainerRef.element.nativeElement;
  }

  ngOnInit(): void {
    // wrap this element with <div class="ng2-auto-complete">
    this.wrapperEl = document.createElement("div");
    this.wrapperEl.className = "ng2-auto-complete-wrapper";
    this.wrapperEl.style.position = "relative";
    this.el.parentElement.insertBefore(this.wrapperEl, this.el.nextSibling);
    this.wrapperEl.appendChild(this.el);


    //Check if we were supplied with a [formControlName] and it is inside a [form]
    //else check if we are supplied with a [FormControl] regardless if it is inside a [form] tag
    if (this.parentForm && this.formControlName) {
      if (this.parentForm['form']) {
        this.formControl = (<FormGroup>this.parentForm['form']).get(this.formControlName);
      } else if (this.parentForm instanceof FormGroupName) {
        this.formControl = (<FormGroupName>this.parentForm).control.controls[this.formControlName];
      }
    } else if (this.extFormControl) {
      this.formControl = this.extFormControl;
    }

    // apply toString() method for the object
    if (!!this.ngModel) {
      this.selectNewValue(this.ngModel);
    } else if (!!this.formControl) {
      this.selectNewValue(this.formControl.value[this.displayPropertyName]);
    }

    // when somewhere else clicked, hide this autocomplete
    //document.addEventListener("click", this.hideAutoCompleteDropdown);
  }

  ngAfterViewInit() {
    // if this element is not an input tag, move dropdown after input tag
    // so that it displays correctly
    this.inputEl = this.el.tagName === "INPUT" ?
        <HTMLInputElement>this.el : <HTMLInputElement>this.el.querySelector("input");

    this.inputEl.addEventListener('focus', this.showAutoCompleteDropdown);
    this.inputEl.addEventListener('blur', this.hideAutoCompleteDropdown);
    this.inputEl.addEventListener('keydown', this.keydownEventHandler);
    this.inputEl.addEventListener('input', this.inputEventHandler);
  }

  ngOnDestroy(): void {
    if (this.componentRef) {
      this.componentRef.instance.valueSelected.unsubscribe();
      this.componentRef.instance.inputChanged.unsubscribe();
    }
    //document.removeEventListener("click", this.hideAutoCompleteDropdown);
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes['ngModel']) {
      this.ngModel = this.addToStringFunction(changes['ngModel'].currentValue);
    }<commit_msg>#130, more checking before set value<commit_after>import {
  Directive,
  Input,
  Output,
  ComponentRef,
  ViewContainerRef,
  EventEmitter,
  OnInit,
  ComponentFactoryResolver,
  Renderer,
  SimpleChanges,
  SkipSelf,
  Host,
  Optional
} from "@angular/core";
import { Ng2AutoCompleteComponent } from "./ng2-auto-complete.component";
import { ControlContainer, AbstractControl, FormGroup, FormControl, FormGroupName } from "@angular/forms";

/**
 * display auto-complete section with input and dropdown list when it is clicked
 */
@Directive({
  selector: "[auto-complete], [ng2-auto-complete]"
})
export class Ng2AutoCompleteDirective implements OnInit {

  @Input("auto-complete-placeholder") autoCompletePlaceholder: string;
  @Input("source") source: any;
  @Input("path-to-data") pathToData: string;
  @Input("min-chars") minChars: number;
  @Input("value-property-name") valuePropertyName: string;
  @Input("display-property-name") displayPropertyName: string;
  @Input("accept-user-input") acceptUserInput: boolean;
  @Input("max-num-list") maxNumList: string;

  @Input("list-formatter") listFormatter: (arg: any) => string;
  @Input("loading-text") loadingText: string = "Loading";
  @Input("blank-option-text") blankOptionText: string;
  @Input("no-match-found-text") noMatchFoundText: string;

  @Input() ngModel: String;
  @Input('formControlName') formControlName: string;
  //if [formControl] is used on the anchor where our directive is sitting
  //a form is not necessary to use a formControl we should also support this
  @Input('formControl') extFormControl: FormControl;

  @Output() ngModelChange = new EventEmitter();
  @Output() valueChanged = new EventEmitter();


  componentRef: ComponentRef<Ng2AutoCompleteComponent>;
  wrapperEl: HTMLElement;
  el: HTMLElement;   // this element element, can be any
  acDropdownEl: HTMLElement; // auto complete element
  inputEl: HTMLInputElement;  // input element of this element
  formControl: AbstractControl;

  constructor(private resolver: ComponentFactoryResolver,
              private renderer: Renderer,
              public  viewContainerRef: ViewContainerRef,
              @Optional() @Host() @SkipSelf() private parentForm: ControlContainer) {
    this.el = this.viewContainerRef.element.nativeElement;
  }

  ngOnInit(): void {
    // wrap this element with <div class="ng2-auto-complete">
    this.wrapperEl = document.createElement("div");
    this.wrapperEl.className = "ng2-auto-complete-wrapper";
    this.wrapperEl.style.position = "relative";
    this.el.parentElement.insertBefore(this.wrapperEl, this.el.nextSibling);
    this.wrapperEl.appendChild(this.el);


    //Check if we were supplied with a [formControlName] and it is inside a [form]
    //else check if we are supplied with a [FormControl] regardless if it is inside a [form] tag
    if (this.parentForm && this.formControlName) {
      if (this.parentForm['form']) {
        this.formControl = (<FormGroup>this.parentForm['form']).get(this.formControlName);
      } else if (this.parentForm instanceof FormGroupName) {
        this.formControl = (<FormGroupName>this.parentForm).control.controls[this.formControlName];
      }
    } else if (this.extFormControl) {
      this.formControl = this.extFormControl;
    }

    // apply toString() method for the object
    if (!!this.ngModel) {
      this.selectNewValue(this.ngModel);
    } else if (!!this.formControl && this.formControl.value) {
      this.selectNewValue(this.formControl.value[this.displayPropertyName]);
    }

    // when somewhere else clicked, hide this autocomplete
    //document.addEventListener("click", this.hideAutoCompleteDropdown);
  }

  ngAfterViewInit() {
    // if this element is not an input tag, move dropdown after input tag
    // so that it displays correctly
    this.inputEl = this.el.tagName === "INPUT" ?
        <HTMLInputElement>this.el : <HTMLInputElement>this.el.querySelector("input");

    this.inputEl.addEventListener('focus', this.showAutoCompleteDropdown);
    this.inputEl.addEventListener('blur', this.hideAutoCompleteDropdown);
    this.inputEl.addEventListener('keydown', this.keydownEventHandler);
    this.inputEl.addEventListener('input', this.inputEventHandler);
  }

  ngOnDestroy(): void {
    if (this.componentRef) {
      this.componentRef.instance.valueSelected.unsubscribe();
      this.componentRef.instance.inputChanged.unsubscribe();
    }
    //document.removeEventListener("click", this.hideAutoCompleteDropdown);
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes['ngModel']) {
      this.ngModel = this.addToStringFunction(changes['ngModel'].currentValue);
    }
{'fraction_non_alphanumeric': 0.12199071575083666, 'fraction_numerical': 0.0018352585555435604, 'mean_word_length': 4.275626423690205, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, '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': '4132965', 'n_tokens_mistral': 2661, 'n_tokens_neox': 2625, 'n_words': 626}