Angular JS Bootstrap UI Modal for Dynamic Images - angularjs

I tried following this example How to zoom image with angularJS This is getting images from a JSON website and has two different picture links for each {}. I'm trying to enlarge thumbnail images that are obtained from my model by clicking the picture and opening a modal. How do I tie the modal to my click on the image and pass in the image and the caption? Incidentally now when the modal opens, it's empty and it's a tiny width. It would need to be at least 600X600.
"use strict";
var app = angular.module('myApp', ['ngResource','ui.bootstrap']);
app.run(function($templateCache){
$templateCache.put('modal.html', '<div><a ng-click="$close(true)" class="pull-right">&times close</a><img ng-src="{{vm.options.imageList.images}}"/></div>');
});
app.controller("MainController", ['$scope','$uibModal','$resource', function($scope,$uibModal,$resource) {
var vm = this;
$scope.showModal = function(imageName) {
$scope.ImageName = "vm.imageList.image" +imageName;
var uibModalInstance = $uibModal.open({
animation: true,
scope:$scope,
templateUrl: 'modal.html'
});
};
vm.selectCategory=selectCategory;
vm.options = {
imageList:[
{
images: 'images/IMG_0321.JPG',
caption: 'cuddly',
category: 'lake'
},
{
images: 'images/IMG_0050.JPG',
caption: 'sleepy',
category: 'lake'
},
{
images: 'images/IMG_0055.JPG',
caption: 'sleepy',
category: 'lake',
},
{
images: 'images/IMG_0056.JPG',
caption: 'cuddly',
category: 'lake'
},
{
images: 'images/IMG_0059.JPG',
caption: 'cuddly',
category: 'lake'
}
],
};
function selectCategory(pos) {
vm.selectedCategory = pos;
};
}]);
HTML
<div class = "row">
<div class = "col-md-12">
<div ng-repeat = "image in vm.options.imageList | filter: {category: vm.selectedCategory}">
<img class = "thumbnail" ng-src="{{image.images}}" hspace ="15" vspace ="10" ng-click="showModal()">

You are not passing the image in your showModal function.
This would be the workaround.
<div class = "row">
<div class = "col-md-12">
<div ng-repeat = "image in vm.options.imageList | filter: {category: vm.selectedCategory}">
<img class="thumbnail" ng-src="{{image.images}}" hspace ="15" vspace ="10" ng-click="showModal(image.images)">
</div>
</div>
</div>
In your modal.html:
$templateCache.put('modal.html', '<div><a ng-click="$close(true)" class="pull-right">&times close</a><img style="max-width:100%; min-height: 600px;" ng-src="{{imageName}}"/></div>');
And the controller:
$scope.showModal = function(imageName) {
var uibModalInstance = $uibModal.open({
animation: true,
templateUrl: 'modal.html',
controller: function($scope){
$scope.imageName = imageName;
},
size: 'lg'
});
};

Related

Load Initial Image to Page AngularJS

I have a list of names from the model that are listed on the page when the page loads. When i click the name, the corresponding image from the model appears on the page. Is there a way within this to load an initial
image [0]when the page loads? This could be a random image or the first image in the model data set.
<!DOCTYPE html>
<html ng-app = "myApp"><head>
<meta charset="UTF-8">
<title>Cat Clicker</title>
<link rel="stylesheet" type="text/css" href="bootstrap.min.css">
<link rel ="stylesheet" type "text/css" href ="clicker.css">
<script type = "text/javascript" src="Libs/angular.js"></script>
<script type = "text/javascript" src="js/CatClickerMe.js"></script>
<body>
<div ng-controller = "MainController as vm">
<div ng-repeat = "cat in vm.options.catList">
<h3 ng-click = "vm.selectCat(cat)">{{cat.name}}</h3>
</div>
<hr>
<h3>{{vm.selectedCat.name}}</h3>
<img ng-src ="{{vm.selectedCat.images}}">
</div>
</div>
</div>
</body>
</html>
JS
"use strict";
angular.module('myApp',[]);
angular.module('myApp').controller('MainController', function($scope) {
var vm = this;
vm.selectCat=selectCat;
vm.options = {
catList:[
{
name: 'Fluffy',
images: 'images/Fluffy.jpeg'
},
{
name: 'Blacky',
images: 'images/blacky.jpeg'
},
{
name: 'Tabby',
images: 'images/tabby.jpeg'
},
{
name: 'Cleo',
images: 'images/Cleo.jpeg'
}
],
};
function selectCat(pos) {
vm.selectedCat = pos;
};
});
Load first image by setting vm.selectedCat just below vm.options
vm.selectedCat = vm.options.catList[0];
Below is the jsfiddle link for your reference
jsfiddle : https://jsfiddle.net/Lpaudwf8/21/
Can you Try this :-
"use strict";
angular.module('myApp',[]);
angular.module('myApp').controller('MainController', function($scope) {
var vm = this;
vm.selectCat=selectCat;
vm.options = {
catList:[
{
name: 'Fluffy',
images: 'images/Fluffy.jpeg'
},
{
name: 'Blacky',
images: 'images/blacky.jpeg'
},
{
name: 'Tabby',
images: 'images/tabby.jpeg'
},
{
name: 'Cleo',
images: 'images/Cleo.jpeg'
}
],
};
function selectCat(pos) {
vm.selectedCat = pos;
};
function Init(){
vm.selectedCat = vm.options.catList[0];
}
Init();
});

