Angular Modal triggering an ng-hide/ng-show - angularjs

I'm building out a modal that takes 10 lines of input and when clicked to close randomizes them and "should" display out side the modal. Through other research I have found that I must use a service to make everything work right. However this service is not properly changing over my var for changing over true/false for my ng-hide.
Some code below
Main HTML
<body ng-controller="ModalDemoCtrl">
<my-modal-content></my-modal-content>
<button class="btn btn-small"
ng click="open(lg,'ModalInstanceCtrl')">Add</button>
<ul ng-controller="MainCtrl" >
<button class="btn" ng-click="test()">Test</button>
<li ng-hide="toggle" ng-repeat="random in randomTeams">{{random.team}}</li>
</ul>
<script src="js/vendor/angular.js"></script>
<script src="js/vendor/angular-animate.js"></script>
<script src="js/vendor/angular-ui.js"></script>
<script src="app.js"></script>
<script src="js/Modal.js"></script>
<script src="js/setTeams.js"></script>
<script src="js/randomizeTeamservice.js"></script>
</body>
My-modal-content
<div class="modal-header">
<h3 class="modal-title">Set Team Names</h3>
</div>
<div class="modal-body" ng-controller="MainCtrl">
<div class="input-append" ng-repeat="team in teams | limitTo: 10">
<input class="form-control" type="text" ng-model="team.team"
placeholder="Team {{$index + 1}}" value="{{$index}}">
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok();
add(this)">OK</button>
<button class="btn btn-warning" type="button" ng-
click="cancel()">Cancel</button>
</div>
</div>
Modal Controller
app.controller('ModalDemoCtrl', function ($scope, $uibModal) {
$scope.animationsEnabled = true;
$scope.open = function (size,controller) {
$uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: controller ,
size: size,
});
};
});
// Please note that $uibModalInstance represents a modal window (instance)
dependency.
// It is not the same as the $uibModal service used above.
app.controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, randomService) {
$scope.toggle = randomService.showTeams();
$scope.ok = function () {
$uibModalInstance.close({
}
);
$scope.toggle = false;
console.log($scope.toggle);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
});
Finally the Service
app.factory("randomService", function(){
var teams = [{},{},{},{},{},{},{},{},{},{}];
var randomTeams = teams.slice(0);
var showTeams = true;
return{
randomTeams: function(){
return randomTeams;
},
teams: function(){
return teams;
},
showTeams: function(){
return showTeams;
}
}
});
So why won't the ng-hide work?

Problem solved. Moved some things around but here it is.
Moved the randomize function to the controller and added a getter so a function will retrieve the toggle (true/false) value.
app.controller('MainCtrl', function($scope, randomService) {
$scope.teams = randomService.teams();
$scope.randomTeams = randomService.randomTeams();
$scope.toggle = function(){
return randomService.getTeams();
}
$scope.add = function(team, show) {
for( var i = 0; i < 10; i++){
$scope.teams.splice(i, 1, team.teams[i]);
}
randomService.shuffle($scope.randomTeams);
$scope.toggle();
};
});
In the service factory in addition to adding the shuffle function and a getter function. I added a line of code that will change the showTeams from true to false.
app.factory("randomService", function(){
var teams = [{},{},{},{},{},{},{},{},{},{}];
var randomTeams = teams.slice(0);
var showTeams = true;
return{
randomTeams: function(){
return randomTeams;
},
teams: function(){
return teams;
},
shuffle: function shuffle(array) {
showTeams = false;
var currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
},
getTeams: function(){
return showTeams;
},
}
});
lastly ng-hide="toggle: changed to ng-hide="toggle()"

Related

How could we chain $uibModal dialogs?

