Angularjs ui bootstrap modal sharing information to same controller - javascript

I have the following modal set up in my cloud controller. I'm not giving this modal a specific controller to work off of because the goal is to share it with my cloud controller.
I don't tell the modal that it should be using the cloud controller because then the controller will get run twice, and I do not want this to happen.
.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('cloud', {
url: '/cloud',
controller: 'cloud',
templateUrl: 'pages/templates/cloud.html'
})
})
.controller('cloud', function($scope, $rootScope, $http, $state, $stateParams, $modal) {
$scope.toggleModal = function () {
$scope.renameModal = $modal.open({
animation: true,
templateUrl: 'pages/templates/modal.html',
size: "md",
scope: $scope
});
}
$scope.submit = function(data) {
console.log($scope.inputData, data);
}
})
The issue I am trying to solve is with an input box in my modal template. I am trying to submit the text, have it be shared, and hopefully updated to one of my $scope variables inside the cloud controller.
Below you can see my modal.html where on submit, it runs the submit() function in my cloud controller. It run's successfully but the console log returns undefined for both $scope.inputData and data.
<div class="modal-header">
<h3 class="modal-title">title</h3>
</div>
<div class="modal-body">
<input type="text" id="rename_item" ng-modal="inputData" value="" />
</div>
<div class="modal-footer">
<button class="btn_submit fade" ng-click="submit(inputData)">Rename</button>
</div>
Could anyone help me figure out what I am doing wrong or how I can get this data over to my current cloud controller?

A BIG shoutout to camden_kid for catching my mistake of misspelling ng-model. I accidentally did ng-modal.
Just correcting that spelling didn't fix it though.
I don't know why (maybe someone can help explain), but I had to use an object that was already created to get this to work. Just using a variable that was pre-defined didn't work.
So this is my change in my cloud controller:
.controller('cloud', function($scope, $rootScope, $http, $state, $stateParams, $modal) {
$scope.toggleModal = function () {
$scope.renameModal = $modal.open({
animation: true,
templateUrl: 'pages/templates/modal.html',
size: "md",
scope: $scope
});
}
$scope.inputText = {data: ""};
$scope.submit = function(data) {
console.log($scope.inputText.data);
}
})
And then I did the following to my html:
<input type="text" ng-modal="inputText.data" />

Related

Unable to fix Argument Controller is not a function, got undefined

Hi This is my first angularjs app and i am facing problem in injecting controller. I have one page called index.html and described as below.
<body ng-app="RoslpApp">
<div ng-controller="RoslpAppController">
<div class="popup">
<label>Language</label>
<select ng-model="selectedItem">
<option>العربية</option>
<option>English</option>
</select>
<button ng-click="clickHandler(selectedItem)">Submit</button>
</div>
</div>
</body>
This is my js file.
var app = angular.module('RoslpApp', ['pascalprecht.translate', 'ui.router']);
app.config(function ($stateProvider, $urlRouterProvider, $urlRouterProvider, $translateProvider, $translatePartialLoaderProvider) {
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state('Registration', {
url: '/Registration',
templateUrl: 'Registration/Registration.html'
});
$translatePartialLoaderProvider.addPart('Main');
$translateProvider.useLoader('$translatePartialLoader', {
urlTemplate: "Scripts/Locales/{part}/{lang}.json"
});
$translateProvider.preferredLanguage('en_US');
app.run(function ($rootScope, $translate) {
$rootScope.$on('$translatePartialLoaderStructureChanged', function () {
$translate.refresh();
});
});
app.controller('RoslpAppController', ['$scope', '$translate', function ($scope, $translate) {
$scope.clickHandler = function (key) {
$translate.use(key);
};
}]);
});
Whenever i select langualge from the dropdown and click on submit i get Argument RoslpAppController is not a function, got undefined error. May i get some help to fix this error?
Any help would be appreciated. Thank you.
Move the controller outside the app.config.
app.controller('RoslpAppController', ['$scope', '$translate', function ($scope, $translate) {
$scope.clickHandler = function (key) {
$translate.use(key);
};
}]);

Angular ui-router runs controller twice on load if it is specified in the $stateProvider

