How to use jsTree events with AngularJS - angularjs

I load my tree successfully using a directive in AngularJS.Now i want to add events (here select node) in my tree, so i did like this. but i can't see my alert .
My code:
app.directive('jstree', function() {
return {
restrict: 'A',
scope: {
jstree: '='
},
link: function(scope, element, attrs)
{
scope.$watch('jstree', function()
{
$(element).jstree({
"json_data" :{
"data":scope.jstree.data
},
"themes" : {
"theme" : "classic",
"dots" : true,
"icons" : true
},
"plugins" : [ "themes", "json_data" ]
}, false);
}, true);
// select a node
element.bind("select_node.jstree",function(e, data) {
$window.alert(e.data);
});
}
};
});
Any idea were i went wrong ?

To use events in jstree, you have to add "ui" in this line :
"plugins" : [ "themes", "json_data", "ui" ]
Now it works.

Looking at the jstree demo, you'll want to call bind on the jstree object, not on the element (you'll be able to bind to click on the element, but this probably isn't what you want)
$(element)
.jstree({
"json_data" : {
"data" : scope.jstree.data
},
"themes" : {
"theme" : "classic",
"dots" : true,
"icons" : true
},
"plugins" : ["themes", "json_data"]
}, false)
.bind('select_node.jstree', function(ev,data) {
console.log('clicked');
});

Related

Update data in MongoDB with Moongoose and MEAN Stack

I have a mongoose data like this:
{
"_id" : ObjectId("58e394cacaa6512ed00e8d83"),
"RoleName" : "Manager",
"UIList" : [
{
"Edit" : false,
"View" : false,
"UiName" : "ElevatorMapping"
},
{
"Edit" : false,
"View" : false,
"UiName" : "ElevatorAssumptions"
},
{
"Edit" : false,
"View" : false,
"UiName" : "ManageUnits"
},
{
"Edit" : false,
"View" : false,
"UiName" : "ManageBuildings"
}
],
"__v" : 0,
"Description" : "fd",
"IsActive" : true
}
Now I want to update UILIST inside UIname:"ElevatorMapping"&"Elevator Assumptions" View and Edit as True. How to write query for this? I have tried something like below.
Here is my Controller page.
$http.put('/ViewEditupdate/' + id +'/' + uiname + '/' + view + '/' + edit).then(function (response) {
refresh();
})
Here id value is taken correctly but the Edit view UI names are not taken. Edit , view name are taken as undefined.
My server.js code
app.put('/ViewEditupdate/:id/:uiname/:view/:edit', RoleEntrypath.RoleViewEditupdate);
my Schema code
newRole.update({ "UIList.UiName": "ManageRole" }, { "$push": { "UIList.$.View": "true", "UIList.$.Edit": "true" } },
function (err, doc) {
res.json(doc);
}
);
Can anyone give the solution?
you should use $set instead of $push to change the value of view from false to true.
Try this:
newRole.update({
"UIList.UiName": "ManageRole"
},{
$set: { "UIList.$.View": "true", "UIList.$.Edit": "true" }
},function (err, doc) {
res.json(doc);
});
i already updated by using this query.
newRole.update
(
{
_id: id,
"UIList.UiName": "ManageRole"
},
{
$set: {
"UIList.$.View": "true",
"UIList.$.Edit": "true"
}
},
function (err, doc) {
res.json(doc);
}
);

Unable to show JSON data injected using service inside the amchart directive dataprovider

I am using amcharts as a custom directive. Now I want to fetch the dataProvider of this AmChart from the output of the $http.get service using webservices.
But I am unable to get this dynamically assigned to the dataprovider of the amChart.
var app=angular.module('mainApp',[]);
app.service('dataProviderService',function($http){
this.getData= function(){
return $http.get('jaxrs/WebService/getJSONData');
};
});
app.directive('myChart',['dataProviderService',function (dataProviderService) {
return {
restrict: 'E',
replace:true,
template: '<div id="chartdiv" style="min-width: 310px; height: 400px; margin: 0 auto"></div>',
link: function (scope, element, attrs) {
scope.data={};
dataProviderService.getData().then(function(response){
scope.data=response.data;
},function(error){
scope.status="Show error";
});
var chart = false;
var initChart = function() {
if (chart) chart.destroy();
var config = scope.config || {};
chart = AmCharts.makeChart( "chartdiv", {
"theme": "none",
"type": "serial",
"dataProvider": dataProviderService.newData(),
"categoryField": "OT",
"depth3D": 20,
"angle": 30,
"categoryAxis": {
"labelRotation": 90,
"gridPosition": "start"
},
"valueAxes": [ {
"title": "availability"
} ],
"graphs": [ {
"valueField": "availability",
"colorField": "color",
"type": "column",
"lineAlpha": 0.1,
"fillAlphas": 1
} ],
"chartCursor": {
"cursorAlpha": 0,
"zoomable": false,
"categoryBalloonEnabled": false
},
"export": {
"enabled": true
}
} );
};
initChart();
}//end watch
}
}]) ;
Assuming your newData() method is an asynchronous $http.get() request like your getData() method, you need to either call makeChart after the request resolves itself or tell the chart to redraw itself by calling validateData() when the request resolves itself. Here's an example of doing this inside the chart's init event:
chart = AmCharts.makeChart( "chartdiv", {
// ... omitted ...
"dataProvider": [],
// ... omitted ...
"listeners": [{
"event": "init",
"method": function(e) {
dataProviderService.newData().then(function(response) {
e.chart.dataProvider = response;
e.chart.validateData();
}, function(error) {
// do something else
});
}
}]
} );