I am complete beginner in AngularJS. Now I want to create the chains of dialogs using ui.bootstrap $uibModal service. I want to receive the data to the dialogs from the .txt file. That means, I won't know initially the quantity of dialogs in the chain, it will depend on the .txt data. For now I tried to do that with the loop, but it`s dumb and then I won't be able to have such functional as "previous", "next", ok and cancel. Is there any wise solution to do that? Thank you in advance for the answer.
var app = angular.module('myApp', ['ui.bootstrap']);
angular.module('myApp').config(['$uibModalProvider', function($uibModalProvider) {
$uibModalProvider.options.windowClass = 'show';
$uibModalProvider.options.backdropClass = 'show';
}]);
app.factory('modalDialog', function($uibModal) {
var arr_items = [];
var showModalDialog =function(items) {
return $uibModal.open({
templateUrl: 'test.html', //just the dialog body for the info
animation: true,
size: 'sm',
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
controller: 'dialogCtrl',
controllerAs: "$ctrl",
resolve: { items: function () { console.log("items before travelling" + JSON.stringify(items));
return items; } }
});
}
return {showModalDialog: showModalDialog};
});
app.controller('TestCtrl', function($scope, $http, modalDialog){
$scope.cancelled = false;
$scope.test = function(){
$http.get('test.txt')
.then(function(response) {
$scope.items=response.data;
for (var i=0; i<$scope.items.length; i++) {
console.log($scope.cancelled);
if ($scope.cancelled) return ;
var showModalDialog = function() {
console.log("here");
modalDialog.items = $scope.items[i];
modalDialog.showModalDialog($scope.items[i]);
};
showModalDialog();
};
});
};
});
app.controller('dialogCtrl', function ($scope, $uibModalInstance, items) {
var $ctrl =this;
console.log("here are my items" + items.request + " " + JSON.stringify(items));
$scope.items = items;
$ctrl.ok = function () {
$uibModalInstance.close($scope.items);
};
$ctrl.cancel = function () {
console.log("cancel");
$scope.cancelled = true;
return $uibModalInstance .dismiss('cancel');
};
});
<!doctype html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.js"></script>
<script src="ui-bootstrap-tpls-2.5.0.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="TestCtrl">
<button class="btn btn-primary" ng-click="test()">Test</button>
</div>
<script type="text/ng-template" id="test.html">
<div><div class="modal-header">
<h1 class="modal-title">Test Modal</h1>
</div>
<div class="modal-body">
Test Data:
<div>{{items}}</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="$ctrl.ok()">OK</button>
<button class="btn btn-primary" type="button" ng-click="$ctrl.cancel()">Cancel</button>
</div>
</div>
</script>
<script src="script.js"></script>
</body>
</html>
Here is my test.txt file:
[{
"request": "new user",
"dialogs": [
["input", "checkbox"],
["input", "radiobutton"],
["input", "input"]
]
},
{
"request": "new project",
"dialogs": [
["input", "input"],
["radiobutton", "radiobutton"],
["input", "input"]
]
},
{
"request": "delete project",
"dialogs": [
["checkbox", "checkbox"],
["input", "radiobutton"],
["input", "input"]
]
}
]
Here you go ! Check this plunkr.
The main logic for loop resides in
function initiateModal(itemList,index){
modalDialog.showModalDialog(itemList[index]).result
.then(function(resp){
if(resp === 'cancel'){ // if user cancel the process in between
$scope.userSeletion.length = 0;
return ;
}else if(itemList.length === (index+1)){ // for pushing the last modal data into array
$scope.userSeletion.push(resp);
return ;
}else{
$scope.userSeletion.push(resp);
index++;
initiateModal (itemList,index);
}
})
}
which waits for the promise of earlier modal to open the next one.
For now, I am passing userInput as a data, which i can fill depending on the user form input

Ng-Click not working on mobile devices. How to change to ngTouch

I have a website which uses angular.js. The ng-click is working fine on laptop/desktop but not on mobile devices. From my research, I learned that i need to use ngTouch and I undertand that. My problem is that I am not a programmer and does not know how to do it.
I am hoping that there is someone who can help me or provide me with the right step or code. this is my code:
<div class="container" ng-controller="MessageBoardCtrl">
<div class="span6">
<div class="row-fluid item" ng-repeat="item in items" ui-animate>
<div class="span2"><img src="../images/post.png" width="48px" height="48px"/></div>
<div class=" well well-small">
<p>{{item.message}}</p>
</div>
</div>
</div>
<div class="span6">
<div class='well'>
<button class="btn btn-primary" ng-click="sendMessage()">Share</button>
Here is the javascript:
<script src="../templates/js/jquery.js"></script>
<script src="../templates/js/angular.js"></script>
<script src="../templates/js/angular-ui.js"></script>
<script src="../templates/js/angular-touch.js"></script>
<script src="../templates/js/angular-touch.min.js"></script>
<script>
function MessageBoardCtrl($scope, $http, $timeout) {
$scope.items = [];
$scope.message = '';
$scope.email = '';
$scope.lastTime = 0;
$scope.refreshMessages = function() {
$http.get('../templates/faucet.php/messages?time=' + $scope.lastTime).success(function(data) {
for(id in data) {
item = data[id];
$scope.items.unshift(item);
if($scope.lastTime<item.time)
$scope.lastTime = item.time;
}
});
}
$scope.sendMessage = function() {
if(!$scope.message)
return;
$http.post('../templates/faucet.php/add_message', {message: $scope.message, email: $scope.email}).success(function() {
$scope.message = '';
});
}
$scope.periodicRefresh = function() {
$scope.refreshMessages();
$timeout($scope.periodicRefresh, 5000, true);
}
$scope.refreshMessages();
}
</script>
Can someone give me a clean code based on the above that will work for ngtouch and instruction as well. Thanks in advance.
You can write your own directive for touch event. Below is an example directive to handle touch events. The directive below only fire the event in case of touch/long touch. scope.isMoved will prevent firing event when user tap on screen and move they finger around.
function directive($timeout) {
var dir = {
link: link,
restrict: 'A',
scope: {
onTouch: '&'
}
};
return dir;
function link(scope, element) {
scope.isMoved = false;
$timeout(function () {
// user start tap on screen
element.bind('touchstart', function () {
scope.isMoved = false;
});
element.bind('touchend click', function (evt) {
if (!scope.isMoved) {
scope.onTouch(evt);
}
});
//
element.bind('touchmove', function () {
scope.isMoved = true;
});
});
}
}
In HTML:
<a on-touch="someFunction()"> Touch</a>

