How can we temporarily exclude a model property in AngularJS when a form field is disabled?

Take a look at this example:

http://codepen.io/troywarr/pen/zxWLeZ

I'm working on a form similar to the one in the example where users can opt out of entering certain data by clicking a checkbox. I am using ng-disabled to disable the relevant field ("Age" in my case) when the checkbox is checked.

It works well if they click the checkbox before entering data into the field. However, if they enter data first and then click the checkbox to disable it, the data remains in both the model and the view; it is just locked from changes.

Here's what I want to achieve:

  • Even if the user enters data into a field that they later disable, remove that data from the model. For instance, if the checkbox is checked and both "Name" and "Age" are filled out, I would like the user object to only be:

    { "name": "John" }
    

    instead of:

    { "name": "John", "age": 35 }
    

Additionally, I would like to:

  • Clear the data from the view as well (emptying the "Age" field).
  • Make the data removal reversible. If a user enters their age as 35, then checks the checkbox to disable it, the "Age" field should empty (and the user model should lose the age property). When they uncheck the checkbox, the value 35 should return to both the "Age" field and the model. In other words, preserving their work if they change their mind.
  • Implement this approach at scale with a reusable directive or a simple expression, as my form is complex with many instances of this behavior and there will be more similar forms in the future.

My initial idea was to either:

  • Set ng-model for the "Age" field conditionally based on the checkbox state
  • Unbind the "Age" field when the checkbox is checked and re-bind it when unchecked

But how can I accomplish this? Is there a simpler method?

I have tried various combinations of directives but haven't found a solution yet. I am now exploring the documentation, but would appreciate some guidance. Thank you!

Answer №1

I propose utilizing a directive for handling both the checkbox and textbox elements.

After reviewing your code pen, I have formulated the age control directive below:

angular
  .module('example', [])
  .controller('exampleController', function($scope) {
    $scope.user = {};
  }).directive('ageControl',
    function() {
        return {
            template: '<input type="checkbox" ng-model="hideAge" ng-click="setAge()" />Hide Age<br />Age: <input type="text" ng-model="age" ng-disabled="hideAge" />',
            scope: {
              age: "="
            },
            link: function (scope, elem, attr) {
              var lastAge = null

              scope.setAge = function() {
                if (scope.hideAge) {
                lastAge = scope.age;
                scope.age = undefined;
              }  else {
                if (lastAge) {
                    scope.age = lastAge;
                }
              }
           }
        }
      }
   });

Find the working codepen example here: http://codepen.io/anon/pen/ZYxMQL

To make this solution universally applicable, you only need to parameterize the labels accordingly.


UPDATE

Check out this sample directive that enables a checkbox to disable multiple form controls and remove their associated values from the model:

http://codepen.io/troywarr/pen/XJExaO?editors=101

Answer №2

A great way to handle this is by utilizing the angular.copy() method. Simply store the array or object in a $scope variable when hiding, and then restore it when unhiding. For a hands-on example, you can check out this demo.

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

receiving an error message due to attempting to access an

I'm facing an issue with replacing objects in an array using JavaScript. I tried to use indexOf and splice methods, but it's not working as expected. The value returned by indexOf is '-1', indicating that the object is not found in the ...

Guide to building interactive dropdown menus in Angular 8

In my user interface, each row contains three dropdowns for level 1, level 2, and level 3, as well as an "Add Level" button. When the "Add Level" button is clicked, a new set of three dropdowns for level 1, level 2, and level 3 should be added dynamically ...

Problem encountered with sending automated responses in Discord bot for updates on current events

Issue with Automated Replies in Discord.js' Functionality I'm currently developing a Discord bot using the Discord.js library in Node.js, and I've encountered a problem with the automatic replies feature. The bot's main task is to retr ...

Adjusting AJAX Parameters with Form.serialize() Before Sending Using jQuery

When a button is clicked, I have a jQuery.ajax() POST request that has its $(this).parents('form').serialize() set as the data parameter. The form contains a Textarea with a default placeholder text that I want to replace with a blank value just ...

Exploring the functionality of Next.js with Links and routes

Currently, I am facing an issue with the popover menu in my header that displays products. The problem arises when I click on a product in the list; it navigates correctly to the path "products/some-product" regardless of the selected item. However, if I a ...

