how to process html using angular and bindings (?) - javascript

here is my testing page :
<div ng-controller="test">
<input ng-keyup="asIwrite($event)" />
<p id="entityContent"></p>
</div>
and my controller :
EntitiesApp.controller('test', ['$scope', function ($scope) {
$scope.asIwrite = function ($event) {
$('#entityContent').html($event.srcElement.value);
}
}]);
this is actually working, if i write click in the input, the paragraph will hold the clickable url (processed html).
I am using jQuery to update the content of the paragraph as to show html element as they render in the page..
But using jQuery is a work-around in my opinion.
I want to achieve that using just Angular. How can I do ?
note : sure I can sweep jQuery off my project and use innerHTML of the
element but I want to know the way of doing that in Angular with
bindings. I used ng-bind on a paragraph element but that just
render the value of the textarea as is, no html process is performed.

See working example below.
You are right by doubting using jQuery is the right thing to do, and as you would expect it is not. The angular way to do that is register your input into the scope using ng-model, and the way to display it is using the ng-bind-html directive. (or simply ng-bind if it was simple text with no HTML)
However, Angular will not allow HTML binding by default as it could be a security issue. If you are sure about what you write, you can use $scope.trustAsHtml as showed in my example.
angular.module('test', [])
.controller('test', ['$scope', '$sce', function ($scope, $sce) {
$scope.trust = function(content) {
return $sce.trustAsHtml(content);
}
}]);
<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>
<div ng-app="test" ng-controller="test">
<input ng-model="content"/>
<p ng-bind-html="trust(content)"></p>
</div>

You probably have tried to do something like this but the content doesn't come out as html
<input ng-model="input" />
<p id="entityContent" ng-bind-html="input"></p>
You need to ensure strict context escaping as described here:
https://docs.angularjs.org/api/ng/service/$sce
Please keep in mind what you're saying you want to do is explicitly prevented by angular developers as a way to mitigate XSS attacks

You don't need to do that, angular is simplier than that.
<div ng-controller="test">
<input ng-model="variable1" />
<p id="entityContent">{{variable1}}</p>
</div>
Angular binds variables automatically. When the input's value change, the new value will be printed.

Related

How to use ng-bind on a td tag?

I have the following <td> element
<td translate="Price-{{product-op}} {{product-np}}" translate-values=GetVal()></td>
Now, GetVal() function is potentially dangerous because it is in a third party app.
So, I have decided to strip off any malicious elements. Decided to use ng-bind
The problem is how to ng-bind and then translate in the above code?
I came up with something like,
<td ng-bind translate="Price-{{product-op}} {{product-np}}" translate-values=GetVal()></td>
but it throws angular exception.
Any ideas ?
If you are using the Angular Translate library (https://angular-translate.github.io), the translate directive should bind the value automatically. If you remove the ng-bind, it should work.
But I am not sure what library you are using for your translations, so my suggestion might not help you. You might have to provide more information.
Also ng-bind requires a value in the $scope - for example put $scope.myValue = 'My Value' in your controller and then use this in your HTML <td ng-bind="myValue"></td>. But again, I do not know what the translate directive is supposed to do.
I don't understood exactly what do you want to do, But I imagine that the exception is because the 'ng-bind' prop needs a value to do a bind like this:
<script>
angular.module('bindExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.name = 'Whirled';
}]);
</script>
<div ng-controller="ExampleController">
<label>Enter name: <input type="text" ng-model="name"></label><br>
Hello <span ng-bind="name"></span>!
</div>

store formatted text in mysql using cakephp and angularjs