Angular. Pass data from component to parent controller

Hot to recive data from component in parent controller.
I have this code:
index.html
<div ng-controller="formController">
<phones-list phone="phone"></phones-list>
<button ng-click="saveForm()">Save</button>
</div>
form.controller.js
var app = angular.module('myApp');
app.controller('formController', ['$scope', function($scope) {
$scope.saveForm = function() {
console.log($scope.phone)
}
}]);
phoneList.component.js
var app = angular.module('myApp');
app.component('phonesList', {
templateUrl: '/scripts/components/phones/phonesList.template.html',
controller: 'phonesListController',
bindings: {
phone: '='
}
});
phoneList.template.html
<select name="" id="" ng-change="$ctrl.change()" ng-model="$ctrl.phone">
<option ng-repeat="phone in $ctrl.phones">{{ phone.name }}</option>
</select>
phoneList.controller.js
var app = angular.module('myApp');
app.controller('phonesListController', function() {
this.phones = [
{
name: 'ABC',
number: '723-543-122'
},
{
name: 'ABCDE',
number: '324-531-423'
}
];
this.change = function() {
console.log(this.phone)
}
});
So I have select list with phones. What I want is to get phone object in formController after select and submit form. For now I get only text value from .
Add an additional binding to your phoneList component with a function to call when the selection changes.
phoneList.component.js
var app = angular.module('myApp');
app.component('phonesList', {
templateUrl: '/scripts/components/phones/phonesList.template.html',
controller: 'phonesListController',
bindings: {
phone: '=',
onChange: '&' //This will allow you to bind a function to your
} //component that you can execute when something
}); //happens
phoneList.controller.js
var app = angular.module('myApp');
app.controller('phonesListController', function() {
this.phones = [
{
name: 'ABC',
number: '723-543-122'
},
{
name: 'ABCDE',
number: '324-531-423'
}
];
this.change = function() {
console.log(this.phone);
this.onChange({phone: phone}); //call our new callback and give it
} //our update
});
index.html
<div ng-controller="formController">
<phones-list phone="phone"
on-change="phoneSelected(phone)">
<!--Tell our component which function we wish to bind to-->
</phones-list>
<button ng-click="saveForm()">Save</button>
</div>
form.controller.js
var app = angular.module('myApp');
app.controller('formController', ['$scope', function($scope) {
$scope.saveForm = function() {
console.log($scope.phone)
}
$scope.phoneSelected(phone){
//Do your stuff here!
}
}]);
I hope that helps!
I found the solution. I changed component template and add ng-options directive to . I don't know why it is more diffucult to do the same in standard list.
index.html
<div ng-controller="ProposalController">
<phones-list phone="phone"></phones-list>
<button ng-click="saveForm()">Zapisz</button>
</div>
phoneList.component.js
var app = angular.module('myApp');
app.component('phonesList', {
templateUrl: '/components/phones/templates/phoneList.template.html',
controller: 'PhoneListController',
bindings: {
phone: '='
}
});
phoneList.controller.js
....
this.change = function() {
this.phone = this.selectedPhone;
}
....
phoneList.template.html
<select ng-model="$ctrl.selectedPhone" ng-change="$ctrl.change()" ng-options="phone.name for phone in $ctrl.phones"></select>
form.controller.js
$scope.saveForm = function(){
console.log($scope.phone)
}

Polymer neon-animation: Element is remains visible after animating

I downloaded the Polymer Starter Kit and am trying to animate an paper-element like so
<section data-route="contact">
<button on-click="_onButtonClick">Toggle</button>
<my-dialog>
<paper-material elevation="1">
<h2 class="page-title">Contact</h2>
<p>This is the contact section</p>
</paper-material>
</my-dialog>
</section>
my-dialog.html as follows:
<dom-module id="my-dialog">
<template>
<content></content>
</template>
</dom-module>
<script>
Polymer({
is: 'my-dialog',
behaviors: [
Polymer.NeonAnimationRunnerBehavior
],
properties: {
opened: {
type: Boolean
},
animationConfig: {
type: Object,
value: function() {
return {
'entry': [{
name: 'slide-left-animation',
node: this
}],
'exit': [{
name: 'fade-out-animation',
node: this
}]
}
}
}
},
listeners: {
'neon-animation-finish': '_onAnimationFinish'
},
_onAnimationFinish: function() {
if (!this.opened) {
this.style.display = '';
}
},
show: function() {
this.opened = true;
this.style.display = 'inline-block';
this.playAnimation('entry');
},
hide: function() {
this.opened = false;
this.playAnimation('exit');
}
});
</script>
The problem I'm facing is that after toggling the animation, my paper-element is squished and remains visible on screen. How do I make it not visible after animation? I've tried hardcoding <paper-material hidden?=true> but that also does not hide the element.
As commented, you simply need to change this.style.display = 'none';

