简体   繁体   中英

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.

在此处输入图片说明

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.

Based on your problem, the best solution is to use ng-model-options .

Each element with ng-model will need the following attribute:

ng-model-options="{ updateOn: 'blur' }"

Then will look like:

<input type="text" ng-model="response.code" name="" ng-model-options="{ updateOn: 'blur' }" placeholder="Code">

With the ng-model-options, the model is only updated when the focus is lost on the form field. You can then have a $watch statement, which is only triggered when the model is updated.

In the $watch callback, when a change to any attributes of the main array if detected, you can run the models through validation to know if all the data is filled out and proceed with the execution of the desired function.

$scope.$watch('responces', function (newVal, oldVal) {
    // onBlur triggered an update to an attribute of **responces**
    // run your input validation here
}, true);

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM