Is it possible to achieve Two-Way Binding in a custom directive without relying on NgModel?

I am creating a custom dropdown without using any input element or ngModel for two-way binding. Is it possible to achieve two-way binding with custom attributes?

var mainApp = angular.module('mainApp', []);

mainApp.directive('tableDropdown', ['$timeout',
  function($timeout) {
    return {
      restrict: 'C',
      scope: {
        selectedFilter: '=?'
      },
      link: function(scope, elem, attrs) {
        $timeout(function() {
          angular.element(elem).find('li:first-child').addClass(angular.element(elem).find('li').hasClass('selected') ? '' : 'selected');
          scope.selectedFilter.cycleStatus = null;
          angular.element(elem).find('li').click(function(e) {
              if (angular.element(this).closest('ul').hasClass('active')) {
                angular.element(this).closest('ul').removeClass('active');
                scope.selectedFilter.selected = angular.element(this).attr('value');
              } else {
                angular.element(this).closest('ul').addClass('active');
                scope.selectedFilter.selected = null;
              }
              angular.element(this).addClass('selected').siblings().removeClass('selected');
            })
        }, 0);
      }
    }
  }
])
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<th ng-app="mainApp" ng-init="datefilter.selected=null">
  --{{datefilter.selected}}
  <ul class="tableDropdown" selected-filter="datefilter.selected">
    <li value="null" class="default"><span>Cycle Status</span>
    </li>
    <li value="completed"><span>Completed</span>
    </li>
    <li value="cancelled"><span>Cancelled</span>
    </li>
  </ul>
</th>

The CSS for the dropdown appearance is not included as I deemed it unnecessary.

I aim to retrieve the selected value in datefilter.selected and utilize it for further actions. Is this achievable? If not, are there any workarounds?

Answer №1

Currently, if you ignore the code for setting up the classes, you can utilize the following code to modify datefilter.selected.cycleStatus from within the directive, resulting in changes reflected in the UI.

UI:

--{{datefilter.selected.cycleStatus}}
  <ul class="tableDropdown" selected-filter="datefilter.selected">
    <li value="null" class="default"><span>Cycle Status</span>
    </li>
    <li value="completed"><span>Completed</span>
    </li>
    <li value="cancelled"><span>Cancelled</span>
    </li>
  </ul>

Code:

scope: {
    selectedFilter: '='
  },
link: function(scope, elem, attrs) {

        $timeout(function() {
          scope.selectedFilter.cycleStatus = null;
          elem.find('li').click( 
            function(e) {
              scope.selectedFilter.cycleStatus =angular.element(this).attr('value');
              scope.$apply();
            });


        }, 0);
      }

Take note of the scope.$apply() , which triggers automatic updating of the value in the UI (as it could otherwise show up late after another element initiates the digest cycle)

An illustration is available on this fiddle: http://jsfiddle.net/Lvc0u55v/5503/

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

Set iframe scroll to match the height of the user's screen resolution

Can the height of an iframe scroll be adjusted to match the size of the screen (browser)? Essentially replacing the default browser scroll with the iframe scroll. Here's what I'm looking to achieve: Currently, my browser scroll is disabled: < ...

execute the function based on the given ID

I've been attempting to dynamically add content using a function. My goal is for the content with the same anchor ID as the clicked anchor to be added, but it seems like nothing is happening. Is there a more effective approach to achieve this? $(&a ...

Should we fulfill the CSV Stringify promise in a test, or should we terminate the test when a function is invoked?

Currently, I'm attempting to simulate CSV Stringify using AngularJS, with the intention of extracting two parameters for future verification. My plan is to verify if certain options were correctly implemented later in the test. it("converts latitude ...

Having trouble running npm start with Express generator

After installing Express Generator according to the instructions on the website, I encountered an issue when trying to run npm start. My Windows system has npm 6.4.1 and node v10.15.3 installed. > [email protected] start C:\Users\ONLINEW ...

Verify the correctness of two password fields using jQuery

