Angular directives enable the addition of DOM elements using ng functions

I'm currently working on creating a custom directive for a small input field that only accepts text. The goal is to dynamically change an icon from a search glass to an X if there is text in the input field, and clear the text when it is clicked on. I have added the necessary HTML code to the input field, but I am struggling to get the native ng directive to function correctly. As I am relatively new to Angular, I am hoping that someone can offer assistance. While I have found some similar questions online, none of the solutions provided have fully resolved my issue.

angular.module('myApp')
    .directive('searchBox', function ($compile) {
        return {
            restrict: 'A',
            scope: {
                ngModel: '='
            }
            link: function(scope, element, attrs) {
                var appendix = angular.element(
                    '<span class="input-group-addon" ng-click="ngModel = none">' +
                    '  <i ng-hide="ng-model" class="fa fa-search"></i>' +
                    '  <i ng-show="ng-model" class="fa fa-close"></i>' +
                    '</span>');
                var wrapper = angular.element(
                    '<div class="input-group input-group-sm search-box-custom"></div>'
                );
                element
                    .wrap(wrapper)
                    .after(appendix);

                element.removeAttr("search-box"); //prevent endless compile loop
                element.removeAttr("data-search-box"); //prevent endless compile loop*/
                $compile(appendix)(scope);

            }
        };
    });

The ng-model is specified within the input field

<input search-box
       type="text"
       ng-model-options="{debounce:1000}"
       ng-model="inputValue"
       placeholder="Hier Tippen..." />

Edit: The directive should have its own scope that is connected to the parent scope, but separate as the parent value may vary in different contexts.

Answer №1

Here is the code snippet that should work effectively:

var appendix = angular.element(
   '<span class="input-group-addon" ng-click="inputValue = null">' +
   '  <i ng-hide="inputValue" class="fa fa-search"></i>' +
   '  <i ng-show="inputValue" class="fa fa-close"></i>' +
   '</span>');

I have also provided a link to a jsFiddle for better understanding.

Important information:

The scope property can be set as true, an object, or a falsy value:

  1. falsy: No separate scope will be created for the directive, it will use its parent's scope.
  2. true: A new child scope will be created that inherits from its parent if multiple directives request new scopes on the same element, only one new scope is created. The root of the template always gets a new scope.
  3. {...} (an object hash): An "isolate" scope is created for the directive's element, which does not inherit from its parent scope. This is useful for creating reusable components without unintentionally affecting the parent scope.

In your directive, no specific scope is created by default, allowing direct access to inputValue within your custom directive.

Edit 1

For more details, refer to the jsFiddle. The key idea is to use modelSetter and modelGetter in conjunction with helpful functions:

let modelGetter = $parse(attrs['ngModel']);
let modelSetter = modelGetter.assign;

scope.reset = function () {
    modelSetter(scope, null);
};

scope.isEmpty = function () {
    return !modelGetter(scope);
};

var appendix = angular.element(
    '<span class="input-group-addon" ng-click="reset()">' +
    '  <i ng-show="isEmpty()" class="fa fa-search">Search</i>' +
    '  <i ng-hide="isEmpty()" class="fa fa-close">Delete</i>' +
    '</span>');

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

Struggling to retrieve information from a JSON file and display it within a component?

After accessing the JSON data and storing the necessary values in a dictionary named details, I am encountering an issue where the values are displayed when console logged from inside the function but appear as undefined when console logged in the parent f ...

The map function yields identical outcomes for all of the buttons

I need help with mapping an object that contains various note titles: ['note_title_test', 'note_title_test2', 'note_title_test32', 'note_title_test232', 'test title', 'testing1'] Below is the map ...

Saving JSON format in VueX State Management

I'm relatively new to using Vue/VueX and I am exploring methods for storing JSON data in the VueX state. Initially, it seemed like a simple task: state { jsonthing: { ... } } However, I encountered an issue where getters return an Observer type ins ...

Is there a way to grab the inner content of an e-mail link by right-clicking on it?

I am currently developing a Chrome Extension that functions similarly to the "Search on Google" feature when you right-click on selected text. However, I am facing an issue with making it work when right-clicking on a mailto: email link. How can I extract ...

