Tips on updating Angular data model when a static HTML element changes

Currently, I am utilizing the editable-table jQuery plugin to enable editing in a table. This tool is simple to implement, lightweight, and highly efficient.

The markup structure for this task looks like this:

<tr ng-repeat="o in orders">
   <td ng-bind="o.name"></td>
   <td ng-bind="o.weight"></td>
   <td ng-bind="o.dimensions"></td>
</tr>

To make the table editable, all it takes is calling the following function:

$('#ordertable').editableTableWidget();

This implementation functions smoothly: the table displays perfectly and supports editing capabilities. In case there are modifications in the data model, the table refreshes automatically.

However, using ng-bind results in one-way binding, meaning that alterations made in the table do not reflect in the data model without manual updates. Unfortunately, employing ng-model is not feasible as it requires an input field.

Since I am still learning Angular, I am uncertain about the appropriate method to synchronize changes back to the data model. While resolving it through plain JavaScript is possible, my preference is to stick with Angular conventions.

What would be the correct approach to update the data model accordingly?

Answer №1

In my opinion, it's best to avoid mixing the Angular way of updating values with an editable plugin. Since Angular is unaware of the plugin, their integration may not work as intended.

Instead of using a plugin, you could try implementing it without one:

<tr ng-repeat="o in orders">
   <td><input type="text"  ng-model="o.name" /></td>
   <td><input type="text"  ng-model="o.weight" /></td>
   <td><input type="text"  ng-model="o.dimensions" /></td>
</tr>

Answer №2

When you make changes using jQuery, the model is not automatically updated in Angular because Angular is not aware of the changes made and the digest cycle is not triggered. You can manually trigger the digest cycle like this:

$scope.$digest();
// However, this may not always work

Therefore, if you are using jQuery, you will need to explicitly assign a value to the model in order to update it.

Answer №3

If you're looking for an alternative solution to this issue, consider using the 'contenteditable' attribute in table cells with ng-model instead of ng-bind, instead of relying on the jQuery editable-table plugin. You can create a directive for contenteditable to update the model, and there is an example provided on the AngularJS site itself at the end of this page.

I have adapted the directive code from that example and made the necessary changes to your HTML.

directive('contenteditable', ['$sce', function($sce) {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function(scope, element, attrs, ngModel) {
      if (!ngModel) return;

      ngModel.$render = function() {
        element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));
      };

      element.on('blur keyup change', function() {
        scope.$evalAsync(read);
      });
      read();

      function read() {
        var html = element.html();
      
        if ( attrs.stripBr && html == '<br>' ) {
          html = '';
        }
        ngModel.$setViewValue(html);
      }
    }
  };
}]);

<tr ng-repeat="o in orders">
   <td contenteditable ng-model="o.name"></td>
   <td contenteditable ng-model="o.weight"></td>
   <td contenteditable ng-model="o.dimensions"></td>
</tr>

Answer №4

It's not recommended to use jquery based plugins in an angular app as they may not integrate well. It's better to search for angular-specific plugins.

What I did was take the input element utilized by the plugin for user input (Editable cell) and compile it using Angular's $compile service.

I believe this approach should be effective.

HTML :

 <div ng-app='app' ng-controller='mainCtrl' my-input>
     <table id="ir" >
       <tr ng-repeat="o in orders">
         <td ng-repeat="(key, value) in o"  ng-bind="value" ng-click="setCurrentCell($parent.$index, key)"></td>
       </tr>
     </table>
 </div>

Controller :

controller('mainCtrl', function($scope){
   setTimeout(function(){
      $('#ir').editableTableWidget();
   });

   $scope.orders = [{name:1, weight : 10}, {name:2, weight : 20}];
   var editableOrder  = {};
   $scope.setCurrentCell = function(index, key){
        editableOrder.index = index;
       editableOrder.key = key;
   }
   $scope.myEdit = function(newVal){
    $scope.orders[editableOrder.index][editableOrder.key] = newVal;
   }
})

Directive

directive('myInput', ['$compile', function( $compile){
   return {
      restrict: 'A',
      link: function(scope, element, attrs) {
            setTimeout(function(){
              var input = element.find('input');
              input.attr('ng-model', 'val');
              input.attr('ng-change', 'myEdit(val)');
              $compile(input)(scope);
           })
       }
   }
}]);

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 absence of localStorage is causing an error: ReferenceError - localStorage is not defined within the Utils directory in nextjs

I've been trying to encrypt my localstorage data, and although it successfully encrypts, I'm encountering an error. Here's the code snippet (./src/utils/secureLocalStorage.js): import SecureStorage from 'secure-web-storage' import ...

Automatically updating client-side values in AngularJS using setInterval()

