Set AngularJS Material Design custom component back to its original state

I've developed a unique AngularJS custom component that acts as a wrapper for a Material Design mdSelect. It allows for easy configuration of available, default, and current values through its bindings.

This component serves as an editing tool within an mdDialog, adapting its options based on the item being edited. It includes a "Next" button to move to the next item for editing. Pressing this button updates the component with new available, default, and current values, like so:

<foo-component default-value="dialog.getDefaultFoo()" current-foo="dialog.currentFoo">
</foo-component>

If no list of available values is provided, the component defaults to one value—the "default-value."

Upon selecting "Next," the values in the mdSelect change according to what's returned by dialog.getDefaultFoo(). The newly selected value becomes dialog.currentFoo.

In situations where dialog.currentFoo is null, I want the control to automatically choose the designated default value or, if none is indicated, the first available value. This is straightforward during component initialization with $onInit. However, how do we determine inside the component when the user has clicked "Next" and the available values have changed?

When the "Next" button is clicked, this.fooForm.$setPristine() is called. According to the documentation, this method affects all controls within the form. My idea was to have the custom control detect the call to $setPristine() to automatically select a default value if the new value is null. Yet, detecting this action still presents a challenge—how can the custom component know when $setPristine() is triggered on the form?

Ultimately, the custom component must identify changes in its bound values and update other values accordingly under specific conditions. Using a getter/setter approach from outside the component is a possibility, but the key dilemma remains: how does the custom component recognize modifications in its bound values?

To complicate matters further, dialog.currentFoo operates as a function recognized by my component as a getter/setter which retrieves/updates the value depending on the dialog's status. Spotting changes in this value is difficult because the function itself doesn't alter—only the value it returns shifts.

Even more complexity arises as the mdSelect is merely one element sent to dialog.currentFoo; otherwise, it isn't propagated beyond the component boundaries.

In summary, my custom component needs to ascertain whether the binding dialog.currentFoo, essentially a getter/setter function, might now yield

null</code. In such cases, the component should select a dynamic default value based on the evolving items listed internally in the <code>mdSelect
. I'm open to alternatives, such as detecting calls to $setPristine() or even resorting to hacks like forcing AngularJS to recreate the component upon external state changes.

Answer №1

Dealing with AngularJS custom components can be quite challenging due to the complexity involved in tracking information for these types of controls.

The key step is to ensure that the custom component utilizes the standard ngModel framework. Attempting to mimic this behavior using a two-way binding like currentValue isn't sufficient for such intricate tasks, as ngModel is the preferred approach according to AngularJS guidelines. To achieve this, incorporating NgModelController becomes essential. Although finding resources on implementing this with a component can be tricky, a helpful resource provides some valuable insight into the process:

require: {
  ngModelCtrl: "ngModel"
},
bindings: {
  ngModel: "<"
  //TODO add defaultValue or any other properties here
},

Interacting with the value should be done through the NgModelController interface:

//get the current value
const foo = this.ngModelCtrl.$modelValue;
//set the current value
this.ngModelCtrl.$setViewValue(foo);

Moreover, adding

ng-model-options="{getterSetter:true}"
to the component will automatically apply the ngModelOptions to your model, enabling automatic invocation of getters/setters.

This integration with the ngModel framework allows for leveraging NgModelController to incorporate validators and advanced functionalities seamlessly.

In terms of resetting the component under specific circumstances, tapping into NgModelController#$setPristine() proves beneficial. By being part of the ngModel framework, the form controller can trigger $setPristine() when reverting the form to its original state.

this.$onInit = () => {

    this.ngModelCtrl.$setPristine = () => {
      myInternalValue1 = null;
      myInternalValue2 = this.defaultValue;
    };

    this.ngModelCtrl.$setPristine(); //initialize default value
};

This clarifies the query regarding the form controller’s mechanism of propagating $setPristine() to all contained controls within the form, as previously mentioned. The crucial aspect is to integrate the component into the authentic ngModel system for seamless interaction in alignment with AngularJS standards and access to vital internal methods.

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

The JQuery loading symbol does not prevent keyboard interactions

I successfully implemented a Jquery busy indicator in my application using the following link: However, I noticed that even though it prevents users from clicking on input elements while loading, I can still navigate to these elements by pressing the tab ...

How can I shift the button's location within a pop-up in Ionic 1?

