Guide on adding an element following a directive in Angular 4

My AngularJS directive is functioning correctly with jQuery, but now I want to convert it to Angular 4.

Previous Directive (AngularJS)

app.directive('errName', function () {
    return {
        link: function (scope, element, attrs) {
            element.bind('error', function () {
                if (attrs.src != attrs.errName) {
                    var name = attrs.errName.split(' ');
                    var attr = '?';
                    if (name.length == 1)
                    {
                        attr = name[0].substring(1, 0);
                    }
                    if (name.length > 1)
                    {
                        attr = name[0].substring(1, 0) + name[1].substring(1, 0);
                    }
                    $(element).hide();
                    $(element).after('<span class="thumb-alpha"><span class="default-thumb"><span class="default-thumb-placeholder">' + attr.toUpperCase() + '</span></span></span>');
                }
            });
        }
    }
});

The old directive checks for errors in the image on load, hides the element, and then creates a span. In my Angular 4 directive, I am able to hide the element and get the value, but struggling to create the span afterwards.

New Directive that I'm working on:

export class ShowInitialsDirective {

    @Input() initials;

    constructor(el: ElementRef, renderer:Renderer) {
        var element = el.nativeElement
        renderer.listen(el.nativeElement, 'error', (event) => {
            var initial_default = '?';
            var name = this.initials;
            name = name.split(' ');
            if (name.length == 1)
            {
                initial_default = name[0].substring(1, 0);
            }
            if (name.length > 1)
            {
                initial_default = name[0].substring(1, 0) + name[1].substring(1, 0);
            }
            this.initials = initial_default;
            renderer.setElementStyle(el.nativeElement,'display','none');
           // element.after('<span class="thumb-alpha"><span class="default-thumb"><span class="default-thumb-placeholder">' + this.initials.toUpperCase() + '</span></span></span>');
        })
    }
}

I would like to know if there's a way to create a span in the Angular 4 directive and insert the specified HTML code.

Answer №1

When working with Angular 2+, it is recommended to create a component if you need to modify the HTML structure. Components in Angular are essentially directives that include HTML templates. In this case, the directive being created is specifically an attribute directive, which does not come with its own HTML template. For further details, please visit the Angular website.

Answer №2

Consider revising your code and converting it into a component for improved organization. If you prefer not to do that, you can utilize the insertBefore method on the parent of nativeElement, coupled with some clever techniques:

const div: HTMLDivElement = document.createElement('div');
div.innerHTML = '<span class="thumb-alpha"><span class="default-thumb"><span class="default-thumb-placeholder">' + this.initials.toUpperCase() + '</span></span></span>';
const insert: HTMLElement = div.firstChild as HTMLElement;
const before: HTMLElement = el.nativeElement.nextElementSibling;
const parent: HTMLElement = el.nativeElement.parentElement;
if (before) {
   parent.insertBefore(insert, before);
} else {
   parent.appendChild(insert);
}

However, a more elegant solution would be to develop an entirely new component to handle all these tasks efficiently.

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

Iterating over ng-repeat, the initial item with a distinct directive

I have this code snippet: <div ng-repeat="i in placeholders" square class="set-holder {{i.class}}" droppable="{{i.type}}"></div> How can I ensure that the first item has the directive bigsquare, while the rest have just square? I attempted: ...

Tips for resolving the AngularFire migration error related to observables

Recently, I decided to upgrade a project that had been untouched for over a year. Originally built on Angular 10, I made the jump to Angular 12. However, the next step was upgrading AngularFire from v6 to v7, and it appears there is an issue with typings. ...

Obtain date and currency formatting preferences

How can I retrieve the user's preferences for date and currency formats using JavaScript? ...

What causes a statically generated page to appear without any style when transmitted to the client?

After setting up the Next.js official boilerplate with npx create-next-app and opening it in the browser, I observed that the static HTML document lacks styling: https://i.stack.imgur.com/mna6K.png I am concerned about potential FOUC issues. How can I en ...

Is there a way to use jQuery to load a ul from a different webpage into a div?

