0

I'm developing a tool at work, whose goal is to display 2 specific files in a table and allow users to apply filters.

I decided to use the web technology, but I am a big beginner and I am facing some issues. I don't know if they are due to a lack of knowledge or to coding errors.

Usually, we develop web tools using MEAN Stack framework, but for this one we wanted to get rid of the server implementation for maintenance concerns.

Consequently, I chose to use only HTML, CSS and Angularjs.

So here are the principles of the tool :

  • The user downloads the project, and via a shortcut opens a HTML file (everything is local then).
  • He can drag-and-drop wherever he wants on the webpage the files he wants to watch in his browser
  • We parse it in a JS "controller" to store it in a set
  • We display the set content's dynamically in a table

My issue :

When I change the value of a binded variable, the view is not updated (neither are the "ng-if", "ng-show", "ng-hide", etc.. expresions) unless I trigger an event such as "ng-click" (even empty)

CODE :

HTML :

<!doctype html>
<html lang="fr" id="drop-zone" ondrop="dropHandler(event)" ondragover="dragOverHandler(event)" ondragleave="dragLeaveHandler(event)">
<head>
<meta charset="utf-8">
<title>Page Title</title>
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<link href="css/style.css" rel="stylesheet"  />
<script src="node_modules/angular/angular.js"></script>
<script src="node_modules/jquery/dist/jquery.js"></script>
<script src="app.js"></script>
<script src="Controllers/fileReader.controller.js"></script>
<script src="node_modules/papaparse/papaparse.js"></script>
<script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="node_modules/alasql/dist/alasql.js"></script>
</head>

<!-- Body -->
<body ng-app="app" ng-controller="HomeController as vm" >
<h1> ... </h1>
<h2> ... </h2>

<div id="visual-drop-zone" class="upload-drop-zone" ng-hide = "vm.dataFed">
Just drag Swap file(s) here
</div>

<table class="table table-striped table-condensed table-bordered text-center" ng-if = "vm.dataFed">
<thead>
<tr>
<th rowspan="2"> ... </th>
<th rowspan="2"> ... </th>
<th rowspan="2"> ... </th>
<th rowspan="2"> ... </th>
<th rowspan="2"> ... </th>
<th rowspan="2"> ... </th>
<th colspan="9"> ... </th>
<th ng-if = "vm.busData.length > 0" colspan="9"> ... </th>
</tr>
<tr>
<div ng-show = "vm.ecoData.length > 0">
<th> ... </th>
<th> ... </th>
<th> ... </th>
<th> ... </th>
<th> ... </th>
<th> ... </th>
<th> ... </th>
<th> ... </th>
<th> ... </th>
</div>
<div ng-show = "vm.bus.length > 0">
<th> ... </th>
<th> ... </th>
<th> ... </th>
<th> ... </th>
<th> ... </th>
<th> ... </th>
<th> ... </th>
<th> ... </th>
<th> ... </th>
</div>
</tr>
</thead>
<tbody>
<div ng-if = "vm.ecoData.length > 0">
<tr ng-repeat="record in vm.ecoData">
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
</tr>
</div>
<div ng-if = "vm.busData.length > 0">
<tr ng-repeat="fltRec in vm.busData">
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
<td>{{record.something}}</td>
</tr>
</div>
</tbody>
</table>
</body>
<!-- /Body -->

</html>

Javascript :

angular.module('app').controller('HomeController', ['$scope', HomeController]);

var vm;

function HomeController($scope){

  vm = this;

  vm.records = [];

  vm.record = {
    something : '',
    something : -1,
    something : '',
    ...
  };

  vm.ecoData = [];
  vm.busData = [];
  vm.joinedData = [];

  vm.dataFed = false;

};

function dropHandler(event){
  var dropZone = document.getElementById('drop-zone');

  event.preventDefault();

  for (var i = 0; i < event.dataTransfer.files.length; i++) { //For each file dropped in the zone
    if(event.dataTransfer.files[i].name.includes("eco")){ //We check its name to know the data type
      Papa.parse(event.dataTransfer.files[i], {
        header: true,
        complete: function(results){ // callback executed when parsing is fully completed
          console.log("before feeding : vm.dataFed => ", vm.dataFed);
          vm.ecoData = results.data;
          vm.dataFed = true;
          console.log("after feeding : vm.dataFed =>", vm.dataFed);
        }
      });
    }
    else{
      Papa.parse(event.dataTransfer.files[i], {
        header: true,
        complete: function(results){  // callback executed when parsing is fully completed
          vm.busData = results.data;
          vm.dataFed = true;
          console.log("vm.busData =>", vm.busData);
        }
      });
    }
  }
}

function dragOverHandler(event){
  event.preventDefault();
  document.getElementById('visual-drop-zone').className = 'upload-drop-zone drop'; // some visual modifications
}

function dragLeaveHandler(event){
  event.preventDefault();
  document.getElementById('visual-drop-zone').className = 'upload-drop-zone'; // some visual modifications
}

**If I click on the div "visal-drop-zone" which has a "ng-click" attribute, all my variables are updated in the view. Is that because I "run" the website locally? It looks like Angularjs isn't watching for value modifications... **

Any help would be very welcome :)

Thanks a lot in advance!!

2 Answers 2

1

That's because Angular doesn't know about your custom functions dropHandler, dragOverHandler, and dragLeaveHandler.

One solution is to call $scope.$apply() at the very end of your custom handler methods.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your answer. I wanted to try this, but I didn't manage to access the $scope var outside the HomeController function. Any idea ?
Right, you can just move the handlers inside the controller declaration.
Yep that's what I just tried and it worked. Thanks a lot !
0

The drop handler is not an AngularJS event, "just" a DOM event, so it does not know that it needs to update everything. You can push the update by calling $scope.$digest() at the end of your drop handler. Of course, this requires that you defined the drop handler inside your controller, so that it can capture the $scope there.

Considering that controllers should not be interacting with the DOM, the better approach would be to have a directive to process the DOM event, but the controller approach will work.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.