AngularJS - input autofocus with ng-if not working - javascript

When I surround my input with ng-if, after hide and show the autofocus attribute does not take effect:
Here is the code:
<!DOCTYPE html>
<html ng-app>
<head>
<script data-require="angularjs#1.5.0" data-semver="1.5.0" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-init="view={}; view.show = true">
<button ng-click="view.show = !view.show">{{view.show ? "hide" : "show"}}</button>
<div ng-if="view.show">
<input autofocus />
</div>
</body>
</html>
And here is the plunker:
http://plnkr.co/edit/k7tb3xw5AsBYrhdlr3bA?p=preview
Just click on hide and after that on show and you will see the autofocus does not working!
In Chrome is working only on the first show, in FF and IE it's not working at all!

The problem is the attribute autofocus isnt an Angular directive. It is a browser supported specification of the <input> element. If you want this to work as intended across multiple browsers and auto focus every time you click hide/show you will need to make a directive.
I took this directive right off Github Gist, credit to mlynch for building this directive.
Heres a working example of your application
angular
.module('App', [
'utils.autofocus',
]);
/**
* the HTML5 autofocus property can be finicky when it comes to dynamically loaded
* templates and such with AngularJS. Use this simple directive to
* tame this beast once and for all.
*
* Usage:
* <input type="text" autofocus>
*
* License: MIT
*/
angular.module('utils.autofocus', [])
.directive('autofocus', ['$timeout', function($timeout) {
return {
restrict: 'A',
link : function($scope, $element) {
$timeout(function() {
$element[0].focus();
});
}
}
}]);
<!DOCTYPE html>
<html ng-app="App">
<head ng-init="view={}; view.show = true">
<script data-require="angularjs#1.5.0" data-semver="1.5.0" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<button ng-click="view.show = !view.show">{{view.show ? "hide" : "show"}}</button>
</body>
<div ng-if="view.show">
<input autofocus />
</div>
<script src="script.js"></script>
</html>

You can use a directive for this. Plunker Demo
angular.module('myApp', []).directive('focusMe', function($timeout) {
return {
scope: {
focusMeIf:"="
},
link: function ( scope, element, attrs ) {
if (scope.focusMeIf===undefined || scope.focusMeIf) {
$timeout( function () { element[0].focus(); } );
}
}
};
});
You could also define a condition in it in focus-me-if attribute in it.
Hope it helps.

First of all you have to wrap the div and it's content inside the body element. You have it outside. please correct it.
Input element should not be blank and may not work sometimes. please add some more attribute like name and type="text" or appropriate.
This is html5 feature and should start with <!DOCTYPE html>.
Please Note : The autofocus attribute of the input tag is not supported in Internet Explorer 9 and earlier versions.visit here for more details

Related

How to trigger an event to an element created dynamically?

I am using daterangepicker like this :
$('#myInput').daterangepicker({
'param1': value1,
'param2': value2,
'param3': value3,
...
}, function(...) {
...
})
This works fine if my input is created with the DOM. But if my input is created dynamically after the DOM, this does not work, normally I should do something like this :
$('body').on('daterangepicker..........event', '#myInput', function() {
})
But I don't know how to do it, thanks for help
You need to make a container and inject it into.
$(function() {
let html = document.getElementById('container');
setTimeout(() => {
// Dynamically adding datepicker
html.innerHTML = '<input type="text" id="datepicker"/>'; //
let dp = document.getElementById('datepicker');
dp.classList.add('DatePicker');
$('.DatePicker').datepicker();
}, 500)
});
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="https://code.jquery.com/jquery-1.9.1.js"></script>
<script src="https://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
</head>
<body>
<div id="container"></div>
</body>
</html>
Simply becuz Your DOM has not been created.
So you can archive this by register element wrapper the #my-input
So that is the reason why you use "body" and works fine.
You can give it a try the following sample
<div id="my-div"> <input id="my-input" /> </div>
$("#my-div").on('daterangepicker..........event', '#myInput', function() {
})

angularJS 1.x how to get current element

i have make many search in getting current element
in jQuery :$(this)
but in Angular J S 1.x i haven't found it here what i have do angular.element(this) but it's not correct
here is my code i like to get current target element
<html>
<head>
<style>
.error{
color:red;
}
</style>
</head>
<body>
<div ng-app="" ng-controller="eventController">
<h2>AngularJS $event example</h2>
<input type="text" ng-change="handleChange($event)" ng-model="test" value="My Text" class="testtt" >
</div>
<script>
function eventController($scope) {
$scope.handleChange = function(event) {
var classname = event.target.currentTarget.className
console.log(classname);
}
}
</script>
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
</body>
</html>
I think you should look into ng-class for what you are trying to do. If you really need direct access to an element, use a directive. The directives link function gets the element at initialisation time.
i have found the solution to my problem by using javascript
document.activeElement

load all javascript and angularjs code before rendering the html and directive in angularjs

