I want to pass the html element into angularjs code. I have some html elements like data-form-selector='#linechart_general_form' and data-url="{% url 'horizon:admin:metering:samples'%}" I want to access these Html elements in angularjs code.
My html templates, what make to change in the following code so that its elements accessible to angularjs code.
<div class="info row detail">
<div class="col-sm-9 chart_container">
<div class="chart"
data-chart-type="line_chart"
data-url="{% url 'horizon:admin:metering:samples'%}"
data-form-selector='#linechart_general_form'
data-legend-selector="#legend"
data-smoother-selector="#smoother"
data-slider-selector="#slider">
</div>
<div id="slider"></div>
<div class="col-sm-3 legend_container">
<div id="smoother" title="Smoothing"></div>
<div id="legend"></div>
</div>
</div>
</div>
--Update-- I just reread your question. To access those ATTRIBUTES (not elements, they are values of an element) you can select the object with an identifier, then manipulate it's attributes, like so (jQuery example):
$('.chart').attr('data-form-selector', 'myNewValue');
You may need to re-initialize sopmething because of the databinding but that's where I'd start.
==================================
You need to create an angular app and controller first, then use the angularjs and ng-model directive to bind the element to a method in your controller, i.e.:
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstName= "John";
$scope.lastName= "Doe";
});
</script>
<div ng-app="myApp" ng-controller="myCtrl">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</div>
In this case, you'd be manipulating the $scope.firstName and $scope.lastName variables in js.
Courtesy W3Schools
http://www.w3schools.com/angular/angular_intro.asp
You can do a Directive for doing that.
https://docs.angularjs.org/guide/directive
Related
This is how my page looks like on initial load
<body>
<div class="col-md-12" id="dataPanes">
<div class="row dataPane"> Chunk of html elements </div>
</div>
<div class"col-md-12 text-right">
<input type="button" class="btn btn-primary" value="Add dynamic row" ng-click="addElementChunk()" />
</body>
I am in need to add rows to div#dataPanes on button click
If I was using jQuery,addElementChunk() function would have looked as below
var addElementChunk = function()
{
var html = "<div class='row dataPane'> Chunk of html elements </div>";
$("#dataPanes").append(html);
}
but how do I implement the same in angular??
You need to use $compile
Compiles an HTML string or DOM into a template and produces a template function, which can then be used to link scope and the template together.
and $sce
Strict Contextual Escaping (SCE) is a mode in which AngularJS constrains bindings to only render trusted values. Its goal is to assist in writing code in a way that (a) is secure by default, and (b) makes auditing for security vulnerabilities such as XSS, clickjacking, etc. a lot easier.
addElementChunk = function(){
var html = '<div class="row dataPane"> Chunk of html elements </div>';
var trustedHtml = $sce.trustAsHtml(html);
var compiledHtml = $compile(trustedHtml)($scope);
angular.element(document.getElementById('dataPanes')).append(compiledHtml);
}
you can append new div using angular ng-repeat directive
lets say you have an array that contain one element and every time you click the button you add another element to the array, while you are repeating it in your "dataPane" div
so you code could be:
HTML
<div ng-app="myApp" ng-controller="myCtr">
<div class="col-md-12" id="dataPanes">
<div class="row dataPane" ng-repeat="element in added_elements"> Chunk of html elements ( {{element}} ) </div>
</div>
<div class="col-md-12 text-right">
<input type="button" class="btn btn-primary" value="Add dynamic row" ng-click="addMoreElements()" />
</div>
</div>
JS
angular
.module('myApp', [])
.controller('myCtr', ['$scope', function($scope) {
$scope.added_elements = ["elem 1"];
$scope.addMoreElements = function(){
$scope.added_elements.push("elem "+ ($scope.added_elements.length+1));
}
}])
so you can add whatever data you want about your repeated row and bind it in html in simple way without having to repeat the whole html code
Working Demo
You can also append a new html element in this way. I think its very easy to write and also understand. hope it will help you.
angular.element used to access the html element.
Here is the html code:
angular.module('myApp',[]).controller('myCtrl', function($scope){
$scope.addElementChunk = function()
{
var htmlStr = '<div class="row dataPane"> Chunk of html elements </div>';
debugger;
angular.element(document.getElementById('dataPanes')).append(htmlStr);
}
});
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.3/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div class="col-md-12" id="dataPanes">
<div class="row dataPane"> Chunk of html elements </div>
</div>
<div class="col-md-12 text-right">
<input type="button" class="btn btn-primary" value="Add dynamic row" ng-click="addElementChunk()" />
</div>
</div>
Here is the fiddle link
I was wondering how to accomplish this with Angular as it seems that ng-click is something to use, then ng-model seems like that could be used.
I want to click on Text and then have a div show its contents and it is not working
My fiddle https://jsfiddle.net/gdxwtoL7/
<div class="well" ng-controller="MyController">
<a class="btn btn-primary" ng-model="selMe" ng-click="handleAnchorClick()">Enter Address</a>
</div>
<br>
<br>
<div ng-if="selMe">
adfadf
</div>
simple module and controller
angular.module('myapp', []);
angular.module('myapp').controller('MyController', MyController)
function MyController($scope) {
}
You're not doing anything inside the ng-click function, and you have the ng-if outside of the controller linked to the variable inside it.
https://jsfiddle.net/gdxwtoL7/1/
HTML
<div class="well" ng-controller="MyController">
<a class="btn btn-primary" ng-click="handleAnchorClick()">Enter Address</a>
<br>
<br>
<div ng-if="selMe">
adfadf
</div>
</div>
JS
angular.module('myapp', []);
angular.module('myapp').controller('MyController', MyController)
function MyController($scope) {
$scope.handleAnchorClick = function () {
$scope.selMe = true
}
}
The controller has to be aware of the div you want it to show.
the ng-if is waiting for the value of the selme which you can alter from the controller.
The ng-model binds your data to your controller in adding two-way data binding.
I made a little enhancement to your code to toggle the div when the text is clicked multiple times.
https://jsfiddle.net/gdxwtoL7/2/
<div class="well" ng-controller="MyController">
<a class="btn btn-primary" ng-model="selMe" ng-click="handleAnchorClick(selMe)">Enter Address</a>
<br>
<br>
<div ng-if="selMe">
adfadf
</div>
</div>
angular.module('myapp', []);
angular.module('myapp').controller('MyController', MyController)
function MyController($scope) {
$scope.handleAnchorClick = function (selMe) {
$scope.selMe = !selMe
}
}
The ngModel directive binds an input,select, textarea (or > custom form control) to a property on the scope using NgModelController, which is created and exposed by this directive.
ngModel is responsible for:
Binding the view into the model, which other directives such as input, textarea or select require.
Providing validation behavior (i.e. required, number, email, url).
Keeping the state of the control (valid/invalid, dirty/pristine, touched/untouched, validation errors).
Setting related css classes on the element (ng-valid, ng-invalid, ng-dirty, ng-pristine, ng-touched, ng-untouched, ng-empty, ng-not-empty) including animations.
Registering the control with its parent form.
The ngClick directive allows you to specify custom behavior when an element is clicked.
Note : we need ng-click to capture the event and manipulate the data stored in ng-model.
Here is simple code without the need of controller:
<div class="well">
<a class="btn btn-primary" href="" ng-click="show=true">Enter Address</a>
</div>
<br>
<br>
<div ng-show="show">
adfadf
</div>
As #MikeHughesIII already pointed out, outside of your controller you can't reach $scope variables.
I am adding a quick snippet made after Mike's answer for completeness sake, showing a show/hide (toggle) approach, where the function sets the visibility variable to the opposite of its current status (true or false) when the function is invoked.
Hope that helps to clarify the issue.
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.6.2" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="myController">
<h1>Hello {{hello}}!</h1>
<a href ng-click="toggleDivVisibility()">Enter your address</a>
<br>
<textarea ng-if="visible" name="address" id="address" cols="30" rows="5"></textarea>
</div>
<script>
angular.module('myApp', []);
angular.module('myApp')
.controller('myController', myController);
function myController($scope) {
$scope.hello = "world";
$scope.visible = false;
$scope.toggleDivVisibility = function() {
$scope.hello = 'mondo';
$scope.visible = !$scope.visible;
}
}
</script>
</body>
</html>
Hi I was just wondering if there is some built-in angular directive (ng-some-directive) that allows you to restrict the scope to a particular model for the desired DOM element.
I belive I have seen something similar done before, but maybe I am thinking of knockout.js
<script>
angular.module('example', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.heading = 'Some Value';
$scope.complexModel = {...}
}]);
</script>
<div ng-controller="ExampleController">
<h1>{{ heading }}</h1>
<div ng-some-directive='complexModel.to.long.really.annoying'>
<input type='text' ng-model='variable' /> // Actually coming from complexModel.to.long.really.annoying.variable
</div>
</div>
This is a drastically simplified version
Though its not meant for it
<div ng-init='sn = complexModel.to.long.really.annoying'>
<input type='text' ng-model='sn' />
</div>
I'm using AngularJS and trying to create a form where I can dynamically add new inputs, similar to this fiddle: http://jsfiddle.net/V4BqE/ (Main HTML below, working code in fiddle).
<div ng-app="myApp" ng-controller="MyCtrl">
<div add-input>
<button>add input</button>
</div>
</div>
I would like to be able to use a HTML template for my form since the input I'm adding is ~300 lines long. My issue is I cannot figure out how to index the scope variable containing the data when used in a template. I've tried to make my own modified version of the above code on plnkr http://plnkr.co/edit/4zeaFoDeX0sGTuBMCQP2?p=info . However, when I click the button no form elements appear.
Online (plnkr) I get a 404 not found for my template.html, but I think that is just a plnkr limitation. On my machine with a Python HttpServer I get an Error: [$parse:syntax] for the $templateRequest and a TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. when using the $http.get method.
Any advice for getting the indexed scope variable array to work with an external html file?
Thanks, JR
Edit: Update plnkr link
You can do it without directive & external template
what you are trying to do does not require a directive (it actually much simple with the basic angularjs tools)
http://plnkr.co/edit/LVzGN8D2WSL2nR1W7vJB?p=preview
html
<body>
<div class="container" ng-app="myApp" ng-controller="MyCtrl">
<button class="btn btn-primary" type="button" ng-click="addPhoneInput()">add input</button>
<form>
<div ng-repeat="item in telephoneNumbers">
<hr>
<input type="text" ng-model="item.phone">
</div>
</form>
<hr>
<div class="well">
<h4>Phone Numbers,</h4>
<p ng-repeat="item in telephoneNumbers">{{item.phone}}</p>
</div>
</div>
</body>
js
var app = angular.module('myApp', []);
app.controller('MyCtrl', ['$scope', function($scope) {
// Define $scope.telephone as an array
$scope.telephoneNumbers = [];
$scope.addPhoneInput = function() {
$scope.telephoneNumbers.push({});
};
// This is just so you can see the array values changing and working! Check your console as you're typing in the inputs :)
$scope.$watch('telephoneNumbers', function(value) {
console.log(value);
}, true);
}]);
If you insist using a directive,
http://plnkr.co/edit/BGLqqTez2k9lUO0HZ5g1?p=preview
phone-number.template.html
<div>
<hr>
<input type="text" ng-model="ngModel" >
</div>
html
<body>
<div class="container" ng-app="myApp" ng-controller="MyCtrl">
<button class="btn btn-primary" type="button" ng-click="addPhoneInput()">add input</button>
<form>
<phone-number ng-repeat="item in telephoneNumbers" ng-model="item.phone"></phone-number>
</form>
<hr>
<div class="well">
<h4>Phone Numbers,</h4>
<p ng-repeat="item in telephoneNumbers">{{item.phone}}</p>
</div>
</div>
</body>
js
var app = angular.module('myApp', []);
app.controller('MyCtrl', ['$scope', function($scope) {
// Define $scope.telephone as an array
$scope.telephoneNumbers = [];
$scope.addPhoneInput = function() {
$scope.telephoneNumbers.push({});
};
// This is just so you can see the array values changing and working! Check your console as you're typing in the inputs :)
$scope.$watch('telephoneNumbers', function(value) {
console.log(value);
}, true);
}]);
app.directive('phoneNumber', function(){
return {
replace:true,
scope: {
ngModel: '=',
},
templateUrl: "phone-number.template.html"
}
});
I need to create dynamic inputs, textareas..etc. So for each input type I have a separate template. So a text field template could look like this:
<script type="text/ng-template" id="/input.html">
<input type="text" ng-model="model" />
</script>
and what I am trying to achieve is something like this:
<div ng-include="" src="'/input.html'" ng-init="model = var1"></div>
<div ng-include="" src="'/input.html'" ng-init="model = var2"></div>
so I can create text fields with the same template and have a different model for each one. That works actually and gets the data passed, but if I type something in the text field it doesn't get applied to the scope variable.
Here's a fiddle to illustrate this: http://jsfiddle.net/uAm99/2/
You could try to implement this feature in "angular directive way". It can empower the HTML tag, such as reusable template (just mentioned in your implementation). Here is a simple example:
HTML
<body ng-app="myApp">
<div ng-controller="myCtrl">
<custom-input data="var1"></custom-input>
<custom-input data="var2"></custom-input>
{{var1}}
{{var2}}
</div>
</div>
JS
angular.module("myApp",[])
.controller("myCtrl",function($scope){
$scope.var1 = "foo";
$scope.var2 = "bar";
})
.directive("customInput",function(){
return {
restrict:'E',
scope: {
data:"="
},
template: '<input type="text" ng-model="data" />'
};
});
And this is a jsfiddle demo
Hope it helpful.