Search code examples
javascriptangularjsonblur

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.


Solution

  • 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.