AngularJS / Javascript create $scope runtime - javascript

I've been looking at this for hours and so apologize if this is a dumb question, but is there a way in AngularJS or Javascript to do the following:
HTML
// I have a number of html piece of code (templates) for different controls
<button data-action="flip" ng-click="imageControl($event)"></button>
// ... 10 other imagecontrol types e.g. rotate, etc.
// objective - show or hide html based on which button is pressed
<div ng-show="(imageControl.flip)> // html stuff </div>
// angular function
$scope.imageControl = function($event) {
// get data-action from html element e.g. flip
var actionType = $event.currentTarget.getAttribute("data-action");
$scope.actionType ? $scope.actionType = false : $scope.actionType = true;
}
HERE IS THE QUESTION:
is there a way from me to use actionType to create and set a variable at runtime
why? so I don't have to create 10 different if statement for each control
btw - I know this won't work, but using it to illustrate example

I would simplify the issue, by not using the data attributes since angular does not need it.
markup:
<button ng-click="imageControl('flip')"></button>
<div ng-show="actions.flip"> // html stuff </div>
and in your controller:
$scope.imageControl = function(action) {
$scope.actions[action] = !$scope.actions[action];
};

Related

Pass Angular scope value to JavaScript variable

I checked the existing similar questions in SO but I think it is bit different. I am aware we don't need to use JavaScript along with Angular. But due to some dependencies, I am using it.
var ProfileApp = angular.module('ProfileApp', []);
ProfileApp.controller('getprofile', function($scope,$http,$location){
$scope.searchok = 1;
$scope.tn_id = '5';
-- Some Angular Codes are here ---
I want to put $scope.tn_id value to JavaScript variable. I tried to like this.
<script type="text/javascript">
var tn_id_from_angular;
</script>
Defined the variable before Angular code. Added below code inside Angular code like this.
tn_id_from_angular = $scope.tn_id;
alert (tn_id_from_angular);
When I run the code I am getting the alert box but it is not showing the value and giving me error undefined.
Edit
In simple words, I want to assign $scope.tn_id value to javascript variable tn_id_from_angular.
you can assign a global variable to the window object, and then retrieve it
warning: this is hacky territory.. we are not making good code here, but it might work
try this in your angular code:
// ...
var ProfileApp = angular.module('ProfileApp', []);
ProfileApp.controller('getprofile', function($scope,$http,$location){
$scope.searchok = 1;
$scope.tn_id = '5';
window.hacks = {tn_id_from_angular: $scope.tn_id};
// ...
and then this in your script:
const {tn_id_from_angular} = window.hacks;
alert (tn_id_from_angular);
so long as the script executes after the angular code does -- it should work
if it doesn't, then you need to figure out some kind of "angular ready callback"

Creating a reusable javascript function instead of copy/paste

I made a page I need to have in different instances. In short it is used to fill in different parts of a script and then display said script on the page for the user to copy it.
This script below handles the main part of the job, getting a field from HTML and then i can call the result in html to be displayed.
var urlField = document.getElementById('urlField').value;
var resultUrl = document.getElementById('resultUrl');
resultUrl.textContent = urlField;
Problem: there are different fields, eg. url, startdate, enddate, adschedule, etc. so I would like to have a reusable script that just says get the respective field and result the value which is assigned to it in html.
Can I do this somehow? I was researching the function "this" in javascript, but it is too complicated for my current knowledge. Bear in mind that I am in only a very basic level.
You can find the whole codepen to understand the issue better here: https://codepen.io/kmb5/pen/GxZbZq
Add parameters to your re-usable function and then call it whenever you need to use it. Use javascript to get the required data and pass it in as parameters.
reusable.js:
function myFuncWithParameters(parm1, parm2, parm3){
}
Alternatively:
function myFuncWithParameters(myObject){
//access properties from the object: myObject.parm1, myObject.parm2, myObject.parm3
}
Using the object route might make it easier since the order of the properties will not matter like parameters. Regardless of either method you will have to validate the input.
In your html pages, you will need some More JavaScript and HTML to bring in the JS and call it.
<html>
<head>
<title>my page</title>
<script scr="path to reusable js"></script>
<script src="path to this path's js"></script>
</head>
<body>
my page
</body>
</html>
If you look at the script tags, by importing the reusable js you can use it in javascript that was written / imported further down into the page.
In order to ensure you have access to an imported function, you can check if the function you need is defined:
if(typeof(myFuncWithParameters) !== 'undefined' && typeof(myFuncWithParameters) == typeof(Function){
//myFuncWithParameters will definitely be defined and is a function, if we get in here
}else{
//myFuncWithParameters is not defined and/or is not a function
}
In your html page to call the re-usable function...
var parm1 = value;
var parm2 = value;
var parm3 = value;
myFuncWithParameters(parm1, parm2, parm3);
In you decide to use the object:
var myObject = {
'parm1' : 4,
'parm2' : 6
}
//myObject.parm1 == 4
myFuncWithParameters(myObject);

Style node of Dabeng's OrgChart library

I am using the Dabeng Orgchart library, but I would like to customize the nodes, specifically creating a diamond instead of the squares they have in most examples. I have seen the createNode method, and I have found various CSS for creating a diamond but I can't figure out how to integrate it in dabeng org chart. What I want to do is display a diamond if some conditions are met, and the default square shapes if others are met. I have searched the web, but no example for changing the shape.
I am currently using the nodeTemplate attribute for the orgchart. Example:
var oc = $('#container').orgchart({
...
'nodeTemplate': orgTemplate,
...
});
In your orgtemplate function, data is whatever you have included in your orgchart data (in the example it would be name and title). You can stuff this object with other flags. For example, I have a chart in which I create new nodes and allow users to enter data into the node before committing it to the graph. I have a flag in my data object for data.isSaved to tell my template whether or not this node is saved or not. If it is saved, I have inline html checks (in AngularJS using ngIf's and the like, if you're familiar with AngularJS at all) to change the template based on the data.
In VanillaJS, you can just return pure HTML without the $compile and all that attached to pump in your own node template. You could actually do your check within the function for example:
function orgTemplate(data) {
if(data.isDiamond) {
return '<div class="diamond">...</div>';
} else {
return '<div class="square">...</div>';
}
}
I'm using AngularJS in my website so I define new scopes and use angular directives to make it more expandable. This is for reference for anyone else who stumbles upon this. My orgTemplate function is defined below.
function orgTemplate(data) {
var newScope = $scope.$new(true);
newScope.data = data;
return ( $compile('<div data-ng-include="\'.../template.html\'"></div>')(newScope));
}
Here's the orgChart Github as I'm sure you've browsed many times. If you look at the bottom you will see the nodeTemplate attribute definition I mention above. Hope this helps!
Side Note: I have had some trouble with styling when using custom templates, especially when defining different graph directions (i.e. 'l2r').
You can now customize your own node structure or shape with option "ndoeTemplate":
var nodeTemplate = function(data) {
return `
<span class="office">${data.office}</span>
<div class="title">${data.name}</div>
<div class="content">${data.title}</div>
`;
}
var oc = $('#chart-container').orgchart({
'data' : ds,
'nodeTemplate': nodeTemplate
});
Feel free to play around with this demo.
I would suggest you to use getorgchart instead it is highly customizable
http://www.getorgchart.com/Demos/Create-Your-Own-Theme-4

Getting external variables inside Angular.js factory

I am giving my first steps with Angular.js and I am facing a little problem which I don't know how to deal with Angular. I know many jQuery ways for solving it, but I am sure that it may exists an Angular way:
Firstly, I have an select element set with currentPlant as ng-model
<select class="form-control" name="planta" ng-model='currentPlant' ng-options='plant.name for plant in plants' >
</select>
I print the current name as page title, I see this element updating when I change the selected value, so I am sure that currentPlant is being correctly updated.
<h1>{{ currentPlant ? currentPlant.name : 'Seleccione una planta'}}</h1>
Now I have the following button:
<button class='btn btn-primary' ng-click='loadTowers()'>
Cargar torres
</button>
When the button is pressed, the loadTowers function is executed, and is now when the problems start. I have set the loadTowers function in the controller that way:
$scope.loadTowers = plants.towers;
plant is a angular service which has implemented the towers function inside. I need to get the value of currentPlant inside this function. Take a look:
.factory('plants', ['$http',function($http){
var o = {
plants: [],
towers : []
};
o.towers = function(){
var id = ¿?; // I NEED SET THIS VARIABLE WITH THE currentPlant.id VALUE
$http.get('/api/v1/plants/'+id+'/towers')
.success(function(data){
angular.copy(data, o.towers);
})
}
return o;
}]);
I could set an data-plant attribute in the option element, and get the selected through jQuery, but I am trying avoid this kind of solutions. How do you deal with this?
NOTE: Take account that I simply want get the option selected when I press the button and make different get requests to the API`in function of that through the service.
Thanks in advance.
Pass the value in the ngclick:
<button ng-click='loadTowers(currentPlant)'>
Then add it in the factory args:
o.towers = function(currentPlant){
}

Displaying json data via angular

I have created a datatable showing a list of persons and their details. When the datatable is clicked, it has to show the entity of the single person with their details but my problem is, when I click the datatable it is opening a chat box showing the entity of the last clicked person changing all other chat box details.
1.How can I limit the append directive, that is, one chatbox for one id?
2.How to display the name of the particular person without changing the older chat box entity?
Here is the link to Plunker http://plnkr.co/edit/VTWcZQjlAda0KQ9sjFzI?p=preview
Actually i really think there is no need for a directive here.
It can simply be done by using ng-repeat and a collection.
See it working in this plunker
I added this in the controller :
$scope.bottomListCollection = [];
$scope.addToBottomList = function(artist) {
$scope.bottomListCollection.push(artist);
}
And this kind of ng-click on your rows :
ng-click="addToBottomList(item)"
Some advices to do things cleaner in angular :
Never use :
$compile.
$element.
$broadcast.
Jquery.
Take care of custom directives, theses are 90% miss-used.
Just a reminder : Directives are intended to add a behavior on an element. Not adding html.
Hope it helped.
Some tips that fix your issue
childScope = $scope.$new(true);
to ve an isolated scope you ve to use the first parameter of $new method
for more info look at the docs ($new(isolate, parent); --> https://docs.angularjs.org/api/ng/type/$rootScope.Scope)
then you need to add a control on the AppendText function like this to check if the same chat already exist
$scope.AppendText = function(idx) {
$scope.userInfo = $scope.artists[idx];
var chat = $('#chat_'+$scope.userInfo.shortname);
console.log(chat);
if ($scope.stage === 'Add' && chat.length==0 ) {
childScope = $scope.$new(true);
childScope.userInfo = $scope.userInfo; //<--- add old scope info to new scope
var compiledDirective = $compile('<div my-directive></div>');
var directiveElement = compiledDirective(childScope);
$('.my-directive-placeholder').append(directiveElement);
} else {
$scope.stage = 'Add';
}
}
working plunker http://plnkr.co/edit/TFjlN0U2i4irKtG2D5yu?p=preview
To answer the second part of your question : Create an isolate scope!
That can be done by passing true while creating a new scope: childScope = $scope.$new(true).
Once the isolate scope is created, you can do:
childScope.userInfo = $scope.userInfo;
PLUNK : http://plnkr.co/edit/IxPh4EmLpr8WAqRWtRlo?p=preview
Also, a hackish solution using one time databinding (not recommended):
http://plnkr.co/edit/RjZNOSyaemqg2eZ4Gma1?p=preview
To answer the first part: You could keep track of the id's that are passed to the $scope.AppendText function perhaps?
PLUNK: http://plnkr.co/edit/BCNju0rToyVYvNjqzVON?p=preview
Hope this helps! IMHO it would be much more simpler if you could just ng-repeat over your json data to generate the chatboxes.

Categories

Resources