I am using button to create element in javascript DOM way as follows
var app = angular.module('app', []);
function createElement2(resource){
el= document.createElement('textarea');
$(el).attr('ID', "Textbox0");
$(el).attr('type', "text");
$(el).attr('value', "Textbox0");
$(el).attr("name","Textbox0");
$(el).attr("ng-model", "html");
//this line will be diffrent for element
document.getElementById("areaT").appendChild(el)
}
app.directive('dynamic', function ($compile) {
return {
restrict: 'A',
replace: true,
link: function (scope, ele, attrs) {
scope.$watch(attrs.dynamic, function(html) {
console.log("test")
ele.html(html);
$compile(ele.contents())(scope);
});
}
};
});
function MyController($scope) {
$scope.click = function(arg) {
alert('Clicked ' + arg);
}
$scope.html = '<a ng-click="click(1)" href="#">Click me</a>';
}
The problem is I want to a tag customize directive Angluarjs to any element create with different validtion and the dirctive code execute only when the page load.In another words I want to execute the next piece of code every time I create element
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js#1.0.7" data-semver="1.0.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
</head>
<body>
<h1>Compile dynamic HTML</h1>
<div id="areaT" ng-controller="MyController">
<textarea ng-model="html"></textarea>
<div dynamic="html"></div>
</div>
<input type="button" onclick="createElement2(this)">
</body>
</html>
note that the textarea in the html code when enter any code the console.log("test") and so on will be execute. what I need when click on button the textarea that will be adding execute what the textarea in the html code execute (console.log("test") and so) when enter text inside it
Related
<!DOCTYPE html>
<html data-ng-app="app">
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
</head>
<body data-ng-controller="SimpleController">
<script>
var app = angular.module('app', []);
app.controller('SimpleController', SimpleController);
function SimpleController($scope) {
$scope.isNumberA = function(val) {
console.log('called');
if (val == 2) return true;
}
}
</script>
<input type="checkbox" ng-model="switcher" />
<h1 ng-if="isNumberA(10)">isNumber</h1>
</body>
</html>
In the above code first time, isNumberA calling because of ng-if="isNumberA(10)" but I don't know why it is calling another time. Check console, it prints two times on DOM render in brower. After that when I click on check box again it calling the function. Why this method calling on check box click? I didn't called it. Is this the two-way binding? And also if I remove the <h1 ng-if="isNumberA(10)"></h1>, it is not calling. What is happening here?
You have used a function call rather then a variable for condition (ng-if).
Angular watch every scope variable used in view, but when you use a function call, it can't decided which variable or event will effect this function return value, so Angular run such function on every digest cycle.
You should call this function in ng-init and store the return value of this function in a variable, and use that variable in ng-if.
$scope.isNumberA = function(val) {
console.log('called');
if (val == 2){
$scope.showIfBlock = true;
} else {
$scope.showIfBlock = false;
}
}
<span ng-init="isNumberA(10)"></sapn>
<h1 ng-if="showIfBlock">isNumber</h1>
ng-if will evaluate its expression when digest cycle runs, basically you shouldn't make an function call from ng-if expression.
DEMO
<!DOCTYPE html>
<html data-ng-app="app">
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
</head>
<body data-ng-controller="SimpleController">
<script>
var app = angular.module('app', []);
app.controller('SimpleController', SimpleController);
function SimpleController($scope) {
$scope.isNumberA = function(val) {
console.log('called');
if (val == 2) $scope.block = true;
$scope.block = false;
}
}
</script>
<input type="checkbox" ng-model="switcher" />
<span ng-init="isNumberA(10)"></sapn>
<h1 ng-if="block">isNumber</h1>
</body>
</html>
Read More here
ng-if being called more times than it should
Following the example provided here , I have fit the slider as per the requirement
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Rating</title>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.0/themes/smoothness/jquery-ui.css">
<script data-require="angular.js#1.4.0-beta.6" data-semver="1.4.0-beta.6" src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.0/jquery-ui.min.js"></script>
<script src="test.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="testController">
<table>
<tr>
<td>Amount:</td>
<td><div slider ng-model="amount" style="width:200px;"></div></td>
<td><input type= "text" ng-model="amount" id="txtAmount"></td>
</tr>
</table>
</div>
</body>
</html>
test.js
var myApp = angular.module("myApp", []);
myApp.controller("testController", function($scope, $http){
$scope.amount = 1;
}); //end controller
myApp.directive('slider', function() {
return {
restrict: 'A',
scope: {
ngModel: '='
},
link: function(scope, elem, attrs) {
console.log(scope.ngModel);
return $(elem).slider({
range: "min",
animate: true,
value: scope.ngModel,
slide: function(event, ui) {
return scope.$apply(function(){
scope.ngModel = ui.value;
});
}
});
}
};
});
The problem is that
a) Max range cannot be set beyond 100. Say I want the min value as 1 and max as 1000. How to do that?
b) Two way binding is not happening. Say if I set the value of the "txtAmount " to 50, then the slider should point to that value(50)
Max range could be changed using max option you can see it in an example down below. If max field won't be specified in element it will set a maximum to 100.
Two binding is working for Angular's elements because it's watching for changes, so you basically need to do the same for jQuery element
Code:
scope.$watch('ngModel', function(val) {
$(elem).slider("value", val);
});
Full fiddle - http://jsfiddle.net/zv78jsz6/
I am trying to add a dynamically added element directive into a page but it is not working and getting compiled in the page it is added. Here is the plunker code. What is wrong with the code?
http://plnkr.co/edit/BFPxAvEahT1I930mvB5r
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller("fCtrl",function($scope,$compile){
$scope.xx = ['x','c','y','z','a'];
$scope.add = function(){
var templ = document.getElementById('test').innerHTML;
templ = templ+'<datan-type content="test1" con="{{xx}}"></datan-type>';
document.getElementById('test').innerHTML = templ;
//$compile(document.getElementById('test').innerHTML)($scope);
alert(document.getElementById('test').innerHTML);
}
});
app.directive('datanType', function ($compile) {
return {
restrict: 'E',
replace: true,
link: function (scope, ele, attrs) {
var testTemplate1 = '<h1 ng-repeat="x in arr">Test{{x}}</h1>';
var testTemplate2 = '<h1>Test2</h1>';
var testTemplate3 = '<h1>Test3</h1>';
var template = '';
scope.arr = eval(attrs.con);
switch(attrs.content){
case 'test1':
template = testTemplate1;
break;
case 'test2':
template = testTemplate2;
break;
case 'test3':
template = testTemplate3;
break;
}
ele.html(template);
$compile(ele.contents())(scope);
}
};
});
</script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body ng-controller="fCtrl">
<p>Result:</p>
<datan-type content="test1" con="{{xx}}"></datan-type>
<div id="test"></div>
<button ng-click="add()">Add Form Elem Eg - Error Area</button>
</body>
</html>
Gary, this was killing me so I made it my morning goal to figure out the silly syntax:
Working Plnkr - Clicky
Change your controller code to :
var elementToAdd = angular.element('<datan-type content="test1" con="{{xx}}"></datan-type>');
$compile(elementToAdd)($scope);
document.getElementById('test').appendChild(elementToAdd[0]);
I would like to open a new tab after $http call. Currently, even-though the call is made after user click, popup blocker doesn't allow new tab to be created.
HTML:
<div ng-controller="ExampleController">
<button ng-click="openNewTab()">Open new tab</button>
</div>
Controller
.controller('ExampleController', ['$scope','$http', function($scope,$http) {
$scope.openNewTab = function(e) {
$http.get("test.com").finally(()=>{
window.open();
});
};
}]);
Plunker
Try this Code to open the new tab call the function
.controller('ExampleController', ['$scope','$http', function($scope,$http,$window) {
$scope.openNewTab = function(e) {
$http.get("test.com").finally(()=>{
$window.open('url','_blank');
});
};
}]);
You can use setInterval out of ajax call where you have to check your variable again and again which will be set in ajax call when condition matches then you can open new tab.
I've also found a workaround for you.
<!DOCTYPE html>
<html ng-app="Demo">
<head>
<meta charset="utf-8" />
<title>Demo</title>
<script data-require="jquery#2.0.1" data-semver="2.0.1" src="http://code.jquery.com/jquery-2.0.1.min.js"></script>
<script src="https://code.angularjs.org/1.3.0-beta.9/angular.js"></script>
<script src="demo.js"></script>
</head>
<body ng-controller="DemoCtrl">
<button ng-click="doesntWork()">This Doesn't Work</button>
</body>
</html>
and the angular code:
angular.module("Demo", []).controller("DemoCtrl", function($scope, $http) {
$scope.doesntWork = function() {
var isSuccess=0;
$http.get('https://api.github.com/users/angular').then(function (result)
{
isSuccess=1;
});
var timer = setInterval(function () {
if (isSuccess!= 0) {
clearInterval(timer);
}
if (isSuccess== 1) {
var newWin = $window.open('', '_blank');
newWin.location = "https://www.google.co.in";
}
},1000);
};
});
You can do this by using the $window service. $window is a wrapper around the global browser object window. Maybe this solves your answer too:
Open a new tab on button click in AngularJS
I've also found a workaround for you.
<!DOCTYPE html>
<html ng-app="Demo">
<head>
<meta charset="utf-8" />
<title>Demo</title>
<script data-require="jquery#2.0.1" data-semver="2.0.1" src="http://code.jquery.com/jquery-2.0.1.min.js"></script>
<script src="https://code.angularjs.org/1.3.0-beta.9/angular.js"></script>
<script src="demo.js"></script>
</head>
<body ng-controller="DemoCtrl">
<button id="test" ng-click="works()">This Works</button>
<button ng-click="doesntWork()">This Doesn't Work</button>
</body>
</html>
and the angular code:
angular.module("Demo", []).controller("DemoCtrl", function($scope, $http) {
function openInNewTab() {
var uri = 'http://www.google.nl';
var link = angular.element('');
angular.element(document.body).append(link);
link[0].click();
link.remove();
};
$("#test").click(function(){
openInNewTab();
});
$("#test").click();
$scope.works = openInNewTab;
$scope.doesntWork = function() {
$http.get('https://api.github.com/users/angular').then(openInNewTab);
};
});
I'm aware of security implications related to my request, but I need to allow a special super admin group of users an ability to create and evaluate angular html contained within variable on current $scope
Here is an example plunk:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.3.x" src="https://code.angularjs.org/1.3.15/angular.js" data-semver="1.3.15"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl" ng-init="variable = 3; content = '{{ variable }}'">
<div>
The value of $scope.variable === "{{ variable }}"
</div>
<div>
The value of $scope.content === "{{ content }}"
</div>
<br>
<div>
The value of $scope.content is <b>ng-model</b>'ed via the following textarea:<br>
</div>
<textarea rows="3" ng-model="content"></textarea>
<div style="border: 1px solid black">
Instead of rendering the value of the $scope.content field which is currently equal to "{{ content }}" I need to render compiled and evaluated value which should be equal to "{{ variable }}"
</div>
</body>
</html>
Any suggestions?
Thank you in advance!
You can make a directive that uses the $compile service to do this for you.
Here is what I came up with, and a fork of your Plunkr to show that it works.
app.directive('compile', function($compile) {
return {
restrict: 'A',
link: function(scope, elem, attrs) {
var prevScope;
scope.$watch(attrs.compile, function(newVal, oldVal) {
// create a span (an inline element) so we have an actual DOM node to
// set the innerHTML of.
var newElem = document.createElement('span');
newElem.innerHTML = newVal;
// clean up first
if (prevScope) {
prevScope.$destroy();
prevScope = null;
}
// clear out the contents of this element
elem.empty();
// and replace it with the raw (uncompiled) node
elem[0].appendChild(newElem);
// now the node is in the DOM so we can compile it
// but we want to use a try..catch because the user
// might be in the middle of typing a new expression,
// but the syntax right now is not valid so the
// expression parser will throw an error.
try {
// compile the node in the DOM with a child of the existing scope
prevScope = scope.$new();
$compile(newElem)(prevScope);
} catch (e) { /* don't need to do anything here */ }
});
}
}
});