enter image description here I am struggling to make the button green underneath the three other buttons. Can someone please assist me with this? Here is my code: $scope.showIntroductionPage = function(childs){ if(childs == 0){ var myPopup = $io ...

The Ng-include tag does not provide highlighting for its text

Within an ng-include template, I have a div that is not highlighting when hovered over. Although the cursor changes to a pointer when hovering over the text, attempting to click and drag to highlight it results in nothing happening. This issue is signific ...

Create animations for ng-repeat elements without using ng-animate

Can the transition for changing the order of the model array in ng-repeat be animated using only CSS, without using ng-animate? ...

The functionality of Ng-Show is acting up

$scope.stay = function() { alert("Inside Keep me In") $scope.timed = false; $scope.isLogStatus = true; } $scope.displayAlert = function() { $scope.timed = true; alert("inside display") } function idleTimer() { var t; $window.o ...

The ultimate guide to personalizing group titles in Angular UI-Select

Is there a way in Angular ui-select to customize the group label? I want to make it larger than the selection items as shown in the image below. https://i.stack.imgur.com/ofcak.png The list is currently grouped by country, but how can I adjust the size o ...

What's causing ng-show to malfunction in IE11 on AngularJS?

I am experiencing a strange issue with my code - ng-show works perfectly fine on Firefox, but not on IE 11. <div ng-show="isExist" class="panel panel-default"> Here is the relevant code snippet from the controller: $scope.isExist = false; if(user ...

Where can I locate a specific child element in this scenario?

Currently, I am exploring the possibilities of integrating AngularJS into my application and have encountered a question regarding the click event implementation. Within my HTML code: <div ng-click='clickMe()' ng-controller='testCtrl&ap ...

Tips for implementing an image as a background in AngularJS

Struggling with a Dilemma: This issue has been driving me insane for the past three days... I am eager to utilize an angularJS variable as a background image without relying on a directive. My objective is to load images of any shape (square, rectangle, ...

Ionic ion-view missing title issue

I'm having trouble getting the Ionic title to display on my page: http://codepen.io/hawkphil/pen/oXqgrZ?editors=101 While my code isn't an exact match with the Ionic example, I don't want to complicate things by adding multiple layers of st ...

What's the reason why Angular stops flickering with the use of "/" in href?

Recently, I've come across a peculiar issue in one of my web applications while using Angular's routeProvider as a template engine. The app functions properly, but the behavior seems inexplicable to me. The problem arises during page transitions ...

Is there a way for me to expand the dropdown menu?

My current dropdown looks like this. I'd like the dropdown menu to span across the screen, something like this: To create my dropdown, I am using https://github.com/angular-ui/ui-select2. AngularJS JQuery Select2 I'm not sure if there is an ...

How can I adjust the height of an iframe dynamically using AngularJS?

I wrote a function that resizes the height of an iframe element to always be 100% after it loads: app.directive('iframeAutoSize', [function() { return { restrict: 'A', link: function(scope, element, attrs) { ...

Turn off the CSS hover effect for a custom button if the ng disabled attribute is set to true

My goal is to disable custom buttons, and the disable(pointer) function is working correctly. The issue arises when we try to hover on the button, as the hover effect still works. I therefore need to disable hover as well. I am looking to apply ng-disabl ...

Troubleshooting problem with infinite scrolling in AngularJS with Ionic framework

I recently created a webpage with an infinite scroll page load more script using Ionic AngularJS. However, I encountered an issue where the page restarts from the beginning once it reaches the bottom. Below is the HTML code snippet: <ion-content class ...

Submitted input in a text field is automatically displayed in a separate text box

Below is a snippet of HTML code from my AngularJS application <input type="text" class="input-xlarge" id="user_name" ng-model="myModel.text" name="user_name" rel="popover" data-content="Enter your first and last name." data-original-titl ...

Firefox experiencing trouble handling flexbox overflow

Having some trouble with a test project that involves using flexbox. The task at hand is to create a dashboard with multiple lists of cards arranged side-by-side with infinite overflow. I was able to achieve this layout, however, the issue arises when eac ...

The issue I'm facing is that the style loader is failing to load the CSS within the <head

I am currently facing an issue with importing my CSS into my webpack bundle for our Angular 1 application. Initially, everything was working fine as we bundled our application using Webpack. The HTML included the bundle and vendor scripts, additional Java ...

Tips for positioning a div next to an input box when it is in focus

I am working on a scenario where I have used CSS to extend the search box when focused. The idea is that when the search box is focused, it should decrease in size and a cancel button should appear next to it. This is the CSS code I am using: .clrble .fr ...

Tips for keeping the main section from scrolling while scrolling through the side navigation

Within my Angular application, I have implemented a sidenav and a main section. My desired behavior is to prevent any scrolling in the main section while I am scrolling in the sidenav, similar to the functionality seen on the Angular Material Design docume ...