Currently i am trying to build an community page in which user can contribute there articles in well text format. My backend is cakephp and front-end is angular-js
How can i store text in well formatted html style for example input text which i want to store in Mysql is
<b> hello </b><br/>
<em>world </em>
and when i fetch text from table output must be like
hello
world
update:-
and it should also work for inline CSS if it is possible then it is great.
<div style="color:#D2691E">hiiii</div>
i don't need to implement fancy animation-css tag but it should support basic css.
thank you in advance
You can use the ngBindHtml directive, but before you must include the $sanitize service and put ngSanitize as a dependency of your application module.
Also implemented a trusted filter with the use of $sce which is a service that provides Strict Contextual Escaping services to AngularJS.
Strict Contextual Escaping (SCE) is a mode in which AngularJS requires bindings in certain contexts to result in a value that is marked as safe to use for that context.
Code:
angular
.module('myApp', ['ngSanitize'])
.filter('trusted', ['$sce', function($sce) {
return function(str) {
return $sce.trustAsHtml(str);
};
}])
.controller('myController', function($scope) {
$scope.myHTML = '<b>hello</b><br/><em>world</em>';
$scope.myHTMLStyled = '<div style="color: #D2691E">hiiii</div>';
});
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-sanitize.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
<div ng-bind-html="myHTML"></div>
<div ng-bind-html="myHTMLStyled | trusted"></div>
</div>

How would I create something similar like this in AngularJS

