Tips for updating data in the AngularJS Smart TableWould you like to learn

I'm still getting the hang of Java Script, so please bear with me if this question is a bit basic.

Does anyone know how to edit rows in tables using Smart-Table with AngularJS? I can't seem to find any tutorials that match the new version of Smart-Table. My goal is to create a simple form for users to input the opening hours for a specific place.

I've managed to add and remove rows from the table using buttons, but when I try to make the content editable by adding "contenteditable=true", none of the changes are saved when I update the object. I realize that "contenteditable" is an HTML5 attribute and not directly related to Smart-Table, but I'm not sure how else to update the data or retrieve the updated information.

The data is fetched from the AngularJS controller through the mean.js routes.

<div class="controls">
    <table st-table="place.openHours" class="table table-striped">
        <thead>
        <tr>
            <th>Day</th>
            <th>Opening Time</th>
            <th>Closing Time</th>
        </tr>
        </thead>
        <tbody>
        <tr ng-repeat="row in place.openHours" contenteditable="true" >
            <td>{{row.day}}</td>
            <td>{{row.open}}</td>
            <td>{{row.close}}</td>
            <button type="button" ng-click="removeOpenHour(row)" class="btn btn-sm btn-danger">
                <i class="glyphicon glyphicon-remove-circle">
                </i>
            </button>
        </tr>
        </tbody>
    </table>

    <button type="button" ng-click="addOpenHour(row)" class="btn btn-sm btn-success">
        <i class="glyphicon glyphicon-plus">
        </i> Add new Row
    </button>
</div>

In the JavaScript file:

    $scope.removeOpenHour = function removeOpenHour(row) {
        var index = $scope.place.openHours.indexOf(row);
        if (index !== -1) {
            $scope.rowCollection.splice(index, 1);
        }
    }

    $scope.addOpenHour = function addOpenHour() {
        $scope.place.openHours.push(
        {
            day: 'Monday',
            open: 540,
            close: 1080
        });
    };

Answer №1

After exploring various options, I found a solution by combining code snippets from this source with my own code.

Here is the snippet from the HTML file:

<tr ng-repeat="row in place.openHours">
   <td><div contentEditable="true" ng-model="row.day">{{row.day}}</div></td>
   <td><div contentEditable="true" ng-model="row.open">{{row.open}}</div></td>
   <td><div contentEditable="true" ng-model="row.close">{{row.close}}</div></td>
   <td>
   <button type="button" ng-click="removeOpenHour(row)" class="btn btn-sm btn-danger">
      <i class="glyphicon glyphicon-remove-circle">
      </i>
   </button>
</td>

And here is the JavaScript snippet:

myApp.directive('contenteditable', function() {
return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
        // view -> model
        elm.bind('blur', function() {
            scope.$apply(function() {
                ctrl.$setViewValue(elm.html());
            });
        });

        // model -> view
        ctrl.render = function(value) {
            elm.html(value);
        };

        elm.bind('keydown', function(event) {
            console.log("keydown " + event.which);
            var esc = event.which == 27,
                el = event.target;

            if (esc) {
                console.log("esc");
                ctrl.$setViewValue(elm.html());
                el.blur();
                event.preventDefault();
            }

        });

    }
};
});

Answer №2

Here is my solution:

Using Angular directive :

app.directive("markdown", function() {

  return {
    restrict: 'EA',
    scope: {

        value: '='},
    template: '<span ng-click="edit()" ng-bind="value"></span><input ng-blur="blur()" ng-model="value"></input>',
    link: function($scope, element, attrs) {
        // Let's get a reference to the input element, as we'll want to reference it.
        var inputElement = angular.element(element.children()[1]);

        // This directive should have a set class so we can style it.
        element.addClass('edit-in-place');

        // Initially, we're not editing.
        $scope.editing = false;

        // ng-click handler to activate edit-in-place
        $scope.edit = function() {
            $scope.editing = true;

            // We control display through a class on the directive itself. See the CSS.
            element.addClass('active');

            // And we must focus the element. 
            // `angular.element()` provides a chainable array, like jQuery so to access a native DOM function, 
            // we have to reference the first element in the array.
            inputElement[0].focus();
        };

        // When we leave the input, we're done editing.

        $scope.blur = function() {
            $scope.editing = false;
            element.removeClass('active');
        }
    }
  };

});

Utilizing HTML:

 <table st-table="displayedCollection" st-safe-src="rowCollection" class="table table-striped">

    <thead>
      <tr>
          <th st-sort="sku">SKU</th>
          <th st-sort="skuSupplier">SKU Supplier</th>
          <th st-sort="name">Description</th>
          <th st-sort="quantity">Quantity</th>
          <th st-sort="price">Unit Price</th>
          <th st-sort="total">Total</th>
      </tr>
      <tr>
          <th colspan="5"><input st-search="" class="form-control" placeholder="Search product ..." type="text"/></th>
          </tr>
    </thead>
    <tbody>
       <tr ng-repeat="row in displayedCollection">
          <td><markdown value="row.sku"></markdown></td>
          <td><markdown value="row.skuSupplier"></markdown></td>
          <td><markdown value="row.name"></markdown></td>
          <td><markdown value="row.quantity"></markdown></td>
          <td><markdown value="row.price"></markdown></td>
          <td><markdown value="row.total"></markdown></td>
          <td>
              <button type="button" ng-click="removeItem(row)" class="btn btn-sm btn-danger">
                 <i class="glyphicon glyphicon-remove-circle"></i>
              </button>
          </td>
      </tr>
    </tbody>
  </table>

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

