I am using angularjs and ng-include in in the view. I need to create a graphic using dygraph. I have 5 templates that show or hide when I click one button. When I click the button ng-include load a template. In this template, I have a div with Id where I want to show the graphic.
The problem is that this id doesn't exist in DOM when I click. If I click again, it shows the graphic without any problem because the Id exist.
My code:
View:
<button class="btn" ng-click="exploreLineChart()">Line chart</button>
<div ng-include="currentTemplate.url"></div>
Template:
<div id="linechart"></div>
Controller:
$scope.templates = [
{url: 'views/explore-dataset/summary.html', title: 'Summary'},
{url: 'views/explore-dataset/line-chart.html', title: 'Line Chart'},
{url: 'views/explore-dataset/bar-chart.html', title: 'Bar Chart'},
{url: 'views/explore-dataset/scatter.html', title: 'Scatter Plot'},
{url: 'views/explore-dataset/pie-chart.html', title: 'Pie Chart'},
{url: 'views/explore-dataset/correlation.html', title: 'Correlation'}
];
$scope.exploreLineChart = function ()
{
$scope.currentTemplate = $scope.templates[1];
linechart = new Dygraph(document.getElementById("linechart"),
$scope.csvContent,
{
height: 320
});
}
I advice you to create a directive to manage better the scope and graph state, for example:
Directive:
angular.module('tAngularApp').directive('ngGraphic', function() {
return {
restrict: 'A',
template: '<button class="btn" ng-click="exploreLineChart(0)">Summary</button><button class="btn" ng-click="exploreLineChart(1)">Line chart</button><div id="linechart"> </div>',
link: function($scope,element, attrs, ctrl) {
$scope.templates = [
{url: 'views/explore-dataset/summary.html', title: 'Summary'},
{url: 'views/explore-dataset/line-chart.html', title: 'Line Chart'},
{url: 'views/explore-dataset/bar-chart.html', title: 'Bar Chart'},
{url: 'views/explore-dataset/scatter.html', title: 'Scatter Plot'},
{url: 'views/explore-dataset/pie-chart.html', title: 'Pie Chart'},
{url: 'views/explore-dataset/correlation.html', title: 'Correlation'}
];
$scope.exploreLineChart = function (index) {
$('#linechart').text('displaying : ' + $scope.templates[index].title + ' template');
// TODO: Create the Graph
}
}
};
});
Html:
<div ng-graphic=""></div>
Related
I'm using a directive to set html, css and javascript code inside of and iframe. These iframes are inside a ng-repeat, so there is an iframe per result.
Then these results are filtered by title and sortby title or date.
So, I have two problems:
Firefox is not showing the iframe html code but the rest of the browsers are.
After selecting a sort option, the title and date are refresing correctly, but the iframe content is not.
Here is a link to Plunker: http://plnkr.co/edit/Kvsbir?p=info
And here is my code:
<body ng-controller="HomeController">
<div class="panel-heading text-center">
<h3>Projects</h3>
<form action="" class="form-inline">
<div class="form-group">
<input class="form-control" type="text" ng-model="query.name" placeholder="Search...">
</div>
<div class="form-group dropdown">
<select class="btn btn-default dropdown-toggle" type="text" ng-model="sortOrder" ng-options="item.value as item.text for item in sortOptions"></select>
</div>
</form>
</div>
<div class="panel-body">
<div ng-model="result" ng-repeat="project in projects | orderBy:sortOrder | filter:query.name" class="col-md-4 col-sm-6">
<div class="single-pen">
<div class="meta">
<h3>{{project.title}}</h3>
<h6> {{project.created_at | date}} </h6>
</div>
<div class="iframe-wrap">
<div theframe="project"></div>
</div>
</div>
</div>
</div>
</body>
The controller
var app = angular.module('plunker', []);
app.controller('HomeController', function ($rootScope,$filter, $scope) {
'use strict';
var vm = this;
// Filter & sort
$scope.sortOptions = [
{ value: "-created_at", text: "Ordenar by Date"},
{ value: "title", text: "Ordenar by Title"}
];
$scope.sortOrder = $scope.sortOptions[0].value;
$scope.result = [
{
title: 'Project 1',
code: [{
css: "body{background-color: pink;}",
html: "<h1>Hello</h1>",
js: ""
}],
created_at: "2016-02-06T22:52:24.900Z"
},
{
title: 'Project 2',
code: [{
css: "body{background-color: blue;}",
html: "<h1>Hello</h1>",
js: ""
}],
created_at: "2016-02-10T11:52:33.055Z"
},
{
title: 'Project 3',
code: [{
css: "body{background-color: yellow;}",
html: "<h1>Hello</h1>",
js: ""
}],
created_at: "2016-02-06T22:52:24.900Z"
},
{
title: 'Project 4',
code: [{
css: "body{background-color: orange;}",
html: "<h1>Hello</h1>",
js: ""
}],
created_at: "2016-02-08T11:52:33.055Z"
},
{
title: 'Project 5',
code: [{
css: "body{background-color: red;}",
html: "<h1>Hello</h1>",
js: ""
}],
created_at: "2016-02-01T13:46:33.917Z"
},
];
$scope.projects = $scope.result;
})
.directive('theframe', function($compile){
return {
restrict: 'A',
scope: {
theframe: '='
},
template: '<iframe id="frame" scrolling="no"></iframe>',
link: function($scope, element, attrs) {
var $head = $(element).find('#frame').contents().find('head');
var $body = $(element).find('#frame').contents().find('body');
$scope.$watch('projects', function(n,o){
$head[0].innerHTML = '<style>'+$scope.theframe.code[0].css+'</style>';
$body[0].innerHTML = $scope.theframe.code[0].html + '<script> (function(){ \n' + $scope.theframe.code[0].js + '\n})();</script>';
}, true);
}
}
})
Any hints of why is not working correctly?
EDIT
SOLVED Firefox issue!
Thanks for the $timeout idea.
This is what i've changed: http://plnkr.co/edit/Kvsbir?p=preview
.directive('theframe', function($compile, $timeout){
return {
restrict: 'A',
scope: {
theframe: '='
},
template: '<iframe id="frame" scrolling="no"></iframe>',
link: function($scope, element, attrs) {
var $head = $(element).find('#frame').contents().find('head');
var $body = $(element).find('#frame').contents().find('body');
var timeout = setInterval(function(){
$head[0].innerHTML = '<style>'+$scope.theframe.code[0].css+'</style>';
$body[0].innerHTML = $scope.theframe.code[0].html + '<script> (function(){ \n' + $scope.theframe.code[0].js + '\n})();</script>';
$scope.$apply();
}, 500);
}
}
})
when i write code direct in my view .the list success display in my tabpanel's tab.look the view underneath
{
xtype: 'tabpanel',
itemId: 'tabfirst',
flex: 1,
//activeItem: 1,
tabBar: {
layout: {
pack: 'center'
}
},
items: [
{
title: 'tab1',
xtype: 'list',
itemTpl: '{title}',
data: [
{title : 'title1'},
{title : 'title2'},
{title : 'title3'}
]
},
{
title: 'tab2',
html: 'here second html2'
}
]
}
but it not success in my controller. there is nothing in my tab.
Ext.define('ylp2p.controller.addtab',{
extend: 'Ext.app.Controller',
launch: function(){
var moneytab = Ext.ComponentQuery.query('.makemoney #tabfirst')[0];//--get my tabpanel
var titlestor = Ext.create('ylp2p.store.loanlist');//---get my store
titlestor.load({
callback: function(records, operation, success){
Ext.each(records, function(record){
var loanname = record.get('loanname');
var myPanel = Ext.create('Ext.Panel',{
//the code is same in my view but not work
title: loanname,
xtype: 'list',
itemTpl: '{title}',
data: [
{title : 'title1'},
{title : 'title2'},
{title : 'title3'}
]
});
moneytab.add([myPanel]);
//add above panel
});
}
});
}
});
when i add only "title" and "html" in panel,it work. then i change it to list.it success in direct write in view. but it not work write it direct in controller.
Use this code to add List. It will work.
var myPanel = Ext.create('Ext.List', {
//the code is same in my view but not work
title: loanname,
itemTpl: '{title}',
data: [
{ title: 'title1' },
{ title: 'title2' },
{ title: 'title3' }
]
});
moneytab.add([myPanel]);
As I don't have enough reputation to comment, I am posting this as answer:
Did you try giving your view fullscreen: true config and also did you include your Controller in the Ext.app.Application list of controllers?
I have the following directive
angular.module("KendoDemos", [ "kendo.directives" ])
.directive('myDirective',function(){
return{
template:'<div k-on-resize="resized()" kendo-splitter k-orientation="horizontal"id="splitter"><div><div kendo-grid="myGrid" options="mainGridOptions"></div></div><div><p>{{hello}}</p></div></div></div></div>',
scope:{},
controller:function($scope,$element){
$scope.hello = "Hello from Controller!";
$scope.mainGridOptions = {
dataSource: {
type: "odata",
transport: {
read: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Customers"
}
},
columns: [{
template: "<div class='customer-photo'" +
"style='background-image: url(../content/web/Customers/#:data.CustomerID#.jpg);'></div>" +
"<div class='customer-name'>#: ContactName #</div>",
field: "ContactName",
title: "Contact Name",
}, {
field: "ContactTitle",
title: "Contact Title"
}, {
field: "CompanyName",
title: "Company Name"
}, {
field: "Country",
}]
};
$scope.resized = function(){
if($("#splitter .k-pane:first").css("width") < '350px'){
$scope.myGrid.hideColumn("ContactName");
$scope.myGrid.hideColumn("Country");
}else{
$scope.myGrid.showColumn("ContactName");
$scope.myGrid.showColumn("Country");
}
};
}
}
})
Basically just creating a kendo Grid with some data and using a kendo splitter, the grid comes on the left side of the splitter. I have attached a event on kendo splitter where if the width is < 300px the grid will hide some columns.
This directive works perfectly if placed used only once on the a page but will not work if used multiple times. How to resolve this ??
I'm working with backbone I'm trying to create a tab view that uses inside panels to render in this case same instance of a table view. My problem is that when the second instance renders removes the first one even though I've been debuging the code and I can see 2 diferent objects for each view.
Here is the code to create object:
var tabs = new Dashboard.Tab({
id: 'reward-tab',
panels: [{
id: 'active-panel',
active: true,
label: 'Actives',
content: new Dashboard.Table({
id: 'active-table',
model: new Dashboard.TableModel(null,{
active: true
})
})
},{
id: 'dismiss-panel',
active: false,
label: 'Not active',
content: new Dashboard.Table({
id: 'dismiss-table',
model: new Dashboard.TableModel(null,{
active: false
})
})
}]
});
Tab view code
Dashboard.Tab = Backbone.View.extend({
template : Handlebars.templates['tabs.hbs'],
panels: [],
events: {
'click .nav-tabs li a' : 'onTabClick'
},
initialize: function() {
this.id = this.options.id;
this.panels = this.options.panels;
},
onTabClick: function(e) {
e.preventDefault();
...
},
render:function(){
//Renders places holders
this.$el.html(this.template({
id: this.id,
tabs : this.panels
}));
$.each(this.panels, function(index, panel){
if(panel && panel.content) {
panel.content.on('ready', function(){
$('#' + panel.id).append(panel.content.el);
});
}
});
}
});
Table code:
Dashboard.Table = Backbone.View.extend({
tableId: 'my-table',
initialize: function() {
var me = this;
this.tableId = this.options.id;
this.model.fetch({reset: true}).done(function () {
me.render();
});
....
},
render: function() {
....
this.trigger("ready");
}
});
Like I said, my problem seem that for some reason the second view its removing the html for the first instance and only rendering the second one.
Any help will be appreciate.
Thanks
I got a AHA moment and I thought the problem could be that I wasn't defining a different el to each view.
When you don't Backbone creates the view inside a generic div element so in this case what I did was to add a new element for each and that made the trick.
The Fix:
var tabs = new Dashboard.Tab({
id: 'reward-tab',
panels: [{
id: 'active-panel',
active: true,
label: 'Actives',
content: new Dashboard.Table({
id: 'active-table',
el: $('<div class="active-table"></div>'),
model: new Dashboard.TableModel(null,{
active: true
})
})
},{
id: 'dismiss-panel',
active: false,
label: 'Not active',
content: new Dashboard.Table({
id: 'dismiss-table',
el: $('<div class="not-active-table"></div>'),
model: new Dashboard.TableModel(null,{
active: false
})
})
}]
});
I'm trying to get my test project working and have it set out with various viewports js files for each screen. I have now managed to load the data onto the screen with the code below however I am struggling with trying to set-up the onItemDisclosure function so that it switches to a detailed view which shows more information about the selection item.
MobileApp.views.Settings_screen = Ext.extend(Ext.Panel, {
title: "Settings ",
iconCls: "settings",
fullscreen: true,
layout: 'card',
dockedItems: [{
xtype: "toolbar",
title: "Settings"
}],
initComponent: function() {
detailPanel = new Ext.Panel({
id: 'detailPanel',
tpl: 'Hello, World'
}),
this.list = new Ext.List({
id: 'indexlist',
store: MobileApp.listStore,
itemTpl: '<div class="contact">{firstName} {lastName}</div>',
grouped: false,
onItemDisclosure: function() {
MobileApp.views.setActiveItem('detailPanel');
}
});
this.items = [this.list];
MobileApp.views.Settings_screen.superclass.initComponent.apply(this, arguments);
}
});
Ext.reg('settings_screen', MobileApp.views.Settings_screen);
I have tried to put some code here to switch to the detailPanel but it comes up with an undefined error.
onItemDisclosure: function() {
MobileApp.views.setActiveItem('detailPanel');
}
Thanks Aaron
You need to define this panel under Settings_screen's namespace, like this:
this.detailPanel = new Ext.Panel({
id: 'detailPanel',
tpl: 'Hello, World'
}),
Also, you need to add the detailPanel to the Settings_screen's items, so that it will become an item of it.
this.items = [this.list, this.detailPanel];