Implementing a value calculator on the client side using AngularJS. I need to update the main value of the calculator every 5 minutes with setInterval(). This is my AngularJS code: $http({method: 'GET', url: '../assets/sources.json'} ...

Jquery: Pressing Enter will cause the input field to lose

Take a look at this fiddle I created: http://jsfiddle.net/7wp9rs2s/. This is the progress I have made on my project so far. In the fiddle above, you can double click on one of the 4 items and a textbox will appear for editing. Instead of clicking out of t ...

Can a blob file be transformed into base64Data using Javascript specifically in Ionic and Angular frameworks?

https://i.stack.imgur.com/3aMyx.png[ async FileZip() { const code = await fetch("./assets/input.txt") var blob = await downloadZip([code]).blob() console.log(blob); function blobToBase64(blob: Blob): Observable<string> { r ...

The contrast between FormData and jQuery's serialize() method: Exploring the distinctions

Recently I came across a situation where I needed to submit a form using AJAX. While researching the most efficient method, I discovered two popular approaches - some developers were utilizing jQuery#serialize() while others were opting for FormData. Here ...

Setting up vibration for local notifications in Ionic and Cordova is a straightforward process

Is there a way to enable vibration in local notifications on my mobile device for every notification I receive? Example of Local Notification Code: $cordovaLocalNotification.schedule({ id : remId, title : name.innerHTML, text : note.value, ...

The useEffect hook is failing to resolve a promise

I have received a response from an API that I need to display. Here is a snippet of the sample response (relevant fields only): [ { ...other fields, "latitude": "33.5682166", "longitude": "73 ...

Using jQuery and Perl to create a dynamic progress bar that is based on the current state of a "pipeline file" and utilizes AJAX

I'm looking to create a small pipeline that enables users to select a file and run multiple scripts using it as an input. Some of these scripts may take several minutes to complete (time depends on the file's size), so I want to display a progres ...

What is the best way to access a variable from a .js file?

Is there a way to access a variable defined in a JavaScript file from a Vue file and pass it to the Vue file? In the following code snippet, there is a template.js file and a contact.vue file. The template file converts MJML to HTML and saves the output to ...

Support the Cause with Paypal Contributions on Angular/Bootstrap Website!

I'm currently in the process of developing a website using Angular and Bootstrap for a non-profit organization that will facilitate donations through Paypal. On the platform, users will have the option to select their donation frequency (Weekly, Mont ...

How can I apply angular ng-repeat filter with specific criteria in mind?

I am currently developing an angular application and I need to present customer data in a table using ng-repeat. While I have successfully added ng-filter for searching the results based on user input, I am now looking to incorporate checkboxes to further ...

There seems to be a problem with how the navbar is being displayed in ResponsiveSlides.js

I am currently using WordPress, but I have come here seeking help with a jQuery/CSS issue. I am utilizing responsiveSlides.js to create a simple slideshow, however, when viewing it here at gallery link, it appears that something is not quite right. STEPS: ...

Is it possible for me to convert my .ejs file to .html in order to make it compatible with Node.js and Express?

I have an index.html file and I wanted to link it to a twitter.ejs page. Unfortunately, my attempts were unsuccessful, and now I am considering changing the extension from ejs to html. However, this approach did not work either. Do .ejs files only work wit ...

What is the process for making an Ajax request in Rails?

I'm attempting to send a variable through jQuery using the POST method, saving it in a controller, and then utilizing that same variable in Rails HTML to query a table. It seems like the variable isn't being passed to the controller. jQuery: v ...

The added class is not being successfully applied to the ClassList

I'm currently working on a page where I want the colors of a button and the background to switch when the button is clicked. document.querySelector("body.light").classList.toggle("dark"); document.querySelector("button.dark").classList.toggle("light" ...

The Node JS API remains unresponsive when the request parameters are increased, continuing to send multiple requests to the server without receiving

Using the API below returns nothing: http://localhost:6150/api/v1/simpleSurveyData/abc/:projectId/:startDate/:endDate/:visitMonth However, if I remove any of the four parameters or provide less than four parameters, and adjust the API route in Node.js acc ...

Using jQuery to serialize parameters for AJAX requests

I could use some help figuring out how to set up parameters for a $.ajax submission. Currently, I have multiple pairs of HTML inputs (i pairs): > <input type="hidden" value="31" name="product_id"> <input > type="hidden" value="3" name="qua ...

"Utilize parameter passing with mapGetters in the Vuex state management system

Hello there! I'm currently working on a Vue.js project and using modules. I am trying to get filtered data from a getter, but I'm unsure how to provide parameters. Specifically, I need to pass a 'name' parameter to the Getter. How can ...

`What is the best way to employ the Return statement in programming?`

Trying to grasp the concepts of functions and methods has been a challenge for me. I often find myself confused about when, where, and how to use return statements in different situations. To illustrate this confusion, let's take a look at two code sn ...

sending data from a callback to an express router

As I embark on learning node.js, I've encountered a challenging issue. In my passportAuth.js file, I create a user and have a callback to ensure the user is created successfully. The code snippet looks something like this: req.tmpPassport = {}; var ...