I am using emojionearea in angularJs project . when i parsed unicode to emojis smiley faces using my custom directive it gives me error Refrence Error . emojione is not defined . here is directive
app.directive('emojifyIt', emojifyIt);
function emojifyIt($timeout) {
console.log('directove bya sad')
return {
link : function(scope, element, attributes){
console.log(attributes['emojifyIt']);
element.html(emojione.unicodeToImage(attributes['emojifyIt']));
}
};
}
if i use $timeout function in this it works fine.
e.g
app.directive('emojifyIt', emojifyIt);
function emojifyIt($timeout) {
console.log('directove bya sad')
return {
link : function(scope, element, attributes){
console.log(attributes['emojifyIt'])
$timeout(function() {
element.html(emojione.unicodeToImage(attributes['emojifyIt']))
}, 1000);
}
};
}
is there solution for this so that i dont use timeout function it should load script and javascript code before rendering the directive
my html code is
<span emojify-it="πŸ˜πŸ˜‚πŸ˜ƒasdπŸ˜ΆπŸ˜šπŸ˜™"></span>
here is complete html file
Edited
<html>
<head>
<link rel="stylesheet" href="components/emojionearea/dist/emojionearea.min.css">
<script src="components/jquery/dist/jquery.js"></script>
<script src="components/emojionearea/dist/emojionearea.min.js"></script>
<title>
emoji example
</title>
<style> .ng-cloak { display: none !important; } </style>
</head>
<body ng-app="emojiApp" ng-controller="mainCtrl">
<span emojify-it="πŸ˜πŸ˜‚πŸ˜ƒasdπŸ˜ΆπŸ˜šπŸ˜™"></span>
<script src="components/angular/angular.js"></script>
<script src="components/angular-sanitize/angular-sanitize.js"></script>
<script type="text/javascript" src="script.js"></script>
</body>
<script>
$(function(){
$("#emojionearea2").emojioneArea({
pickerPosition: "bottom",
tonesStyle: "radio"
});
})
</script>
want this result without timeout
fiddle link is
fiddle link

preventDefault is not stopping default mouse handlng

I have this simple angular example where I want to capture a mouse right click for a custom action. The default context menu must not show up. I read the questions here at SO. Unfortunately I cannot stop it from opening the browser built in context menu. I'm sure I'm missing something simple here. (see plunker http://plnkr.co/edit/YieQh23xNUFmPrjZscGB)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>My Plunk</title>
<script data-require="jquery#2.2.0" data-semver="2.2.0" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="plunker" ng-controller="myController">
<p ng-mousedown="mouseClicked($event)">Click me!</p>
</body>
</html>
script.js
var app = angular.module('plunker', []);
app.controller('myController', ['$scope', '$log', function($scope, $log) {
$scope.mouseClicked = function(event) {
if (event.button===2) {
$log.debug('right mouse click detected')
// don't do anything else
event.preventDefault();
event.stopPropagation();
}
};
}]);
If you are going to disable the context menu, you need to listen to the contextmenu event in order to stop it.
To achieve this in angular, maybe you need to add a custom directive:
app.directive('noContextMenu', [function() {
return function(scope, ele, attr){
ele.on('contextmenu', function(e) {
e.preventDefault();
});
}
}]);
<p no-context-menu >Click me!</p>

Trigger Event Click upon page load

I do not know why I can not trigger a click event on my controller upon page load. What I want is the checkboxed to be click literally.
<!DOCTYPE html>
<html >
<head>
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
</head>
<body ng-app="ngToggle">
<div ng-controller="AppCtrl">
<input type="checkbox" ng-model="dean" ng-click="btnChange($event, values, 1)" id="one" name="one" class="here" >
<input type="checkbox" ng-model="armada" ng-click="btnChange($event, values, 2)" id="two" name="one" class="here" >
<!--<p ng-repeat="btn in btns">-->
<!-- <input type="checkbox" ng-model="btn.bool" class="here" > {{ btn.value }}-->
<!--</p>-->
{{btn }}
{{values }}
</div>
<script type="text/javascript">
angular.module('ngToggle', [])
.controller('AppCtrl',['$scope', function($scope){
$scope.btns = [{}, {}, {}];
$scope.values = [];
$scope.btnChange = function(event, model, val){
_this = angular.element(event.target);
x = _this.prop("checked");
if(x){
model.push(val);
}else{
index = model.indexOf(val);
model.splice(index, 1);
}
};
angular.element("#one").triggerHandler("click");
}]);
</script>
</body>
</html>
Here is the plunker: http://plnkr.co/edit/7DpCvkKLlKhRc3YwFTq0?p=preview
I see that you have used jQuery on the page. So you can simply do this :
$(function(){
angular.element("#one").trigger("click");
});
A complete jQuery solution would be :
$(function(){
$("#one").click();
});
A complete angular solution would be (like others mentioned) :
angular.element(document).ready(function() {
angular.element("#one").trigger("click");
});
http://plnkr.co/edit/0OHDIVB2JGqDZnF56E6M?p=preview
You are triggering the code to click when the document is not completely ready/rendered so you need to wait till the entire document(or in this case, your checkbox) is loaded and only then you can perform actions on your elements.
You can place it on controller like this
angular.element(document).ready(function() {
angular.element("#one").trigger("click");
});
Here is the Plunker
You just need to add a small timeout to trigger a click
$timeout(function() {
angular.element('#one').click();
}, 100);
I have updated your plunker link check it out Plunker
Or You can do
angular.element(document).ready(function() {
angular.element("#one").trigger("click");
});

Categories