Calling method from an AngularJS Controller in SSRS Report - angularjs

I created an angularJS Controller with 1 method.
Controller.js
var project = angular.module('project',[]);
project.controller('TestCtrl', function($scope){
$scope.run = function(){
alert('Test');
};
});
I created a placeholder in a textbox in SSRS RDLC. I changed the placeholder properties. From General pane, I selected HTML-Interpret HTML tags as styles under Markup type section. Then, under Value, I entered this: ="< a onclick='run()'> Run Report < /a>"
However, it did not work. Is it possible to call an javascript method that was implemented in an AngularJs controller in SSRS RDLC??

user ng-click instead of onclick

Related

How do I dynamically create clickable keywords that display a modal (uibModal) dialog in AngularJS

I am new to AngularJS. I have been developing a site that displays a list. Each element in the list is a delivered from the server as a string. Within each element I use bars as delimeters for keywords that I'd like the user to be able to click on (i.e. this is a |keyword| in this element).
I use a controller/filter to create html to remove the delimiters and make the keywords red (using a class). So the html looks ends up looking like this:
<span ng-controller="formatForGlossaryAndCodeTextCtrl" class="ng-scope">
<span ng-bind-html="formattedLineItem" class="ng-binding">
this is a
<span class="glossaryLookup" >keyword</span> <!--here is my keyword-->
in this element
</span>
</span>
I tried having the filter also generate ng-controller=xxx and ng-click=xxx in order to stay in the angular world but that doesn't work (my keyword is not clickable when I do that).
I DO have jQuery code that binds the click event to the elements with class=glossaryLookup. It currently displays an alert when I click on the keyword.
I am at a loss as to how to get that click to display an angular modal dialog. I want it to use an angular modal dialog because there is another part of the same application that already displays an angular modal dialog and I want to be consistent
So, in short... the server delivers a string containing one or more delimited words to the browser. I'd like the angular/js/jquery code on the browser to not only highlight the delimited word(s) but allow me to click on them, look up a definition (I am not concerned about how to look up the definition, at least not yet) and display that definition in a $uibModal.
Thanks for any help.
I think I actually figured it out. I created a dummydiv and gave it an id (id=dummydiv). I "assign" a controller to that div (ng-controller=dummyCtrl).
`<div id=dummydiv ng-controller=dummyCtrl></div>`
In the jQuery code that binds the click event to my keyword I use this line of code to run the function in the dummy controller that displays the dialog:
`$(document).ready(function () {
$(document)
.on("click", ".glossaryLookup", "NEED TO LOOKUP IN GLOSSARY", function (x) {
angular.element($("#dummydiv")).scope().testclick();
})
.on("click", ".codeTextLookup", "NEED TO LOOKUP CODE TEXT", function (x) {
alert(x.data)
})
});`
BTW - the dummy controller looks like this:
`//DUMMY CONTROLLER TO TEST DYNAMIC CLICK
Hydroware_Checkbox_List_Prototype_App.controller('dummyCtrl', function ($scope, $uibModal) {
$scope.testclick = function () {
alert("I WAS CLICKED BUDDY");
var modalInstance = $uibModal.open({
templateUrl: 'line_item_help.html',
controller: "LineItemHelpDialogCtrl",
scope: $scope
});
};
});`

Angular hide dirrective depending on action in another directive

