jquery function runs first than the DOM

2

I am working with AngularJs and I have a code in jQuery that should be executed once the DOM is loaded, but I realized with alert () that .ready appeared before the view was ready and therefore the code could not be run, does not give error simply does not work the code

My code in jQuery

$('.form-control').on('focus blur', function (e) {
    $(this).parents('.form-group').toggleClass('focused', (e.type === 'focus' || this.value.length > 0));
}).trigger('blur');

How can I manage to load this code once the view is ready but globally ?, which can be present in all the view

    
asked by Luis Ruiz Figueroa 22.03.2016 в 02:29
source

2 answers

1

I think you're focusing on the problem. In angular it is a bad practice to use DOMReady to execute code since angular has its own initialization cycle.

  

Angular is automatically initialized when the DOMContentLoaded event is invoked or when the angular.js script is finished loading in the event that the document.readyState property is equal to 'complete'

Remember that angular is a SPA or that once the framework takes control the rest of the views are loaded using calls to ajax and inserting the content in specific points of the DOM tree, so the event DOMReady will not be executed anymore.

  

In a SPA all HTML, JavaScript, and CSS codes are loaded at one time or the necessary resources are loaded dynamically as required by the page and are added, usually as a response to the user's actions. The page does not have to load again at any point of the process nor is it transferred to another page.

To deal with this you can use directives or services to encapsulate your code and run it for specific elements or in response to certain user actions. What you have can be rewritten in this way.

function focusBlur() {
    return {
        restrict: 'A',
        link: function($scope, $element) {
            $element.on('focus blur', function (e) {
                $element.parents('.form-group').toggleClass('focused', (e.type === 'focus' || this.value.length > 0));
            });
            $element.trigger('blur');
        }
    };
}

focusBlur.$inject = [];

angular.module('app')
    .directive('focusBlur', focusBlur);

And then you apply it to your elements like this

<input focus-blur id="sample" name="sample" class="form-control" value="4">

Here you have a demo

function focusBlur() {
  return {
    restrict: 'A',
    link: function($scope, $element) {
      $element.on('focus blur', function(e) {
        $element.parents('.form-group').toggleClass('focused', (e.type === 'focus' || this.value.length > 0));
      });
      $element.trigger('blur');
    }
  };
}

focusBlur.$inject = [];

angular.module('app', [])
  .directive('focusBlur', focusBlur);
.form-group.focused {
  box-shadow: inset 0 0 2em gold;
  webkit-box-shadow: inset 0 0 1em gold;
  moz-box-shadow: inset 0 0 1em gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>

<div ng-app="app">
  <div class="form-horizontal">
    <div class="form-group">
      <label class="control-label col-md-3">Nombre</label>
      <div class="col-md-9">
        <input focus-blur id="nombre" name="nombre" class="form-control" value="Jose">
      </div>
    </div>
    <div class="form-group">
      <label class="control-label col-md-3">Apellidos</label>
      <div class="col-md-9">
        <input focus-blur id="apellidos" name="apellidos" class="form-control" value="">
      </div>
    </div>
    <div class="form-group">
      <label class="control-label col-md-3">Edad</label>
      <div class="col-md-9">
        <input focus-blur id="edad" name="edad" class="form-control" value="25">
      </div>
    </div>
  </div>
</div>

Of course this implies that you have to add this directive to each of the elements whose behavior you wish to modify which at first glance may seem to be laborious but this is the way in which the architecture of the angular is thought so that your code can be reusable, testable, etc.

This link (in English) can explain a bit better why you should structure your code in this way link

    
answered by 22.03.2016 / 14:09
source
0

You could try doing something like this and see if it works:

$('body').on('focus blur', '.form-control', function (e) {
    $(this).parents('.form-group').toggleClass('focused', (e.type === 'focus' || this.value.length > 0));
})

Just as you have $(selector).on(eventos, controlador) , the event handlers focus and blur will only be associated to the elements that already exist in the DOM when the command is executed; on the other hand, if you do $(elemento).on(eventos, selector, controlador) you will be creating delegated events, which have the advantage that they do process the events of the elements that comply with the selector and that are added after executing that command ( source ).

    
answered by 22.03.2016 в 05:29