0
votes

I am fairly new to Angular.I hope someone could help me figure out what I am doing wrong. I have been trying to figure this out for ages.

I am using pdftron an external api that gives you an ability to show the pdf, select a text and display it. So, I have instantiated the pdftron and as soon as highlight I listen to the event annotation added, I get the data (selected text). Now as soon as people select a text I want it to be displayed on the input field that I have but I am not able to do so. I am displaying all the input fields with the via ngfor iteration. I have a model that defines what goes on form.

This my form model:

export class FormModel {
  id: number;
  inputText: string;
  placeholder: string;
  required: boolean;
  firstCheck: boolean;
  secondCheck: boolean;
  value: any;
  metadata: any;
}

This is my form component:

<div class="row form_content">
  <div class="col-12">
    <form>
      <div
        *ngFor="let item of formelement"
        [class.selected]="item.id === selectedInput"
        class="form-group row"
      >
        <label for="{{ item.inputText }}" class="col-sm-4 col-form-label">{{
          item.inputText
        }}</label>
        <div class="col-sm-6">
          <i
            class="fas fa-exclamation-circle fa-lg mr-1"
            [hidden]="!item.required"
          ></i>
          <input
            type="text"
            class="form-control"
            id="{{ item.inputText }}"
            (click)="onfocus(item.id)"
            placeholder="{{ item.placeholder }}"
            [(ngModel)]="item.value"
            [ngModelOptions]="{ standalone: true }"
          />
        </div>
        <div
          class="col-1 check_circle first_check_circle col-1 d-flex justify-content-center align-items-center"
        >
          <i
            class="fas"
            [ngClass]="
              item.firstCheck
                ? 'fa-check-circle fa-check-circle-checked'
                : 'fa-check-circle'
            "
          ></i>
        </div>

        <div
          class="col-1 check_circle col-1 d-flex justify-content-center align-items-center"
        >
          <i
            class="fas fa-check-circle"
            [ngClass]="
              item.secondCheck
                ? 'fa-check-circle fa-check-circle-checked'
                : 'fa-check-circle'
            "
          ></i>
        </div>
      </div>
    </form>
  </div>
</div>

This is my component typescript file.

import {
  Component,
  OnInit
} from '@angular/core';
import { FormModel } from './form.model';
import { PdfTronService } from 'src/app/components/home/pdftron/pdftron.service';

@Component({
  selector: 'app-form',
  templateUrl: './form.component.html',
  styleUrls: ['./form.component.css']
})
export class FormComponent implements OnInit {
  selectedInput: number;
  formelement: FormModel[] = [
    {
      id: 0,
      inputText: 'Increase Amount',
      placeholder: 'Increase Amount',
      required: true,
      firstCheck: true,
      secondCheck: false,
      value: '',
      metadata: ''
    },
    {
      id: 1,
      inputText: 'Increase Frequency',
      placeholder: 'Increase Frequency',
      required: true,
      firstCheck: false,
      secondCheck: true,
      value: '',
      metadata: ''
    }
  ];

  constructor(
    private pdftronService: PdfTronService
  ) {}

  ngOnInit() {}

  onfocus(id) {
    this.selectedInput = id;
    this.pdftronService.webViewerInstance.setToolMode(
      'AnnotationCreateTextHighlight'
    );
    this.pdftronService.annotManager.on(
      'annotationChanged',
      (event, annotations, action) => {
        if (action === 'add') {
          // this should update the input value and show on UI but it does not until i click the other input field. 
          this.formelement[
            this.selectedInput
          ].value = annotations[0].getContents();
          // code reaches all the way to the end
          console.log('Running from here');
        }
      }
    );
  }
}

As you can see when somebody clicks the input field. I call onfocus and set the pdftron tool to highlight and listen to the event listener on annotationchanged. Once they add highlight annotation, I get the text using the annotation.getContents and update the value for an input. But this does not change the value in the input automatically neither does it when I click outside the input field. It gets updated only when I click the other input field within my form.

But I does not want that instead I want it to be updated as soon as the someone stops selecting text.I don't know what I am doing wrong and has been trying to figure this out for last 2 weeks. I hope the question make sense. I would love to clarify it further. Any kind of help will be much appreciated.

Thank you.

1
Stack Overflow has vary good feature to embed your code while posting a question/answer. Better try using that instead of attaching images of the code file. Posting code improves readability that interns results in quick and better answer to the problem. You never when the link to the images get broken then your question can loose it's meaning. - Atul Dwivedi
I will try that. It was my first time. I will keep that in my mind from now on. - Saugat Dahal
We reviewed your question and it appears to Not be specific to PDFTron Web SDK, but a instead a question for an Angular expert. Hopefully someone more familiar with Angular than myself can assist you. - Ryan
Thanks Ryan for your time. - Saugat Dahal
meta.stackoverflow.com/a/285557/6294072 You will increase your chance to get answers if you post your code as code. I for one don't look twice on a question that has only images. It's very unreadable and no one is going to write an answer long hand not being able to copy your source code. So I really suggest you to refactor your code to get some help :) - AT82

1 Answers

1
votes

I don't know if its the right way to do it but I was able to solve it using the ChangeDetectorRef. I called the method detectChanges once I update the value. Even though I have solved it I don't know if its a right way to do it. Here is what my component typescript looks like and it updates the value as soon as people select the text.

import {
  Component,
  OnInit,
  ChangeDetectorRef
} from '@angular/core';
import { FormModel } from './form.model';
import { requiredDataService } from './form.service';
import { PdfTronService } from 'src/app/components/home/pdftron/pdftron.service';

@Component({
  selector: 'app-form',
  templateUrl: './form.component.html',
  styleUrls: ['./form.component.css']
})
export class FormComponent implements OnInit {
  selectedInput: number;
  formelement: FormModel[] = [
    {
      id: 0,
      inputText: 'Increase Amount',
      placeholder: 'Increase Amount',
      required: true,
      firstCheck: true,
      secondCheck: false,
      value: '',
      metadata: ''
    },
    {
      id: 1,
      inputText: 'Increase Frequency',
      placeholder: 'Increase Frequency',
      required: true,
      firstCheck: false,
      secondCheck: true,
      value: '',
      metadata: ''
    }
  ];

  constructor(
    private requiredData: requiredDataService,
    private pdftronService: PdfTronService,
    private changeRef: ChangeDetectorRef
  ) {}

  ngOnInit() {}

  onfocus(id) {
    this.selectedInput = id;
    this.pdftronService.webViewerInstance.setToolMode(
      'AnnotationCreateTextHighlight'
    );
    this.pdftronService.annotManager.on(
      'annotationChanged',
      (event, annotations, action) => {
        if (action === 'add') {
          // this should update the input value and show but it does not unless i click the other input field
          this.formelement[
            this.selectedInput
          ].value = annotations[0].getContents();
          // Detecting the change in application state. 
          this.changeRef.detectChanges();
          // code reaches all the way to the end
          console.log('Running from here');
        }
      }
    );
  }
}