So I used JHipster to generate my app.
I could see the navbar using the has-authority directive to show/hide menus.
Now what I would to do is to use the directive on a button to show it only to users with ROLE_ADMIN
here's the code of the directive
.directive('hasAuthority', ['Principal', function (Principal) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var setVisible = function () {
element.removeClass('hidden');
},
setHidden = function () {
element.addClass('hidden');
},
defineVisibility = function (reset) {
if (reset) {
setVisible();
}
Principal.hasAuthority(authority)
.then(function (result) {
if (result) {
setVisible();
} else {
setHidden();
}
});
},
authority = attrs.hasAuthority.replace(/\s+/g, '');
if (authority.length > 0) {
defineVisibility(true);
scope.$watch(function(scope) {
return Principal.isAuthenticated();
}, function(newValue) {
defineVisibility(true);
});
}
}
};
}]);
here's where it's working
<li ng-class="{active: $state.includes('admin')}" ng-switch-when="true" has-authority="ROLE_ADMIN" class="dropdown pointer">
and here is where I want it to work
<table class="jh-table table table-striped">
<thead>
...
</thead>
<tbody>
<tr
ng-repeat="offeredService in travelRequest.offeredServices track by offeredService.id">
<td><a
ui-sref="offeredServiceType.detail({id:offeredService.offeredServiceType.id})">{{offeredService.offeredServiceType.name}}</a>
</td>
<td>{{offeredService.sellingPrice}}
{{offeredService.currency.symbol}}</td>
<td>{{offeredService.cost}}
{{offeredService.currency.symbol}}</td>
<td>{{offeredService.confirmationDate | date:'medium'}}</td>
<td><a
ui-sref="serviceProvider.detail({id:offeredService.serviceProvider.id})">{{offeredService.serviceProvider.name}}</a>
</td>
<td class="text-right">
<div class="btn-group flex-btn-group-container">
<button type="submit"
ui-sref="offeredService.detail({id:offeredService.id})"
class="btn btn-info btn-sm">
<span class="glyphicon glyphicon-eye-open"></span> <span
class="hidden-xs hidden-sm" translate="entity.action.view"></span>
</button>
<button type="submit"
ui-sref="offeredService.edit({id:offeredService.id})"
class="btn btn-primary btn-sm">
<span class="glyphicon glyphicon-pencil"></span> <span
class="hidden-xs hidden-sm" translate="entity.action.edit"></span>
</button>
<button has-authority="ROLE_USER" type="submit"
ui-sref="offeredService.delete({id:offeredService.id})"
class="btn btn-danger btn-sm">
<span class="glyphicon glyphicon-remove-circle"></span> <span
class="hidden-xs hidden-sm" translate="entity.action.delete"></span>
</button>
</div>
</td>
</tr>
</tbody>
</table>
It seems to me that your condition is wrong:
<button has-authority="ROLE_USER" type="submit"
ui-sref="offeredService.delete({id:offeredService.id})"
class="btn btn-danger btn-sm">
An admin user has both authorities ROLE_USER and ROLE_ADMIN.
So in your case the button will always show.
Shouldn't it be like below?
<button has-authority="ROLE_ADMIN" type="submit"
Related
Here is my code:
<body ng-app="intranet_App" ng-controller="myCtrl">
<div class="container">
<div class="modal" id="deleteProject">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body" id="confirmMessage">
Are you sure do you want to delete this project??
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" id="confirmOk" ng-click="deleteProject(x.Id)">Ok</button>
<button type="button" class="btn btn-default" id="confirmCancel" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
<div class="col-xs-12 margin20 padding table-responsive">
<table class="col-xs-12 table table-hover table-bordered" id="projectList">
<thead class="colorBlue">
<tr><th>Project Name</th><th>Client</th><th>Client Co-ordinator</th><th>Action</th></tr>
</thead>
<tbody id="projectListTBody" >
<tr ng-repeat="x in projectList | filter:ProjectName">
<td>{{ x.ProjectName}}</td>
<td>{{ x.Client}}</td>
<td>{{ x.OnsiteCoordinator}}</td>
<td>
<i class="fa fa-user-plus fa-2x" ng-click="addResource()"></i>
<i class="fa fa-edit fa-2x" ng-click="editProj(x.Id)"></i>
<i class="fa fa-trash fa-2x" data-toggle="modal" data-target="#deleteProject"></i>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
<script>
var app = angular
.module("intranet_App", [])
.controller("myCtrl", function ($scope, $http) {
$scope.projDetails = [];
$http.post('/Project/getProjectsList')
.then(function (response) {
console.log(response)
$scope.projectList = response.data;
})
$scope.deleteProject = function (id) {
alert(id)
}
});
</script>
Here when I click delete icon in a table, I am displaying one bootstrap popup modal.In that modal I need to pass x.Id inside deleteProject method on the on click on ok button.But I am unable to hit the method,how to pass it?
In HTML code, add ng-click to delete button
<i class="fa fa-trash fa-2x" data-toggle="modal" data-target="#deleteProject" ng-click="delete(x.id)"></i>
In controller add following method
$scope.delete = function (id) {
$scope.deleteId = id;
}
Using that in deleteProject method
$scope.deleteProject = function () {
//use $scope.deleteId here
alert($scope.deleteId);
}
You're trying to access the x var outside of the ng-repeat in which it is defined it, so naturally, it won't know what x is. This is why you're getting undefined.
Here's the quickest solution I could come up with, there should be a better way, though:
<i class="fa fa-trash fa-2x"
data-toggle="modal"
data-target="#deleteProject"
ng-click="current = x"></i>
Which will assign the last clicked x into current. Then, you should refer to current inside the modal:
<button type="button"
class="btn btn-default"
id="confirmOk"
ng-click="deleteProject(current.Id)">
Ok
</button>
I am newbie on angular 2. I am trying to do simple crud operations. However I have problem with using bootstrap modal. The code below, opens bootstrapmodal but I can't send selected movie on DeleteMovie() method.
<div style="margin: 20px">
<h2>Movies List</h2>
<input type="button" Value="Add Movie" class="btn btn-primary" (click)="AddMovie()"/>
<hr/>
<div class="row">
<div class="col-md-12">
<table class="table table-bordered">
<thead>
<tr>
<th>Movie Name</th>
<th>Genre</th>
<th>Edit</th>
<th>Delete</th>
<th>Delete2</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let mv of movies">
<td>{{mv.MovieName}}</td>
<td>{{mv.MovieGenre}}</td>
<td><a routerLink="/movies/{{mv.movieID}}"><i class="glyphicon glyphicon-edit"></i></a></td>
<td><i class="glyphicon glyphicon-remove clickable" (click)="removeMovie(mv)"></i></td>
<td><i class="glyphicon glyphicon-remove clickable" data-toggle="modal" data-target="#myModal2" data-id="{{mv.MovieName}}" (click)="SelectMovie(mv)"></i></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="myModal2" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">Delete Record</h4>
</div>
<div class="modal-body">
Do you want to delete {{selectedMovie.MovieName}}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" (click)="removeMovieV2(selectedMovie)" data-dismiss="modal">Delete</button>
</div>
</div>
</div>
</div>
#Component({
selector: 'movies2',
templateUrl: '/templates/movies.component.html',
providers: [MoviesService]
})
export class MoviesComponent implements OnInit {
isLoading = true;
movies: any = [];
selectedMovie:any={};
constructor(private _moviesService: MoviesService, private router: Router, private notificationService: NotificationService) {
}
ngOnInit() {
this.GetMovies();
}
AddMovie() {
this.router.navigate(['/newmovie']);
}
GetMovies() {
this._moviesService.getMovies().subscribe(p => {
this.movies = p;
});
}
SelectMovie(mv: any) {
this.selectedMovie = mv;
}
removeMovieV2(val: any) {
this._moviesService.deleteMovie(val).subscribe(res => {
this.notificationService.printSuccessMessage(val.MovieName + ' has been deleted.');
this.GetMovies();
}, error => {
this.notificationService.printErrorMessage(error);
});
}
}
I think you need to use attribute binding instead of property binding for boostrap to get the value
attr.data-id="{{mv.MovieName}}"
(only for strings)
or
[attr.data-id]="mv.MovieName"
(also supports objects)
I'm using AngularJS and Smart Table to show items from Database and Filter the items by Date. I want to use a Datetimepicker (Bootsrap.UI http://angular-ui.github.io/bootstrap/)
My Problem is if I type the text into the input of the Datetime-element it works but if I select a date via Datetimepicker, the text changes but the Filter is not set.
Is there any way to give the smart-table the picked Filter?
My Table Head looks like this:
<table st-table="feedBacks" st-pipe="callServer"
class="table table-striped table-bordered table-hover table-highlight table-checkable">
<thead>
<tr>
<th style="width: 160px">Datum</th>
<th>Produkt</th>
<th>Version</th>
<th>Plattform</th>
<th>FeedBack</th>
<th style="width: 125px">Option</th>
</tr>
<tr>
<th>
<p class="input-group">
<input type="text" class="form-control"
datepicker-popup="{{format}}" ng-model="dt"
is-open="opened" datepicker-options="dateOptions"
ng-required="true"
close-text="Close" st-search="Timestamp" id="dateFilter" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="openDate($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</th>
<th><input st-search="ApiKey.Product.ProductName" /></th>
<th><input st-search="ApiKey.ProductVersion" /></th>
<th>
<div class="btn-group">
<button class="btn btn-default btn-xs" st-plattform-filter="" st-plattform-filter-column="Plattform">
<span class="fa fa-reorder"></span>
</button>
<button class="btn btn-default btn-xs" st-plattform-filter="0" st-plattform-filter-column="Plattform">
<span class="fa fa-android"></span>
</button>
<button class="btn btn-default btn-xs" st-plattform-filter="1" st-plattform-filter-column="Plattform">
<span class="fa fa-windows"></span>
</button>
<button class="btn btn-default btn-xs" st-plattform-filter="2" st-plattform-filter-column="Plattform">
<span class="fa fa-apple"></span>
</button>
</div>
</th>
<th></th>
<th></th>
</tr>
</thead>
I know this is not elegant solution But it will work.
st-input-event="focus"
<input st-input-event="focus" st-search="end_time" class="input-sm form-control" type="text" ng-model="end_time" is-open="status.end_time_open" close-text="Close" uib-datepicker-popup="yyyy-MM-dd" datepicker-options="dateOptions" />
i use this pluging https://github.com/fragaria/angular-daterangepicker
as i like the date range and its pure angular.
hope it helps you :)
my html:
<div ng-controller="dateRange" class="text-right">
<st-date-range start="dateRange.start" end="dateRange.end"></st-date-range>
<ta-date-range-picker class="well" ng-model="dateRange" ranges="customRanges" callback="dateRangeupdate(dateRange)"></ta-date-range-picker>
</div>
Directive:
.directive('stDateRange', ['$timeout', function ($timeout) {
return {
restrict: 'E',
require: '^stTable',
scope: {
start: '=',
end: '='
},
link: function (scope, element, attr, table) {
var query = {};
var predicateName = attr.predicate;
scope.$watch('start', function () {
if (scope.start) {
query.start = moment(scope.start).format('YYYY-MM-DD');
}
if (scope.end) {
query.end = moment(scope.end).format('YYYY-MM-DD');
}
table.search(query, predicateName);
});
}
}
}])
Controller
//Select range options
$scope.customRanges = [
{
label: "This week",
range: moment().range(
moment().startOf("week").startOf("day"),
moment().endOf("week").startOf("day")
)
},
{
label: "Last month",
range: moment().range(
moment().add(-1, "month").startOf("month").startOf("day"),
moment().add(-1, "month").endOf("month").startOf("day")
)
},
{
label: "This month",
range: moment().range(
moment().startOf("month").startOf("day"),
moment().endOf("month").startOf("day")
)
},
{
label: "This year",
range: moment().range(
moment().startOf("year").startOf("day"),
moment().endOf("year").startOf("day")
)
},
{
label: "Last year",
range: moment().range(
moment().startOf("year").add(-1, "year").startOf("day"),
moment().add(-1, "year").endOf("year").startOf("day")
)
}
];
$scope.mycallback = "None";
$scope.dateRangeChanged = function () {
$scope.mycallback = " from " + $scope.dateRange.start.format("LL") + " to " + $scope.dateRange.end.format("LL");
}
}]);
I know this is old. But if anybody is struggling to get this on Angular 1.6 here's my answer:
Directive:
var app = angular.module("datePickerFilter", []);
app.directive("datePickerFilter", function () {
function link(scope, element, attr, table) {
scope.$watch('dateToFilter', function () {
//check if is different from null
if (scope.dateToFilter) {
//format if it's not null
var formatedDate = moment(scope.dateToFilter).format('YYYY-MM-DD');
table.search(formatedDate, scope.stSearch);
}
//trigger the search
table.search(formatedDate, scope.stSearch);
});
//Opciones para input de fecha
scope.dateOptions = {
formatYear: 'yy',
startingDay: 1
};
scope.dateFormat = 'yyyy-MM-dd';
scope.altInputFormats = ['M!/d!/yyyy'];
scope.dateInputOpened = false;
scope.openDateInput = function () {
scope.dateInputOpened = true;
};
}
return {
scope: {
stSearch: "="
},
link: link,
restrict: "E",
//We need this directive to be under a stTable directive instance
require: "^stTable",
template:
` <div class="input-group">
<input class="form-control" type="text" uib-datepicker-popup="{{format}}" is-open="dateInputOpened"
ng-model="dateToFilter" datepicker-options="dateOptions" close-text="Cerrar"
alt-input-formats="altInputFormats" ng-click="openDateInput()" ng-focus="openDateInput()" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="openDateInput()">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</div>`
};
});
HTML:
<date-picker-filter st-search="'nameOfDateFieldToFilter'"></date-picker-filter>
I'm stuck with this problem for 2 days and I couldn't locate its core so any help on the matter is really appreciated.
I was creating a form that was inline editable with xeditable and the edit(save/cancel) buttons were working as expected but the DELETE button is not calling the given method from the controller. I tried placing it on other parts in the code both as a button and a link and ng-click was not working both ways! I'm quite new at Angular so any debugging tips on how to solve this kinds of problems are welcome! Thanks in advance!
Here is the code from the app file:
var app = angular.module('app', ["Controllers", "xeditable"])
app.run(function (editableOptions) {
editableOptions.theme = 'bs3';
});
Here is the code for the controller (in different .js file from app.js)
angular.module("Controllers", [])
.controller("controller", ["$scope", "$http", function ($scope, $http) {
$scope.users= {};
//get display data
$http.get("/User/All").success(function (data) {
$scope.users= data;
});
//form methods
$scope.editUser = function (data, id) {
edit_data.UserID = id;
$http.post("/User/Edit", edit_data).success(function () {
angular.extend(data, { id: id });
});
};
$scope.deleteUser = function (index, id) {
$http.post("/User/Delete", id).success(function() {
$scope.users.splice(index, 1);
});
};
}]);
Here is the code from the form:
<container ng-app="app" ng-controller="controller">
<table class="table">
<tr>
<th>
Name
</th>
<th>
Surname
</th>
<th></th>
</tr>
<tr ng-repeat="user in users">
<td>
<span editable-text="user.Name" e-name="Name" e-form="rowform" e-required>
{{user.Name}}
</span>
</td>
<td>
<span editable-text="user.Surname" e-name="Surname" e-form="rowform" e-required>
{{user.Surname}}
</span>
</td>
<td style="white-space: nowrap">
<form editable-form name="rowform" onbeforesave="editUser($data, user.UserID)" ng-show="rowform.$visible" class="form-buttons form-inline" shown="inserted == user">
<button type="submit" ng-disabled="rowform.$waiting" class="btn btn-primary">
save
</button>
<button type="button" ng-disabled="rowform.$waiting" ng-click="rowform.$cancel()" class="btn btn-default">
cancel
</button>
</form>
<div class="buttons" ng-show="!rowform.$visible">
<button type="button" class="btn btn-primary" ng-click="rowform.$show()">edit</button>
<button type="button" class="btn btn-danger" ng-click="deleteUser($index,user.UserID)">delete</button>
</div>
</td>
</tr>
I am using a simple CRUD API in MEAN STACK with a delete function
app.delete('/api/users/:user_id', function(req, res) {
users.remove({
_id : req.params.user_id
}, function(err, user) {
if (err)
res.send(err);
users.find(function(err, users) {
if (err)
res.send(err)
res.json(users);
});
});
});
The controller
var app = angular.module('usersList', []);
app.controller('usersController', function($scope, $http) {
$http.get('/api/users')
.success(function(userData) {
$scope.users = userData;
$scope.length = userData.length;
})
.error(function(data) {
console.log('Error: ' + data);
});
$scope.deleteUser = function(id) {
$http.delete('/api/users/' + id)
.success(function(data) {
$scope.users = data;
console.log(data);
})
.error(function(data) {
console.log('Error: ' + data);
});
};
});
In the HTML file I populate a table as follow with a btn to open modal with corresponding user details by getting the {{$index}}
<body data-ng-controller="usersController">
<table>
<thead>
<tr>
<th>#</th>
<th>ID</th>
<th>Login</th>
<th>Email</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="userData in users" >
<td><input type="checkbox"/></td>
<td>{{ userData._id }}</td>
<td>{{ userData.id_userLogin }}</td>
<td>{{ userData.email }}</td>
<td>
<!-- Button trigger for Delete modal -->
<button type="button" data-toggle="modal" data-target="#deleteModal{{$index}}" data-ng-click="Clear()">
<span class="glyphicon glyphicon-trash"></span>
</button>
<!-- Delete Modal -->
<div class="modal fade" id="deleteModal{{$index}}" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Delete <strong>{{ userData.id_userLogin }}</strong> account</h4>
</div>
<div class="modal-body">
<div class="alert alert-danger" role="alert">Are you sure you want to delete this account?</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-danger" data-ng-click="deleteUser(user._id)">Delete</button>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
How can I use the API to delete the corresponding user from the modal as following does not work
<button type="button" class="btn btn-danger" data-ng-click="deleteUser(user._id)">Delete</button>
It is important that the modal is not a confirm delete popup but a modal with content from where the delete button will delete the corresponding user. Any help would be appreciated.
Seem like the problem is solved. I'll just post the answer here. The html of the button should be:
<button type="button" class="btn btn-danger" data-ng-click="deleteUser(userData._id)">Delete</button>
<!-- Use userData._id instead of user._id-->