1

I am using ui-grid to upload a XLS file through a directive and push the data

I am trying to move data between my directive and controller (pretty new to angular). I have gone through a bunch of threads (this, this, this, and this) to try to understand how to use the &, @, =, $watch, and $observe, but I still do not understand how to move my data from the directive (which has a JSON object) to an array (myData) in my controller. If someone could please help me solve this problem...

Controller

.controller('ListCtrl', function ($scope, $state, $log, ServerRequest, $localStorage, $sessionStorage, uiGridConstants) {

        var vm = this, c = console;
        $scope.sortAlert = sortAlert;
        $scope.myData = [
          {
            "alert": "2",
            "firstName": "Rob",
            "lastName": "McBob",
            "dob": "03/12/1941",
            "sex": "M",
            "mi": "C",
            "referralReason": "Morbid Obesity",
            "userStatus": "Schedules",
            "timeSched": "02:00PM",
            "homeNum": "416-555-5555",
            "cellNum": "905-555-5555",
            "notes": "cool",
            "uniqueId": "638768756304"
          }
      ];


      //this formats the row
      $scope.highlightFilteredHeader = function( row, rowRenderIndex, col, colRenderIndex ) {
        if( col.filters[0].term ){
          return 'header-filtered';
        } else {
          return '';
        }
      };

      //handles the functionality of the grid
      $scope.gridOptions = {
        enableFiltering: true,
        onRegisterApi: function(gridApi){
          $scope.gridApi = gridApi; //so we can use gridapi functions of ui-grid
          //handler for clicking rows
          gridApi.selection.on.rowSelectionChanged($scope, function(row){
            var thisRow = gridApi.selection.getSelectedRows() //gets the clicked row object
            $log.log(thisRow);
            //creates new tab -> the tabby part itselfid="' + thisRow[0].uniqueId + '"
            $('.ui.top.attached.tabular.menu').append('<a class="active item" style="border-radius: 0px !important; background-color: #4B6A89; font-family: Roboto; font-size: 16px; color: white; font-weight: 300; letter-spacing: 1.5px;" id="' + thisRow[0].uniqueId + '" data-tab="' + thisRow[0].uniqueId + '">' + thisRow[0].firstName + ' ' + thisRow[0].lastName + '<i id="' + thisRow[0].uniqueId + '" class="material-icons" style="position: relative; right: -60px; font-weight: 200;">clear</i></a>');                //add ui bottom - the body of the tab
            $('.tab-container').append('<div id="' + thisRow[0].uniqueId +'" class="ui bottom attached tab segment" data-tab="' + thisRow[0].uniqueId + '">' + 'new page' + '</div>');
            reinitializeTabs(); //jquery to add ui-semantic tabs functionality to new tabs

          });
        },
        data: 'myData',
        columnDefs: [
          {
            field: 'alert', displayName: 'ALERTS', headerCellClass: $scope.highlightFilteredHeader,
              sort: {
                direction: uiGridConstants.DESC,
                priority: 1
              }
          },
          {
            field: 'firstName', displayName: 'FIRST NAME', headerCellClass: $scope.highlightFilteredHeader
          },
          {
            field: 'lastName', displayName: 'LAST NAME', headerCellClass: $scope.highlightFilteredHeader
          },
          {
            field: 'dob', displayName: 'DOB', headerCellClass: $scope.highlightFilteredHeader
          },
          {
            field: 'referralReason', displayName: 'REFERRAL REASON', headerCellClass: $scope.highlightFilteredHeader
          },
          {
            field: 'userStatus', displayName: 'STATUS', headerCellClass: $scope.highlightFilteredHeader
          },
          {
            field: 'timeSched', displayName: 'TIME', headerCellClass: $scope.highlightFilteredHeader
          },
          {
            field: 'homeNum', displayName: 'HOME #', headerCellClass: $scope.highlightFilteredHeader
          },
          {
            field: 'cellNum', displayName: 'CELL #', headerCellClass: $scope.highlightFilteredHeader
          },
          {
            field: 'mi', displayName: 'MI', headerCellClass: $scope.highlightFilteredHeader
          },
          {
            field: 'sex', displayName: 'SEX', headerCellClass: $scope.highlightFilteredHeader
          },
          {
            field: 'notes', displayName: 'NOTES', headerCellClass: $scope.highlightFilteredHeader
          },
          {
            field: 'uniqueId', displayName: 'UNIQUE ID', headerCellClass: $scope.highlightFilteredHeader
          }
        ]
      };


      });

  })//end of controller

Directive

.directive("fileread", [function () {
    return {
      scope: {
        opts: '@'
      },
      link: function ($scope, $elm, $attrs) {
        $elm.on('change', function (changeEvent) {
          var reader = new FileReader();

          reader.onload =function (evt) {
            $scope.$apply(function () {
              var data = evt.target.result;

              var workbook = XLSX.read(data, {type: 'binary'});

              var headerNames = XLSX.utils.sheet_to_json(
                                  workbook.Sheets[workbook.SheetNames[0]],
                                  { header: 1 }
                                )[0];

              var data = XLSX.utils.sheet_to_json( workbook.Sheets[workbook.SheetNames[0]]);

              // $scope.opts.columnDefs = [];
              // headerNames.forEach(function (h) {
              //   $scope.opts.columnDefs.push({ field: h });
              // });

              $scope.opts.data = data;
              console.log(data);
              // addRows(data);
              $elm.val(null);
              //this is where we add the new data to the existing data

              $scope.opts.data.push({
                "alert": data[0].alert
                , "firstName": data[0].firstName
                , "lastName": data[0].lastName
                , "dob": data[0].dob
                , "referralReason": data[0].referralReason
                , "userStatus": data[0].userStatus
                , "timeSched": data[0].timeSched
                , "homeNum": data[0].homeNum
                , "cellNum": data[0].cellNum
                , "mi": data[0].mi
                , "sex": data[0].sex
                , "notes": data[0].notes
                , "uniqueId": data[0].uniqueId
                });
            });
          };
          reader.readAsBinaryString(changeEvent.target.files[0]);
        });
      }
    }
  }]); //end of directive
Community
  • 1
  • 1
IWI
  • 1,528
  • 4
  • 27
  • 47

1 Answers1

1

In your directive, declare reference to myData (can be any name):

scope: {
    myData: '=',
    opts: '='
}

Directive usage (myData is the object from your controller):

<fileread my-data="myData"></fileread>

Now $scope/scope in both the controller and directive point to the same resource.

@ is for one-way data-binding, hence the error your posted under comments.

George Kagan
  • 5,913
  • 8
  • 46
  • 50