I'm new in angular and i'm looking for the best way to do what I want.
In my main page I have 2 directives, one is used to display a button (and maybe other stuff). And another used to display a kind of dialog box/menu.
Each directive has its own controller.
I want to show or hide the second directive when I click on the button in the first one.
I don't really know what are goods or wrong approaches. Should I use a service injected in both controller and set a variable with ng-show in the second directive? This solution doesn't really hide the directive because I need a div inside the directive to hide its content and isn't too much to use a service only for one boolean?
Should I use a kind of global variable (rootscope?) or inject the first controller inside the second one?
Or maybe use a third controller in my main page (used with a service?) or use only one controller for both directive?
Basically without directive I would probably used only one main controller for my whole page and set a variable.
In fact the first directive is just a kind of button used to display "something", and the second directive just a kind of popup waiting a boolean to be displayed. That's why I finally used a service containing a boolean with a getter and a setter to avoid any interaction beetween both controller.
My both controller use this service, the first one to set the value when we click on the element and the second controller provide just a visibility on the getter for my ng-show.
I don't know if it is the best way to do but I am satisfied for now.
Small example here (without directive but with same logic) :
http://codepen.io/dufaux/pen/dXMrPm
angular.module('myModule', []);
angular.module("myModule")
.controller("ButtonCtrl", buttonCtrl)
.controller("PopUpCtrl", popUpCtrl)
.service("DisplayerService", displayerService);
//ButtonCtrl
buttonCtrl.$inject = ["DisplayerService", "$scope"];
function buttonCtrl(DisplayerService, $scope) {
var vm = this;
vm.display = function(){
DisplayerService.setDisplay(!DisplayerService.getDisplay());
}
}
//PopUpCtrl
popUpCtrl.$inject = ["DisplayerService"];
function popUpCtrl(DisplayerService) {
var vm = this;
vm.displayable = function(){
return DisplayerService.getDisplay();
}
}
//Service
function displayerService(){
var vm = this;
vm.display = false;
vm.setDisplay = function(value){
vm.display = value;
}
vm.getDisplay = function(){
return vm.display;
}
}
--
<body data-ng-app="myModule">
<div data-ng-controller="ButtonCtrl as btnCtrl" >
<button data-ng-click="btnCtrl.display()">
display
</button>
</div>
[...]
<div data-ng-controller="PopUpCtrl as popUpCtrl" >
<div data-ng-show="popUpCtrl.displayable()">
hello world
</div>
</div>
</body>

AngularJS two directives with template on same element

I'm trying to create a context menu directive for my angular application.
I want this directive to be used for any element in the application that needs a context menu.
The problem is that in my app there are many 'user controls', that is - directives for extending buttons, inputs, grid etc. If I try to put the my-context-menu directive on any of them I get a multidir error, since both of the directives are defining templates.
The context menu directive looks something like this:
angular.module('myApp').directive('myContextMenu', function () {
var myContextMenu= {};
myContextMenu.restrict = 'A';
myContextMenu.templateUrl = 'templates/myContextMenuTemplate.html';
// Here I have scope and controller with all the functionality
return myContextMenu;
});
Another directive for example:
angular.module('myApp').directive('myGrid', function () {
var myGrid= {};
myGrid.restrict = 'E';
myGrid.templateUrl = 'templates/myGridTemplate.html';
// Here I have scope, controller and link function with all the functionality
return myGrid;
});
I want to have a context menu on the grid, and that in the grid directive I will be able to access the context menu controller.
What I tried is this: <my-grid id="grid" my-context-menu /> which failed as expected...
Do you have any solution or other idea on how to achieve this?
Thanks in advance!
My angular version: 1.3.8
You can share controllers between directives writing the same controller on the controller attribute of the directive object. And you can use transclude to embed html inside a directive with its own template. https://docs.angularjs.org/api/ng/directive/ngTransclude

How do I load an external HTML file and have the scope variables renderred properly in angularJS?