AngularJS NG-Repeat Seems to Not Work on Array with Single Object

I have found many posts about how ng-repeat does not play well with objects, and expects the data to be an array, but my data is an array, it just happens to have a single object(list2). I get list1 fine, and everything works perfect. According to everything that I have found, list2 should work. Anyone know why it doesn't?
Data coming from my factory:
(function(){
var Factory = function(){
var model = {
list1: [
{
id: "1_1",
type: "header",
headerText: "1_1 Header",
secondaryHeaderText: "",
paragraphText: "1_1 Paragraph",
image: ""
},
{
id: "1_2",
type: "header",
headerText: "Header 1_2",
secondaryHeaderText: "",
paragraphText: "1_2 Paragraph",
image: ""
},
{
id: "1_3",
type: "header",
headerText: "1_3 Header1",
secondaryHeaderText: "1_3 Header2",
paragraphText: "",
image: ""
}
],
list2: [
{
id: "2_1",
type: "link",
headerText: "2_1 Header",
paragraphText: "2_1 Paragraph",
linkText: "2_1 Link Text",
image: ""
}
]
};
var factory = {};
factory.getList1 = function(){
return model.list1;
};
factory.getList2 = function(){
return model.list2;
};
return factory;
};
angular.module('designApp').factory('Factory', Factory);
}());
HMTL
<div>
<!--works perfectly fine -->
<div ng-repeat="item in list1" ng-include="'app/partial/list1.html'"></div>
</div>
<div>
<div ng-repeat="item in list2" ng-include="'app/partial/list2.html'"></div>
</div>
Controller
(function(){
var Controller = function($scope, Factory){
$scope.list1 = [];
$scope.list2 = [];
function init(){
$scope.list1 = Factory.getList1();
$scope.list2 = Factory.getList2();
}
init();
};
Controller.$inject = ['$scope', 'Factory'];
angular.module('designApp')
.controller('Controller', Controller);
}());
This is all that is in list2.html. Does not render any of the model data but renders the html tags, and throws no errors.
<h2>{{list2.headerText}}</h2>
<p>{{list2.paragraphText}}</p>
Thanks in advance for any help!
You have to replace
<h2>{{list2.headerText}}</h2>
<p>{{list2.paragraphText}}</p>
by
<h2>{{item.headerText}}</h2>
<p>{{item.paragraphText}}</p>
working plunkr:
https://plnkr.co/edit/FC5KPpOl7gsmfva63veq?p=preview

Updating ng-include from directive in Angular

I am trying to click on a list item that is created via a repeater and update the template value that is being used by ng-inlude. The initial value that is being set in the controller is working fine (shows up in DOM), however when i change the value in the directive, it is not updating the DOM (stays as initial included DOM). When i use fire bug on the directive it looks as though the scope has changed, although I'm not sure if I am missing something, or if i should be doing this some other way.
This is my partial
<div ng-controller="menuCtrl" >
<ul class="sub-menu">
<li ng-repeat="item in menuItems.left" menu-repeater-directive>
<span>{{item.name}}</span>
<a class="reset-menu-btn">×</a>
</li>
</ul>
<div id="lft-wrapper" class="a-wrapper">
<div ng-include="template.url" id="lft-scroller" class="a-scroller"></div>
</div>
</div>
This is my Menu Control
angular
.module('simApp')
.controller("menuCtrl", function($scope, $element) {
$scope.menuItems = {
left: [
{
name: "Table of Context",
url: "static/partials/tree.html"
},
{
name: "Index",
url: "static/partials/dictionary.html"
},
{
name: "Exercises",
url: "static/partials/exercises.html"
},
{
name: "Search Results",
url: "static/partials/results.html"
}
],
right: [
{
name: "About Writer's Help",
url: "static/partials/about.html"
},
{
name: "Tags & Tools",
url: "static/partials/tools.html"
},
{
name: "Your Class",
url: "static/partials/class.html"
},
{
name: "Top Ten",
url: "static/partials/top10.html"
}
]
}
$scope.template = $scope.menuItems.left[0];
});
This is my directive
angular
.module('simApp')
.directive("menuRepeaterDirective", function() {
return function(scope, element, attrs){
var self = this;
this.scope = scope;
this.element = element;
var $ele = $(element);
$ele.find("span").fastClick(function(ev){
//angular specific
var index = $(ev.currentTarget).parent().index();
self.scope.template = self.scope.menuItems.left[index];
//end angular specific
....some other Jquery stuff
});
}
});
Try:
self.scope.$apply(function(){ //Use $apply to let angular aware of the changes.
var index = $(ev.currentTarget).parent().index();
self.scope.$parent.template = self.scope.menuItems.left[index]; //accessing self.scope.$parent instead of self.scope
});
DEMO
Explanation why we have to access self.scope.$parent:
self.scope is the scope of the current item generated by ng-repeat while your ng-include is binding to menuCtrl's scope. self.scope.$parent is menuCtrl's scope in this case.

Resources