Dropping Element on specific Json entries with Angularjs and Dragula? - angularjs

I am learning Angularjs and Dragular.
I have a data set, and on drop I have to insert the data into another container's data set value. For example:
This is the data set
$scope.items1 = [
{
'name' : 'x',
'age' : '4'
},
{
'name' : 'y',
'age' : '5'
},
{
'name' : 'z',
'age' : '6'
}
];
And I want to drop each element of items1 into items2 values. items2 looks like:
$scope.items2 = [
{
'key' : 'aaa',
'value' :""
},
{
'key' : 'bbb',
'value' : ""
},
{
'key' : 'ccc',
'value' : ""
},
{
'key' : 'ddd',
'value' : ""
}
];
Once it's dropped, items2 should look like:
{
name:'aaa',
value: [{
'key' : 'aaa',
'value' :""
}]
}
for each one. How do I do this?

Here is on of possible solutions:
angular.module('myApp', ['dragularModule']).controller('MyCtrl', function(dragularService, $element, $scope, $timeout) {
$scope.items1 = [{
name: 'x',
age: '4'
}, {
name: 'y',
age: '5'
}, {
name: 'z',
age: '6'
}];
$scope.items2 = [
{
'key': 'info',
'value': []
}, {
'key': 'info',
'value': []
}, {
'key': 'info',
'value': []
},
];
// timeout due to document not ready, jsfiddle settings issue?
$timeout(function() {
dragularService('#items1');
dragularService('.items2');
});
});
div {
border: 1px solid blue;
min-width: 200px;
padding: 10px
}
.can-be-empty {
min-height: 10px;
min-width: 200px;
}
<link href="https://rawgit.com/luckylooke/dragular/master/dist/dragular.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://rawgit.com/luckylooke/dragular/master/dist/dragular.js"></script>
<div class='app' ng-app="myApp" ng-controller="MyCtrl">
<h2>items1</h2>
<div id="items1" class="can-be-empty">
<div ng-repeat="item in items1">item {{item.name + ' age:' + item.age}}</div>
</div>
<h2>items2</h2>
<div ng-repeat="container in items2" class="items2">
<div class="can-be-empty" ng-repeat="item in container.value">
<div>item {{item.name + ' age:' + item.age}}</div>
</div>
</div>
</div>
Link to codepen: https://codepen.io/luckylooke/pen/LyoWzR

Related

AngularJS setting data from controller function

