Reputation: 10240
I'm building a gallery UI with a collection of items in a json. Each item has a plethora of stuff with it (checkboxes for options, text, aditional images, etc, etc, etc. When in the original gallery page, if you click on an item, it opens a page that shows all of these items. However, if the user wants to see the next, he/she has to back up and click on the next. That is inconvenient. I would like to implement a next/prev feature so that the user can see the next item right from the details view. And back up to the previous as well of course.
I've minimized it a great deal for simplicity sake. And I put it inside an angular material tabs so that you can see the desired effect when you click on the tabs. However, that effect must happen when the buttons are clicked. The tabs are only for mimicking the functionality for your visual aid. The original design is not built on these tabs.
Here is the HTML I have:
<div ng-controller="TempController">
<div>
<md-button class="md-fab md-mini md-primary" ng-click="prevMedia()">
<i class="fa fa-chevron-left"></i>
</md-button>
<md-button class="md-fab md-mini md-primary" ng-click="nextMedia()">
<i class="fa fa-chevron-right"></i>
</md-button>
</div>
<div>
<md-content>
<md-tabs md-dynamic-height="" md-border-bottom="">
<div ng-repeat="data in data.data">
<md-tab label="{{data.id}}">
<md-content class="md-padding">
<md-checkbox ng-repeat="eachTag in data.tags">
{{eachTag}}
</md-checkbox>
<p>{{data.text}}</p>
</md-content>
</md-tab>
</div>
</md-tabs>
</md-content>
</div>
</div>
A shortened version of the controller:
.controller('TempController', function($scope) {
$scope.data = {
"data": [{
"id": 1,
"tags": [
"tag1",
"tag2"
],
"text":"Something here"
}, {
"id": 2,
"tags": [
"tag1",
"tag2",
"tag3",
"tag4"
],
"text":"Something else here"
},{
"id": 3,
"tags": [
"tag1",
"tag2",
"tag3"
],
"text":"Something else again here"
}]
}
function nextMedia(){
data.data++;
}
function prevMedia(){
data.data--;
}
});
Here is a CODEPEN for you
And if it helps, here is the real controller:
(function ()
{
'use strict';
angular
.module('app.scala-media')
.controller('MediaController', MediaController);
/** @ngInject */
function MediaController($scope, $document, $state, MediaService, Media)
{
var vm = this;
// Data
vm.taToolbar = [
['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'bold', 'italics', 'underline']
];
vm.media = Media;
vm.categoriesSelectFilter = '';
vm.ngFlowOptions = {
};
vm.ngFlow = {
// ng-flow will be injected into here through its directive
flow: {}
};
vm.dropping = false;
vm.imageZoomOptions = {};
// Methods
vm.saveMedia = saveMedia;
vm.nextMedia = nextMedia;
vm.prevMedia = prevMedia;
vm.gotoMedias = gotoMedias;
vm.onCategoriesSelectorOpen = onCategoriesSelectorOpen;
vm.onCategoriesSelectorClose = onCategoriesSelectorClose;
vm.fileAdded = fileAdded;
vm.upload = upload;
vm.fileSuccess = fileSuccess;
vm.isFormValid = isFormValid;
vm.updateImageZoomOptions = updateImageZoomOptions;
/////////
init();
/**
* Initialize
*/
function init()
{
if ( vm.media.images.length > 0 )
{
vm.updateImageZoomOptions(vm.media.images[0].url);
}
}
/**
* Save media
*/
function saveMedia()
{
if ( vm.media.id )
{
MediaService.updateMedia(vm.media.id, vm.media);
}
else
{
MediaService.createMedia(vm.media);
}
}
/**
* Next Media - not working
*/
function nextMedia()
{
vm.media++;
}
/**
* Previous Media - not working
*/
function prevMedia()
{
vm.media--;
}
/**
* Go to medias page
*/
function gotoMedias()
{
$state.go('app.scala-media.medias');
}
/**
* On categories selector open
*/
function onCategoriesSelectorOpen()
{
$document.find('md-select-header input[type="search"]').on('keydown', function (e)
{
e.stopPropagation();
});
}
/**
* On categories selector close
*/
function onCategoriesSelectorClose()
{
// Clear the filter
vm.categoriesSelectFilter = '';
// Unbind the input event
$document.find('md-select-header input[type="search"]').unbind('keydown');
}
/**
* File added callback
* Triggers when files added to the uploader
*
* @param file
*/
function fileAdded(file)
{
// Prepare the temp file data for media list
var uploadingFile = {
id : file.uniqueIdentifier,
file: file,
type: 'uploading'
};
// Append it to the media list
vm.media.images.unshift(uploadingFile);
}
/**
* Upload
* Automatically triggers when files added to the uploader
*/
function upload()
{
// Set headers
vm.ngFlow.flow.opts.headers = {
'X-Requested-With': 'XMLHttpRequest',
//'X-XSRF-TOKEN' : $cookies.get('XSRF-TOKEN')
};
vm.ngFlow.flow.upload();
}
/**
*
* @param file
* @param message
*/
function fileSuccess(file, message)
{
angular.forEach(vm.media.images, function (media, index)
{
if ( media.id === file.uniqueIdentifier )
{
var fileReader = new FileReader();
fileReader.readAsDataURL(media.file.file);
fileReader.onload = function (event)
{
media.url = event.target.result;
};
// Update the image type so the overlay can go away
media.type = 'image';
}
});
}
/**
* Checks if the given form valid
*
* @param formName
*/
function isFormValid(formName)
{
if ( $scope[formName] && $scope[formName].$valid )
{
return $scope[formName].$valid;
}
}
/**
* Update image zoom options
*
* @param url
*/
function updateImageZoomOptions(url)
{
vm.imageZoomOptions = {
images: [
{
thumb : url,
medium: url,
large : url
}
]
};
}
}
})();
And this is what the json actually looks like:
{
"data": [
{
"id": 1,
"name": "HTML5 Script",
"path": "/museum/html5_script.js",
"description": "Officia amet eiusmod eu sunt tempor voluptate laboris velit nisi amet enim proident et. Consequat laborum non eiusmod cillum eu exercitation. Qui adipisicing est fugiat eiusmod esse. Sint aliqua cupidatat pariatur mollit ad est proident reprehenderit. Eiusmod adipisicing laborum incididunt sit aliqua ullamco.",
"volume":250,
"categories": [
"Museum",
"Scripts"
],
"tags": [
"video",
"short play"
],
"images": [
{
"default": true,
"id": 1,
"url": "assets/images/media/html5.png",
"type": "image"
}
],
"approvalicon":"ti-na",
"approvalmsg":"Not Approved",
"typeicon":"ti-html5",
"detailType":"156.7 MB",
"detailDimensions":"1366 x 1920",
"detailDuration":"",
"detailFolder":"Museum",
"modifiedDate":"2016-2-10 16:19:22",
"modifiedRevision":"1",
"modifiedUsed":"1 time",
"modifiedWhere":"#",
"priceTaxExcl": 9.309,
"priceTaxIncl": 10.24,
"taxRate": 10,
"comparedPrice": 19.90,
"quantity": 3,
"sku": "A445BV",
"width": "22cm",
"height": "24cm",
"depth": "15cm",
"weight": "3kg",
"extraShippingFee": 3.00,
"active": true
},
{
"id": 2,
"name": "Leopard Family",
"path": "/playlists/leopard_fam.jpeg",
"description": "Duis anim est non exercitation consequat. Ullamco ut ipsum dolore est elit est ea elit ad fugiat exercitation. Adipisicing eu ad sit culpa sint. Minim irure Lorem eiusmod minim nisi sit est consectetur.",
"volume":250,
"categories": [
"Video",
"Playlist",
"Animals"
],
"tags": [
"video",
"long play"
],
"images": [
{
"default": true,
"id": 1,
"url": "assets/images/media/leopard.jpeg",
"type": "image"
},
{
"default": false,
"id": 2,
"url": "assets/images/media/leopard.jpeg",
"type": "image"
},
{
"default": false,
"id": 3,
"url": "assets/images/media/leopard.jpeg",
"type": "image"
}
],
"approvalicon":"ti-na",
"approvalmsg":"Not Approved",
"typeicon":"ti-control-play",
"detailType":"100 MB",
"detailDimensions":"2730 x 3836",
"detailDuration":"0:01:09.76",
"detailFolder":"",
"modifiedDate":"2016-5-5 16:19:22",
"modifiedRevision":"1",
"modifiedUsed":"1 time",
"modifiedWhere":"#",
"priceTaxExcl": 22.381,
"priceTaxIncl": 24.62,
"taxRate": 10,
"comparedPrice": 29.90,
"quantity": 92,
"sku": "A445BV",
"width": "22cm",
"height": "24cm",
"depth": "15cm",
"weight": "3kg",
"extraShippingFee": 3.00,
"active": true
},
... About a hundred of these...
]
}
Thanks in advance for the help
Upvotes: 0
Views: 494
Reputation: 1789
Make the index of the data array a scope variable that can be updated.
Here's a codepen: http://codepen.io/o4ohel/pen/PWvJOP
HTML
<md-content class="md-padding">
<md-checkbox ng-repeat="eachTag in data.data[current].tags">
{{eachTag}}
</md-checkbox>
<p>{{data.data[current].text}} </p>
</md-content>
JS
...
$scope.current = 0;
$scope.nextMedia = nextMedia;
$scope.prevMedia = prevMedia;
...
function nextMedia() {
$scope.current = ($scope.current === $scope.data.data.length - 1) ? 0 : $scope.current + 1;
}
function prevMedia() {
$scope.current = $scope.current === 0 ? $scope.data.data.length - 1 : $scope.current -1;
}
Upvotes: 1