What is the most effective method for creating a personalized select in Angular?

I am currently working with the MEAN stack (Angular 6) and exploring different methods to build a custom and reusable <select> form control that utilizes an array of strings fetched from the backend server to generate all the <option> tags. For instance, let's consider having 3 materials: wood, metal, and plastic. The returned array can be structured in two ways as shown below:

(in my example.component.ts)

form = new FormGroup({
  'material' = new FormControl('')
});

get material() {return this.form.get('material');}

materials = [
  {
    key: "mat_wood",
    value: "Wood"
  },
  {
    key: "mat_metal",
    value: "Metal"
  },
  {
    key: "mat_plastic",
    value: "Plastic"
  }
]

or

(in my example.component.ts)

form = new FormGroup({
  'material' = new FormControl('')
});

get material() {return this.form.get('material');}

materials = [
  {"mat_wood": "Wood"},
  {"mat_metal": "Metal"},
  {"mat_plastic": "Plastic"}
]

Now, we need to implement this structure in our HTML code which will look like this:

(in my example.component.html)

<form [formGroup]="form">
  <div class="select-wrap">
    <span class="select-value">{{}}</span>

    <select formControlName="material">
      <option *ngFor="let mat of materials" value="{{}}">{{}}</option>
    </select>
  </div>
</form>

The expected output should be:

  <select formControlName="material">
    <option value="mat_wood">Wood</option>
    <option value="mat_metal">Metal</option>
    <option value="mat_plastic">Plastic</option>
  </select>

This is a typical example of a custom select structure where the selected option text is displayed in the

<span class="select-value">
. The <select> tag has an opacity set to 0 and positioned over the <span>, enabling users to click on it to activate.

To achieve the desired functionality, each option must have the corresponding key prefixed with mat_ inside the value attribute and display the readable value as text within the option element.

My question is: What is the best way to insert the selected option text into the <span> element? I am seeking a reusable approach to accomplish this task.


EDIT:
After reviewing the initial response, I realize the usage of a template variable can address the issue. However, if there are multiple dynamically generated selects within an *ngFor loop, is it feasible to have dynamically created template variables for each?

Answer №1

One suggestion is to assign a template variable such as mySelect to your select element.

<select #mySelect formControlName="material">
  <option value="mat_wood">Wood</option>
  <option value="mat_metal">Metal</option>
  <option value="mat_plastic">Plastic</option>
</select>

You can access its options.text property in this way:

{{ mySelect && mySelect.selectedIndex > -1 ? mySelect.options[mySelect.selectedIndex].text : ''}}
within your span tag.

More information on template variables can be found here

Answer №2

Give this dynamic option example a try

Using Html

<mat-form-field>
  <mat-select placeholder="Select"    [(value)]="selected">
    <mat-option *ngFor="let data of materials" [value]="getKey(data)">{{getValue(data)}}</mat-option>
  </mat-select>
</mat-form-field>

<p>Your selection: {{selected}}</p>

In TypeScript

