Updating parent model with select list value using a directive

Seeking help with a directive that produces a select list. I'm trying to pass in the id and value keys of the object for reusability. However, the list isn't binding to its parent model when it's updated. Any ideas on why this might be happening?

Link to code example

index.html

  <!doctype html>
<html ng-app="app">
<head>
</head>
<body>
  <div ng-controller="Ctrl">
    <my-dir list="characters" 
            model="model.character"
            selected-item="model.character.id"
            value-key="id" 
            text-key="name">
    </my-dir>
    <button ng-click="check()">Check</button>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
  <script src="script.js"></script>
</body>
</html>

script.js

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

app.controller('Ctrl', function($scope) {

  $scope.model = { character: { id: 2, name: 'Link' } };
  $scope.characters = [
      { id: 1, name: 'Mario' },
      { id: 2, name: 'Link' },
      { id: 3, name: 'Bowser' }
    ];

  $scope.check = function() {
    alert($scope.model.character.name);
  };
});

app.directive('myDir', function() {
  return {
    restrict: 'E',
    controller: function($scope) {
    },
    template: "<select ng-model='vm.model'>"
    + "<option value=''></option>"
    + "<option ng-repeat='item in vm.list' ng-selected='item[vm.valueKey]===vm.selectedItem' "
    + "value='item[vm.valueKey]' ng-bind='item[vm.textKey]'>"
    + "</option>"
    + "</select>",
    controllerAs: 'vm',
    bindToController: true,
    scope: {
      model:'=',
      list:'=',
      valueKey:'@',
      textKey:'@',
      selectedItem:'='
    }
  };
});

Edit:

This solution works, but is there a cleaner way to handle the blank option without creating clutter? Open to suggestions.

<select ng-model="vm.model" ng-options="item as item[vm.textKey] for item in vm.list track by item[vm.valueKey]"></select>

Edit 2:

Is there a method to make the blank option actually bind to the model with null properties instead of setting the entire model as null when selected?

For instance, selecting the blank value should result in:

$scope.model = { character: { id: null, name: null } };

Rather than:

$scope.model = { character: null };

This refactor would be beneficial for a reusable control like this one. It would be preferable to implement it here rather than altering source data for every object array to include a null value.

I managed to tackle this issue using:

<select ng-model="vm.model" ng-change="selectChange()" ng-options="item as item[vm.textKey] for item in vm.list track by item[vm.valueKey]">
    <option value=""></option>
</select>

...

    $scope.selectChange = function () {
        if ($scope.vm.model === null) {
            var blankItem = {};
            blankItem[$scope.vm.valueKey] = null;
            blankItem[$scope.vm.textKey] = null;
            $scope.vm.model = blankItem;
        }
    };

Answer №1

Two solutions proposed by Michael_J and sara involve utilizing the angular directive for select and including additional content to insert an empty value at the start of the select menu:

<select ng-model="vm.model" ng-options="item as item[vm.textKey] for item in vm.list track by item[vm.valueKey]">
    <option value=""></option>
</select>

This code properly generates all the characters linked to the model and also adds a blank option that will display null when saving the model.

If we would rather use:

$scope.model = { character: { id: null, name: null } };

instead of

$scope.model = { character: null };

to bind to our model on the select element, then we can implement the following:

<select ng-model="vm.model" ng-change="selectChange()" ng-options="item as item[vm.textKey] for item in vm.list track by item[vm.valueKey]">
    <option value=""></option>
</select>

...

    $scope.selectChange = function () {
        if ($scope.vm.model === null) {
            var blankItem = {};
            blankItem[$scope.vm.valueKey] = null;
            blankItem[$scope.vm.textKey] = null;
            $scope.vm.model = blankItem;
        }
    };

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

Managing errors with Node.js and handling https certificates

In short: I am developing a node application that sends requests using the secure version of HTTP, which is HTTPS. When I incorrectly configure my request options, I encounter the following error: Node.js Hostname/IP doesn't match certificate' ...

Remain on the current webpage following the submission of comparable ajax-forms

Seeking assistance with an issue involving Ajax that I believe is unique. Desired Outcome I have a newsfeed with various posts and interspersed forms, such as polls, for user interaction and submission of results. Objectives Users should be able to inter ...

The Material UI autocomplete unexpectedly closes on click instead of displaying a popover as intended

I'm facing a challenge with adding a button to the Material UI autocomplete using the renderOption prop. I added a button to each row that was intended to display a PopOver component, but when clicking on the button, it automatically closes the autoco ...