Persisting Undefined Values Even After Proper Prop Passing

I'm currently working on fetching and passing coaching data as props to another component for rendering on the frontend. I need to pass these props to the CoachingCard Component in order to display the coaching values. However, I'm encountering ...

Is there a way to retrieve the current route on a custom 404 page in Next.JS?

I have set up a custom 404 page for my Next.JS application (404.js). I want to display a message stating The route <strong>/not-a-route</strong> does not exist, but when I use Next.js's useRouter() and router.pathname, it incorrectly ident ...

Is there a way to continually monitor for collisions between webpage elements?

After successfully implementing the algorithm, I am currently struggling with finding a way to continuously check if the element has collided with other elements. For example: When the div with id 'water' collides with the div with id 'ora ...

Switching jQuery on various sections of a webpage

In my attempt to replicate the functionality of Facebook's Like button, I have encountered a challenge regarding where exactly to click in order to change the button state. When the button is not liked yet, users should be able to click anywhere on t ...

Creating dynamic div shapes in HTML is a fun and creative way

Is it possible to create a div with a unique shape? I know that by default, divs are rectangular and you can achieve some shapes using the border-radius property, but what I really want is a semi-leaf shaped element. Something like this: The image might n ...

"Creating a dynamic Map using the HERE Maps API and adjusting its size: A step-by-step guide

I am currently working on a Website project and I am interested in incorporating an interactive map from HERE Maps that spans the entire screen under my navigation bar. How can I achieve this? After initially using Google Maps, I switched to HERE Maps due ...

Having difficulty scrolling through content on Onsen UI with AngularJS

As a newbie to AngularJS, I find myself grappling with the transition from jQuery and its associated bad habits. Currently, I am working on a mobile page using Onsen UI along with AngularJS and jQuery. While the content displays correctly, I'm facing ...

JavaScript - How can I prevent receiving multiple alerts during long polling success?

After following a video tutorial on implementing long polling, I managed to get it working. However, I encountered an issue where my alert message pops up multiple times even though I only receive one response from the server. I was under the impression th ...

Detect a custom button click event to trigger a re-render of dates in the controller for the AngularJS date picker

I have customized the datepicker popup by adding a custom button inside the <script id="template/datepicker/popup.html" type="text/ng-template"> directive. The custom button is visible in the image below, but I am looking to capture the click event ...

Guide to choosing and unchoosing a div / button using angularJs

I am attempting to create a functionality where items are displayed in a div instead of a list. When an item is clicked, the background color of the div changes and the item is added to a column. Clicking on the item again will revert it back to its origin ...

Using interpolation brackets in Angular2 for variables instead of dots

I'm curious if Angular2 has a feature similar to the bracket notation in Javascript that allows you to use variables to select an object property, or if there is another method to achieve the same functionality. Here is the code snippet for reference ...

Is there a way to update a div element with an image without having to refresh

Currently working on a project for my studies where I am reading the x and y coordinates from a touch pad and drawing it in real time using PHP. I have created a draw page that takes these coordinates and displays them on an image, which is then shown on ...

executing functions that return a JSX component within the render method

In an effort to enhance readability, I am striving to condense the length of the render() method by utilizing class methods that contain isolated JSX elements. A snag arises when attempting to apply this technique to more than one JSX element. Despite en ...

I am looking to customize the folder name dynamically in the flowFactoryProvider configuration so that I can subsequently send it to the upload.php file for the purpose of storing

Currently, I am utilizing the ng-flow plugin for uploading .zip files and it is functioning properly. However, I am looking to pass dynamic values like user_id and job_id in order to create dynamic folders where the uploaded files will be saved. The issue ...

Retrieve a key from the JSON response and then transmit it through a socket

In the context of a node server code using a monitoring module to track function properties, I am facing an issue where I need to retrieve a specific property from a JSON output and then transfer it to a socket. The function 'meter' looks like t ...

Conflicts in SwiperJS Timeline Management

Having a Timeline on my Website using SwiperJS presents challenges with conflicting functions. The goal is to navigate swiper-slides by clicking on timespans in the timeline. The desired functionality for the timeline includes: Sliding to the correspondi ...

In Node.js and JavaScript, attempt to access a variable within the catch block in order to remove a Cloudinary image in the event

I've encountered a situation where I successfully upload an image to cloudinary, but run into a MongoDB error afterwards. In this case, I need to delete the image from cloudinary. However, I'm unsure of how to access the value of "cloudinary_id" ...

"Encountering issues with autocomplete feature loading empty data when attempting to populate several fields simultaneously

Encountering issues with autocomplete when trying to select a value and fill in multiple fields. Seeing small blank lines on autocomplete and search stops while typing. Suspecting the problem lies within .data("ui-autocomplete")._renderItem or ...

Delay the loading of templates when utilizing ng-controller

I am trying to delay the loading of my main controller/template (AppController) until I fetch the user's profile from a service. For all navigation routes, I am using $routeProvider with resolve. .when('/edit/:editId', { te ...

At what point does the chaining of async/await come to an end?

I was experimenting with node-fetch and encountered a question while using async / await: Do I need to make my function async if I use await in it? But then, since my function is async, I need to await it and make the parent function async. And so on... He ...