What causes Next.JS to automatically strip out CSS during the production build process?

Encountering unpredictability in CSS loading while deploying my Next.JS site. Everything appears fine locally, but once deployed, the CSS rules seem to vanish entirely. The element has the attached class, yet the corresponding styling rules are nowhere to ...

Looking to implement pagination in Vue.js - what steps should I take?

Hi there, I'm currently facing an issue while trying to paginate my data. The error message in my console reads: Property or method "$index" is not defined on the instance but referenced during render. Below is my HTML template where I display the da ...

Unable to display a cube using Three.js on a custom WebGL layer in Mapbox GL JS

Attempting to showcase the cube using this example: Add a 3D model. The example functions fine up to version 117 on three.js. However, starting from version 118, the cube disappears immediately after refreshing the page. After reviewing the changelog, it ...

Utilize a CSS selector to target all deleted nodes using the MutationObserver in the HTML5 API

Is there a way to retrieve all removed nodes from the DOM that have specific classes using CSS selectors? Below is an example of how it can be done with some complexity, but is there a simpler and more general approach? new MutationObserver(mut =& ...

Traversing an array of objects in TypeScript and appending to a separate array if not already present

I have been given an array containing objects in the following format: export interface Part { workOrder?: string; task?: string; partNumber?: string; qty?: number; image?: string; name?: string; } My goal is to loop through each object in th ...

Displaying events in the all-day section can be achieved by setting the defaultView of fullCalendar.js to 'agendaDay'

Trying to use fullCalendar.js with defaultView set to agendaDay, and pulling events from mysql as JSON. However, I'm encountering an ERROR where it displays the events in the 'all-Day' section. Here are some of the solutions I attempted: e ...

Changing an object to an array in Angular

As a newcomer to javascript and angular, I am facing a challenge. I have a JSON object like this: {"xyz":{Key:info}}. My goal is to add {Key:info} into an array. Specifically, I want to transform "xyz" into an array format. For example: {"xyz":[{Key:info} ...

Angular code is malfunctioning and not delivering the expected results

I currently have setup the code below: var videoControllers = angular.module('videoControllers', []); videoControllers.videoControllers('VideoDetailController', function($scope, $routeParams, $http){ $http.get('http://localho ...

Deliver JavaScript and HTML through an HTTP response using Node.js

My attempts to send both a JavaScript file and an HTML file as responses seem to be failing, as the client is not receiving either. What could be causing the client to not receive the HTML and JavaScript files? I am using Nodejs along with JavaScript and H ...

Tips for organizing JSON data in AngularJS are as follows:

Can someone assist me in looping this array value into 3 columns using angularjs? Currently, my view appears as an HTML table with 3 columns, but the values are displayed vertically instead of horizontally. You can see an example of how it looks here. Bel ...

Exploring the method to retrieve data on the server side through Express when it is shared by the client within a put request

Here is the angular http put request I am working with: sendPutRequest(data) : Observable<any>{ return this.http.put("http://localhost:5050", data).pipe(map(this.handleData)); } After making this call, the server side method being invoked is ...

Utilize NodeJS API to convert a base64 data string into a downloadable PDF file

My NodeJS API is set up to communicate with another API and fetch a data object in the form of a Base64 string. The client making the API call needs to be able to download a PDF file generated from this base64 data. What is the best way to return the dat ...

Using localStorage in Next.js, Redux, and TypeScript may lead to errors as it is not defined

Currently, I am encountering an issue in my project where I am receiving a ReferenceError: localStorage is not defined. The technologies I am using for this project are Nextjs, Redux, and Typescript. https://i.stack.imgur.com/6l3vs.png I have declared ...

Changing the color of a marker on hover in Mapbox using leaflet.js

I have encountered an issue where setting the geojson triggers the mouseover event, causing an infinite loop and breaking functionality. I managed to fix it by changing it to click, but now I need to figure out how to make it work with hover. My goal is t ...

Can you explain the significance of this HTML code?

While examining some source code, I came across the following: <div class="classname {height: 300px; width: 200px}"></div> I am aware that element styling can be done using the style="" attribute. Could you explain what this code snippet sig ...