Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

custom angular implemention of photo gallery #20

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,17 @@ Clone this repo and create a responsive image gallery using the gallery.json fil
Make sure to document your decision process in your code and elaborate on challenges and solutions in your commit messages and pull requests.

Keep in mind, this is more about problem solving rather than strictly skill with code. Highlight areas you are strong in, but don't sweat any weaker areas too much.


#To Run:

Serve files from a local server in order for json to be fetched with angular $http.

e.g.

```
cd to/location/of/UIDev-substrate
python -m SimpleHTTPServer 8080
```

Then in browser go to localhost:8080 and see result
31 changes: 31 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<title>Photo Gallery</title>

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.css">
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tell me about your choice to use bootstrap.

<!-- I like to keep code modular so I stuck css for gallery in gallery directive folder -->
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so do we 👍

<link rel="stylesheet" type="text/css" href="src/directives/gallery/gallery.css">
</head>
<body ng-app="galleryApp" ng-cloak>

<div ng-controller="appCtrl as appCtrl" class="container">
<div class="row">
<div class="col-md-12">

<!-- passing the data from the controller into the ng-model of the gallery directive keeps better code separation rather than doing an http request from the gallery itself-->
<gallery ng-model="appCtrl.data"></gallery>

</div>
</div>
</div>


<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.1/angular.js"></script>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tell me about your choice to use angular

<script type="text/javascript" src="src/index.js"></script>
<script type="text/javascript" src="src/controllers/appController.js"></script>
<script type="text/javascript" src="src/directives/gallery/galleryDirective.js"></script>
</body>
</html>
11 changes: 11 additions & 0 deletions src/controllers/appController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
galleryApp.controller('appCtrl', function ($http) {
var ctrl = this;
this.data = [];
$http.get('gallery.json')
.success(function(data) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ctrl.data = data;
})
.error(function(error) {
console.error(error);
});
});
73 changes: 73 additions & 0 deletions src/directives/gallery/gallery.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*organized alphabetically where it made sense*/
.gallery {
position: relative;
}
.gallery-title {
text-align: center;
}
.gallery-navs {
position: absolute;
top: 12em;
width: 100%;
z-index: 1000;
}
.gallery-nav {
cursor: pointer;
display: inline-block;
font-size: 25px;
font-weight: bold;
height: 100%;
width: 20px;
}
.gallery-nav.disabled {
color: #aaa;
cursor: not-allowed;
}

.main.photo {
width: 100%
}
.photo {
display: inline-block;
text-align: center;
}
.photo .title {
min-height: 19px;
}
.photo img {
max-width: 248px;
max-height: 240px;
}
.photo.peripheral {
display: none;
overflow: hidden;
opacity: 0.5;
}
.photo.peripheral img{
max-width: 240px;
max-height: 180px;
}
@media (min-width: 768px) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you choose these brakepoints?

.main img {
max-width: 450px;
max-height: 310px;
}
}
@media (min-width: 992px) {
.main.photo.col-xs-6 {
width: 50%;
}
.photo.peripheral {
display: inline-block;
}
.photo.peripheral img {
max-width: 205px;
max-height: 150px;
}
}
@media (min-width: 1200px) {
.photo.peripheral img {
max-width: 250px;
max-height: 200px;
}
}
83 changes: 83 additions & 0 deletions src/directives/gallery/galleryDirective.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@

galleryApp.directive('gallery', function() {
return {
restrict: 'E',
require: ['ngModel', 'gallery'],
templateUrl: 'src/directives/gallery/galleryTemplate.html',
bindToController: true,
scope: {
gallery: '=ngModel'
},
controllerAs: 'galleryCtrl',
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So happy to see this!

controller: function() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are some of the values of a directive having a controller?

/*
I decided to take the approach of displaying a main image in the gallery
with a previous or next photo if available.
*/
this.title = null;
this.viewableImages = [];
this.previous = [];
this.next = [];
this.start = 0;
this.end = this.start + 1;

this.setValues = function(gallery) {
this.title = gallery['gallery-title'] || 'Untitled Gallery';
this.gallery = gallery;
if (gallery.photos) {
this.setPhotos(gallery.photos);
}
};

// This is where the majority of the logic for the gallery takes place.
// using arrays for viewableImages, previous, and next allows future me to
// display multiple items rather than just one per array.
this.setPhotos = function(photos) {
if (photos[this.start]) {
this.viewableImages = photos.slice(this.start, this.end);
}

if (photos[this.start - 1]) {
this.previous = photos.slice(this.start - 1, this.start);
} else {
this.previous = [];
}
if (photos[this.end + 1]) {
this.next = photos.slice(this.end, this.end + 1);
} else if(photos[this.end]) {
this.next = photos.slice(this.end);
} else {
this.next = [];
}
};

this.viewPrevious = function() {
if (this.start > 0) {
this.start--;
this.end = this.start + 1;
}

this.setPhotos(this.gallery.photos);
};

this.viewNext = function() {
if (this.end < this.gallery.photos.length) {
this.start++;
this.end = this.start + 1;
}

this.setPhotos(this.gallery.photos);
};
},
link: function(scope, el, attrs, ctrls) {
var ngModel = ctrls[0];
var galleryCtrl = ctrls[1];

// allows the gallery model of the galleryCtrl to be set after value is fetched
// ngModelController provides a nice way to accomplish this.
ngModel.$render = function() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

galleryCtrl.setValues(ngModel.$viewValue);
}
}
}
})
29 changes: 29 additions & 0 deletions src/directives/gallery/galleryTemplate.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!-- Using a little bit of custom styling and a lot of bootstrap, I'm able to make the gallery responsive. The majority of the work is taken care of with angular. adding a few media queries allows
me to get the image sizes right, and there you have it.-->
<div class="gallery container-fluid">
<h2 class='gallery-title'>{{galleryCtrl.title}}</h2>
<div class="gallery-navs row">
<div class="gallery-nav pull-left" ng-class="{disabled:!galleryCtrl.previous.length}" ng-click="galleryCtrl.viewPrevious()"><span class="glyphicon glyphicon-menu-left"></span></div>
<div class="gallery-nav pull-right" ng-class="{disabled:!galleryCtrl.next.length}" ng-click="galleryCtrl.viewNext()"><span class="glyphicon glyphicon-menu-right"></span></div>
</div>

<div class="gallery-container row">
<div class="photo peripheral col-xs-3">
<img ng-src="{{photo.src}}" alt="{{photo.title}}" ng-repeat="photo in galleryCtrl.previous">
</div>

<div class="main photo col-xs-6" ng-repeat="photo in galleryCtrl.viewableImages">
<h4 class="title">{{photo.title || 'Untitled'}}</h4>
<img ng-src="{{photo.src}}" alt="{{photo.title}}">
<div ng-if="photo.attribution">
<label for="credit">Credit:</label>
<span id="credit">{{photo.attribution}}</span>
</div>
<p>{{photo.description}}</p>
</div>

<div class="photo peripheral col-xs-3">
<img ng-src="{{photo.src}}" alt="{{photo.title}}" ng-repeat="photo in galleryCtrl.next">
</div>
</div>
</div>
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
var galleryApp = angular.module('galleryApp', []);