I need help finding a script that can actively check if the passwords entered in two password fields match while typing. The script should indicate if the passwords do not match without needing to click the Submit button. Below are the two password fields ...

Assistance needed for iterating through JSON data

I need assistance retrieving specific data from a JSON response in my JavaScript code. Unfortunately, the current approach is not providing the desired results: This is my JavaScript code snippet: function retrieveArtists(response){ var artistList ...

It is not possible to utilize a JavaScript function once the script has been loaded through

I am attempting to programmatically load a local JavaScript file - PapaParse library, and then utilize one of its functions: $.getScript("./Content/Scripts/papaparse.js", function () { console.log("Papaparse loaded successfully"); Papa.parse(file, ...

Can VueJS bind the SVG fill attribute with url() when using VueJS?

I am facing an issue with dynamically binding the fill attribute of an SVG rect element in VueJS. To illustrate this problem, here is a simple VueJS component that I have created (also accessible on codepen) <template> <div> <!-- this exa ...

Save picture in localStorage

Hello, I am currently working on a page where I need to retrieve an image from a JSON file and store it locally. Below is the code I have been using: <!DOCTYPE html> <html> <head> <script src="http://code.jquery.com/jquery-1.10.1.min. ...

Transmit an Array using Ajax and retrieve it on an ASP Classic page

I am facing a challenge where I need to pass an array using AJAX on an ASP page. After trying to send it as GET method and checking the data being received, I noticed that only the LAST record of the array is being processed by ASP. How can I successfu ...

Encountered a 'angular is not defined' error message when attempting to upgrade an AngularJS1 component

I am currently in the process of upgrading AngularJS1 components to Angular6. My approach involves creating wrappers for all existing AngularJS1 components by extending "UpgradeComponent" and placing them under the folder "directive-wrappers" in my example ...

After a full day has passed, remove nodes from the Firebase database

Upon initializing my server, I populate Firebase with seed data. In the 24 hours that follow, users contribute additional data, but after this time period elapses, I aim to purge all user data while retaining the original seed information. What is the opt ...

Display map.svg on the browser and execute a function when any area is clicked

Creating an online parking system that is compatible with desktop, iPad, and Android devices is my current project. I have a .svg formatted map for the parking area. I am looking for advice on how to display this map in a browser and execute JavaScript fu ...

Issue with jQuery selector not updating when variable changes

'I am attempting to create a functionality where a function is triggered upon clicking the "hit" class, but only when the correct parent "box" id is selected. var currentSelection = 1; $('#box-' + currentSelection + ' .hit'). ...

What is the best way to access a variable from a different function in JavaScript?

In my current project, I have implemented a function that fetches a JSON string from an external URL. The JSON data is being retrieved successfully and is functioning as expected. However, I am facing an issue with the variable 'procode'. I need ...

Struggling to organize and paginate numbers in angularjs and facing filtering and sorting issues

I'm running into some issues with getting the paging feature to work properly while applying filters. Currently, when the filters are active, the paging numbers do not display correctly and only filter the first page of results. What I'm aiming ...

Having trouble with Autocomplete not entering cities into the form?

While experimenting with Google's API, I have encountered confusion regarding why cities like Staten Island, Brooklyn, Queens, and various others are not being placed into the form like other cities. According to Google's API, "locality" is suppo ...

Guide on creating a darkening effect for lights

Seeking assistance on how to create a light-off effect when clicking on any of my textboxes. I discovered this concept on the following website: What I aim to achieve is that upon clicking a specific textbox, it will be highlighted. Upon clicking the sam ...

Something is seriously wrong with the datetime in fullcalendar JavaScript

I've been diving into a tutorial for creating a calendar scheduler in asp.net MVC5 from this link. One issue I'm facing is the datetime being passed and stored as the min value in the database (1/1/0001 12:00:00 AM), almost like it's null b ...

What is the best approach to assigning a default value to each cascading dropdown using Angular?

I've successfully implemented the dropdown functionality below. Now, I just need help setting default values for each level in the hierarchy. While I know how to do this for the top-level, I'm unsure of how to set defaults for subsequent levels. ...