EL Kamel EL Kamel - 1 month ago 11
AngularJS Question

How to detect when the focus is out of a Div?

I'am working on a dynamic form that generates a number of Divs. I would like to detect if the focus was lost from the entire div not just from one input.

enter image description here

As the picture shows , I have multiple identical forms , the issue here is how to detect if the user is done editing one of the forms?

The forms are created dynamically using an ng-repeat.

<fieldset data-ng-repeat="response in responces" ng-init="sectionIndex = $index" >
<div id="customFrom">
<input type="text" ng-model="response.code" name="" placeholder="Code">
<input type="text" ng-model="response.rank" name="" placeholder="{{ 'app.forms.responses.rank' | translate }}" >
<input type="text" ng-model="response.value" name="" placeholder="{{ 'app.forms.responses.value' | translate }}">
<input type="text" ng-model="response.name" name="" placeholder="{{ 'app.forms.createQuiz.fields.name' | translate }}" class="labelTextQuestionCreation">
<button class="remove" ng-click="removeResponse($index)" ng-show="deteteResponceOption">-</button>
</div>
</fieldset>


What is the best way to add an action when the users jumps from one form to another? I need to detect when a form (Div) lost the focus in order to execute a function.
Thank You.

Answer

I Fixed The Problem By using a hidden input that indicates the index of the form, the value of this input is add to the model, because, I'am using a ng-repeat so each row has its own scope. In addition, I used the ng-focus directive to check if an input has focus, and when it does, I call a function that I called `getSelectedElement(index), the function verifies if the index has changed or not, and if we are in a new index we update/Insert the row in the data base. Here is my code for the solution :

HTML

 <fieldset  data-ng-repeat="response in responces track by $index" ng-init="sectionIndex = $index">
    <div ng-model-options="{ updateOn: 'blur' }"  >
    <input type="text" ng-model="response.code" name="" placeholder="Code"  ng-focus="getSelectedElement(sectionIndex)">
     <input type="text" ng-model="response.index"  ng-init="response.index=sectionIndex"   ng-value="sectionIndex"  ng-focus="getSelectedElement(sectionIndex)" ng-show="false">
    <input type="text" ng-model="response.rank" name="" placeholder="{{ 'app.forms.responses.rank' | translate }}"  ng-focus="getSelectedElement(sectionIndex)">
    <input type="text" ng-model="response.value" name="" placeholder="{{ 'app.forms.responses.value' | translate }}" ng-focus="getSelectedElement(sectionIndex)">
    <input type="text" ng-model="response.name" name="" placeholder="{{ 'app.forms.createQuiz.fields.name' | translate }}" class="labelTextQuestionCreation" ng-focus="getSelectedElement(sectionIndex)" >
    <button class="remove"  ng-click="removeResponse($index)" ng-show="deteteResponceOption">-</button>
    </div>
</fieldset>

JavaScript

$scope.getSelectedElement=function(index){
 var oldIndex=$scope.responcesSelectedIndex;//Variable to watch, it gets updated when we gain focus. initially it has -1 as a value, and we gain focus on a field it gets updated
 if(oldIndex==-1){//-1 indicates that we are in the first element, no previous index, no need to do any thing just update the old index.
     oldIndex=index;
 }
 $scope.responcesSelectedIndex=index;//Update the old index to be the current so when we call the function again we will have two index values, the new one (As a parameter) and the old one ($scope.responcesSelectedIndex)
 var newIndex=$scope.responcesSelectedIndex;
     if(oldIndex!=newIndex){//Jumping to the new Form
        console.log("Update or Create");
        //Do What You want Here

    }

}

It is not a perfect solution, but it works just fine.