@Component({
  selector: 'select-value-binding-example',
  templateUrl: 'select-value-binding-example.html',
  styleUrls: ['select-value-binding-example.css'],
})
export class SelectValueBindingExample {
  selected = 'option2';
  materials = [
  {"mat_wood": "Wood"},
  {"mat_metal": "Metal"},
  {"mat_plastic": "Plastic"}
]
getValue(obj)
{
return obj[Object.keys(obj)[0]]
}
getKey(obj)
{
return Object.keys(obj)[0]
}
checkValue()
{
 console.log( this["mySelect"])
}
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

generate an array composed of promises to be used with Promise.all

Currently, I am working with an array of file paths and my goal is to read all the files inside a Promise.all function, followed by carrying out several tasks. var files = ["./file1.txt", "./file2.txt"] Promise.all(files.forEach(file=>{ /* read file ...

Ways to assign a CSS class specifically for images

.calendarList { background-image: url('/resource3/hpsc/common/images/calendar.png'); background-position: 135px 50%; background-repeat: no-repeat; cursor:pointer; } <input type="text" id="toDatepicker" class="cal ...

Flow of logic for AngularJS ns-show

Being a newcomer to angularjs, I am exploring ways to display an html element based on a property of the $scope object without utilizing any form element. Here is the code snippet: <div id="ListApp"> <div ng-controller="ListCtrl"> ...

What is causing the javascript in my svg files not to function when embedded in an html document?

I have the following code for an SVG: <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="470px" height="260px" version="1.1" onload="addEvent ...

Do you know the steps to writing a directive on a class in Angular Js?

The restrict option is usually configured as: 'A' - for matching only attribute names 'E' - for matching only element names 'C' - for matching only class names 'M' - for matching only comments However, ' ...

Decomposing a Vue.js API response into multiple variables

Utilizing vue to send http requests and store data in variables can be done like so: the api response will have the following structure: data: data: [id:1... etc] function: fetchOffers() { this.$http.get('http://127.0.0.1:8000/api/of ...

Update the href attribute with values from the form fields

My current project involves creating a form with 5 input fields: Service type Number of days Number of children Number of adults I want to dynamically change the value of a button based on these variables using JavaScript. Here is my code so far: JS ...

Achieving Vertical Centering of Text in Bootstrap 5 Buttons with Flex Box to Prevent Overlapping Icons

How can I prevent the text on a Bootstrap 5 button with horizontally and vertically centered text, along with a right aligned icon, from overlapping when it wraps? Additionally, how do I ensure that the icon stays vertically centered when the button text w ...

Rule of authentication using Firebase Database

I need to establish a rule in my Firebase Database to prevent unauthorized access for reading and writing purposes. Within my database, there is a collection of words, each containing a "uid" field that corresponds with the uid of the authUser key stored ...

Smoothly scroll to the bottom of a dynamically updated div using native JavaScript

I am in the process of developing a chat application and my goal is to achieve a smooth scrolling animation that automatically moves the page down to the bottom of the div when dynamic messages are loaded. <ul id="messages"> <li ...

Transitioning code from gatsby to nextjs has caused an issue with the aws-sdk integration

I have successfully integrated the aws-sdk with Gatsby by using a .env file to upload a file to an S3 bucket. Now, I am in the process of migrating this functionality to Next.js, but I'm encountering an error in Next.js. Uncaught (in promise) Credent ...

Sorting data by percentages in AngularJS

I am currently facing an issue with sorting percentages in a table column. Despite using methods like parseFloat and other AngularJS (1.5.0) sorting techniques, the percentages are not being sorted as expected. [ {percentage: 8.82} {percentage: 0. ...

Inaccurate ray tracing using an orthographic camera in three.js

Currently working on a 2D CAD drawing viewer using the three.js library. I need the ability to click on objects within the scene to perform operations. However, when utilizing an orthographic camera, I've noticed that the precision of the three.js ra ...

KnockoutJS's data binding feature is failing to display any content within the table rows

My JavaScript function creates a model and applies it to an HTML document using knockoutJS. In the HTML file, I have two different ways of displaying the same data: 1- A select list (which is working fine) 2- A table (not showing the same data) I need a ...

Each time I use console.log to display a user's radio button choice, the output is consistently lagging by one step

It seems that I am experiencing an issue where the console.log output for a user's radio button selection is always one step behind. This occurs even though I have initially set the default radio button selection to "all". For example, when a user cli ...

The error message "npm ERR! enoent" indicates that npm is unable to locate a specific file

How do I troubleshoot this issue? After attempting the master version, I encountered a similar error. My operating system is OSX Yosemite: bash-3.2$ yo meanjs You're utilizing the official MEAN.JS generator. ? Which version of mean.js would you like ...

Utilizing ResolveComponentFactory() with a String Key: A Step-by-Step Guide

My goal: I want to find a way to use something similar to the "resolveComponentFactory()", but with a 'string' identifier to obtain Component Factories. Once I have them, I plan to utilize the "createComponent(Factory)" method. Check out this P ...

Employing ng-click within a displayed column of Datatable

Currently, I am utilizing a plain Datatable in AngularJS without any Angular-Datatable libraries. Everything appears to be working well except for one issue. Here is the datatable code snippet: $scope.siInfoTable = $('#siInfoTable').DataTable({ ...

Whenever the click event is triggered, Ajax is making numerous duplicate calls

Each time I click to fetch my content using an AJAX call, the calls end up duplicating themselves. I've tried various on-click events I came across on Stackoverflow threads, but unfortunately none of them seem to be solving the issue. $(document).rea ...

Issues with displaying images in Fancybox

I've integrated FancyBox into my website, but I'm experiencing a minor issue. While the FancyBox works perfectly in Dreamweaver, it seems to malfunction in various browsers. As someone who is not well-versed in programming, I'm struggling t ...