Encountering a ValueError when attempting to validate form fields with Django and JavaScript

I encountered an error while trying to validate a field using Javascript and Django. Error: ValueError at /insert/ invalid literal for int() with base 10: '' Request Method: POST Request URL: http://127.0.0.1:8000/insert/ Django Version: ...

Submitting an Ajax form refreshes the page

After submitting the form, the page reloads and I am trying to prevent that from happening. Latest Update: After receiving some feedback, I have made changes to my code. The form submission now works correctly, but the page still reloads. Previously, this ...

Transitioning from Webpack version 4 to version 5 resulted in a failure to detect certain styles

After migrating my React project to Webpack v5, I am facing an issue where none of my .scss files are being picked up when I run the project. I meticulously followed the guide on migrating webpack https://webpack.js.org/migrate/5/, updated all plugins and ...

Upgrade button-group to dropdown on small screens using Bootstrap 4

I am currently developing a web application and incorporating Bootstrap 4 for certain components such as forms and tables. Within the design, I have included buttons grouped together to display various actions. Below is an example code snippet: <li ...

Troubleshooting Material-UI Menus

I need the menu to adjust its height dynamically as the content of the page increases vertically. Even though I have applied "height:100%" in the styles, it doesn't seem to work. Can anyone assist with this issue? Here is the code snippet: import R ...

Is it possible to integrate Angular 2 with Thymeleaf in a single application?

I'm trying to combine Thymeleaf th: with Angular2 templates, but I'm having trouble getting them to compile together. Is there a way to make them work simultaneously? import {Component, NgModule} from '@angular/core' import {BrowserMod ...

Transforming a form submission into an AJAX post while already in an AJAX post

I am looking to convert a form submission to an ajax post request while working within the codeigniter framework. The current JavaScript code is: $('#book-appointment-submit').click(function(event) { event.preventDefault(); var formData ...

Adding data to a deeply nested array structure in MongoDB using Mongoose

My backend, built with Node.js using Express and MongoDB through Mongoose, features an array structure comprising three levels. At the third level, some files are stored. However, I now face the challenge of dynamically adding entries at any level based on ...

Failure to Reach AngularJS ng-click Function

When trying to add a new product to the product list, I am facing an issue. The products load correctly but the ng-click function is not being triggered. (The alert I set up in the addProduct function is not appearing). HTML <div ng-controller="Produc ...

Invoking JavaScript function from an Android Activity

I have a simple JS function that is supposed to set values of some html contents, but it doesn't seem to be working properly. Here is the code for the JS function: function SetEdits(name,email,pic,date) { document.getElementById("myPic").src=pic; doc ...

Is there a way to dismiss a modal window from the parent?

How can I close a modal window from its parent? This task seems quite challenging to accomplish. Essentially, I am opening a non-modal window. In some cases, the user may open a modal window from this non-modal window. If I close the non-modal window, I al ...

Close the overlay by clicking outside of it

I'm working on creating a unique pop-up window that appears when a customer adds a product to their cart. The design features red and green background divs with a darker overlay (#overlay-daddy) and a white child div (#overlay). My issue arises from ...

Display different website content in a div when the page loads

My current project involves creating a team website hosted on a LAMP server. This website includes various "team pages" dedicated to different age groups. I am facing the challenge of integrating "external" content (from another page within my domain) into ...

Identify when 2 sets of radio buttons are chosen using jQuery

I need assistance with a webpage that presents the user with two simple yes-no inquiries. Below each question, there are two radio buttons for selecting either yes or no. <p>Question 1: Yes or No?</p> <input type="radio" name="q ...

Executing a callback function in Swift using JavaScriptCore

Struggling to figure out how to call a Javascript Function with a callback from Swift, but it's not working as expected. Here's what I have: Javascript: global.calculateWithCb = function(temp,cb){ cb(5 * temp) } global.calculate = functi ...

jQuery toggle function not working properly on first click

Why does my first click not work, but the second one does? This is the code snippet: $(function () { $("#clickme").toggle(function () { $(this).parent().animate({left:'0px'}, {queue: false, duration: 500}); }, function () { ...