I am seeing that code in my controller is being ran twice , thus showing in the console.log windows output in chrome dev tools
questions.html
<div ng-controller="questionController as vm"> </div>
questionController.js
var questionController = function($location, questionService, $env) {
var vm = this;
console.log('in the controller') // this runs twice
}
app.js
app.config([
'$stateProvider',
'$urlRouterProvider',
'$locationProvider',
function ($stateProvider, $urlRouterProvider, $locationProvider) {
var viewBase = '/apps/src/views/';
$urlRouterProvider.otherwise("/");
$locationProvider.hashPrefix(''); // get rid of ! was getting #!
$stateProvider
.state('questions',
{
url: "/questions",
templateUrl: viewBase + "questions.html"//,
//controller: "questionController"
//views: {
//
//}
});
}]
);
Notice that I commented out the controller: "questionController" in the route, otherwise it ran twice.
I know that I used ui-router last year and i always used controller: without any problems.
Perhaps some new version combinations causing a bug?
Based on an answer i was trying but not data not displaying
I am using ui-grid
<!--<div ng-controller="questionController as vm">-->
<div ui-grid="{ data: vm }" class="grid"></div>
<!--</div>-->
Notice i commented out div with the ng-controller
var vm = this
var promise = questionService.getAllQuestions();
promise.then(function(response) {
vm.myData = response;
console.log('questionCtrl promise data', vm.myData);
});
The console.log does work to spit out data
Fixed
Seems that I had to do
route
controller: "questionController",
controllerAs : "vm"
OR
controller: "questionController"
Then
<div ui-grid="{ data: vm.myData }" class="grid"></div>
This is because you are including the controller in your $stateProvider as well as the template itself by doing
<div ng-controller="questionController as vm"></div>
You can remove ng-controller from your HTML

Angular: passing object to different view in same controller