Adjusting the height of the Sencha Touch container to accommodate its content

In Sencha Touch, I have a view that generates a popup box from the right when a button in the bottom toolbar is clicked: Ext.define('TheApp.view.PopupTablet',{ extend: 'Ext.form.Panel', xtype: 'popupbox', confi ...

Transfer information to component displayed via $mdDialog

I am currently working with angular version 1.6.2 and angular-material version 1.1.4. Below is the implementation of a component I am using for $mdDialog: class CommentReplySettingsController { /** @ngInject */ constructor($mdDialog, $log) { this. ...

How can I set up an automatic refresh for an angularjs iframe?

This code utilizes Angularjs and is designed to be run on a localhost server. The first part of the code can be found in index.html: <iframe src="{{Url}}" width="100%" height="500"></iframe> The second part of the code is located in app.js: ...

I am struggling to set a required input in Angular2

I am new to Angular and currently working on a project that requires input validation to ensure that no field is left blank. The project consists of an HTML file along with a .ts file for functionality. Below is a snippet from the HTML: <div class="f ...

Retrieve the outcome of an AJAX request in JavaScript within a separate function

My uploadFunction allows me to upload files to my server using a Rest web service called with JQuery ajax. I also use this method for another function and need to determine the result of the web service call in order to add a row with the name of the uploa ...

Avoid inputting numbers and special characters

In my coding work, I have crafted a function that detects the key pressed by the user through an event. NameValidation(e){ if(!e.key.match(/^[a-zA-Z]*$/)) { e.key = ''; console.log(e.key); } }, This function essentia ...

Tips for resolving issues with this end-to-end test

Issue arises when clicking on the "Add Rule" button as new "Search Term" and "Search textarea" fields are generated, but Protractor is unable to detect them. describe('Checking for two rules and search terms on "Add New Audience Rule" page', () ...

Creating a three.js visualization of a cheerful X-Y coordinate graph

I am looking to generate a positive X-Y plane in mesh format using three.js. Additionally, I would like the ability to click on any intersection point and retrieve the coordinate values, resembling a graph paper layout. Design.prototype.mouseUp = functi ...

Which takes precedence: the end of the script tag or the backtick?

Currently, I am working on developing a page builder widget. My goal is to save the entirety of the HTML code for the edited page to both local storage and a database. The PHP script will load the saved HTML from the database, while JavaScript will handle ...

Enhance user interface by dynamically updating date options

Incorporating AngularJS ui-date to link Jquery datepicker, I currently have two date pickers on my page - one labeled 'start' and the other 'end.' I am seeking a way to modify the initial value of the end date based on the start date. ...

Retrieving a new child in FireBase using AngularFire

I have structured my data in Firebase using Angular Fire, as shown below: { "notification" : { "1" : { "unseen" : { "upvote" : { "570e10eac28a97de5b17fbcb" : { "-KFJE74zMavEKe5g7J7z" : { "comment" ...

Organize the rows of the table based on two variables

Currently, I am tackling the challenge of dynamically sorting a table using javascript/jQuery. The table rows come with two crucial attributes: deadline (measured in Unix timestamp) status (either 1 or 2) The primary requirement is to sort the table by s ...

ReactJS component's function become operational only after double tapping

Dealing with the asynchronous nature of react hook updates can be a common challenge. While there are similar questions out there, I'm struggling to find a solution for my specific case. The issue arises when trying to add a new product object into a ...

The function JSON.parse appears to be malfunctioning within the code, yet it operates smoothly when executed in

I am facing an issue with my Angular $http post service that communicates with a WCF service. The success handler in the http post is as follows: .success(function (data) { var response = JSON.parse(data); var tsValid = response.Outcome; defer ...

Tips for locating the index while performing a drag and drop operation between two different containers

Can anyone help me figure out how to determine the exact index of an item when performing a jQuery drag and drop between two containers? I'm having trouble identifying the correct index, especially when it's dropped outside of its original contai ...

Example: Utilizing data transfer from model to directive

I have a question regarding a specific part in an example from Thinkster. I believe my confusion is due to my limited understanding of JavaScript and AngularJS fundamentals. I've been teaching myself since December, starting with the basics of JavaScr ...

What is the best way to send a distinct identifier using JavaScript or PHP?

I am looking for a way to replace "INSERT+ORDER+ID" with a unique ID when a user clicks on our "Request Information" button to improve visitor tracking. Can anyone provide guidance on how to achieve this? Your assistance is greatly appreciated, thank you ...