Unable to get the scope data to the html page using factory in angularjs

I'm able to send the same json data from home.js to content.js.But I'm unable to populate the content.js scope data into the html page
Can anyone please help me out regarding this issue ...
My home.js:
angular.module('myApp')
.controller('firstCtrl', ['$scope', 'myService',
function ($scope,myService) {
$scope.list1= [];
$scope.list2= [];
var sampleItem = this.item;
myService.setJson(sampleItem);
$.each($scope.samples, function (i, x) {
if (x.name === sampleItem .secName && x.id === sampleItem .id) {
if (sampleItem .secName === $scope.secsList[0]) {
$scope.list1.push(x);
}
else {
$scope.list2.push(x);
}
$scope.myData = x.dataList;
}
});
});
My content.js :
angular.module('myApp')
.controller('secondCtrl', function ($scope,myService) {
$scope.myreturnedData = myService.getJson();
console.log($scope.myreturnedData);
})
.factory('myService', function(){
var sampleItem = null;
return {
getJson:function(){
return sampleItem;
},
setJson:function(value){
sampleItem = value;
}
}
});
My content.html :
<div ng-controller="secondCtrl" > {{myreturnedData.sampleName}}</div>
My home.html:
<div ng-controller="firstCtrl" ng-repeat="item in list1" >
<div > {{item.sampleName}} </div>
</div>
This is work solution jsfiddle
angular.module('ExampleApp',[])
.controller('firstCtrl', function($scope, myService) {
$scope.sampleItem = {
sampleName: "sampleName"
};
myService.setJson($scope.sampleItem);
}
)
.controller('secondCtrl', function($scope, myService) {
$scope.myreturnedData = myService.getJson();
console.log($scope.myreturnedData);
})
.factory('myService', function() {
var sampleItem = null;
return {
getJson: function() {
return sampleItem;
},
setJson: function(value) {
sampleItem = value;
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="firstCtrl">
<h2>
firstCtrl
</h2>
<input ng-model="sampleItem.sampleName">
</div>
<div ng-controller="secondCtrl"> <h2>
secondCtrl
</h2>{{myreturnedData.sampleName}}</div>
</div>

why the ng-class not changed?

Examples of the problem:
http://jsfiddle.net/paloalto/DTXC2/
HTML:
<div ng-app="app">
<div id="wrapper" ng-controller="AppController" ng-class="showChatPanel">
<div id="tabBar" class="ui vertical icon menu inverted" ng-controller="TabBarController">
<a class="item switchChatBtn" data-tab="showChatWraper">Open Chat Panel</a>
</div>
<div id="chatWraper" class="ui segment">Chat Panel Opend!!</div>
</div>
</div>
Javascript:
angular.module('app', ['app.controllers']);
var controllers = angular.module('app.controllers', []);
controllers.controller('AppController', function AppController($scope, $log, $http) {
$scope.showChatPanel = '';
$scope.$on("switchChatPanel", function (event, msg) {
console.log(msg);
$scope.showChatPanel = msg;
console.log($scope.showChatPanel);
// $scope.$broadcast("switchChatPanel-done", msg);
});
$scope.$watch('showChatPanel', function(newVal, oldVal) {
if(newVal){
console.log('yeah! It is a newVal !!!');
} else {
console.log('still oldVal ');
}
});
});
controllers.controller('TabBarController', function TabBarController($scope, $log, $http) {
var tabBarItem =$('#tabBar > .item');
tabBarItem.click(function(){
var tabClass = $(this).data('tab');
console.log(tabClass);
$scope.$emit("switchChatPanel", tabClass);
});
});
CSS:
#chatWraper {
display:none;
}
.showChatWraper #chatWraper{
display:block;
}
=====
I finally solved it using jQuery, but I still wonder why angular not success.
controllers.controller('TabBarController',function TabBarController ($scope,$log,$http) {
var tabBarItem =$('#tabBar > .item');
var chatPanelOpen = false;
tabBarItem.click(function(){
var tabClass = $(this).data('tab');
if(!chatPanelOpen){
$('#wrapper').addClass(tabClass);
chatPanelOpen = true;
} else{
$('#wrapper').removeClass(tabClass);
chatPanelOpen = false;
}
})
})
https://gist.github.com/naoyeye/7695067
========
UPDATE
http://jsfiddle.net/paloalto/DTXC2/17/
You shouldn't be doing DOM manipulation like that in the controller. The correct way to do this is like this
<div ng-controller="TabBarController">
<div ng-click="toggleChatPanel()" ng-class="{tabClass: isChatPanelOpen}">
</div>
controllers.controller('TabBarController', function ($scope) {
$scope.isChatPanelOpen = false;
$scope.toggleChatPanel = function () {
$scope.isChatPanelOpen = !$scope.isChatPanelOpen;
};
});

Accessing a service or controller in my link function - Angular.js

I have a directive, but I am having a problem access the controller and my service that is injected into it. Here is my directive:
angular.module('clinicalApp').directive('chatContainer', ['encounterService', function(encounterService) {
return {
scope: {
encounter: '=',
count: '='
},
templateUrl: 'views/chat.container.html',
controller: 'EncounterCtrl',
link: function(scope, elem, attrs, controller) {
scope.addMessage = function(message) {
//RIGHT HERE
scope.resetChat();
};
scope.resetChat = function() {
scope.chatText = '';
scope.updateCount(scope.chatText);
};
}
};
}]);
You can see that I am attaching a couple of functions to my scope inside the link function. Inside those methods, like addMessage, I don't have access to my controller or the service that is injected into the directive. How do I acceess the controller or service?
UPDATE
Here is the service:
angular.module('clinicalApp').factory('encounterService', function ($resource, $rootScope) {
var EncounterService = $resource('http://localhost:port/v2/encounters/:encounterId', {encounterId:'#id', port: ':8280'}, {
search: {
method: 'GET'
}
});
var newEncounters = [];
var filterTerms = {};
EncounterService.pushNewEncounter = function(encounter) {
newEncounters.push(encounter);
$rootScope.$broadcast('newEncountersUpdated');
};
EncounterService.getNewEncounters = function() {
return newEncounters;
}
EncounterService.clearNewEncounters = function() {
newEncounters = [];
}
EncounterService.setFilterTerms = function(filterTermsObj) {
filterTerms = filterTermsObj;
$rootScope.$broadcast('filterTermsUpdated');
EncounterService.getFilterTerms(); //filter terms coming in here, must redo the search with them
}
EncounterService.getFilterTerms = function() {
return filterTerms;
}
return EncounterService;
});
and the chat.container.html
<div class="span4 chat-container">
<h5 class="chat-header">
<span class="patient-name-container">{{encounter.patient.firstName }} {{encounter.patient.lastName}}</span>
</h5>
<div class="chat-body">
<div class="message-post-container">
<form accept-charset="UTF-8" action="#" method="POST">
<div class="text-area-container">
<textarea id="chatBox" ng-model="chatText" ng-keyup="updateCount(chatText)" class="chat-box" rows="2"></textarea>
</div>
<div class="counter-container pull-right">
<span class="muted" id="counter">{{count}}</span>
</div>
<div class="button-container btn-group btn-group-chat">
<input id="comment" class="btn btn-primary btn-small btn-comment disabled" value="Comment" ng-click="addMessage(chatText)"/>
</div>
</form>
<div messages-container messages="encounter.comments">
</div>
</div>
</div>
</div>
Here is Demo Plunker I played with.
I removed scope{....} from directive and added 2 values in controller and directive to see how they change regards to action.
JS
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
// listen on any change of chatText in directive
$scope.$watch(function () {return $scope.chatText;},
function (newValue, oldValue) {
if (newValue == oldValue) {return;}
$scope.chatTextFromController = newValue;
}, true);
});
app.directive('chatContainer', ['encounterService', function(encounterService) {
return {
templateUrl: 'chat.container.html',
link: function(scope, elem, attrs) {
scope.countStart = scope.count;
scope.updateCount = function(chatText) {
alert('updateCount');
scope.count = scope.countStart - chatText.length;
};
scope.addMessage = function(message) {
alert('addMessage');
encounterService.sayhello(message);
scope.resetChat();
};
scope.resetChat = function() {
alert('resetChat');
scope.chatText = 'someone reset me';
scope.name = "Hello " + scope.name;
scope.updateCount(scope.chatText);
};
}
};
}]);
app.service('encounterService', function() {
var EncounterService = {};
EncounterService.sayhello = function(message) {
alert("from Service " + message);
};
return EncounterService;
});
HTML
<body ng-controller="MainCtrl">
<div chat-container></div>
<pre>chatText from directive: {{chatText|json}}</pre>
<pre>chatText from controller: {{chatTextFromController|json}}</pre>
<pre>name: {{name|json}}</pre>
</body>

Resources