Onclick of a video should open the popup box using angularjs - angularjs

Onclick of a video should open the popup window.In the popup window the video should be playing and should have an option for closing the popup window,if not needed.
Can anyone please help me out regarding this ...
My html :
<div class="container-fluid" ng-controller="videocontroller">
<div class="panel panel-default">
<div class="panel-heading">
<h3>
<b>Video Segment</b>
</h3>
</div>
<div class="panel-body">
<div ng-show="videoSources.length">
<video width=176 height=99
style="margin-left: 70px; margin-right: 10px;"
ng-repeat="videoSource in videoSources | paginate:pageNum:pageSize track by $index"
controls ng-src="{{videoSource | trustUrl}}">
</video>
<div style="margin-left: 46px;">
<button style="margin-left: 750px" ng-disabled="isFirstPage()"
ng-click="prevPage()">Previous</button>
<button style="margin-left: auto;" ng-disabled="isLastPage()"
ng-click="nextPage()">Next</button>
</div>
</div>
<div ng-hide="videoSources.length">
<a href="#" ng-click='loadVideos()'>Load videos</a>
</div>
</div>
</div>
</div>
My js:
app.controller(
'videocontroller',
function($scope) {
$scope.pageNum = 0;
$scope.pageSize = 3;
$scope.isFirstPage = function() {
return $scope.pageNum === 0;
};
$scope.isLastPage = function() {
return $scope.pageNum >= Math.floor($scope.videoSources.length
/ $scope.pageSize);
};
$scope.prevPage = function() {
$scope.pageNum--;
};
$scope.nextPage = function() {
$scope.pageNum++;
};
$scope.videoSources = [
'http://Video/Digital_Hiring.mp4',
'http://Video/Digital_Hiring.mp4',
'http://Video/Digital_Hiring.mp4',
'http://Video/Digital_Hiring.mp4',
'http://Video/Digital_Hiring.mp4' ];
}).filter("trustUrl", [ '$sce', function($sce) {
return function(recordingUrl) {
return $sce.trustAsResourceUrl(recordingUrl);
};
} ]).filter(
'paginate',
function() {
console.log('creating paginate function', arguments);
return function(inputArray, pageNumber, pageSize) {
console.log('paginating', arguments);
pageNumber = pageNumber || 0;
pageSize = pageSize || 4;
if (!Array.isArray(inputArray))
return inputArray;
return inputArray.slice(pageNumber * pageSize, (pageNumber + 1)
* pageSize);
};
});

Here is a possible solution based on Angular ui-bootstrap modal:
var app = angular.module('app', ['ngAnimate', 'ui.bootstrap']);
app.controller('MainCtrl', function($scope, $log, $uibModal) {
$scope.open = function(size, videoSource) {
$log.info("open", videoSource);
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModal.html',
controller: 'ModalInstanceCtrl',
backdrop: true,
size: size,
resolve: {
videoSource: function() {
return videoSource;
}
}
});
modalInstance.result.then(function(result) {
//
}, function() {
$log.info('Modal dismissed at: ' + new Date());
});
};
$scope.videoClick = function($event, videoSource) {
$log.info("videoClick", videoSource)
$scope.open('lg', videoSource);
};
});
app.controller('ModalInstanceCtrl', function($scope, $uibModalInstance, videoSource, $log) {
$log.info("ModalInstanceCtrl", videoSource);
$scope.id = Math.floor((Math.random() * 100) + 1);
$scope.videoSource = videoSource;
$scope.ok = function() {
$uibModalInstance.close('ok');
};
$scope.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
});
app.controller(
'videocontroller',
function($scope) {
$scope.pageNum = 0;
$scope.pageSize = 3;
$scope.isFirstPage = function() {
return $scope.pageNum === 0;
};
$scope.isLastPage = function() {
return $scope.pageNum >= Math.floor($scope.videoSources.length / $scope.pageSize);
};
$scope.prevPage = function() {
$scope.pageNum--;
};
$scope.nextPage = function() {
$scope.pageNum++;
};
$scope.videoSources = [
'http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4',
'http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4',
'http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4',
'http://Video/Digital_Hiring.mp4',
'http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4'
];
});
app.filter("trustUrl", ['$sce', function($sce) {
return function(recordingUrl) {
return $sce.trustAsResourceUrl(recordingUrl);
};
}]);
app.filter(
'paginate',
function() {
console.log('creating paginate function', arguments);
return function(inputArray, pageNumber, pageSize) {
console.log('paginating', arguments);
pageNumber = pageNumber || 0;
pageSize = pageSize || 4;
if (!Array.isArray(inputArray))
return inputArray;
return inputArray.slice(pageNumber * pageSize, (pageNumber + 1) * pageSize);
};
});
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link data-require="bootstrap-css#3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.8/angular.js" data-semver="1.4.8"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.0.3.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div class="container-fluid" ng-controller="videocontroller">
<div class="panel panel-default">
<div class="panel-heading">
<h3><b>Video Segment</b></h3>
</div>
<div class="panel-body">
<div ng-show="videoSources.length">
<video width=176 height=99 style="margin-left: 70px; margin-right: 10px;"
ng-repeat="videoSource in videoSources | paginate:pageNum:pageSize track by $index" ng-src="{{videoSource | trustUrl}}"
ng-click="videoClick($event, videoSource)">
</video>
<div style="margin-left: 46px;">
<button style="margin-left: 750px" ng-disabled="isFirstPage()" ng-click="prevPage()">Previous</button>
<button style="margin-left: auto;" ng-disabled="isLastPage()" ng-click="nextPage()">Next</button>
</div>
</div>
<div ng-hide="videoSources.length">
<a href="#" ng-click='loadVideos()'>Load videos</a>
</div>
</div>
</div>
</div>
<script type="text/ng-template" id="myModal.html">
<div id="my-modal-{{id}}" click-outside="cancel()">
<div class="modal-header">
<h3 class="modal-title">{{title}}</h3>
</div>
<div class="modal-body">
<div class="media">
<video style="width:100%;height:100%;" controls autoplay ng-src="{{videoSource | trustUrl}}"></video>
</div>
<pre>src = {{videoSource | trustUrl}}</pre>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok()">OK</button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</div>
</div>
</script>
</body>
</html>

