2

I have a series of input boxes that are inside of an element and I want to make the parent element of the input boxes to individually have a border based on where the mouse is focused. The code looks like this:

HTML (just one of the input elements, because they are all coded the same way):

<div class="parent-element">
  <input type="text"
    [class.bordered]="myBooleanVariable"
    (focus)="addBorder()"
    (blur)="removeBorder()"
  />
</div>

TypeScript:

addBorder() {
  this.myBooleanVariable = true;
}

removeBorder(event) {
  this.myBooleanVariable = false;
}

The problem that I am having is that when the bordered class is applied on focus, all of the .parent-element divs get borders since myBooleanVariable is either true or false. I want to avoid making static variables like myBooleanVariable1, myBooleanVariable2, etc.

How can I accomplish this?

0

2 Answers 2

7

you can add and remove classes using JS from the component methods, for that all you need, it's create a template variable for your wrapper and paste this variable in the method params, in the method you get HTMLElement of the wrapper

@Component({
  selector: 'my-app',
  template: `
    <div class="parent-element" *ngFor="let i of items" #wrap>
      <input type="text"
        (focus)="addBorder(wrap)"
        (blur)="removeBorder(wrap)"
      />
    </div>
  `,
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  items = [1,2,3];

  addBorder(wrap: HTMLElement) {
    wrap.classList.add('bordered');
  }

  removeBorder(wrap: HTMLElement) {
    wrap.classList.remove('bordered');
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, @izmaylovdev!
1

If you give each input an index, you can have one local variable that controls the reference to the focussed input.

foccused: number | string;

Then you can use [ngClass] to apply the border to your parent element with something like:

<div class="parent-element" [ngClass]="{ 'bordered' : isFocussed(1) }">

So instead of setting a boolean, you set a number with addBorder(1), e.g..

<div class="parent-element" [ngClass]="{ 'bordered' : isFocussed(1) }">
   <input type="text"
   (focus)="addBorder(1)"
   (blur)="removeBorder()"/>
</div>

Where addBorder() becomes:

addBorder(index: number) {
  this.foccused = index;
}

Here's a stackblitz that shows you how: https://stackblitz.com/edit/angular-qqwqjd

You can do some more fancy things with ElementRef and Renderer2, but for what you need, the above should be sufficient.

This way comes with the added bonus of being extendable in a loop, if you had an array of inputs you wanted to output one after another, just replace index with the index provided by *ngFor

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.