I'm new to angularjs and i'm getting some troubles. Usually I find a way to fix it but not this time.
So the problem is I want to use an md-button as a link to another page. But, when I add an href, the button disappears from the page.
Here is my code:
home.html
<body ng-app="friend-s-app">
<div ng-controller="friendsappController">
<md-toolbar>
<div class="md-toolbar-tools">
<md-button href="/home.html" >
Home
</md-button>
</div>
</md-toolbar>
</div>
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/angular-aria/angular-aria.min.js"></script>
<script src="bower_components/angular-animate/angular-animate.min.js"></script>
<script src="bower_components/hammerjs/hammer.min.js"></script>
<script src="bower_components/angular-material/angular-material.min.js"></script>
<script src="bower_components/angular-messages/angular-messages.min.js"></script>
<script src="app.js"></script>
app.js in case you want it :
(function(angular, undefined){
"use strict";
angular
.module('friend-s-app', ['ngMaterial', 'ngMessages', 'ng'])
.controller('friendsappController', inscriptionEditor)
.controller('InscriptionSheet', InscriptionSheet);
function inscriptionEditor($scope, $mdDialog) {
var alert;
$scope.myPathVariable = 'path/to/somewhere';
$scope.showInscription = showInscriptionSheet;
$scope.showSignIn = showSignIn;
function showInscriptionSheet($event) {
$mdDialog.show({
targetEvent: $event,
template:
'<md-dialog layout="column">' +
'<md-content>' +
'<form style="padding: 20px;">' +
'<div layout="row">' +
'<md-input-container>' +
'<label>First name</label>' +
'<input ng-model="user.firstName" required/>' +
'<div ng-messages="userForm.firstName.$error" ng-show="userForm.firstName.$dirty">' +
'<div ng-message="required">This is required!</div> '+
'</div>' +
'</md-input-container>' +
'<md-input-container>' +
'<label>Last name</label>' +
'<input ng-model="user.lastName" required/>' +
'<div ng-messages="userForm.lastName.$error" ng-show="userForm.lastName.$dirty">' +
'<div ng-message="required">This is required!</div> '+
'</div>' +
'</md-input-container>'+
'</div>'+
'<md-input-container style="width: 50%">' +
'<label>Nickname</label>' +
'<input ng-model="user.nickname" required minlength="5" maxlength="15"/>' +
'</md-input-container>' +
'<div layout="row">' +
'<md-input-container>' +
'<label>Password</label>' +
'<input ng-model="user.password" type="password" required minlength="5" maxlength="15"/>' +
'</md-input-container>' +
'<md-input-container>' +
'<label>Repeat password</label>' +
'<input ng-model="user.repassword" type="password" required minlength="5" maxlength="15"/>' +
'</md-input-container>'+
'</div>'+
'<md-input-container>' +
'<label>E-mail</label>' +
'<input ng-model="user.email" required/>' +
'</md-input-container>'+
'<div layout="row">'+
'<md-button ng-Click="closeDialog()" style="width:50%">' +
'Cancel' +
'</md-button>' +
'<md-button style="width: 50%">' +
'Validate' +
'</md-button>' +
'</div>'+
'</form>'+
'</md-content>'+
'</md-dialog>',
controller: 'InscriptionSheet',
onComplete: afterShowAnimation,
locals: { employee: $scope.userName }
});
function afterShowAnimation(scope, element, options) {
}
}
function showSignIn($event) {
$mdDialog.show({
targetEvent: $event,
template:
'<md-dialog>' +
'<md-content>' +
'<md-input-container>' +
'<label>Nickname</label>' +
'<input ng-model="user.nickName" required/>' +
'<div ng-messages="userForm.nickName.$error" ng-show="userForm.nickName.$dirty">' +
'<div ng-message="required">This is required!</div>' +
'</div>' +
'</md-input-container>' +
'<md-input-container>' +
'<label>Password</label>' +
'<input ng-model="user.password" required type="password"/>' +
'<div ng-messages="userForm.password.$error" ng-show="userForm.password.$dirty">' +
'<div ng-message="required">This is required!</div> '+
'</div>' +
'</md-input-container> ' +
'<div layout="row">'+
"<md-button ng-Click=\"closeDialog()\" style=\"width: 50%\" >" +
'Cancel' +
'</md-button>' +
'<md-button style="width: 50%" href="home.html">' +
'Validate' +
'</md-button>' +
'</div>'+
'</md-content>' +
'</md-dialog>',
controller: 'InscriptionSheet',
onComplete: afterShowAnimation,
locals: { employee: $scope.userName }
});
function afterShowAnimation(scope, element, options) {
}
}
}
function InscriptionSheet($scope, $mdDialog, employee) {
$scope.employee = employee;
$scope.closeDialog = function() {
$mdDialog.hide();
};
}
})(angular);
And there are the results :
Without the href :
http://i.stack.imgur.com/zKRKS.png
With it :
http://i.stack.imgur.com/M4JqC.png
thanks for helping me.
I just experienced a similar issue. Note when you switch from an ng-click to an ng-href it will inject an anchor tag instead of a button. To maintain the same visual characteristics I needed to apply an display: inline-block; to the .md-button class (which gets added to the aforementioned anchor tag) in my CSS. This may be the cause of it disappearing on your side.
Let me know if that makes sense or requires any further elaboration.
Related
I need to use recursion in angular directives.
Follow the code with the template without recursion.
It is a left menu that must be created recursively.
I'm not sure how to put the recursion.
I tried '<leftmenu menuLeft = "itemmenu"> </ leftmenu>', but so only the profile image appears several times.
.directive('leftmenu', ['$compile', function ($compile) {
return {
retrict: 'E',
scope: { menuLeft: '=?' },
template: '<div class="user-panel">' +
'<div class= "pull-left image">' +
'<img src="{{ menuLeft.profileImgSrc }}" class="img-circle" alt="{{ menuLeft.profileName }}" />' +
'</div>' +
'<div class="pull-left info">' +
'<p>{{ menuLeft.profileName }}</p>' +
'</div>' +
'</div>' +
'<ul class="sidebar-menu">' +
'<li class="header">{{ menuLeft.header }}</li>' +
'<li class="treeview" ng-repeat="itemmenu in menuLeft.itens">' +
'<a href="{{ itemmenu.actionLink }}">' +
'<i class="{{ itemmenu.visualClass }}"></i> <span>{{ itemmenu.label }}</span>' +
'<span class="pull-right-container" ng-show="{{ itemmenu.subItems.length > 0 }}">' +
'<i class="fa fa-angle-left pull-right"></i>' +
'</span>' +
'</a>' +
'<ul class="treeview-menu">' +
'<li ng-repeat="subItem in itemmenu.subItems">' +
'<a ng-if="subItem.openInNewWindow" target="_blank" href="{{ subItem.actionLink }}">' +
'<i {{ subItem.class }}></i>{{ subItem.label }}' +
'</a>' +
'<a ng-if="!subItem.openInNewWindow" target="_self" href="{{ subItem.actionLink }}">' +
'<i {{ subItem.class }}></i>{{ subItem.label }}' +
'</a>' +
'</li>' +
'</ul>' +
'</li>' +
'</ul>',
compile: function (element) {
},
controller: function ($location, $http, $scope) {
$scope.menuLeft = {
"profileName": "",
"profileImgSrc": response.data.msgSaida[0].profileImgSrc,
"header": "",
"itens": response.data.msgSaida[0].itens,
"token": token
};
}
}
}
}
};
A little late to the party, if you're still looking to resolve this with a recursive directive, it depends what your data structure looks like, but assuming from what you've posted it looks like this:
{
"profileName": "",
...
"items": [{
"label": "title1",
"class": "class1",
"items: [...]
},{
"label": "title1",
"class": "class1",
"items: [...]
}]
}
You can split them into two directives:
One is the parent sidePanel directive that contains the top level
One is the menuList directive that will recursively display sub items
// profile image
// profile name
// etc
<menu-list items="leftMenu.items"></menu-list>
where menu list template was like:
<ul>
<li ng-repeat="item in items">
<span class="{{item.class}}">{{item.label}}</span>
<menu-list ng-if="item.items" items="item.items"></menu-list>
</li>
</ul>
So in each instance of a menu object (label,class,items) the items will be converted into a sub menu-list. You might need to play with it a little and add in some other features.
What i want to do is when i click for example on some button with binded function like this, it will create whole DOM element structure for private chat window purpose
$scope.openPrivateChatWindow = function () {
//here i want to do some coding to create whole div structure
}
With jQuery i will do something like this
function openPrivateChatWindow() {
var div = '<div id="' + ctrId + '" class="ui-widget-content draggable" rel="0">' +
<div class="header">' +
'<div style="float:right;">' +
'<img id="imgDelete" style="cursor:pointer;" src="/Images/delete.png"/>' +
'</div>' +
'<span class="selText" rel="0">' + userName + '</span>' +
'<span class="selText" id="msgTypeingName" rel="0"></span>' +
'</div>' +
'<div id="divMessage" class="messageArea">' +
'</div>' +
'<div class="buttonBar">' +
'<input id="txtPrivateMessage" class="msgText" type="text" />' +
'<input id="btnSendMessage" class="submitButton button" type="button" value="Send" />' +
'</div>' +
'<div id="scrollLength"></div>' +
'</div>';
}
is there something how i can archieve this using angular and if it is, what is the best way how to do that, for example if i can load some html template for that or do it like i showed right up here with jQuery
You should not add html nodes to the DOM from the within the controller.
Either use a custom directive or just hide your div using ng-if and make it appear on button click.
$scope.isChatHidden = true;
$scope.openPrivateChatWindow = function () {
$scope.isChatHidden = false;
}
<div ng:if="isChatHidden">
Other DOM Elements
</div>
I am using ng-admin and I created a custom directive(following this example http://plnkr.co/edit/rYC3nd7undqJz2mr8Old) to upload a excel sheet, when I upload the file, I get the following TypeError: Cannot set property 'columnDefs' of undefined, my code
Module:
var myApp = angular.module('myApp', ['ng- admin','ngStorage','chart.js','ui.grid']);
Controller
myApp.controller('MainCtrl', ['$scope', function ($scope) {
var vm = this;
vm.gridOptions = {};
vm.reset = reset;
function reset() {
vm.gridOptions.data = [];
vm.gridOptions.columnDefs = [];
}
}]);
Directive:
myApp.directive('fileread', ['$http', function ($http) {
return {
restrict: 'E',
scope: {
opts: '='
},
link: function ($scope, $elm, $attrs) {
$elm.on('change', function (changeEvent) {
var reader = new FileReader();
reader.onload = function (evt) {
$scope.$apply(function () {
var data = evt.target.result;
var workbook = XLSX.read(data, {type: 'binary'});
var headerNames = XLSX.utils.sheet_to_json( workbook.Sheets[workbook.SheetNames[0]], { header: 1 })[0];
var datasheet = XLSX.utils.sheet_to_json( workbook.Sheets[workbook.SheetNames[0]]);
console.log(datasheet);
$scope.opts.columnDefs = [];
headerNames.forEach(function (h) {
$scope.opts.columnDefs.push({ field: h });
});
$scope.opts.data = datasheet;
var json_string = JSON.stringify($scope.opts.data);
console.log(json_string);
$elm.val(null);
});
};
reader.readAsBinaryString(changeEvent.target.files[0]);
});
}, template:
'<div ng-controller="MainCtrl as vm">'+
'<button type="button" class="btn btn-success"
ng-click="vm.reset()">Reset Grid</button>'+
'<br />'+
'<br />'+
'<div id="grid1" ui-grid="vm.gridOptions" class="grid">'+
'<div class="grid-msg-overlay"
ng-show="!vm.gridOptions.data.length">'+
'<div class="msg">'+
'<div class="center">'+
'<span class="muted">Select Spreadsheet File</span>'+
'<br />'+
'<input type="file" accept=".xls,.xlsx,.ods" fileread="" opts="vm.gridOptions" multiple="false" />'+
'</div>'+
'</div>'+
'</div>'+
'</div>'+
'</div>'
}
}]);
Template from I am calling the directive
var customDashboardTemplate =
'<div class="row dashboard-starter"></div>' +
'<question-stats></question-stats>'+
'<div ng-controller="MainCtrl" >'+
'<fileread>'+
'<button type="button" class="btn btn-success" ng-click="reset()">Reset Grid</button>'+
'<br />'+
'<br />'+
'<div id="grid1" ui-grid="gridOptions" class="grid">'+
'<div class="grid-msg-overlay" ng-show="!gridOptions.data.length">'+
'<div class="msg">'+
'<div class="center">'+
'<span class="muted">Select Spreadsheet File</span>'+
'<br />'+
'<input type="file" accept=".xls,.xlsx,.ods" fileread="" opts="gridOptions" multiple="false" />'+
'</div>'+
'</div>'+
'</div>'+
'</div>'+
'</fileread>'+
'</div>'+
'<div class="row dashboard-content">' +
'<div class="col-md-6">' +
'<div class="panel panel-green">' +
'<ma-dashboard-panel collection="dashboardController.collections.last_users" entries="dashboardController.entries.last_users" datastore="dashboardController.datastore"></ma-dashboard-panel>' +
'</div>' +
'</div>'+
'<div class="col-md-6">' +
'<div class="panel panel-yellow">' +
'<ma-dashboard-panel collection="dashboardController.collections.last_tips" entries="dashboardController.entries.last_tips" datastore="dashboardController.datastore"></ma-dashboard-panel>' +
'</div>' +
'</div>'+
'</div>'+
'</div>'
;
It may just be the space inside the template separating the ng-click calling the reset function:
(ng- click)
With that space you are not calling the reset therefore not actually assigning the defaults?
Edit:
You are calling the directive within the directive within the directive's template. This seems fishy. Can we see the HTML implementation of where you are calling the directive?
I'm using AngularJS and i'm writing my own directive. I want to use conditional logic in my custom directive. The problem is caused in the template part. Here's a piece of my code:
angular.module('myDirectives').directive('widget', function() {
return {
replace: true,
restrict: 'E',
template:
'<div class="widget">' +
'<div class="panel panel-default">' +
'<div class="panel-heading">' +
'<a href="" class="btn btn-default" ng-click="isCollapsed = !isCollapsed">' +
'<i class="fa" ng-class=" { 'fa-angle-up': !isCollapsed, 'fa-angle-down': isCollapsed } "></i>' +
'</a>' +
'</div>' +
'<div class="panel-body" collapse="isCollapsed">' +
'<p>Panel Content</p>' +
'</div>' +
'</div>' +
'</div>',
transclude: true
}
});
This line throws an error.
'<i class="fa" ng-class=" { 'fa-angle-up': !isCollapsed, 'fa-angle-down': isCollapsed } "></i>'
The '' around fa-angle-up and fa-angle-down are causing this.
There's probably a very simple workaround, but I haven't figured it out yet. So my question for you guys; Is there any other way to write this line?
You have to escape the apostrophes
'<i class="fa" ng-class=" { \'fa-angle-up\': !isCollapsed, \'fa-angle-down\': isCollapsed } "></i>'
I am trying to get HTML to compile in a growl alert. Here is my code:
var html = '<h3>' + rejection.config.method + ' '+ rejection.config.url + '</h3>' +
'<hr><div>' +
(_.isObject(rejection.data) ? ('<pre>' + JSON.stringify(rejection.data, null, 2) + '</pre>') : rejection.data) +
'</div>' + '<a ng-click="reportError($event)"><i class="fa fa-bullhorn hoverable"></i> Report this error</a>';
growl.addErrorMessage(html,
{
enableHtml: true
});
$compile(html)($scope);
On the page the HTML looks like:
<div ng-bind-html="message.text" ng-switch-when="true" class="ng-scope ng-binding"><h3>GET services/link</h3><hr><div>null</div><a><i class="fa fa-bullhorn hoverable"></i> Report this error</a></div>
The html should have the directive that I appended: "<a ng-click="reportError($event)" and it is not being added. Any ideas?