I am working on an Ionic app where, I need to pass an item (json object) to a view and bind the items there.
I've gone through a lot of similar questions, likely:
Unable to access $scope variable within same controller
AngularJS: Pass an object into a state using ui-router
But, seems like none is working in my case.
Here is my HTML markup of index.html page (from where I'm passing item):
<div class="list card slide-in" ng-repeat="item in posts track by $index">
<h2 ng-bind="item.title" class="assertive"></h2>
//comes inside ng-repeat loop; I'm passing the whole json object as parameter to next view
<button class="button button-full" ng-click="getPostDetail(item);"> Read More </button>
</div>
Html Markup of posts.html page (where I need to access item):
<ion-view view-title="Read More ">
<ion-content class="card-background-page ">
<div class="list padding-20">
<h2 ng-bind="selectedPost.title" class="assertive"></h2>
</div>
</ion-content>
</ion-view>
My Config:
app.config(function ($stateProvider, $urlRouterProvider, localStorageServiceProvider) {
$stateProvider
.state('tabs.posts', {
url: "/posts",
params: {
obj: null // as per other suggestion, added a param here
},
views: {
'home-tab': {
templateUrl: "templates/post.html",
controller: 'main'
}
}
})
My Controller:
app.controller('main', function ($scope, $http, $state, $ionicModal, $location, $stateParams, localStorageService) {
$scope.getPostDetail = function (data) {
var selectedPost = data;
$state.go("tabs.posts", { obj: selectedPost });
}
})
On click of button, the Posts View loads successfully, but no content is bound i.e. the view is blank
Unless I'm missing something, selectedPost needs to be on $scope. Otherwise it cannot be accessed from the view. So something like this.
$scope.getPostDetail = function (data) {
$scope.selectedPost = data;
$state.go("tabs.posts", { obj: selectedPost });
}

TypeError: Cannot read property 'open' of undefined modal

I am trying to display a modal with the information of a certain item. But when I call the function it reads:
TypeError: Cannot read property 'open' of undefined at Scope.$scope.openModal
I was hoping someone could tell me why, here is the relevant code:
Template
<div ng-controller="View1Ctrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">Item Details</h3>
</div>
<div class="modal-body">
<ul ng-repeat="i in items">
<li>Type: <span ng-bind="i.type"></span></li>
<li>Description: <span ng-bind="i.description"></span></li>
<li>Date: <span ng-bind="i.createDate"></span></li>
<li>Priority: <span ng-bind="i.priority"></span></li>
<li>Finished: <span ng-bind="i.isDone"></span></li>
</ul>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="$close()">OK</button>
</div>
</script>
</div>
App.Js
'use strict';
// Declare app level module which depends on views, and components
angular.module('myApp', [
//'ngRoute',
'ui.router',
'ui.bootstrap',
'myApp.view1',
'myApp.view2',
'myApp.version',
'myApp.items'
])
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/view1');
$stateProvider
.state('view1', {
url: '/view1',
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
})
.state('view2', {
url: '/view2',
templateUrl: 'view2/view2.html',
controller: 'View2Ctrl'
});
});
Controller
'use strict';
angular.module('myApp.view1', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
});
}])
.controller('View1Ctrl', ['$scope','itemsService',function($scope,itemsService, $uiModal) {
$scope.$on('itemSwitch.moreInfo', function(event, obj){
$scope.openModal(obj);
});
$scope.openModal = function (obj) {
var modalInstance = $uiModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'templates/modalTemplate.html',
controller: 'View1Ctrl',
resolve: {
items: function () {
return obj;
}
}
});
}
}]); //END
Can anyone point me in the right direction to fix this issue?
Thanks
The error is gone, but now it doesn't show anything but the grey-out screen, the console shows the modal html is loading but not displaying properly.
Your injection signature is not correct. You are missing $uiModal. Observe the following...
.controller('View1Ctrl', ['$scope', 'itemsService',
function($scope, itemsService, $uiModal) {
=>
.controller('View1Ctrl', ['$scope', 'itemsService', '$uiModal',
function($scope, itemsService, $uiModal) {
I am not totally sure the exact name of the service you are intending to inject. I guess here based on your variable that is named $uiModal, however, I notice the docs state it is $uibModal. You'll need to verify this.
In response to your updated newly found issue, my best observation is that templateUrl: '' and <script id=""> must match. Try changing your <script> tag to the following...
<script type="text/ng-template" id="templates/modalTemplate.html">
<!-- <div> -->
I stumbled upon this while playing around with the default plunker found in the docs. If both values are not the same there is an error.

How to pass form data from angular ui bootstrap modal to view

I'm creating a webapp and I want to implement an option to add friends. I've created the add friend page as a modal with a text input field. I want to test this by displaying the input on my view page. How do I display this data onto my view page?
Here's what I currently have
index.html
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<form name = "addFriendForm">
<input ng-model = "user.name"class="form-control" type = "text" placeholder="Username" title=" Username" />
{{ user.name }}
</form>
<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>
<button class="btn btn-default" ng-click="open()">Add Friend</button>
<div> Username: {{user.name}}</div>
</div>
my JavaScript file:
angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $modal, $log) {
$scope.user = {name: ""}
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function () {
$scope.user.name = user.name;}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
});
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $modalInstance) {
$scope.ok = function () {
$modalInstance.close($scope.user.name);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
plunkr: http://plnkr.co/edit/JIoiNx47KXsY8aqbTUDS?p=preview
Resolve - plunkr
You could make use of modalInstance's resolve property; this acts as the link between the modal instance and the parent controller.
You inject the object in to the ModalInstanceController, and assign it to the scope of your modal instance.
UI Bootstraps resolve works exactly the same as ngRouter's; as such if for whatever reason resolve cannot resolve an object, the modal will not open.
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
user: function() {
return $scope.user;
}
}
});
Scope - plunkr
An alternative, and arguably simpler method would be to pass in the parents scope in to the modal. Note that currently this doesn't work when using controllerAs syntax on the parent controller.
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
scope: $scope
});
I would suggest using the promise from the result to set the value to your controller's variables instead. The "resolve" from my understanding is for passing controller's variable to the dialog for using inside the dialog, not to be changed directly. In your code example, passing result you set in $modalInstance.close() to modalInstance.result.then() will do the trick. In other words, changing line #18 and #19 to the following,
modalInstance.result.then(function (data) {
$scope.user.name = data;
To improve the code a bit, you can actually pass the entire user object to allow adding additional attributes such as email, address, etc. to your user object easily. I had create an example at http://plnkr.co/edit/oztYRNrCRlF1Pw289i1M?p=preview.

Categories