Angular and youtube iframe issue - javascript

I'm trying to add a youtube video to my app, but angular removes the iframe code and does not appear, I'm using this
<div class="content-read" ng-bind-html="data.content"> </ div>
try using ng-bind-html-unsafe, but I think this was removed from the current version of angularjs
I'm using angular 1.2.3
I have also this
app.config(['$sceDelegateProvider', function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist([
'self',
'http://www.youtube.com/**',
]);
}]);
Any ideas?
thanks

the best solution I found, is to create a directive that meets the function of ng-bind-html-unsafe
app.directive('ngBindHtmlUnsafe', ['$sce', function($sce){
return {
scope: {
ngBindHtmlUnsafe: '=',
},
template: "<div ng-bind-html='trustedHtml'></div>",
link: function($scope, iElm, iAttrs, controller) {
$scope.updateView = function() {
$scope.trustedHtml = $sce.trustAsHtml($scope.ngBindHtmlUnsafe);
}
$scope.$watch('ngBindHtmlUnsafe', function(newVal, oldVal) {
$scope.updateView(newVal);
});
}
};
}]);

Related

AngularJS directive not recognised when starting with data-*

I'm new to AngularJS. Need some help with the directive I created.
This is My HTML:
<data-table template-url="dataTable.html" info="someData"></data-table>
I get "someData" from server in my controller - directive.js:
app.directive('dataTable', function() {
return{
restrict: 'E',
scope: {
data : '=info'
},
link: function($scope,elem,attrs){
///some code here.
},
templateUrl : function(elem, attrs) {
return attrs.templateUrl;
}
});
The issue is when I debug my code, it come to the directive by doesn't go inside. (I used javascript debug in chrome). Is there anything I'm missing. The restrict Tag is proper, name is correct what else is needed? I did look at the similar questions but couldn't find any solution. Here is a fiddle : Demo
You can't use directive names starting with data-* because its reserved by AngularJS ng core namespaces. Just use an other name to start with and you will be fine.
<my-data-table template-url="dataTable.html" info="someData"></my-data-table>
And your directive:
myApp.directive('myDataTable', function() {
return {
scope: {
data: '=info'
},
link: function($scope, elem, attrs) {
///some code here.
console.log(attrs.templateUrl);
},
templateUrl: function(elem, attrs) {
return attrs.templateUrl;
}
}
});

Any way to dynamically load angular directives?

Here's a short fiddle:
http://jsfiddle.net/aSg9D/
Basically, neither <div data-foo-{{letterA}}></div> nor <div data-ng:model="foo-{{letterB}}"></div> are interpolated.
I'm looking for a way to dynamically load one of several inline templates.
Pardon me if this has already been asked before, but I searched and couldn't find it.
I believe Radim Köhler has the correct answer. Just before it was posted, I hacked together something to load directives from another directive like this:
angular.module('myApp', []).directive('loadTmpl', function($compile) {
return {
restrict: 'A',
replace: true,
link: function($scope, $element, $attr) {
$element.html("<div data-card-"+$attr.loadTmpl+"></div>");
$compile($element.contents())($scope);
}
};
});
And:
<div data-load-tmpl="{{directiveName}}"></div>
I think that's the minimalist approach, but there's probably something wrong with it, so just look at the answer below.
Let's adjust it this way (the udpated fiddle). The view:
<div my-selector name="letterA"></div>
<div my-selector name="letterB"></div>
the controller:
function myCtrl($scope) {
$scope.letterA = 'bar';
$scope.letterB = 'baz';
}
And here is new directive mySelector, containing the selector
.directive('mySelector',
[ '$templateCache','$compile',
function($templateCache , $compile) {
return {
scope: {
name: '='
},
replace: true,
template: '',
link: function (scope, elm, attrs) {
scope.buildView = function (name) {
var tmpl = $templateCache.get("dir-foo-" + name);
var view = $compile(tmpl)(scope);
elm.append(view);
}
},
controller: ['$scope', function (scope) {
scope.$watch('name', function (name) {
scope.buildView(name);
});
}],
};
}])
.run(['$templateCache', function ($templateCache) {
$templateCache.put("dir-foo-bar", '<div data-foo-bar></div>');
$templateCache.put("dir-foo-baz", '<div data-foo-baz></div>');
}])
In case you like it, all credits goes to Render a directive inside another directive (within repeater template) and AngularJS - Directive template dynamic, if you don't, blame me.

AngularJS' $sce.trustAsHtml being ignored

I'm new to AngularJS and I feel like I'm just scratching the surface of what's possible with the framework. However, I'm running into problems with the sce.trustAsHtml function. I'm running AngularJS 1.2.4.
In my application, I'm loading items using JSON. These items are displayed in a list using a directive. Sometimes, I would want to inject HTML into the retrieved content (e.g. to make links clickable).
I've read I can use $sce.trustAsHtml to allow html in the binds. However, the following snippet isn't working. I would expect all items to be replaced with a bold text 'test', but instead it's displaying <strong>Test</strong> for each item.
Is there a simple way to make this snippet work?
angular.directive('ngStream', function($timeout, $sce) {
var url = "getitems.json";
return {
restrict: 'A',
scope: {},
templateUrl: 'templates/app_item.html',
controller: ['$scope', '$http', function($scope, $http) {
$scope.getItems = function() {
$http.get(url,{}).success(function(data, status, headers, config) {
$scope.items = data;
});
}
}],
link: function(scope, iElement, iAttrs, ctrl) {
scope.getItems();
scope.$watch('items', function(newVal) { if (newVal) {
angular.forEach(newVal, function(vars,i) {
# Example html string for testing purposes.
var editedContent = '<strong>Test</strong>';
newVal[i].contentHtml = $sce.trustAsHtml(editedContent)
});
}});
},
}
});
What's on your template? $sce.trustAsHtml must be used with ng-bind-html instead of normal ng-bind (or {{}})

How to require a controller in an angularjs directive

Can anyone tell me how to include a controller from one directive in another angularJS directive.
for example I have the following code
var app = angular.module('shop', []).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/', {
templateUrl: '/js/partials/home.html'
})
.when('/products', {
controller: 'ProductsController',
templateUrl: '/js/partials/products.html'
})
.when('/products/:productId', {
controller: 'ProductController',
templateUrl: '/js/partials/product.html'
});
}]);
app.directive('mainCtrl', function () {
return {
controller: function ($scope) {}
};
});
app.directive('addProduct', function () {
return {
restrict: 'C',
require: '^mainCtrl',
link: function (scope, lElement, attrs, mainCtrl) {
//console.log(cartController);
}
};
});
By all account I should be able to access the controller in the addProduct directive but I am not. Is there a better way of doing this?
I got lucky and answered this in a comment to the question, but I'm posting a full answer for the sake of completeness and so we can mark this question as "Answered".
It depends on what you want to accomplish by sharing a controller; you can either share the same controller (though have different instances), or you can share the same controller instance.
Share a Controller
Two directives can use the same controller by passing the same method to two directives, like so:
app.controller( 'MyCtrl', function ( $scope ) {
// do stuff...
});
app.directive( 'directiveOne', function () {
return {
controller: 'MyCtrl'
};
});
app.directive( 'directiveTwo', function () {
return {
controller: 'MyCtrl'
};
});
Each directive will get its own instance of the controller, but this allows you to share the logic between as many components as you want.
Require a Controller
If you want to share the same instance of a controller, then you use require.
require ensures the presence of another directive and then includes its controller as a parameter to the link function. So if you have two directives on one element, your directive can require the presence of the other directive and gain access to its controller methods. A common use case for this is to require ngModel.
^require, with the addition of the caret, checks elements above directive in addition to the current element to try to find the other directive. This allows you to create complex components where "sub-components" can communicate with the parent component through its controller to great effect. Examples could include tabs, where each pane can communicate with the overall tabs to handle switching; an accordion set could ensure only one is open at a time; etc.
In either event, you have to use the two directives together for this to work. require is a way of communicating between components.
Check out the Guide page of directives for more info: http://docs.angularjs.org/guide/directive
There is a good stackoverflow answer here by Mark Rajcok:
AngularJS directive controllers requiring parent directive controllers?
with a link to this very clear jsFiddle: http://jsfiddle.net/mrajcok/StXFK/
<div ng-controller="MyCtrl">
<div screen>
<div component>
<div widget>
<button ng-click="widgetIt()">Woo Hoo</button>
</div>
</div>
</div>
</div>
JavaScript
var myApp = angular.module('myApp',[])
.directive('screen', function() {
return {
scope: true,
controller: function() {
this.doSomethingScreeny = function() {
alert("screeny!");
}
}
}
})
.directive('component', function() {
return {
scope: true,
require: '^screen',
controller: function($scope) {
this.componentFunction = function() {
$scope.screenCtrl.doSomethingScreeny();
}
},
link: function(scope, element, attrs, screenCtrl) {
scope.screenCtrl = screenCtrl
}
}
})
.directive('widget', function() {
return {
scope: true,
require: "^component",
link: function(scope, element, attrs, componentCtrl) {
scope.widgetIt = function() {
componentCtrl.componentFunction();
};
}
}
})
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.name = 'Superhero';
}

