3

I have attached the stackblitz below

https://stackblitz.com/edit/angular-dgx3pe

What i am trying to achieve is while clicking on the label element it should focus on the input.Hence the input:focus class gets activated.What I belive is that it can be achievable through javascript/jquery.But i prefer the angular way to achieve this.

In Brief,these are the two things i am trying to do,

  • Make focus on the input element when label is clicked.
  • When the focus is changed to another input element and if the previous element is not empty(If some value is typed in).The label should maintain its position in the top.

HTML

<input class="input" type="text">
<label class="label">Name</label>

<div>
<input class="input" type="text">
<label class="label">Name</label>
</div>

CSS

p {
  font-family: Lato;
}
.input
{
  border:none;
  border-bottom:1px solid grey;
  outline:none;
   margin-top:20%;
}
.input:focus
{
    border-bottom:1px solid orange;
}
.label
{
  position:relative;
 left:-170px;
}
.input:focus + .label
{
   bottom:20px;
}
3
  • Do you want label to be constants after first focus event on the element? Commented Jun 1, 2019 at 5:43
  • Why don't you try Mat-Input Commented Jun 1, 2019 at 5:46
  • Label should be back to the position if input has no value..but if it has some value it should be constant and when the value is removed and focus is out it should return back to the original position..Thanks for suggestion but i am trying to avoid material.. Commented Jun 1, 2019 at 5:55

4 Answers 4

3
  1. In the html, add a reference to your input text - #firstNameField and add a method to click event of the label - (click)="focusOnFirstName()"
    <input #firstNameField class="input" type="text">
    <label class="label" (click)="focusOnFirstName()">First Name</label>

  1. In your component declare ViewChild and implement a method to click of label field.
      @ViewChild("firstNameField") firstNameField;

      focusOnFirstName(){
        this.firstNameField.nativeElement.focus();
      }


Sign up to request clarification or add additional context in comments.

1 Comment

Thanks it almost solved my question except the second part..when if there is a value ,the lable should remain at top.When removed it should be back to its original position
2

You can do this with pure markup. You need to add an id to the input and a for element to the label

<input class="input" type="text" id="firstName">
<label class="label" for="firstName" >First Name</label>

This is just part of the html spec - labels can be associated with inputs - the out of the box functionality here is that on clicking a label it sets focus to its associated input. id and for attributes must match for this to work.

For the second part of your question, and to reuse your css classes - add matching variables to your component. Use ngClass to add the .go-top class when the variable has a value

In component -

firstName: string;

Then in the html -

  <input class="input" type="text" id="firstName" [(ngModel)]="firstName">
  <label class="label" for="firstName" [ngClass]="{'go-top': firstName}">First Name</label>

3 Comments

Thanks now i am able to do first part..but can you explain me how it actually works??And also can can you help me while input has some value..label should stay top
Thanks it solved it..Only thing can you suggest me if there is a way to make it dynamically without creating seperate variables for each input
[(ngModel)] is perfect solution for tracking your input value. Make sure you import the forms module so that you don't get an unknown directive error: import { FormsModule } from '@angular/forms'
1

I'm looking at this from the perspective of making a more "Angular" solution for your conditional style request. To that end, you should focus on rolling your input/label combination into a custom input component. Once you've created a component with your original elements as a starting template you can enact the following more effectively.

Basic strategy is to conditionally apply your styles using Angular's [class] property binding or [NgStyle] directives.

  1. Do a ViewChild query on the template for the input element
    1. Add an event listener on the input element in the template
    2. Whenever a keyup event is detected, it will trigger of check of your <input> field value and update a class property representing whether the field is empty
    3. Change detection will trigger, and the [NgClass] or [class] bindings will trigger updates to the element's class
//component.ts

import { Component, Input, ViewChild, ElementRef } from '@angular/core'

@Component({
  selector: 'app-input',
  styleUrls: ['./input.component.css'],
  templateUrl: './input.component.html'
})

export class InputComponent{
  @Input() labelName: string = "Your Label Here"
  @ViewChild("input") myInput:ElementRef<any> //ViewChild query

  empty: Boolean = true; // this property will track whether input value is truthy

  isEmpty(){ // attached to keyup event on input element in your template file

   if (this.myInput.nativeElement.value){
      this.empty = false;
    } else{
      this.empty = true;
    }
  }

  styles(){ // attached to the [ngClass] directive binding on input element in template file
    return {
      'empty': this.empty ? true: false,
      'not-empty': this.empty ? false: true
    }
  } 

}

//component.html with [ngClass] directive

<label for="my-input" #label> {{ labelName }}
<input type="text" id="my-input" [ngClass]="styles()" (keyup) = "isEmpty()" #input>

//component.html with [style] property binding
// in this instance, empty is a reference to the property in the .ts file

<label for="my-input" #label> {{ labelName }}
<input type="text" id="my-input" [class.empty]="empty" #input>

2 Comments

Thanks for you time..If you are making it as a directive how can we attach it to the form..In my case it is reactive form..The specific input directive will ask for a form group which is only availabe at the parent component..Is there a way to overcome this ?
Also the attached code seems little bit confusing can you share the stackblitz.?
0

Please utilize following using class name(Even Id can be used)

 const inputElement: HTMLElement = document.querySelector('.class-name') as HTMLElement;
 if(inputElement){
   inputElement.focus();
 }

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.