When you press at the image the youtube video will popup in a nice way
<a data-video="https://www.youtube.com/embed/GdC7jOuk4g8?autoplay=1" class="video" data-toggle="modal" data-target="#videoModal" ><%= image_tag "WatchNow.jpg",width:"250" %></a>
<div class="modal fade" id="videoModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<iframe width="500" height="445" src="https://www.youtube.com/embed/GdC7jOuk4g8?autoplay=1&mute=1&enablejsapi=1" allow="autoplay">
</iframe>
</div>
</div>
<script type="text/javascript">
$(function() {
$(".video").click(function () {
var theModal = $(this).data("target"),
videoSRC = $(this).attr("data-video"),
videoSRCauto = videoSRC + "";
$(theModal + ' source').attr('src', videoSRCauto);
$(theModal + ' video').load();
$(theModal + ' button.close').click(function () {
$(theModal + ' source').attr('src', videoSRC);
});
});
});</script>

Related

getting error while opening model dialog in angular js

I want to add model dialog in my project.
My html code is like:
<div ng-controller="bodyController">
<!-- This html would live at the path specified in the controller: path/to/your/modal-template.html -->
<button class="btn" ng-click="open()">Open Modal</button>
<div modal="showModal" close="cancel()">
<div class="modal-header">
<h4>Modal Dialog</h4>
</div>
<div class="modal-body">
<p>Example paragraph with some text.</p>
</div>
<div class="modal-footer">
<button class="btn btn-success" ng-click="ok()">Okay</button>
<button class="btn" ng-click="cancel()">Cancel</button>
</div>
</div>
</div>
And My app.js is like this:
var app = angular.module("MyApp", ["ui.bootstrap.modal"]);
app.controller("bodyController", function($scope) {
$scope.open = function() {
$scope.showModal = true;
};
$scope.ok = function() {
$scope.showModal = false;
};
$scope.cancel = function() {
$scope.showModal = false;
};
});
I have added angular UI Bootstrap JS in my index.html file.Still I am not getting model dialog. I am getting an error which i am getting.
My error is like:
Can anyone suggest me how to do resolve this error.
This is an example for bootstrap modal. I think the way you are trying to do where you are not using bootstrap classes
There are quite a few issues in your code, so better try the sample and develop as you need
<button data-toggle="modal" data-target="#test">CLick</button>
<div class="modal fade" id="test" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
</div>
</div>
</div>
Refer below.. This will help you.
var app = angular.module("MyApp", ["ui.bootstrap"]);
app.controller("bodyController", function($scope,$uibModal) {
$scope.open = function() {
var modalInstance = $uibModal.open({
animation:true,
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
template: `<div modal="showModal" close="cancel()">
<div class="modal-header">
<h4>Modal Dialog</h4>
</div>
<div class="modal-body">
<p>Example paragraph with some text.</p>
</div>
<div class="modal-footer">
<button class="btn btn-success" ng-click="ok()">Okay</button>
<button class="btn" ng-click="cancel()">Cancel</button>
</div>
</div>`,
size: 'sm',
controller:'modalCtrl',
resolve: {
items: function () {
// return $ctrl.items;
}
}
});
modalInstance.result
.then(function (result) {
console.log('okay');
},
function (result) {
console.log('cancel');
});
};
});
app.controller('modalCtrl', function($scope,$uibModalInstance){
$scope.ok = function() {
$uibModalInstance.close();
};
$scope.cancel = function() {
$uibModalInstance.dismiss();
};
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.js"></script>
<body ng-app="MyApp">
<div ng-controller="bodyController">
<!-- This html would live at the path specified in the controller: path/to/your/modal-template.html -->
<button style="margin:20px" class="btn" ng-click="open()">Open Modal</button>
</div>
</body>

how to toggle the bootstrap modal pop-up when we check and uncheck the checkbox using angular js

I am need of showing two different bootstrap modal pop-up's when we check and uncheck the checkbox like if i check the checkbox i need to display first modal pop-up and when i un check the same checkbox then i need to display second modal pop-up.
Here is my sample html:
<!doctype html>
<html ng-app="plunker">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.6.0.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3>I'm a modal!</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
<a ng-click="selected.item = item">{{ item }}</a>
</li>
</ul>
Selected: <b>{{ selected.item }}</b>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
<script type="text/ng-template" id="myModalContent2.html">
<div class="modal-header">
<h3>I'm a modal!</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
<a ng-click="selected.item = item">{{ item }}</a>
</li>
</ul>
Selected: <b>{{ selected.item }}</b>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
<input type="checkbox" class="btn" ng-click="open()">
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>
</body>
</html>
here is my sample controller :
angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
};
var ModalInstanceCtrl = function ($scope, $modalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
I am new to angular js little bit confused with the controllers.
I guess you just have to add a few conditions that change your open() function behaviours depending on checkbox value :
Just add a model to your checkbox so you can know its value
<input type="checkbox" class="btn" ng-model="checkbox" ng-click="open()">
And now you can add a conditions depending on checkbox value
$scope.open = function() {
if ($scope.checkbox == true) {/* open modal 1 */}
else {/* open modal 2 */}
}

AngularJS Modal Form Login

First of all , I m new in angularJS.
And I m using in my first App the following versions :
AngularJs 1.5
Bootstrap 3.3.6
my First AngularJS App is structued like the following :
index.html
----js:app.js
-------controllers:controller.js
-------services:service.js
:angular.js
:angular-route.js
:angular-animate.js
:ui-bootstrap-tpls-1.1.2.min.js
----html:home.html
:header.html
:footer.html
----modal:login.html
:register.html
----css:main.css
in index.html:
**<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<title>my First Angular App</title>
</head>
<body>
<div ng-view class="'slide-animation'"></div>
<script src="js/angular.js"></script>
<script src="js/angular-route.js"></script>
<script src="js/angular-animate.js"></script>
<!-- <script src="js/angular-ui-bootstrap.js"></script> -->
<script src="js/ui-bootstrap-tpls-1.1.2.min.js"></script>
<script src="js/app.js"></script>
<!-- <script src="js/service/services.js"></script> -->
<script src="js/controller/controllers.js"></script>
<link href="css\bootstrap.min.css" rel="stylesheet" media="screen">
<link rel="stylesheet" type="text/css" href="css\mainstyle.css">
</body>
</html>**
app.js :
'use strict';
var app = angular.module('myApp', ['ngRoute','ngAnimate','ui.bootstrap']);
app.config(function($routeProvider){
//console.log($routeProvider);
$routeProvider
.when('/', { templateUrl: 'html/home.html', controller: "HomeCtrl"})
.when('/login', { templateUrl: 'modal/login.html', controller: "LoginCtrl"})
.when('/register', { templateUrl: 'modal/register.html', controller: "RegisterCtrl"})
.otherwise({redirecTo: '/'});
});
controller.js :
'use strict';
app.controller('HomeCtrl', function($scope,$rootScope){
//console.log($scope);
$scope.login=false;
$scope.slogan = "Jump inside AngularJS";
$rootScope.loading=false;
});
app.controller("LoginCtrl", function($scope,$uibModal,$log) {
$scope.open = function (size) {
console.log(size);
var modalInstance = $uibModal.open({
animate: true,
templateUrl: 'html/login.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
});
app.controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, items) {
$scope.ok = function () {
$uibModalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
});
/*app.controller("modalAccountFormController", ['$scope', '$uibModal', '$log',
function ($scope, $uibmodal, $log) {
console.log('LoginCtrl');
//$scope.showForm = function (Type) {
// $scope.message = "Show Form Button Clicked:"+Type;
// console.log($scope.message);
var modalInstance = $uibModal.open({
templateUrl: 'modal4.html',
controller: ModalInstanceCtrl,
scope: $scope,
resolve: {
userForm: function () {
return $scope.userForm;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
//};
}]);*/
var ModalInstanceCtrl = function ($scope, $modalInstance, userForm) {
$scope.form = {}
$scope.submitForm = function () {
if ($scope.form.userForm.$valid) {
console.log('user form is in scope');
$modalInstance.close('closed');
} else {
console.log('userform is not in scope');
}
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
app.controller('RegisterCtrl', function($scope,$rootScope) {
console.log('RegisterCtrl');
});
home.html
<div>
<div id="wrapper">
<div class="container-fluid">
<header ng-include="'header.html'" ></header>
<div id="content">
<div class="row main-top-margin text-center">
<div class="col-md-8 col-md-offset-2 " >
<h1 class="animated flash">my First AngularJS App</h1>
<p>{{slogan}}</p>
</div>
</div>
</div>
<footer ng-include="'footer.html'"></footer>
</div>
</div>
</div>
header.html
<!-- Header -->
<div id="header">
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<img src="img/headlogo.png" class="img-rectangle" alt="Logo" width="150" height="60">
</div>
<div>
<ul class="nav navbar-nav">
<li>Home</li>
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Info<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><span class="glyphicon glyphicon-info-sign"></span> About</li>
<li><span class="glyphicon glyphicon-envelope"></span> Contact</li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a ng-show="login">Hello</a></li>
<li><span class="glyphicon glyphicon-log-out"></span> Logout</li>
<li><span class="glyphicon glyphicon-user"></span> Sign Up</li>
<li><span class="glyphicon glyphicon-log-in"></span> Login</li>
</ul>
</div>
</div>
</nav>
</div>
And login.html
<div>
<modal title="Login form" visible="showModal">
<form role="form">
<div class="form-group">
<label for="email">Email address</label>
<input type="email" class="form-control" id="email" placeholder="Enter email" ng-model="email" />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" id="password" placeholder="Password" ng-model="password"/>
</div>
<button type="button" class="btn btn-default" ng-click="submit()">Submit</button>
</form>
</modal>
</div>
And my problem is : myApp NOT working :-(
And I don't know how to solve or debug it .
Could you please tell first of all on what I have done is it the right way of handling with Angularjs 1.x ?
Second thing , How to solve my issue ?
Thank you .
/Koul

Display Images in AngularJS Modal inside ng-repeat

here is the index.html
<!DOCTYPE html>
<html ng-app="myApp" ng-app lang="en">
<head>
<meta charset="utf-8">
<link href="css/bootstrap.min.css" rel="stylesheet">
<style type="text/css">
ul>li, a{cursor: pointer;}
</style>
<title>get some data from the database</title>
</head>
<body ng-controller="delayController">
<div ng-controller="customersCrtl">
<div class="container">
<br/>
<blockquote><h4 dir="rtl" align="center">test</h4></blockquote>
<br/>
<div dir="rtl" class="row">
<div class="col-md-2">num of items per page:
<select ng-model="entryLimit" class="form-control">
<option>5</option>
<option>10</option>
<option>20</option>
<option>50</option>
<option>100</option>
</select>
</div>
<div class="col-md-3">search:
<input type="text" ng-model="search" ng-change="filter()" placeholder="enter what you are looking for" class="form-control" />
</div>
<div dir="rtl" class="col-md-4">
<h5>showing {{ filtered.length }} out of {{ totalItems}} items</h5>
</div>
</div>
<br/>
<div dir="rtl" align="center" class="alert alert-info" ng-show="loading"><img ng-src="images/131.gif"/><h2>loading details...</h2>
<div ng-controller="customersCrtl" class="container">
<progressbar class="progress-striped active" type="info" animate="true" max="100" value="progressBar.progress"><b>{{progressBar.progress}}%</b></progressbar>
</div>
</div>
<div class="row" dir="rtl">
<div dir="rtl" class="col-md-12" ng-show="filteredItems > 0">
<table align="right" dir="rtl" class="table table-striped table-bordered">
<thead>
<th>item name <a ng-click="sort_by('name');"><i class="glyphicon glyphicon-sort"></i></a></th>
<th>item price <a ng-click="sort_by('price');"><i class="glyphicon glyphicon-sort"></i></a></th>
</thead>
<tbody>
<tr ng-repeat="data in filtered = (list | filter:search | orderBy : predicate :reverse) | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">
<td>{{data.name}}</td>
<td>{{data.price}}
<img src="images/binoculars.png" height="12" width="12"></td>
</tr>
</tbody>
</table>
</div>
<div dir="rtl" class="col-md-12" ng-show="filteredItems == 0">
<div class="col-md-12">
<h4>לא נמצאו מוצרים.</h4>
</div>
</div>
<div class="col-md-12" ng-show="filteredItems > 0">
<div pagination="" page="currentPage" on-select-page="setPage(page)" boundary-links="true" total-items="filteredItems" items-per-page="entryLimit" class="pagination-small" previous-text="דף קודם" next-text="דף הבא"></div>
</div>
</div>
</div>
</div>
<script src="js/angular.min.js"></script>
<script src="js/angular-bootstrap-lightbox.js"></script>
<script src="js/ui-bootstrap-tpls-0.10.0.min.js"></script>
<script src="js/angular-count-to.js"></script>
<script src="app/app.js"></script>
</body>
</html>
This is the app.js
var app = angular.module('myApp', ['ui.bootstrap','countTo']);
app.filter('startFrom', function() {
return function(input, start) {
if(input) {
start = +start; //parse to int
return input.slice(start);
}
return [];
}
});
app.config(['$compileProvider', function($compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|http?|file|data):/);
}]);
app.controller('customersCrtl', function ($scope, $http, $timeout) {
$scope.$emit('LOAD');
$scope.progressBar = { progress : 0 };
$http.get('ajax/getCustomers.php').success(function(data){
$scope.list = data;
$scope.currentPage = 1; //current page
$scope.entryLimit = 50; //max no of items to display in a page
$scope.filteredItems = $scope.list.length; //Initially for no filter
$scope.totalItems = $scope.list.length;
$scope.$emit('UNLOAD');
});
(function progress(){
if($scope.progressBar.progress < 100){
$timeout(function(){
$scope.progressBar.progress += 1;
progress();
},100);
}
})();
$scope.setPage = function(pageNo) {
$scope.currentPage = pageNo;
};
$scope.filter = function() {
$timeout(function() {
$scope.filteredItems = $scope.filtered.length;
}, 10);
};
$scope.sort_by = function(predicate) {
$scope.predicate = predicate;
$scope.reverse = !$scope.reverse;
};
});
app.controller('delayController',['$scope',function($scope){
$scope.$on('LOAD',function(){$scope.loading=true});
$scope.$on('UNLOAD',function(){$scope.loading=false});
}]);
As you can see, at the moment, the image is opened in a new tab/window and it looks a bit off. This is the reason for wanting it to be opened in a modal like window.
You can pass any controller to the bootstrap modal service as so.
Just create your controller and place your image data on its scope.
Then, pass it to the open call of the modal service.
http://plnkr.co/edit/8TfCPs?p=preview
angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log,$sce) {
var parentScope = $scope;
$scope.imgs =[];
$scope.imgs.push($sce.trustAsUrl("http://dummyimage.com/64X64/000/f00"));
$scope.imgs.push($sce.trustAsUrl("http://dummyimage.com/64X64/000/0f0"));
$scope.imgs.push($sce.trustAsUrl("http://dummyimage.com/64X64/000/00f"));
$scope.open = function () {
$modal.open({
templateUrl: 'myModalContent.html',
backdrop: true,
windowClass: 'modal',
controller: function ($scope, $modalInstance) {
$scope.imgs = parentScope.imgs;
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}
});
};
};
Now, as an addendum based on your comments, if you are using image data encoded in base64 you will need to build up the url using $sce.trustAsResourceUrl
https://docs.angularjs.org/api/ng/service/$sce
http://plnkr.co/edit/jRXHL3zSR8rDT1sJJ1tw?p=preview
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.3.16" data-semver="1.3.16" src="https://code.angularjs.org/1.3.16/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="testCtrl">
<img ng-src="{{imgUri}}"/>
<script>
var app = angular.module("app",[]);
app.controller("testCtrl",function($scope,$sce){
var data="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";
$scope.imgUri = $sce.trustAsResourceUrl("data:image/png;base64," + data);
});
angular.bootstrap(document,[app.name]);
</script>
</body>
</html>
You can use ng-src Use:
<img ng-src="data.imagedata" alt="Description"/>

Error: [ng:areq] Argument 'ChatAppCtrl' is not a function, got undefined

Hi I was trying to run this angular based chat app, but it's giving me this error. Kindly please help me fix this.
the code is already available on
https://github.com/tamaspiros/AngularChat
the error i am getting is
Error: [ng:areq] Argument 'ChatAppCtrl' is not a function, got undefined
http://errors.angularjs.org/1.3.9/ng/areq?p0=ChatAppCtrl&p1=not%20a%20function%2C%20got%20undefined
at REGEX_STRING_REGEXP (angular.js:63)
at assertArg (angular.js:1577)
at assertArgFn (angular.js:1587)
at angular.js:8418
at angular.js:7592
at forEach (angular.js:331)
at nodeLinkFn (angular.js:7579)
at compositeLinkFn (angular.js:7075)
at compositeLinkFn (angular.js:7078)
at publicLinkFn (angular.js:6954)
the index.html is
<!DOCTYPE html>
<html ng-app="chat">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="css/app.css">
<link rel="stylesheet" href="css/bootstrap.yeti.css">
<link rel="stylesheet" href="css/flags.css">
<link rel="stylesheet" href="components/font-awesome/css/font-awesome.css">
</head>
<body ng-controller="ChatAppCtrl" ng-cloak>
<!-- Fixed navbar -->
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#" ng-click="about()">AngularChat</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li>About</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><p class="navbar-text online" ng-if='status === "online"'>{{ status }}</p><p class="navbar-text offline" ng-if='status === "offline"'>{{ status }}</p></li>
<li class="dropdown" ng-show="joined">
{{ peopleCount }} online <b class="caret" ng-if="peopleCount > 0"></b>
<ul class="dropdown-menu">
<li ng-repeat="user in users"><p class="white">{{ user.name }} <span ng-if="user.countrycode"><img class="flag flag-{{user.countrycode}}"></span> <i class="fa fa-{{user.device}}"></i></p></li>
</ul>
</li>
<li class="dropdown" ng-show="joined">
{{ roomCount }} room<span ng-if="roomCount === 0 || roomCount > 1">s</span> <b class="caret" ng-if="roomCount > 0"></b>
<ul class="dropdown-menu">
<li ng-repeat="room in rooms">
<form class="form-inline" role="form"><div class="form-group"><p class="white">{{ room.name }}</p></div><button class="btn btn-success btn-xs" type="submit" ng-click='joinRoom(room)' ng-hide='room.id === user.owns || room.id === user.inroom || user.owns || user.inroom'>Join</button>
<button type="submit" ng-click='deleteRoom(room)' class="btn btn-xs btn-danger" ng-show='room.id === user.owns'>Delete</button>
<button type="submit" ng-click="leaveRoom(room)" class="btn btn-xs btn-info" ng-hide='room.id === user.owns || !user.inroom || user.owns || user.inroom !== room.id'>Leave</button></form>
</li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
<!-- Begin page content -->
<div class="container" ng-show="!joined">
<form class="form-inline" role="form">
<div class="form-group">
<label class="sr-only" for="username">Name: </label>
<input type="text" class="form-control" name="username" id="username" ng-model="username" placeholder="Enter desired name">
</div>
<button type="submit" class="btn btn-default btn-sm" ng-click='joinServer()'>Enter chat</button>
</form>
<small ng-if="error" class="text-danger">{{ error.join }}</small> <small ng-if="suggestedUsername" class="text-info" ng-click="setUsername(suggestedUsername)">How about <span class="text-success" style="cursor: pointer;">{{ suggestedUsername }}</a>?</small>
</div>
<div ng-hide="!joined" class="container" >
<p >Hello {{ user.name }}. <span ng-if="user.owns">You own a room: <strong>{{ user.roomname }}</strong>.</span> <span ng-if="!user.owns && user.inroom">You have joined a room: <strong>{{ user.roomname }}</strong>.<br> You can create your own room as well (but you need to leave the current one first)
</span><br>
<small ng-if="user.owns">You can remove your room by clicking delete in drop-down menu in the top right corner.</small></p>
<p ng-show="!user.inroom">Create a chat room or join one (top right corner).
<div id="createroom">
<form class="form-inline" role="form" ng-hide="user.owns && user.inroom">
<div class="form-group">
<label class="sr-only" for="roomname">Room name: </label>
<input type="text" placeholder="Enter room name" class="form-control" ng-model="roomname" name="roomname" id="roomname">
</div>
<button type="submit" class="btn btn-default btn-sm" ng-click="createRoom()">Create room</button>
<small ng-if="error" class="text-danger">{{ error.create }}</small>
</form>
</div>
<div id="chatpanel" ng-show="user.inroom" >
<div id="chat">
<form class="form-inline" role="form" ng-show="user.owns || user.inroom">
<div class="form-group">
<label class="sr-only" for="message">Message: </label>
<input type="text" placeholder="Enter message" class="form-control" ng-model="message" name="message" id="message" ng-keypress="typing($event, user.inroom)" on-focus="focus(true)" on-blur="focus(false)">
</div>
<button type="submit" class="btn btn-default btn-sm" ng-click='send()'>Send message</button>
</form>
<small ng-if="error" class="text-danger">{{ error.send }}</small>
</div>
<div class="row">
<div class="col-lg-6">
<div id="messages">
<ul>
<li class="list-unstyled" ng-repeat="message in messages track by $index" autoscroll ng-class="{dark: $index % 2 === 0}"><strong>{{ message.name }}</strong>: {{ message.message }}</li>
</ul>
</div>
</div>
<div class="col-lg-6">
<div id="sidebar">
<ul ng-if="isTyping">
<li ng-repeat="person in typingPeople track by $index" class="text-muted list-unstyled"><small>{{ person }} is typing</small></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div class="container">
<p class="text-muted">AngularChat by Tamas Piros | http://tamas.io/ | <a href="https://twitter.com/tpiros" target="_blank">#tpiros</p>
</div>
</div>
<!-- about modal -->
<script type="text/ng-template" id="aboutModal" />
<div class="modal-header">
<h3>About AngularChat</h3>
</div>
<div class="modal-body">
<p>Hello and thanks for visiting AngularChat.</p>
<p>This is an experimental project for testing new JavaScript technologies.</p>
<p>First, please enter your username. Once you've done this you have two options. You can create a room or you can join an already existing one.</p>
<p>Please note that once you've joined a room you can't create one (basically you can be part of one room at one time). Also note that if you're a room owner and you disconnect from the server, delete or leave your room all other participants will be removed from the room as well.</p>
<p>If you'd like to read more about the project please check out this article: http://tamas.io/angularchat/</p>
<p>If you're interested in the code behind this project, please go to: https://github.com/tamaspiros/angularchat</p>
</div>
<div class="modal-footer">
<button class="btn btn-warning btn-sm cancel" ng-click="cancel()">Cancel</button>
</div>
</div>
</script>
<script src="/socket.io/socket.io.js"></script>
<script src="components/angular/angular.js"></script>
<script src="components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="components/jquery/dist/jquery.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/directives.js"></script>
<script src="js/services.js"></script>
</body>
</html>
and the function ChatAppCtrl is
'use strict';
function ChatAppCtrl($scope, $q, $modal, socket, useragent, geolocation) {
$scope.peopleCount = 0;
$scope.messages = [];
$scope.user = {}; //holds information about the current user
$scope.users = {}; //holds information about ALL users
$scope.rooms = []; //holds information about all rooms
$scope.error = {};
$scope.typingPeople = [];
$scope.username = '';
$scope.joined = false;
var typing = false;
var timeout = undefined;
/* ABOUT PAGE */
$scope.about = function() {
var modalInstance = $modal.open({
templateUrl: 'aboutModal',
controller: aboutModalCtrl
});
};
var aboutModalCtrl = function($scope, $modalInstance) {
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
};
/* ABOUT PAGE END */
$scope.setUsername = function(suggestedUsername) {
$scope.username = suggestedUsername;
}
function timeoutFunction() {
typing = false;
socket.emit('typing', false);
}
$scope.focus = function(bool) {
$scope.focussed = bool;
}
$scope.typing = function(event, room) {
if (event.which !== 13) {
if (typing === false && $scope.focussed && room !== null) {
typing = true;
socket.emit('typing', true);
} else {
clearTimeout(timeout);
timeout = setTimeout(timeoutFunction, 1000);
}
}
}
socket.on('isTyping', function(data) {
if (data.isTyping) {
$scope.isTyping = data.isTyping;
$scope.typingPeople.push(data.person);
} else {
$scope.isTyping = data.isTyping;
var index = $scope.typingPeople.indexOf(data.person);
$scope.typingPeople.splice(index, 1);
$scope.typingMessage = '';
}
});
$scope.joinServer = function() {
$scope.user.name = this.username;
if ($scope.user.name.length === 0) {
$scope.error.join ='Please enter a username';
} else {
var usernameExists = false;
socket.emit('checkUniqueUsername', $scope.user.name, function(data) {
usernameExists = data.result;
if (usernameExists) {
$scope.error.join = 'Username ' + $scope.user.name + ' already exists.';
socket.emit('suggest', $scope.user.name, function(data) {
$scope.suggestedUsername = data.suggestedUsername;
});
} else {
socket.emit('joinSocketServer', {name: $scope.user.name});
$scope.joined = true;
$scope.error.join = '';
}
});
}
}
$scope.send = function() {
if (typeof this.message === 'undefined' || (typeof this.message === 'string' && this.message.length === 0)) {
$scope.error.send = 'Please enter a message';
} else {
socket.emit('send', {
name: this.username,
message: this.message
});
$scope.message = '';
$scope.error.send = '';
}
}
$scope.createRoom = function() {
var roomExists = false;
var room = this.roomname;
if (typeof room === 'undefined' || (typeof room === 'string' && room.length === 0)) {
$scope.error.create = 'Please enter a room name';
} else {
socket.emit('checkUniqueRoomName', room, function(data) {
roomExists = data.result;
if (roomExists) {
$scope.error.create = 'Room ' + room + ' already exists.';
} else {
socket.emit('createRoom', room);
$scope.error.create = '';
if (!$scope.user.inroom) {
$scope.messages = [];
$scope.roomname = '';
}
}
});
}
}
$scope.joinRoom = function(room) {
$scope.messages = [];
$scope.error.create = '';
$scope.message = '';
socket.emit('joinRoom', room.id);
}
$scope.leaveRoom = function(room) {
$scope.message = '';
socket.emit('leaveRoom', room.id);
}
$scope.deleteRoom = function(room) {
$scope.message = '';
socket.emit('deleteRoom', room.id)
}
socket.on('sendUserDetail', function(data) {
$scope.user = data;
});
socket.on('listAvailableChatRooms', function(data) {
$scope.rooms.length = 0;
angular.forEach(data, function(room, key) {
$scope.rooms.push({name: room.name, id: room.id});
});
});
socket.on('sendChatMessage', function(message) {
$scope.messages.push(message);
});
socket.on('sendChatMessageHistory', function(data) {
angular.forEach(data, function(messages, key) {
$scope.messages.push(messages);
});
});
socket.on('connectingToSocketServer', function(data) {
$scope.status = data.status;
});
socket.on('usernameExists', function(data) {
$scope.error.join = data.data;
});
socket.on('updateUserDetail', function(data) {
$scope.users = data;
});
socket.on('joinedSuccessfully', function() {
var payload = {
countrycode: '',
device: ''
};
geolocation.getLocation().then(function(position) {
return geolocation.getCountryCode(position);
}).then(function(countryCode) {
payload.countrycode = countryCode;
return useragent.getUserAgent();
}).then(function(ua) {
return useragent.getIcon(ua);
}).then(function(device) {
payload.device = device;
socket.emit('userDetails', payload);
});
});
socket.on('updatePeopleCount', function(data) {
$scope.peopleCount = data.count;
});
socket.on('updateRoomsCount', function(data) {
$scope.roomCount = data.count;
});
socket.on('disconnect', function(){
$scope.status = 'offline';
$scope.users = 0;
$scope.peopleCount = 0;
});
}
Recent versions of Angular do not allow global functions to be used as controllers, see docs under "Arguments". The solutions:
(preferred) Use angular.module('chat').controller('ChatAppCtrl', ChatAppCtrl);
Configure the $controllerProvider: In a coonfig block, inject the $controllerProvider and run: $controllerProvider.allowGlobals().

Resources