What I am trying to do is after clicking on a buddy in the buddy list, load a chat dialog template HTML file without disturbing other elements in current DOM just like chatting in facebook.
My problem is that after loading the html template file the scope variables such as {{contact.jid}} are not properly rendered, and the controller for the dialog is not even called.
How can I force a rerender or a call on the controller so that those variables are properly renderred? Or should I not use the jQuery.load function to do this? I can't figure out any other way.
Thank you.
Code of the controllers:
// Controller for the chat dialog
ctrl.controller('ChatCtrl',function($scope){
$scope.test = "Test"
});
// Controller for the buddy list
// $scope.toggleDialog is called when a buddy is clicked
ctrl.controller('ContactCtrl',function($scope){
$scope.contacts = window.contactList;
$scope.toggleDialog = function(to){
$.("#chatarea").load("chatdialog.html")
};
});
The controller function of chat dialog is not called after loading chatdialog.html which has an attribute of ng-controller, so the {{test}} variable is not set.
You need to wrap your content that will be compiled inside a directive.
This directive receives the variables and the HTML that will be compiled.
You can wrap this directive in the element that you like:
http://plnkr.co/edit/RYVCrlDmgVXT3LszQ9vn?p=preview
For example, given the following html and variables:
// In the controller
$scope.controllerHtml = '<span>{{variables.myVariable}}</span>';
$scope.controllerVariables = {myVariable: 'hello world'};
<!--In the HTML-->
<div compile-me html-to-bind="controllerHtml" variables="controllerVariables"></div>
You will get the following:
<div>
<span>hello world</span>
</div>
You are loading the external HTML via jQuery and Angular has no way of knowing how to use it. There are two ways to solve this issue:
use ngInclude to load the template from the server, angular will load it from the server and compile it for you to use.
continue to use jQuery load the HTML from the server and use the $compile service to teach angular how to use it
I would highly suggest using method #1 to load your external template.
I suppose the:
$.("#chatarea").load("chatdialog.html")
is the jQuery .load, or something similar. I would get the template via ngInclude, checking if test is setted or not; html:
<div id="chatarea" ng-if="test">
<div ng-include="'chatdialog.html'"/>
</div>
controller:
ctrl.controller('ContactCtrl',function($scope){
$scope.contacts = window.contactList;
$scope.test = '';
var callbackFunction = function(data) {
$scope.test = data.test;
};
$scope.toggleDialog = function(to){
AjaxRequestToGetBuddyInfoAndMessages(to, callbackFunction);
};
});
Obviously test will be a more complex object, so the ngIf test will be different (and you will need to take into account the fact that:
$scope.test = data.test
if they are objects, they will lose the reference and have an unwanted behaviour).

AngularJS Directive-Controller-Service Interaction

I'm trying to design a single page pagination app that displays the different pages of a document beneath each other in the same window. It has to meet the following requirements:
A pagination toolbar where the user can click next/previous/... and submit a page to go to.
The window scrolls to the right page of the document after a page has been submitted
If the user scrolls manually, the current page should update automatically
I tried some different stuff but was never really satisfied with the result. This is how I see the solution:
The app consists of 1 factory:
DocumentFactory: Stores the current page of the document and has the following methods:
setPage(page): sets the page in a factory so different controllers/directives can use this page
broadcast(pageChanged): broadcasts an event after the page has changed so the controllers/directives can listen to this even and react approprialty
2 controllers:
PaginationCtrl[DocumentFactory]: The pagination toolbar controller, updates the page by calling the setPage(method) of the DocumentFactory and listens to the pageChange event to update it's own scope when the page changes in an other controller/directive
DocumentCtrl: The controller of the document
1 Directive:
Page[DocumentFactory]: Resembles a page in the document and has the following methods/listeners
scrollToPage(): If the currentPage equals this pages number (added to the directive as an attribute, scroll to this page)
If this page is visible and the highest in the window of all visible pages, change the current page to this page's number by calling the DocumentFactory setPage(page) method.
Is this the right approach to store the page in a service and use events for the other controllers/directives to listen to it?
Should I create a controller in the directive to listen to the event or add a $watch in the link function to watch for changes in the current page (inherited from the parent Ctrl scope)?
Should I let each directive check if it's page number equals the current page on page change or should I let the DocumentCtrl scroll to the right element?
AS you already have the methods in the controller calling the factory, what you need is to use the '&' isolate scope in the directive to call the method you want.
Create the methods in the controller
var app = angular.module('app', []);
app.controller("Ctrl", function ($scope) {
$scope.goForward = function (){
alert("call to the paginator page up service");
};
$scope.goBack = function (){
alert("call to the paginator page down service");
};
});
Then set up the '&' scope isolates in the directive:
app.directive('paginator', function (){
return{
restrict: 'E',
scope:{
forward: '&',
back: '&'
},
template: '<button ng-click="forward()">Page up</button>' +
'<button ng-click="back()">Page down</button>'
}
});
Finally add the directive to the page with your attributes as defined in the directive:
<paginator forward="goForward()" back="goBack()"></paginator>
Here's the code in Plnkr.
HTH

Resources