Using directives in angularjs with templateUrl

I wrote a code with angularjs that uses a directive to bring a list of categories from show-category.html file and show them on the index page, I did everything as I've learned but still can't get the categories to be displayed when index.html is loaded.
inside app.js file
app.directive('showCategories', function() {
return {
restrict: 'E',
templateUrl: 'show-categories.html'
};
});
you can see the full code on plunker here:
http://plnkr.co/edit/FSsNAq?p=preview
You placed your directive definition right in the middle of the controller, take it outside and it works (barring some other non-existing functions you have there):
app.controller("BookCtrl", function($scope) {
$scope.categories = [{
"id": 0,
"name": "Type"
}, {
"id": 1,
"name": "Date"
}, {
"id": 1,
"name": "Name"
}
];
...
});
app.directive('showCategories', function() {
return {
restrict: 'E',
templateUrl: 'show-categories.html'
};
});
Plunker

$.fn.dataTable.Editor is not a constructor - RequireJS with DataTables

Library versions:
jQuery : 2.1.1
DataTables : 1.10.1-dev
dataTablesTableTools : 2.2.1
dataTables.dataTables.editor.min.js : 1.2.3
I'm trying to implement CRUD operation using datatableseditor using Backbone, RequireJS and Datatables.But I'm getting the error message:
$.fn.dataTable.Editor is not a constructor"
What could be the reason?
Here is my configuration:
require.config({
baseUrl: 'js',
paths: {
jquery: 'vendor/jquery.min',
datatables: 'vendor/jquery.dataTables.min',
datatablesTableTools: 'vendor/dataTables.tableTools.min',
datatablesEditor: 'vendor/dataTables.editor.min'
},
shim: {
jquery : {
exports : '$'
},
datatables: {
deps: [
'jquery',
]
},
datatablesTableTools: { deps: ['datatables'] },
datatablesEditor: { deps: ['datatables'] }
}
});
Using it as follows:
require(["jquery", "datatables"], function () {
var editor = new $.fn.dataTable.Editor( {
"ajax": "table.line.php"
} );
$('#myGrid').dataTable( {
"aaData": [
['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C']
],
"aoColumns": [
{ "sTitle": "Engine" },
{ "sTitle": "Browser" },
{ "sTitle": "Platform" },
{ "sTitle": "Version" },
{ "sTitle": "Grade" }
],
"tableTools": {
"sRowSelect": "os",
"aButtons": [
{ "sExtends": "editor_create", "editor": editor },
{ "sExtends": "editor_edit", "editor": editor },
{ "sExtends": "editor_remove", "editor": editor }
]
}
});
});
I think you have made a mistake in your table of dependencies. In your second code, it should be like this :
require(["jquery", "datatablesEditor"], function () {
[...]
instead of
require(["jquery", "datatables"], function () {
[...]
I've checked and it's more vicious. When you look the source code of the plugin datatables-fixedcolumns for example, its name is specified so you need to use it instead of your own alias/name.
The source code dataTables.fixedColumns.js :
[...]
// Define as an AMD module if possible
if ( typeof define === 'function' && define.amd ) {
define( 'datatables-fixedcolumns', ['jquery', 'datatables'], factory );
}
else if ( jQuery && !jQuery.fn.dataTable.FixedColumns ) {
// Otherwise simply initialise as normal, stopping multiple evaluation
factory( jQuery, jQuery.fn.dataTable );
}
[...]
So in your requirejs.config, you need to write this :
[...]
paths: {
jquery: 'vendor/jquery.min',
datatables: 'vendor/jquery.dataTables.min',
datatables-fixedcolumns: 'vendor/dataTables.fixedColumns'
[...]
instead of
[...]
paths: {
jquery: 'vendor/jquery.min',
datatables: 'vendor/jquery.dataTables.min',
datatablesFixedColumns: 'vendor/dataTables.fixedColumns'
[...]

scope of event arguments in angular directive

I have the following angular app to create a menu of sections/products.
at present when rendered and hitting the 'add' button that is rendered within each li I want to add a section/product as a sub of that section however multiple new children are created.
ultimately I wish to display a form which when submitted will create the child but that is the next step. Right now I need to limit the scope to the current section and not have multiple bound clicks.
If you need more information please state and I will post in an edit.
Some sample data data.
{
"sections":[
{
"name":"Flags",
"sections":[
{
"name":"Europe",
"sections":[],
"products":[
{ "name": "France" },
{ "name": "Germany" },
{ "name": "Ireland" },
{ "name": "England" }
]
},
{
"name": "Africa",
"sections":[],
"products":[
{ "name": "Egypt" },
{ "name": "Nigeria" },
{ "name": "Chad" }
]
},
{
"name": "South America",
"sections":[],
"products": [
{ "name": "Brasil" },
{ "name": "Argentina" },
{ "name": "Peru" }
]
}
],
"products":[]
},
{
"name": "Maps",
"sections":[
{
"name": "Africa",
"sections":[],
"products":[
{ "name": "Egypt" },
{ "name": "Nigeria" },
{ "name": "Chad" }
]
},
{
"name": "South America",
"sections":[],
"products": [
{ "name": "Brasil" },
{ "name": "Argentina" },
{ "name": "Peru" }
]
}
],
"products":[]
}
],
"products":[]
}
The app.
'use strict';
var menuApp = angular.module('menuApp', []);
menuApp
.directive('sections', function () {
return {
restrict: "E",
replace: true,
scope: {
sections: '='
},
template: '<ul><section ng-repeat="section in sections" section="section" /></ul>'
};
})
.directive('section', function ($compile) {
return {
restrict: "E",
replace: true,
scope: {
section: '=section'
},
template: '<li class="section">{{section.name}} <button ng-click="addSub(section)">Add</button></li>',
link: function (scope, element, attrs, controller) {
if (angular.isArray(scope.section.sections)) {
element.append("<sections sections='section.sections'></sections>");
$compile(element.contents())(scope);
}
if(angular.isArray(scope.section.products)){
element.append("<products products='section.products'></products>");
$compile(element.contents())(scope);
};
},
controller : function($scope){
console.log($scope);
$scope.addSub = function (section){
//console.log(section,'Adding Sub');
section.sections.push({"name":"Section","sections":[],"products":[]});
};
}
};
})
.directive('products', function () {
return {
restrict: "E",
replace: true,
scope: {
products: '='
},
template: '<ul><product ng-repeat="product in products" product="product"></product></ul>'
};
})
.directive('product', function ($compile) {
return {
restrict: "E",
replace: true,
scope: {
product: '='
},
template: '<li class="product">{{product.name}}</li>'
};
});
menuApp.controller('menuCtrl', function menuCtrl($scope,$http) {
$http.get('/ajax/getvenuesmenu?venueID='+venueMenu.venueId).success(function(resp) {
$scope.sections = resp;
});
$scope.add = function(data){
data.push({"name":"Section","sections":[]});
};
});
Took me a bit to figure it out but here's the basic problem, you are compiling the full contents of section 2 extra times and each compile seems to add a new event handler.
Instead of compiling the contents of element each time you make an append of new template, compile the template itself (outside of the DOM) and then append the compiled template. This way the ng-click handler doesn't get compiled again other than initial scope creation
Here's an abbreviated version with one template appended:
link: function (scope, element, attrs, controller) {
if (angular.isArray(scope.section.sections)) {
/* compile outside of the DOM*/
var subsections = $compile("<sections sections='section.sections'></sections>")(scope);
/* append compilation*/
element.append(subsections);
}
DEMO
Another approach would be to create a complete template string in link by checking for subsections and products, then compiling everything all at once....instead of using template option
Code for alternate approach compiling complete section at once:
.directive('section', function ($compile, $timeout) {
return {
restrict: "E",
scope: {
section: '=section'
},
link: function (scope, element, attrs, controller) {
var template = '<li class="section">{{section.name}} <button ng-click="addSub(section)">Add</button>';
if (angular.isArray(scope.section.sections)) {
template += "<sections sections='section.sections'></sections>";
}
if (angular.isArray(scope.section.products)) {
template += "<products products='section.products'></products>";
};
template += '</li>';
var compiledTemplate = $compile(template)(scope);
element.replaceWith(compiledTemplate);
scope.addSub = function (section) {
section.sections.push({ "name": "Section", "sections": [], "products": []
});
};
}
};
})
DEMO-Alt

Resources