Progress is being made as I work on making two nearly identical pages function seamlessly together. One page features an alphabet list, and when a letter is selected, the other page filters results (last names from a PHP database query) and displays them o ...

Tips for utilizing the Raycaster in tandem with a CombinedCamera?

When trying to implement a Raycaster for selection, I encountered an issue where it worked fine with a PerspectiveCamera but not with a CombinedCamera. It appears that the Raycaster does not support CombinedCamera, so I made some modifications in the thre ...

Leverage route middleware in a Node.js application using Handlebars template engine

When transitioning from using jade to handlebars in expressjs, the Route() middleware becomes a common factor. However, with handlebars having its own way of defining routes, it's possible to encounter issues with controllers within app.js. I have in ...

Stack one series in jQplot while leaving another series unstacked

I managed to get the chart set up with four stacked series, but I'm struggling with positioning the last one outside the stack as a separate bar. Can't seem to figure out how to remove it from the stack. I tried using "paint" to visually represe ...

Enable lodash access throughout a React Native application

Is it possible to have lodash automatically accessible in all files within a React Native project without needing to import it every time? ...

Strip away the HTML tags and remove any text formatting

How can I effectively remove HTML tags and replace newlines with spaces within text? The current pattern I am using is not ideal as it adds extra space between words. Any suggestions on how to improve this pattern? replace(/(&nbsp;|<([^>]+)> ...

changing a one-dimensional array into a two-dimensional array using TypeScript

I need help transforming a flat array into a 2D array, like this: ['-', '-', '-', '-', '-', '-', '-', '-', '-'] My desired output is: [ ['-', '-&apo ...

Generating a dynamic dropdown menu in Ruby on Rails

In my Rails 5 application, I have a 'Course' model with a table setup like this: class CreateCourse < ActiveRecord::Migration[5.1] def change create_table :projects do |t| t.string :name t.string :department t.st ...

How can I enable the assignment of values to $.myPlugin.defaults.key in plugin development?

Challenging question: Note: The plugin pattern showcased here is inspired by the official jQuery documentation. I'm facing a hurdle... How can I modify the plugin pattern below to support the statement $.hooplah.defaults.whoop = 'there it was&a ...

Determine the presence of either one or both values in a JavaScript object

I was looking at an Object like this: {"user": { "name": "Harry Peter", "phoneNumber": "12345", "products": [ { "type": "card", "accountId": "5299367", }, { "type": "Loan", ...

Encountering an issue: Unable to initiate a local server when running `npm start`

Currently diving into the world of React, I successfully set up a React app. However, upon running npm install after typing cd davidsapp, I encountered numerous warnings and errors. Subsequently, when issuing the command npm start, all of the errors are di ...

Customizing the size of dateBox icons in JQuery Mobile

Is there a way to increase the button size within the input box of a dateBox? Currently, it appears small and difficult to click accurately. Additionally, it would be beneficial if clicking anywhere in the input field could open the calendar, instead of ju ...

What are the steps for utilizing POST in conjunction with jQuery Autocompleter?

Version 1.2.6 of jQuery The jQuery.autocompleter plugin version 1.1pre (downloaded from the jQuery website) I'm encountering an issue where I can't submit using 'type: "POST"' back to my webservice with the autocompleter. Any ideas on ...

What is the process for clearing a selection from a table?

I have been facing this issue for some time now. I am working with a basic table where selecting a row highlights it. However, I want to enhance my button functionality by adding a "Remove Selection" feature. When clicked, I need the selected row to lose i ...

Tips for Resolving the "Connection Error: ECONNREFUSED" with Mailchimp API

I've been attempting to connect to the Mailchimp API with the following code: const client = require('@mailchimp/mailchimp_marketing'); client.setConfig({ apiKey: "MY REAL API KEY", server: "MY REAL SERVER", }); asy ...

How can I create an SVG node on a ref using TypeScript?

I'm currently working on creating a reference in React with TypeScript: class BarChart extends Component { private node: React.RefObject<SVGSVGElement | null>; constructor(props) { super(props); this.node = React.createRef(); } .. ...