Having a hard time grasping AngularJs.. How would you build something like this simple textfields and animations in AngularJS? I had been looking into using directives but it just isn't adding up to me much. I had been trying to base this from what I learned online but was not having much luck
http://codepen.io/yusufbkr/pen/RPBQqg
HTML:
<div class="materialContainer">
<div class="title">LOGIN</div>
<div class="input">
<label for="name">Username</label>
<input type="text" name="name" id="name">
<span class="spin"></span>
</div>
<div class="input">
<label for="pass">Password</label>
<input type="password" name="pass" id="pass">
<span class="spin"></span>
</div>
<div class="button login">
<button><span>GO</span> <i class="fa fa-check"></i></button>
</div>
Forgot your password?
<div class="title">REGISTER</div>
<div class="input">
<label for="regname">Username</label>
<input type="text" name="regname" id="regname">
<span class="spin"></span>
</div>
<div class="input">
<label for="regpass">Password</label>
<input type="password" name="regpass" id="regpass">
<span class="spin"></span>
</div>
<div class="input">
<label for="reregpass">Repeat Password</label>
<input type="password" name="reregpass" id="reregpass">
<span class="spin"></span>
</div>
<div class="button">
<button><span>NEXT</span></button>
</div>
just use the codepen link ( http://codepen.io/yusufbkr/pen/RPBQqg ), stackoverflow won't let me input the rest of the code...
Thanks! Any help would be incredible
I'm just learning Angular myself. From what I know, you're on the right track to be thinking of directives for swapping out interactive parts of the DOM. I suspect you'll also be needing ui-router for dealing with the widget outcomes (I hear it's the industry standard, vs the built-in ngRouter).
I'm partly writing this out to make sure I understand it, so I hope other, more knowledgeable people will come by and answer any questions you have about it (or point out where I'm misundertanding something.)
So you bring the webpage into the Angular world by, for instance, making the <html></html> tags into <html ng-app="yourApp"></html>. The unchanging html that will be the same on every view is in the index.html file. Put the html for the boxes is in another html file, say box.html. On the index.html file in the place where you want to have your boxes appear, put <div ui-view></div>. The ui-view connects to ui-router. Down at the bottom of the index.html right before closing the body tag, put
<script src="lib/angular/angular.js"></script>
<script src="lib/angular-ui-router/release/angular-ui-router.js"></script>
<script src="app/app.js"></script>.
In app.js, you put something like,
angular.module('yourApp', [
'yourApp.box',
'ui.router'
])
.config(function($stateProvider, $urlRouterProvider, $httpProvider) {
$urlRouterProvider
.otherwise('/signin/child');
$stateProvider
.state('box', {
url: '/signin',
templateUrl: 'app/box/box.html',
controller: 'BoxController'
})
.state('box.child', {
url: '/child',
template: '<span>{{ definedProperty }}</span>'
});
})
});
Starting at the top, you name angular, call its module function, and give it the parameters ('theNameYouChose', ['dependencies','required'])
In the config bit there, you're telling it about dependencies config needs. $stateProvider and $urlRouterProvider are ui-router things, and $httpProvider is, I believe, an angular thing that is still necessary.
In the urlRouterProvider, you're providing the default address the website goes to: in this case it happens to be a template within a template, /signin from the signin state, and /child from the specifics pasted into signin
In the states, you are giving names and properties to the URLs that will be part of your app: like, if someone goes to index.html/signin, the 'signin' state is summoned.
The template within a template might be how you'd get the box variability that you're looking for. In box.html you will have another <div ui-view></div> and that's where the varying thing described in 'signin.child' gets put in.
box.html is also the place you put your specially created html tags, the ones you will make with the directive. I'll talk through those below.
The parent template, 'signin', talks about BoxController. Let's say you built that in box.js. It would look like this:
angular.module('yourApp.box', [])
.controller('BoxController', function ($scope) {
$scope.definedProperty = 'reRegPass',
$scope.arrayOfObjects = [{prop: 'red'},{prop: 'blue'}]
})
.directive('specificBox', function(){
return {
restrict: 'EA',
templateUrl: 'app/box/box-guts.html',
replace: true,
scope: {
source: '='
},
link: function(scope, element, attribute) {
element.on('click', function() {
alert('Functionality in specificBox is working');
}
}
}
});
The first line is again summoning angular module, and then naming it: note we already listed this, 'yourApp.box', as a requirement in app.js. Then we have the controller-naming function, and the appearance of specific properties in their $scope.
The directive is taking the more useful of the two forms a directive can take. They can either return functions (with signatures like the one in .link), or they can return objects that describe new HTML entities. This one is named specificBox, which Angular will translate into <specific-box></specific-box>. This object (technically called a 'directive definition object') can be translated into HTML tags because of the restrict property... 'E' is for element. 'A' is for attribute. I don't know how something that can be an element could also be an attribute, but having both options works, so I'm going with it. (Maybe for your various signin boxes you want a directive that has just 'A' to make new types of attributes.)
You put these specifically-crafted tags into box.html, and everything in box-guts.html will be between those tags... In fact, replacing those tags because of the replace: true.
The .link property is where you would put a function that would do something interesting to that element; turn it red if clicked, whatever. I have an alert example. Uses jQuery Lite for events.
The .scope property is odd. I believe if left off, the specific-box stuff would have the same controller as box (ie, BoxController), with box's scope and dependencies. But here, instead, we're making an isolate scope. box-guts will not depend on anything or have access to anything built before. How will it get interesting changeable data, then..? Every property in the scope object becomes an attribute on specific-box.
The '=' means that you will pass it objects from somewhere, and they will have 2-way data binding (changes made in box-guts will be reflected in the object collection in your app). Other options are '#', one-way data binding, which means you're passing box-guts a string or something that, if it changes in the DOM, you don't care to reflect in your app; or '&' to give it a function from a controller somewhere else in your app.
So ultimately, in box.html, you will have something like
<div class="box-holder">
<div ui-view></div>
<specific-box source="thing" ng-repeat="thing in arrayOfObjects"></specific-box>
</div>
Like I said above, ask questions and maybe we can sort this out.

Can an Angular controller bind to multiple parts of a web page?

Suppose that I've written a web page that requires the user to key in data into forms. Suppose that there are two parts of the page that are completely separate in the DOM, yet are logically related. I need to bind them to a single model.
The first (bad) solution I can think of is to completely restructure the page so that everything to be bound to the model is contained in a single <div> element (or perhaps even put the controller on the <body> element).
Another solution might be to bind the inputs to a object that could be made a member of two different controllers, but that sounds like a bit of a kludge.
Suppose the HTML looks like this:
<input ng-model='data1' />
<div>
<!-- something complicated -->
</div>
<input ng-model='data2' />
You can create a shared service and inject into both controllers. This can be achieved by either the factory or service pattern. See SO post angular.service vs angular.factory for some insight on the difference/similarity between the two.
This is the Angular way to do this. See the AngularJS services docs for more information. A simple example may include...
<div ng-app="app">
<div ng-controller="ctrlA"></div>
<div ng-controller="ctrlB"></div>
</div>
app.service('sharedService', [function () {
this.someValue = 'yo!'
}]);
app.controller('ctrlB', ['$scope', 'sharedService', function($scope, sharedService) {
console.log(sharedService.someValue) // yo!
}]);
app.controller('ctrlA', ['$scope', 'sharedService', function($scope, sharedService) {
console.log(sharedService.someValue) // yo!
}]);
JSFiddle Link

Bind ng-models in input type checkbox

I have a problem when binding ng-models with ng-repeat in a input tag type checkbox.
I will first attach my code and then explain more in detail.
app/main.html:
<div ng-repeat="feature in features">
<input type="checkbox" ng-model="features[$index].name">{{features[$index].name}}
</div>
<br></br>
<div class="highlighter">
<span ng-class="{emo:Emotions}">Manually</span> <span ng-class="{feel:Feelings}">create</span> the <span ng-class="{emo:Emotions}">entire</span>
</div>
main.js
angular.module('webClientApp')
.controller('MainCtrl', function ($scope,$http) {
[...other variables...]
$scope.features = [{'name':'Emotions'},{'name':'Feelings'}];
[...other parts of code]
});
Let's also assume that in the main.css file there are references to the classes .emo' and.feel' respectively to highlight the target word when the user ticks the box relative to the feature.
Now, the application works correctly when I listed all the inputs one by one like the following:
<input type="checkbox" ng-model="Emotions">Emotions
<input type="checkbox" ng-model="Feelings">Feelings
but I wanted to wrap it into an ng-repeat and list the features in the controller scope, since the features I will considered will be more. When I try the code above when I tick on the box the name changes to `true'.
I have read a lot about how to bind models to an ng-repeat inside a input tag but none of the solutions apply to my case.
Can someone please help me?
I changed thigs up quite a bit from your original model but... I did get something to behave similar to what you are looking for.
HTML
<div ng-app="webClientApp">
<div ng-controller="MainCtrl">
<div ng-repeat="(feature,enabled) in features">
<input type="checkbox" ng-model="features[feature]">{{feature}}</input>
</div>
<div class="highlighter">
<span ng-class="{emo:features.Emotions}">Manually</span> <span ng-class="{feel:features.Feelings}">create</span> the <span ng-class="{emo:features.Emotions}">entire</span>
</div>
{{features}}<br>
{{features.Emotions}}<br>
{{features.Feelings}}
</div>
JS
var app = angular.module('webClientApp', []);
app.controller('MainCtrl', function($scope, $http) {
$scope.features = {Emotions: true, Feelings: true};
});
Here's the fiddle: http://jsfiddle.net/rodhartzell/8YrxQ/
Hope this helps.
(i should add this as a comment, but I don't have enough rep. yet)
There is an issue on github which concerns your issue: https://github.com/angular/angular.js/issues/1404 and the comment of caitp shows some workarounds: https://github.com/angular/angular.js/issues/1404#issuecomment-30859987
You could (also) define a new javascript object in your controller and map the elements to that.
In controller: $scope.awnsers = {};
In template: ng-model="awnsers[feature.name]"
I hope this helps
You must use ng-checked instead of ng-model.
Check out this jsfiddle
http://jsfiddle.net/fizerkhan/z5z9s/24/
ngModel and ngChecked are not meant to be used together.
ngChecked is expecting an expression, so by saying ng-checked="master". If the expression is truthy, then special attribute "checked" will be set on the element
You should be able to just use ngModel, tied to a boolean property on your model. If you want something else, then you either need to use ngTrueValue and ngFalseValue (which only support strings right now), or write your own directive.

Categories