I have a function in controller in which I am calling it from ng-class directive. My code is working but I am not getting right output. Something is wrong but I am not being able to capture it because I am new in AngularJS. So anyone please have a look at my code and tell me what mistake I made and if possible discuss with rectified code.
My code
<div ng-app="myApp">
<ul ng-controller="MyController">
<li ng-class="setColor(item.businessTime,item.name)" ng-repeat="item in products">{{item.name}} — {{item.price}} — {{clsName}} — {{diff}}</li>
</ul>
</div>
var myApp = angular.module('myApp', []);
myApp.controller('MyController', function MyController($scope) {
$scope.dbTime='02/09/2013 15:00:00';
$scope.diff='';
$scope.clsName='';
$scope.setColor = function(businessTime,name) {
//alert('businessTime '+businessTime);
//alert('dbtime '+$scope.dbTime);
//var diff =$scope.dbTime.diff(businessTime, 'minutes')
//alert(diff);
var _diff=0;
var ms = moment($scope.dbTime,"DD/MM/YYYY HH:mm:ss").diff(moment(businessTime,"DD/MM/YYYY HH:mm:ss"));
var d = moment.duration(ms);
//alert(d.asMinutes());
_diff=Math.round(d.asMinutes());
if(_diff.between(-2000, -6000))
{
//alert(name+' clsRed '+_diff);
$scope.diff=Math.round(d.asMinutes());
$scope.clsName="clsRed";
return "clsRed";
}
else if(_diff.between(-6001, -8000))
{
//alert(name+' clsGreen '+diff);
$scope.diff=Math.round(d.asMinutes());
$scope.clsName="clsYello";
return "clsYello";
}
else if(_diff.between(1000, 2000))
{
//alert(name+' clsYello '+_diff);
$scope.diff=Math.round(d.asMinutes());
$scope.clsName="clsGreen";
return "clsGreen";
}
}
$scope.products = [
{
'name' : 'Xbox',
'clearance' : true,
'price' : 30.99,
'businessTime':'05/09/2013 15:00:00'
},
{
'name' : 'Xbox 360',
'clearance' : false,
'salesStatus' : 'old',
'price' : 99.99,
'businessTime':'04/09/2013 14:20:00'
},
{
'name' : 'Xbox One',
'salesStatus' : 'new',
'price' : 50,
'businessTime':'06/09/2013 18:12:10'
},
{
'name' : 'PS2',
'clearance' : true,
'price' : 79.99,
'businessTime':'07/09/2013 19:22:00'
},
{
'name' : 'PS3',
'salesStatus' : 'old',
'price' : 99.99,
'businessTime':'01/09/2013 09:00:00'
},
{
'name' : 'PS4',
'salesStatus' : 'new',
'price' : 20.99,
'businessTime':'10/09/2013 07:00:00'
}
]
})
Number.prototype.between = function(a, b) {
var min = Math.min.apply(Math, [a, b]),
max = Math.max.apply(Math, [a, b]);
return this > min && this < max;
};
css
.clsRed {
font-weight: bold;
color: red;
}
.clsYello {
font-weight: bold;
color: yellow;
}
.clsGreen {
font-weight: bold;
color: green;
}
within if else logic i am setting class name $scope.clsName="clsYello"; but in output i have notice some time wrong class name in showing in html.
here is screen shot
now see the first data where class name is showing clsGreen but in output clsRed is applied. right output would be clsRed and also clsRed should be applied. clsRed has applied but clsGreen is showing as class name in output which is not right.
so please guide me where i made the mistake. please guide me with rectified code.
js fiddle https://jsfiddle.net/tridip/czjo9f1m/8/
thanks
see this. if you use $scope.diff as array probably you find out what is your problem.
var myApp = angular.module('myApp', []);
myApp.controller('MyController', function MyController($scope) {
$scope.dbTime='02/09/2013 15:00:00';
$scope.diff=[];
$scope.clsName=[];
$scope.setColor = function(businessTime,name) {
var _diff=0;
var ms = moment($scope.dbTime,"DD/MM/YYYY HH:mm:ss").diff(moment(businessTime,"DD/MM/YYYY HH:mm:ss"));
var d = moment.duration(ms);
_diff=Math.round(d.asMinutes());
if(_diff.between(-2000, -6000))
{
$scope.diff.push(Math.round(d.asMinutes()));
$scope.clsName.push("clsRed");
console.log($scope.diff);
return "clsRed";
}
else if(_diff.between(-6001, -8000))
{
$scope.diff.push(Math.round(d.asMinutes()));
$scope.clsName.push("clsYello");
console.log($scope.diff);
return "clsYello";
}
else if(_diff.between(1000, 2000))
{
$scope.diff.push(Math.round(d.asMinutes()));
$scope.clsName.push("clsGreen");
console.log($scope.diff);
return "clsGreen";
}
}
$scope.products = [
{
'name' : 'Xbox',
'clearance' : true,
'price' : 30.99,
'businessTime':'05/09/2013 15:00:00'
},
{
'name' : 'Xbox 360',
'clearance' : false,
'salesStatus' : 'old',
'price' : 99.99,
'businessTime':'04/09/2013 14:20:00'
},
{
'name' : 'Xbox One',
'salesStatus' : 'new',
'price' : 50,
'businessTime':'06/09/2013 18:12:10'
},
{
'name' : 'PS2',
'clearance' : true,
'price' : 79.99,
'businessTime':'07/09/2013 19:22:00'
},
{
'name' : 'PS3',
'salesStatus' : 'old',
'price' : 99.99,
'businessTime':'01/09/2013 09:00:00'
}
];
})
Number.prototype.between = function(a, b) {
var min = Math.min.apply(Math, [a, b]),
max = Math.max.apply(Math, [a, b]);
return this > min && this < max;
};
.clsRed {
font-weight: bold;
color: red;
}
.clsYello {
font-weight: bold;
color: yellow;
}
.clsGreen {
font-weight: bold;
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.js"></script>
<div ng-app="myApp">
<ul ng-controller="MyController">
<li ng-repeat="item in products track by $index"><span ng-class="setColor(item.businessTime,item.name)">{{$index}} — {{item.price}} — {{clsName[$index]}} — {{diff[$index]}}</span></li>
</ul>
</div>
i think that this is better solution.
var myApp = angular.module('myApp', []);
myApp.controller('MyController', function MyController($scope) {
$scope.dbTime='02/09/2013 15:00:00';
$scope.diff=[];
$scope.clsName=[];
$scope.products = [
{
'name' : 'Xbox',
'clearance' : true,
'price' : 30.99,
'businessTime':'05/09/2013 15:00:00'
},
{
'name' : 'Xbox 360',
'clearance' : false,
'salesStatus' : 'old',
'price' : 99.99,
'businessTime':'04/09/2013 14:20:00'
},
{
'name' : 'Xbox One',
'salesStatus' : 'new',
'price' : 50,
'businessTime':'06/09/2013 18:12:10'
},
{
'name' : 'PS2',
'clearance' : true,
'price' : 79.99,
'businessTime':'07/09/2013 19:22:00'
},
{
'name' : 'PS3',
'salesStatus' : 'old',
'price' : 99.99,
'businessTime':'01/09/2013 09:00:00'
},
{
'name' : 'PS4',
'salesStatus' : 'new',
'price' : 20.99,
'businessTime':'10/09/2013 07:00:00'
}
];
angular.forEach( $scope.products,function(product,i){
var _diff=0;
var ms = moment($scope.dbTime,"DD/MM/YYYY HH:mm:ss").diff(moment(product.businessTime,"DD/MM/YYYY HH:mm:ss"));
var d = moment.duration(ms);
_diff=Math.round(d.asMinutes());
$scope.products[i].diff = _diff;
});
console.log($scope.products);
})
.clsRed {
font-weight: bold;
color: red;
}
.clsYello {
font-weight: bold;
color: yellow;
}
.clsGreen {
font-weight: bold;
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.js"></script>
<div ng-app="myApp">
<ul ng-controller="MyController">
<li ng-repeat="item in products track by $index">
<span ng-class="{'clsYello':-6000>item.diff,'clsRed':-2000>item.diff,'clsGreen':item.diff > 1000}">{{$index}} — {{item.price}} — {{clsName[$index]}} — {{item.diff}}</span></li>
</ul>
</div>

How to put multiple condition in ng-class [duplicate]

This question already has answers here:
Adding multiple class using ng-class
(12 answers)
Closed 6 years ago.
suppose i am showing product information. i want if price less than 50 then item color should be red. if price more than 50 then item color should be yellow and if price more than (50+(50*60/100)) then item color should be green. now tell me how could i achieve it best way. guide me with best approach to complete it.
this way i tried but i came to know there will be more iteration due to dirty check when work with ng-repeat. see my code and tell me how could i put multiple condition in ng-class to set class dynamically.
<div ng-app="myApp">
<ul ng-controller="MyController">
<li ng-class="setColor(item.price)" ng-repeat="item in products">{{item.name}} — {{item.price}}</li>
</ul>
</div>
var myApp = angular.module('myApp', []);
myApp.controller('MyController', function MyController($scope) {
$scope.setColor = function(price) {
alert(price);
}
$scope.products = [
{
'name' : 'Xbox',
'clearance' : true,
'price' : 30.99,
},
{
'name' : 'Xbox 360',
'clearance' : false,
'salesStatus' : 'old',
'price' : 99.99,
},
{
'name' : 'Xbox One',
'salesStatus' : 'new',
'price' : 50,
},
{
'name' : 'PS2',
'clearance' : true,
'price' : 79.99,
},
{
'name' : 'PS3',
'salesStatus' : 'old',
'price' : 99.99,
},
{
'name' : 'PS4',
'salesStatus' : 'new',
'price' : 20.99,
}
]
})
tell me without calling function from ng-class how could i place multiple if else condition in ng-class?
if price > 50
return "css-class-yello"
else if price < 50
return "css-class-red"
else if price > (50+(50*60/100))
return "css-class-green"
if possible please guide me with code. thanks
try like this.
var app = angular.module("app",[]);
app.controller("ctrl" , function($scope){
$scope.products = [{
'name': 'Xbox',
'clearance': true,
'price': 30.99,
}, {
'name': 'Xbox 360',
'clearance': false,
'salesStatus': 'old',
'price': 99.99,
}, {
'name': 'Xbox One',
'salesStatus': 'new',
'price': 50,
}, {
'name': 'PS2',
'clearance': true,
'price': 79.99,
}, {
'name': 'PS3',
'salesStatus': 'old',
'price': 99.99,
}, {
'name': 'PS4',
'salesStatus': 'new',
'price': 20.99,
}];
});
.css-class-yellow{
background-color: yellow;
}
.css-class-red{
background-color: red;
}
.css-class-green{
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl" class="panel-group" id="accordion">
<ul class="nav nav-pills" ng-init="catVal = 1">
<li ng-repeat="item in products" ng-class="{'css-class-yellow' : item.price > 50,'css-class-red' : item.price <50, 'css-class-green' : item.price > 50+50*60/100}">
{{item.name}}
</li>
</ul>
</div>
You could set ng-class to call a function in your controller and pass the object.
Example: https://jsfiddle.net/5hgLshhz/
<ul>
<li ng-repeat="p in ctrl.products" ng-class="ctrl.setClass(p)">{{p.name}}</li>
</ul>
function Controller() {
var vm = this;
vm.products = [{
'name': 'Xbox',
'clearance': true,
'price': 30.99,
}, {
'name': 'Xbox 360',
'clearance': false,
'salesStatus': 'old',
'price': 99.99,
}, {
'name': 'Xbox One',
'salesStatus': 'new',
'price': 50,
}, {
'name': 'PS2',
'clearance': true,
'price': 79.99,
}, {
'name': 'PS3',
'salesStatus': 'old',
'price': 99.99,
}, {
'name': 'PS4',
'salesStatus': 'new',
'price': 20.99,
}];
vm.setClass = setClass;
function setClass(p) {
if (p.price > 50) {
return 'css-class-yellow';
}
if (p.price < 50) {
return 'css-class-red';
}
if (p.price > (50 + (50 * 60 / 100))) {
return 'css-class-green';
}
}
}
There are several different ways to use ng-classthe way I most commonly use this directive is by setting your css class to a boolean $scope variable... something like:
HTML:
ng-class="{your-css-class:$scope.myVariable}"
Angular controller:
//to add class
$scope.myVariable = true
//to remove class
$scope.myVariable = false
To use multiple classes simply seperate them by commas something like:
ng-class="{your-css-class:$scope.myVariable, my-other-class:$scope.myOtherVariable}"
fiddle here

AngularJS: setting class dynamically based on time difference

i am comparing time time and based on that i am setting css class name but i made some mistake and that is why code is not working. please anyone see my code and tell me where i made the mistake.
<div ng-app="app" ng-controller="ctrl" class="panel-group" id="accordion">
<ul class="nav nav-pills" ng-init="catVal = 1">
<li ng-repeat="item in products" ng-class="{'css-class-yellow' : moment($scope.dbTime, 'HH:mm:ss').diff(moment(item.businessTime, 'HH:mm:ss'), 'minutes') > 60,'css-class-red' : moment($scope.dbTime, 'HH:mm:ss').diff(moment(item.businessTime, 'HH:mm:ss'), 'minutes') > 200, 'css-class-green' : moment($scope.dbTime, 'HH:mm:ss').diff(moment(item.businessTime, 'HH:mm:ss'), 'minutes') > 300 }">
{{item.name}}
</li>
</ul>
</div>
var app = angular.module("app",[]);
app.controller("ctrl" , function($scope){
$scope.dbTime='12:05:05';
$scope.products = [{
'name': 'Xbox',
'clearance': true,
'price': 30.99,
'businessTime':'04:15:22'
}, {
'name': 'Xbox 360',
'clearance': false,
'salesStatus': 'old',
'price': 99.99,
'businessTime':'12:10:22'
}, {
'name': 'Xbox One',
'salesStatus': 'new',
'price': 50,
'businessTime':'06:25:22'
}, {
'name': 'PS2',
'clearance': true,
'price': 79.99,
'businessTime':'08:11:22'
}, {
'name': 'PS3',
'salesStatus': 'old',
'price': 99.99,
'businessTime':'17:41:22'
}, {
'name': 'PS4',
'salesStatus': 'new',
'price': 20.99,
'businessTime':'21:05:22'
}];
});
.css-class-yellow{
background-color: yellow;
}
.css-class-red{
background-color: red;
}
.css-class-green{
background-color: green;
}
I would propose to move such a complex comparison back to controller:
//template
<li ng-repeat="item in products" ng-class="{'css-class-yellow' : isYellowLess() }">
//controller
$scope.isYellowLess = function(){
return moment($scope.dbTime, 'HH:mm:ss').diff(moment(item.businessTime, 'HH:mm:ss'), 'minutes') > 60;
}
Then you can debug it easier.
UPD
Check the updated fiddle: https://jsfiddle.net/4jz8uh2y/3/
The problem was that you need to do the moment parsing in the controller, not in the template. Since you use plain version of momentjs (not angular-moment), your controller knows nothing about the momentjs functions hence could not evaluate the time comparison properly.

Angular formly - assign key to property in array

I am working on list of languages and levels of proficiency. This would be a array of objects:
languages : [
{ name : 'English', level : 'native' },
{ name : 'Spanish', level : 'good' }
]
So I have such definitions of fields:
{
className : 'col-xs-4',
type : 'ui-select',
key : 'languages[' + index + '].name',
templateOptions : {
label : 'Some label',
options : [ ... data there ... ],
required : true
}
},
{
className : 'col-xs-8 btn-radio-language',
type : 'btn-radio',
key : 'languages[' + index + '].level',
templateOptions : {
label : 'Proficiency',
options : ... data for native, good, so so ...
}
}
Those definition would repeat several times with respect of index.
However instead of array languages being addressed with values series of properties in model like:
"languages[0].level": "native",
"languages[1].level": "advanced",
"languages[0].name": "German"
have been created...
How I can point to languages array in model ?
If I've understood it correctly you could map your data with languages.map(function(language) {...}).
Please have a look at the demo below or at this jsfiddle.
angular.module('demoApp', ['formly', 'formlyBootstrap'])
.controller('MainController', function() {
var vm = this;
vm.model = {};
var languages = [
{ name : 'English', level : 'native' },
{ name : 'Spanish', level : 'good' }
];
var createOptionTmpl = function(value) {
return {
name: value,
value: value
};
};
/*
console.log(languages.map(function(lang) {
return {
name: lang.level,
value: lang.level
};
}));*/
vm.fields = [{
className: 'col-xs-4',
type: 'select',
key: 'languages.name',
templateOptions: {
label: 'Some label',
options: languages.map(function(lang) {
return createOptionTmpl(lang.name);
}), //[...data there...],
required: true
}
}, {
className: 'col-xs-8 btn-radio-language',
type: 'radio',
key: 'languages.level',
templateOptions: {
label: 'Proficiency',
options: languages.map(function(lang) {
return createOptionTmpl(lang.level);
})
}
}];
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/api-check/7.5.5/api-check.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-formly/7.3.9/formly.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-formly-templates-bootstrap/6.2.0/angular-formly-templates-bootstrap.min.js"></script>
<div ng-app="demoApp" ng-controller="MainController as vm">
<form ng-submit="vm.onSubmit()">
<formly-form model="vm.model" fields="vm.fields"></formly-form>
<button class="btn btn-primary">
submit
</button>
</form>
{{vm.model}}
</div>

Add Event in ng-google-chart

I'm using Angular Google Chart but i do not know how to add a select event.
In the API Doc can be seen the method 'registerWrapperListener', but i dont used it
Some idea to add select-event in this example?
Thanks you
'use strict';
angular.module('google-chart-example', ['googlechart']).controller("MainCtrl", function($scope) {
var chart1 = {};
chart1.type = "OrgChart";
chart1.cssStyle = "height:200px; width:300px;";
chart1.data = {
cols: [{
id: 'Name',
label: 'Name',
type: 'string'
}, {
id: 'Manager',
label: 'Manager',
type: 'string'
}, {
id: 'ToolTip',
label: 'ToolTip',
type: 'string'
}],
rows: [{
c: [{
v: '0',
f: 'CEO'
}, {
v: ''
}, {
v: 'The CEO'
}]
}, {
c: [{
v: '1',
f: 'worker 1'
}, {
v: '0'
}, {
v: ''
}]
}]
};
$scope.chart = chart1;
});
<html xmlns="http://www.w3.org/1999/html">
<body ng-app="google-chart-example" ng-controller="MainCtrl">
<div>
<div google-chart chart="chart" style="{{chart.cssStyle}}" />
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="http://bouil.github.io/angular-google-chart/ng-google-chart.js"></script>
<script src="example.js"></script>
</body>
</html>
In your html code, it would be:
<div google-chart chart="chart" style="{{chart.cssStyle}}" on-select="selectCallbackMethodYouWant(selectedItem)" />

Resources