AngularJS - Directives cannot pass their class name into inner template

My goal is to create a directive that can apply a class name conditionally. However, I encountered an issue where the code only works if the class name is hardcoded into the class attribute. When I attempt to use it with any expression, it fails to work.

For example:

// HTML

// Does not work (unable to find class="editable" in the final output template)
<tit-txt ng-class="true ? 'editable' : ''" ng-model="mdEnt.phone"></tit-txt>

// Works! (class="editable" is found in the final output template)
<tit-txt class="editable" ng-model="mdEnt.phone"></tit-txt>

//JS

.directive('titTxt', function () {
    return {
        restrict: 'E',
        scope: {
            ngModel: '=',
        },
        link: function (scope, element, attrs) {
            scope.editable = element.hasClass('editable') ? 'editable' : '';
        },
        template: '<input ng-class="editable" ng-model="ngModel" />',
    };
})

I am seeking an explanation as to why this is happening and how I can use it with an expression.


UPDATE 1

// HTML

// Does not work
<tit-txt ng-class="{'editable': true}" ng-model="mdEnt.phone"></tit-txt>

//JS

.directive('titTxt', function () {
    return {
        restrict: 'E',
        scope: {
            title: '@',
            fieldName: '@',
            ngModel: '=',
        },
        link: function (scope, element, attrs) {
            console.log(element.hasClass('editable'));
            scope.editable = element.hasClass('editable') ? 'editable' : '';
        },
        template: '<div><span>{{title}}: </span><input id="{{fieldName}}" ng-class="{editable: true}" name="{{fieldName}}" ng-model="ngModel" /></div>',
    };
})

Can someone clarify why I am receiving false in the

console.log(element.hasClass('editable'));
?

Answer №1

When the class attribute is utilized, JavaScript sets the element's class. On the other hand, the AngularJS framework sets the class using the ng-class directive. It should be noted that when multiple directives are present on an element, the order of execution of their respective code is not guaranteed.

It is recommended to prevent AngularJS from manipulating the DOM directly and subsequently altering the model based on the DOM state. In MVC frameworks, the Model stands as the single source of truth, with the DOM being determined directly by the Model.

<tit-txt inner-class="true ? 'editable' : ''" my-model="mdEnt.phone">
</tit-txt>
app.directive('titTxt', function () {
    return {
        restrict: 'E',
        scope: {
            title: '@',
            fieldName: '@',
            innerClass: '<',
            myModel: '=',
        },
        link: function (scope, element, attrs) {
            scope.$watch(attrs.innerClass, function(newValue) {
                console.log("inner-class=", newValue);
            });
        },
        template: `<div><span>{{title}}: </span>
                      <input id="{{fieldName}}" ng-class="innerClass"
                             name="{{fieldName}}" ng-model="myModel" />
                   </div>`,
    };
})

The directive showcases the use of one-way, '<', binding to calculate the value of the inner-class attribute using an AngularJS Expression.

Furthermore, it is important to note the change of ng-model to my-model. The ng- prefix is exclusively for core AngularJS directives. Usage of ng-model should be refrained unless the custom directive effectively integrates with the ngModelController.

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

Guide on sending a JSON object to an EJS javascript loop efficiently

Seeking assistance with passing a Json object named myVar to the home.ejs file below. How should I assign the value to the variable called data? <table id="example" class="table table-striped table-bordered dataTable" cellspacing="0" width="100%"> ...

Video margins within a webview

After numerous attempts to embed a YouTube video in a WebView, I'm still struggling with a persistent small margin on the right side of the video. I've researched similar issues and attempted to address it through JavaScript adjustments without ...

Javascript functions fail to execute as intended

I have a project called calc, which includes various functions such as init. Within this project, there are three buttons that I am adding to the div using jquery. When a user clicks on any of these buttons, it should trigger the inputs function. Based on ...

Accessing BIM Components: Identifying Global and Express IDs through Selection

As I delve into the task of handpicking specific elements from the intricate web of an IFC model, my approach involves utilizing a SimpleRayCaster to cast a ray onto the object with relative success. The challenge lies in identifying the exact entity inter ...

