I used this directive to add a random background to each of my wrapper divs:
To use it in your app simply define a list of classes in your controller:
app.controller("MyCtrl", function MyCtrl($scope) {
/* A random class is picked from this list */
$scope.classes = [
//"bg-buildings",
"red",
"blue",
"yellow",
"green",
"orange",
"black",
"purple"
];
});
Then add the directive to your page (can be an existing element):
A random class will then be selected from the list and appended to the elements current list of classes (if any).
The easiest way to see how it’s done is probably just to check out the fiddle above, but there’s a code dump below if you need it:
The Random Class Directive
app.directive("ngRandomClass", function () {
return {
restrict: 'EA',
replace: false,
scope: {
ngClasses: "="
},
link: function (scope, elem, attr) {
//Add random background class to selected element
elem.addClass(scope.ngClasses[Math.floor(Math.random() * (scope.ngClasses.length))]);
}
}
});
/*
http://www.whatibroke.com/?p=899
Adds a random class to element
Usage: add ng-random-class to element
*/
var app = angular.module('myApp', []);
app.controller("MyCtrl", function MyCtrl($scope) {
/* A random class is picked from this list */
$scope.classes = [
//"bg-buildings",
"red",
"blue",
"yellow",
"green",
"orange",
"black",
"purple"
];
});
And then to access the ID parameter I used $routeParams:
/* Used to display the lesson planner for customers */
app.controller("CustomerPlannerController", function ($scope, $routeParams /*, ... */) {
console.log($routeParams);
console.log($routeParams.id);
}
Using that setup, a route to /Businesses/Details/:id will display the following output in the console:
//Route to: /Businesses/Details/:id
Object {id: "1"}
1
I’ve been mucking around with directives for that last few days and one of my requirements has been a simple timepicker. Nothing too fancy, but if anyone would like to use it – feel free.
The hours and minutes will then be updated whenever the user changes the value. If you need any other hooks it’s fairly easy to modify and there are a heap of comments.
You may also want to put the HTML in an external template. Just make the following changes to the directive (note templateURL):
The JSFiddle is probably the easiest way to see how it all works. You can simply copy it from there to your app. Alternatively, I’ve dumped the code below:
Uncondensed HTML (for those who prefer to use a template)
{{displayHours()}}
{{displayMinutes()}}
= 12" class="display">
PM
<div ng-if="hours
AM
Timepicker Directive
/*
http://www.whatibroke.com/?p=899
*/
var app = angular.module('myApp', []);
app.controller("MyCtrl", function MyCtrl($scope) {
$scope.hours = 11;
$scope.minutes = 45;
});
app.directive("ngTimeSelector", function () {
return {
restrict: 'EA',
template: '
{{displayHours()}}
{{displayMinutes()}}
= 12" class="display"> PM
<div ng-if="hours AM
',
scope: {
hours: "=",
minutes: "="
},
replace: true,
link: function (scope, elem, attr) {
//Create vars
scope.period = "AM";
/* Increases hours by one */
scope.increaseHours = function () {
//Check whether hours have reached max
if (scope.hours < 23) {
scope.hours = ++scope.hours;
}
else {
scope.hours = 0;
}
}
/* Decreases hours by one */
scope.decreaseHours = function () {
//Check whether hours have reached min
scope.hours = scope.hours = 59) {
scope.minutes = 0;
}
else {
scope.minutes++;
}
}
/* Decreases minutes by one */
scope.decreaseMinutes = function () {
//Check whether to reset
if (scope.minutes 12) {
hoursToDisplay = scope.hours - 12;
}
//Check for 12 AM etc
if (hoursToDisplay == 0) {
//Set to am and display 12
hoursToDisplay = 12;
}
else {
//Check whether to prepend 0
if (hoursToDisplay <= 9) {
hoursToDisplay = "0" + hoursToDisplay;
}
}
return hoursToDisplay;
}
/* Displays minutes */
scope.displayMinutes = function () {
return scope.minutes = 12 ? scope.hours - 12 : scope.hours + 12;
}
}
}
});
This is just a quick post to help out anyone who runs into the same problems with directives that I did today. I was able to call the controllers function from the directive, however none of the parameters were being passed.
The issue ended up being that the parameters need to be named. For instance:
app.directive('ngPlanner', function () {
return {
restrict: 'EA',
templateUrl: '/Businesses/PlannerDirective',
scope: {
lessons: "=",
business: "=",
lessonClicked: "&",
addLesson: "&"
},
replace: true,
link: function (scope, elem, attr) {
var selectedIndex = null;
console.log(scope);
console.log(scope.lessons);
scope.test = function (tester) {
selectedIndex = tester;
console.log("Directive: " + selectedIndex);
scope.lessonClicked({ lesson: selectedIndex });
}
}
}
});
/* Used for handling business details, planner, etc */
app.controller("BusinessDetailsController", function ($scope) {
//Fired when the new lesson button is clicked in the planner directive
$scope.newLesson = function (date) {
console.log("New Lesson Clicked: " + date);
}
//Fired when a lesson is clicked on
$scope.editLesson = function (lesson) {
console.log("Lesson Clicked: " + lesson);
}
});
Note particularly the scope.lessonClicked line. Instead of passing parameters normally, they should be named (scope.lessonClicked({lesson: selectedIndex}).
The naming should match that used in the HTML where your directive is added:
<ng-planner lessons=”plannerLessons” lesson-clicked=”editLesson(lesson)” add-lesson=”newLesson()” business=”true”></ng-planner>
You’ll notice that in the markup, the value is actually an index. This is pretty misleading, but Angular will actually assign the appropriate value to the model (“enabled”, “disabled”, etc).
Another thing that you can do fairly easily, is to remove the default value. Simply make the status null. You can test both these by outputting the JSON or using http://jsfiddle.net/rtR6e/5/.
Another quick post. Working with AngularJS this morning I had a need for a link to redirect to a login page that was not contained within the “angular” part of the app. Unfortunately Angular was overriding the behavior and trying to route it.
The solution is fairly easy for this, simply add a target attribute:
Started redoing Learner Lessons in MVC4 and AngularJS today. I ran into this little issue while trying to retrieve JSON:
This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet
It turns out that this behavious is intentionally prevented in order to avoid JSON hijacking. Thankfully the data I’m working with is not at all sensitive so the workaround is pretty straight forward:
public ActionResult Index()
{
return Json(db.Regions.ToList(), JsonRequestBehavior.AllowGet);
}
For those of you working with sensitive data that don’t want to risk exposing it, posting is suggested as an alternative on StackOverflow: http://stackoverflow.com/a/6440163/522859