I'm using a combination of Angular and a contenteditable div to try and create a two way binding that I can later use an Angular controller to manipulate the data. Everything has been working great, with the exception of certain html characters that make there way into the model.
For example, when I type & I get & when there is a nonbreaking space I get nbsp;
How do I modify the contenteditable directive to clean the encoded values out and only keep the unencoded versions?
Plunkr here - http://plnkr.co/edit/ToylycanYcMJq15K36Yd?p=preview
You will see in the contenteditable directive I have this line:
html = element.html().replace(' ','');
To try and replace the values, but it's having no affect...
Although you can do something like this, but I think you would be better using input or textarea for the same. According to docs AngularJS Models support only input, select or textarea.
Also there is an open issue for the same problem that you are facing.
Here is the code if you intend to use contenteditable div:
var myApp = angular.module('app',[]);
myApp.controller('chatterCtrl', ['$scope', function($scope) {
$scope.$watch('comment', function(){
if($scope.comment != undefined){
$scope.comment = unescape($scope.comment);
}
}, true);
}]);
Related
I am trying to create an html elemnt from string in js.
The string is: "<p class='text-muted'> come and see how good I look </p>".
In the past I did this with php by echo it out and now I build the client side only with angularJS and I have no clue how to do it.
I tried to bind the string to the page but, as expected, it prints the whole string without encode the string to html elemnt..
I tried to look for an answer in the internet and specificly in this community without succuess..
Does it possible, and if so, How?
Thanks in advance
You can use the ng-bind-html directive to bind a string of html to an element. The string should be sanitised first for example by injecting $sceand calling $sce.trustAsHtml() on the string to bind.
Example controller:
app.controller('MainCtrl', function($scope, $sce) {
$scope.template = $sce.trustAsHtml('<p class="text-muted"> come and see how good I look </p>');
});
And in html
<div ng-bind-html="template"></div>
Here's a quick example plunker
You can type in html and click to bind it
You can attach a String definition of html to any DOM Elment using the property 'innerHTML'.
yourDomEl.innerHTML = '<div class="your-class"><a>Link</a></div>';
I need to append a directive's template AFTER an input field. The original input field needs to remain - I can't just create a duplicate of it. My thought for this was to, in the controller, use jQuery to add a DIV after the input field, and add an attribute for the directive to the div. However, in practice, that doesn't work - the div is created and added, but the directive doesn't activate.
The problem, I know, is that the jQuery-added div is not yet recognized by the angularjs controller - it appears AFTER angularjs runs over the controlled html.
I know that part of the problem is that you're not supposed to use jQuery in the controller, but I honestly can't think of another way to do it. Is there some way to cause the angularjs controller to look at this new div?
The original HTML looks like the following.
<input name="generatedString_1234567890">
I run jquery over the page to add a controller to the body. The relevant code looks similar to this:
jQuery('body').attr('ng-controller','MainCtrl');
angular.module('app',['DataTools']);
angular.element(document).ready(function(){
angular.bootstrap(document, ['app']);
});
Inside the angularjs, I run a resource to get a json string containing the relevant changes to the DOM, in terms of attributes that need to get added to the inputs and certain understood flags that require specific coding. The relevant task I'm trying to accomplish looks like this, where $(this) is the input field for the DOM.
jQuery(document).find('input.FormField,select.FormField').each(function(){
// Inside a case statement based on certain flags
var d = $('<div/>');
d.attr("ng-model", 'adors.'+label);
// Relevant code that adds attributes to the div - including the required directives
$(this).hide().after(d);
}
I am trying to create code that looks more like this (VERY GENERIC):
<input name="generatedString_1234567890" ng-hide="true" ng-model="input.uniqueKey">
<div special-input="time" ng-model="input.uniqueKey">
<select ng-repeat="hour in hours">
<select ng-repeat="minute in minutes">
</div>
I want to show MathML DOM object dynamically with Angularjs.
This is what I wrote:
var mathML = angular.module('mathML', ['ngSanitize']);
mathML.controller('mathMLCtrl', ['$scope', function ($scope) {
$scope.result = function(){
return "<math xmlns='http://www.w3.org/1998/Math/MathML'><msup><msqrt><mrow><mi>a</mi><mo>+</mo><mi>b</mi></mrow></msqrt><mn>27</mn></msup></math>";
//return "<p>p tag</p>";
};
}]);
With ng-bind-html, I can insert text as a HTML text, but MathML's XML is not inserted properly. (All tags are deleted.)
It looks like necessary to insert MathML text as DOM Objects. But I don't know how to do it.
How can I show MathML with Angularjs?
ng-bind-html sanitizes the output by removing tags that are not listed as "safe". The math tag is not listed under the allowed tags. If you trust this html to never have exploits, you'll want to use the $sce service to mark the code as trusted. See this answer:
https://stackoverflow.com/a/19417443/1248889
Another alternative would be to save this text as a partial, in it's own separate file. Then in your html, use ng-include to load the partial into the dom.
i am trying to write a directive that replaces an input field with an custom made input field. However, I can not get the databinding to work as the model does not show in the directive input field.
I have created a jsFiddle here:
http://jsfiddle.net/6HcGS/392/
I guess i dont really know what to place here for the databinding to work:
tElement.replaceWith('<input ng-model="ngModel" type="text" />');
If anybody could help me out i would be very grateful as this has been a problem for me for a whole day now.
Cheers!
tElement.replaceWith('<input ng-model="ngModel" type="text" />');
Angularjs doesn't know that ngModel is a binding. It's interpreted as a simple string. So you need to tell angular this.
I've updated your jsfiddle to show you how to do this:
http://jsfiddle.net/6HcGS/393/
But you can do it even simpler by removing the isolated scope in the directive:
http://jsfiddle.net/6HcGS/394/.
Like lort already mentioned the attributes are getting passed to the element during replacement. Of course only if you dont use isolated scope.
I don't understand what you're trying to do but it seems that following code example is all you need:
angular.module('zippyModule', [])
.directive('zippy', function(){
return {
restrict: 'C',
replace: true,
template: '<textarea></textarea>',
}
});
This one changes initial input into textarea. Binding through ng-model still works because other attributes are not deleted from element during replacement.
I'm currently working on a simple editor built with angular. The main textbox is just a div with the contenteditable set to true and the ng-bind-html attribute, like this:
<div contenteditable="true" ng-bind-html="field.content">HTML content here</div>
The value is set and rendered properly with the right tags and look at page load. But since it's only bound one way I my data or model isn't updated upon edit.
I've tried some contenteditable directivs but most of them requires ng-model, but if I add that my html tags are not rendered and converted into symbols.
How would I go about updating my data after the div's content have been changed and also keep the HTML tags and so on formatted correctly?
EDIT: Just using this temporary "fix" for the time being, but I would like something more robust.
<div contenteditable="true" ng-bind-html="field.content"
ng-blur="saveHTML($event)"></div>
$scope.saveHTML = function(event) {
this.field.content = event.target.innerHTML;
}