Can loading HTML and js through ajax be considered secure?

I am currently utilizing the Jquery load function $('#result').load('test.php'); in order to dynamically load a page within another page when clicking on a tab. The page being loaded contains javascript, php, and a form. Upon inspecting ...

Exploring Vue Slots: A guide to parsing and rendering slot components

Currently facing a challenge while developing a web page using Vue, specifically with parsing and rendering the child components inside the <slot>. I need to extract the slot content, convert it into an array of components, and display these compo ...

Despite importing jQuery, the variable '$' cannot be located

Whenever I try to click the button labeled test, it doesn't do anything. However, an error message appears in the console debug indicating: Error: Unable to locate variable '$'. I suspect this might be a jQuery issue, even though I' ...

Invoke a function within the React library through ReactDOM.render

Within my index.js file, I have the following code: const store = createStore( combineReducers({ i18n: i18nReducer }), applyMiddleware(thunk) ); syncTranslationWithStore(store) store.dispatch(loadTranslations(translationsObject)); stor ...

Wordpress team exhibition

Does anyone know how to create a Team showcase slider in Wordpress? I have been using slick slider, but I'm looking for a way to add team members easily through a plugin rather than manually. I found an image of what I want it to look like. Can any ...

jQuery Filter for Page Content - choose specific text within paragraphs and clickable links

I recently created a page search filter using Bootstrap 5, but it seems to only display text content and not any content enclosed within the a tags. You can check out the JS Fiddle link provided below for reference: https://jsfiddle.net/mfen723/rozy16pt/1 ...

After upgrading, my npm is completely dysfunctional – it keeps showing the error "Cannot read property 'get' of undefined."

Recently, I updated Node.js to the latest version on my computer. Prior to the update, the 'npm' command functioned flawlessly in the command prompt. However, after installing the new version of Node.js, it stopped working completely. All comma ...

Unusual class exhibiting peculiar async/await patterns

Node 7.9.0 The situation goes like this: class TestClass { constructor() { const x = await this.asyncFunc() console.log(x) } async asyncFunc() { return new Promise((accept) => { setTimeout(() => accept("done"), 1000) }) ...

Is there a method to adjust the styling of my <header> once the page hits a specific #anchor point?

Seeking some assistance with a website design challenge I am facing. I am currently working on a one-page portfolio site with four #anchor points that serve as "pages". Each div has a height of 100% to fill the entire browser height. The header, which co ...

Trouble with launching Semantic UI modal

I have implemented a button using Semantic UI and set up a click event to open a modal when clicked, but nothing is happening. When I click on the link, there is no response. I'm unsure what the issue might be. Below is the code for the button: < ...

Ways to render component solely based on the alteration of the class props

In my ReactJS project, I am fetching JSON data from a RESTful Django host and using it to create a table with filters. Here is my Table class: class MainTable extends React.Component { constructor(props) { super(props); this.state = { res ...

What exactly is the purpose of FormControl and why is it employed? In what ways should FormControl be properly utilized?

I'm a bit confused about how to properly use FormControl in Material-UI when creating forms in React. Can someone simplify for me what exactly FormControl does and why I should consider using it in my project? Currently, I have a Form.js Component wh ...

Ways to ensure that a function completes in an Express route

I currently have a route set up like this: app.get("/api/current_user", (req, res) => { //It takes about 3 seconds for this function to complete someObj.logOn(data => { someObj.setData(data); }); //This will return before ...

Is the automatic garbage collection of components a built-in feature of

Consider this scenario, where I have the following HTML document: <html> <head>... including all the necessary js and css files here...</head> <body> <div class="placeholderForExtPanel"></div> </b ...

Locating the Active Object's Coordinates in fabric.js

When using fabric js, I have successfully drawn various shapes like circles and rectangles. However, I encountered an issue while trying to obtain the coordinates of the rectangle using the fabric.rect() method. canvas.getActiveObject().get('points& ...

Displaying a pop-up window upon clicking on an item in the list view

After creating a list where clicking an item triggers a popup, issues arose when testing on small mobile screens. Many users found themselves accidentally tapping buttons in the popup while trying to view it. What is the most effective way to temporarily ...