AngularJS Navigation does not work after tinymce directive

I have problem I can't figure out but I do have a hint. Before integrating TinyMCE the main navigation was working fine eg links Settings, Analytics, Setup; it isn't working now if you click them.
Here is my js file:
var app_htmleditor_module = angular.module('app_htmleditor', ['components']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {templateUrl: getBaseURL()+'public/tpl/app/htmleditor.htm', controller: HtmlEditorCtrl, reloadOnSearch:false }).
otherwise( {redirectTo: '/'});
}
]);
angular.module('components', []).directive('imageUpload', function () {
return {
restrict: 'E',
scope: {
uploaderid:'#uploaderid'
},
templateUrl: '/public/tpl/imageupload.htm'
}
});
app_htmleditor_module.directive('uiTinymce', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
element.tinymce({
// Location of TinyMCE script
script_url: 'http://resources.holycrap.ws/jscripts/tiny_mce/tiny_mce.js',
// General options
theme: "simple",
// Change from local directive scope -> "parent" scope
// Update Textarea and Trigger change event
// you can also use handle_event_callback which fires more often
onchange_callback: function(e) {
if (this.isDirty()) {
this.save();
// tinymce inserts the value back to the textarea element, so we get the val from element (work's only for textareas)
//ngModel.$setViewValue(e.getBody().innerHTML);
ngModel.$setViewValue(element.val());
scope.$apply();
return true;
}
}
});
}
}
});
And I added above tinymce directive into textarea using ui:tinymce like this:
<textarea ui:tinymce ng-model="data.html_tab" id="{{fileUploaderID}}_html_tab" name="{{fileUploaderID}}_html_tab" style="width:600px; height:300px"></textarea>
Notice ui:tinymce above. If I remove that, the navigation works fine again. So how do I make my navigation work with ui:tinymce added in textarea?
DEMO URL:
http://dev-socialapps.rkm-group.com/app/htmleditor/index#/
Any help will be greatly appreciated. Thanks
Update:
As suggested, I added ui js file to my template file first:
<script src="https://raw.github.com/angular-ui/angular-ui/master/build/angular-ui.js"></script>
Then In my js file, I added:
var app_htmleditor_module = angular.module('app_htmleditor', ['components', 'ui']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: getBaseURL()+'public/tpl/app/htmleditor.htm',
controller: HtmlEditorCtrl,
reloadOnSearch:false
}).
otherwise( {redirectTo: '/'});
}
]);
app_htmleditor_module.value('ui.config', {
tinymce: {
theme: 'simple'
}
});
And in textarea tag:
<textarea ui-tinymce ng-model="tinymce" id="{{fileUploaderID}}_html_tab" name="{{fileUploaderID}}_html_tab" style="width:600px; height:300px"></textarea>
But I am getting error:
ReferenceError: tinymce is not defined
Though ui js file is added fine, I confirmed by viewing source code and clicking on link
Have you tried the latest version of the tinymce directive in the angular-ui library?
Demo
JS file

Categories