Ionic modal - document.getElementById not working in modal - javascript

I have an ionic modal presented like so:
$ionicModal.fromTemplateUrl('templates/my-modal.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal
$scope.modal.show()
})
The modal looks like this:
<ion-modal-view ng-controller="EditCtrl" class="modal">
<ion-header-bar class="modal-header-bar">
<button class="button button-clear">Cancel</button>
<h1 class="title">Edit</h1>
<button class="button button-clear">Save</button>
</ion-header-bar>
<ion-content>
<div id="foo"></div>
</ion-content>
</ion-modal-view>
Then in edit_controller.js:
document.getElementById('foo')
Returns null. How can I have document refer to the currently shown modal?

Related

Angularjs Ui-Bootstrap modal popup inside specified element

i have a problem with my code , this code is about append a modal to element with specific id. so that when button clicked ,this modal popup will showed inside div element with id="forModal" (div element with this id is inside view.html) ,my app using angularjs that have base html(index.html) ,one template for route(view.html),one template for modal(modal.html).
index.html
<html>
<head>
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!--Ui Route-->
<script src="lib/ionic/js/angular-ui/angular-ui-router.min.js"> </script>
<!--UI Bootstrap-->
<script src="lib/ionic/js/angular-ui/ui-bootstrap-2.5.0.min.js"></script>
<!--UI Bootstrap TPLS-->
<script src="lib/ionic/js/angular-ui/ui-bootstrap-2.5.0-tpls.min.js"></script>
<!--ngCoockies-->
<script src="js/angular-cookies.js"></script>
<!-- my app's js -->
<script src="js/app.js"></script>
<!--controller js-->
<script src="js/controller.js"></script>
</head>
<body ng-app="starter">
<ui-view></ui-view>
</body>
</html>
app.js
var moduleapp = angular.module('starter', ['ionic','ui.router','ngCookies','ui.bootstrap']);
moduleapp.config(function($stateProvider,$urlRouterProvider){
$stateProvider.state("dashboard",{
url:"/dashboard",
templateUrl:"templates/dashboard.html",
controller : "dashboardCtrl"
})
$stateProvider.state("dashboard.view",{
url : "/view",
templateUrl : "templates/view.html",
controller: "viewDataCtrl"
})
$urlRouterProvider.otherwise("/dashboard.view")
})
controller.js
moduleapp.controller('dashboardCtrl',[function(){
//some code
}])
moduleapp.controller('viewDataCtrl',['$document','$uibModal','$scope','$http','$cookies',function($document,$uibModal,$scope,$http,$cookies){
// reserve variable,declare it as object
$scope.dataColumn = {};
$scope.dataData = {};
// reserve variable for user authetication level
$scope.userLevel= $cookies.get('userLevel');
//function for finding available column
function caricolumn(){
$http.get('link for search column.php').success(function(hasil){
$scope.dataColumn = hasil;
});
}
//executing function when controller running
caricolumn();
//function for get data,return result to $scope.dataData as object
function caridata(){
$http.get('link for search data.php').success(function(hasil){
$scope.dataData = hasil;
})
}
//execute function when controller running
caridata();
//function for edit
$scope.edit = function(x){
var modalInstance = $uibModal.open({
templateUrl:'templates/modal.html',
controller:'viewDataCtrl',
//THIS IS THE PROBLEM ,appendTO doesnt work,still inject modal popup to body element
appendTo : angular.element(document.querySelector('#viewElement'))
});
}
//function for delete data
$scope.delete = function(x){
$http.post('link for deletedata.php',x).success(function(hasil){
alert(hasil);
//if output(php echo) same as string ,this condition considered as success
if(hasil == "Delete Success"){
caridata();
}
})
}
}]);
modal.html
<div class="modal-header">
<h3>Hayy</h3>
</div>
<div class="modal-body">
<p>this is Body</p>
</div>
<div class="modal-footer">
this is footer
</div>
dashboard.html
<ion-side-menus enable-menu-with-back-views="false">
<ion-side-menu-content>
<ion-nav-bar class="bar-stable">
<ion-nav-back-button>
</ion-nav-back-button>
<ion-nav-buttons side="left">
<button class="button button-icon button-clear ion-navicon" menu-toggle="left">
</button>
</ion-nav-buttons>
</ion-nav-bar>
<ui-view>
<!--This is where view.html injected-->
</ui-view>
</ion-side-menu-content>
<ion-side-menu side="left">
<ion-header-bar class="bar-stable">
<h1 class="title">Menu</h1>
</ion-header-bar>
<ion-content>
<ion-list ><a ui-sref="dashboard.add">
<ion-item>Tambah Data</ion-item></a>
</ion-list>
<ion-list ><a ui-sref="dashboard.view">
<ion-item>Tampil Data</ion-item></a>
</ion-list>
<ion-list >
<a ng-click="logout()">
<ion-item>Log Out</ion-item>
</a>
</ion-list>
</ion-content>
</ion-side-menu>
</ion-side-menus>
view.html
<div id="viewElement" class="container" style="margin-top:50px;">
<h2>Data-Data</h2>
<hr/>
<table class="table table-bordered">
<thead>
<tr>
<th ng-repeat="dc in dataColumn">{{dc.KOLOM}}</th>
<th ng-if="userLevel == 'LV02' || userLevel == 'LV01'">Edit</th>
<th ng-if="userLevel == 'LV01'">Delete</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="dd in dataData" id="dt{{dd.IDROW}}">
<td ng-repeat="ddd in dd.DATA">{{ddd}}</td>
<td ng-if="userLevel == 'LV01' || userLevel == 'LV01'"><button type="button" ng-click="edit({{dd.IDROW}})" class="btn btn-warning">Edit</button></td>
<td ng-if="userLevel == 'LV01'"><button type="button" ng-click="delete({{dd.IDROW}})" class="btn btn-danger">Delete</button></td>
</tr>
</tbody>
</table>
</div>
as you can see ,when app running .route default will go to "dashboard.view"
dashboard state is code for left sidemenu ,then dashboard.view state for viewing data(view state in child from dashboard state)
what i want is when edit button clicked inside view.html(controller : viewDataCtrl,state : dashboard.view), modal popup will appear inside div element with id="forModal" (div element with this id is inside view.html)
but with this code ,modal popup always appear inside body tag element not inside div element with id="forModal".
how can i approach this condition ? thanks

Ionic hiding and showing elements ng-show?

New to JS, Ionic framework, AngularJS. I'm trying to work with ng-show && ng-click to display the header on the event of a click on a button. I am still not getting the intended result, any ideas??
Here is my index:
<body ng-app="starter" ng-controller="HomeCtrl as home">
<!--
The nav bar that will be updated as we navigate between views.
-->
<ion-nav-bar ng-show="display('on')" class="bar-balanced">
<ion-content>
<ion-nav-back-button class="bar-balanced">
</ion-nav-back-button>
</ion-content>
</ion-nav-bar>
<!--
The views will be rendered in the <ion-nav-view> directive below
Templates are in the /templates folder (but you could also
have templates inline in this html file if you'd like).
-->
<ion-nav-view></ion-nav-view>
</body>
My controller:
.controller('HomeCtrl', function($scope) {
$scope.display = function (x) {
if (x == 'on'){
return true;
}
else if (x == 'off'){
return false;
}
}
})
My view:
<ion-view ng-controller="HomeCtrl as home">
<ion-content class="splash">
</ion-content>
<ion-footer-bar class="bar-balanced">
<button ng-click="display('on')" class="button-large button-full button-clear">
<a class="button button-icon icon ion-log-in"href="#/login" >
</a>
</button>
</ion-footer-bar>
</ion-view>
If i have missed anything will edit post with updates**
I see a couple issues here, first of all both the navbar and footer-bar elements should be inside the ng-controller element. This will give the navbar access to the scope to determine if it should be shown or not.
Also, you should use a variable on the scope to determine if the navbar is shown, full example below.
var app = angular.module('myApp', []);
app.controller('HomeCtrl', function($scope) {
$scope.isNavVisible = false;
$scope.displayNav = function(x) {
if (x == 'on') {
$scope.isNavVisible = true;
} else if (x == 'off') {
$scope.isNavVisible = false;
}
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="myApp">
<div ng-controller="HomeCtrl">
<ion-nav-bar ng-show="isNavVisible" class="bar-balanced">
<span>Nav Content</span>
<ion-content>
<ion-nav-back-button class="bar-balanced">
</ion-nav-back-button>
</ion-content>
</ion-nav-bar>
<ion-footer-bar class="bar-balanced">
<button ng-click="displayNav('on')" class="button-large button-full button-clear">
<a class="button button-icon icon ion-log-in" href="#/login">Login</a>
</button>
</ion-footer-bar>
</div>
</html>
If you need to manipulate the nav from multiple controllers you could do that with a service like so
var app = angular.module('myApp', []);
app.service('navService', function() {
this.isNavVisible = false;
});
app.controller('RootCtrl', ['$scope', 'navService',
function($scope, navService) {
$scope.navService = navService;
}
]);
app.controller('HomeCtrl', ['$scope', 'navService',
function($scope, navService) {
$scope.displayNav = function(x) {
if (x == 'on') {
navService.isNavVisible = true;
} else if (x == 'off') {
navService.isNavVisible = false;
}
}
}
])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" ng-controller="RootCtrl">
<!--
The nav bar that will be updated as we navigate between views.
-->
<ion-nav-bar ng-show="navService.isNavVisible" class="bar-balanced">
<span>Nav Content</span>
<ion-content>
<ion-nav-back-button class="bar-balanced">
</ion-nav-back-button>
</ion-content>
</ion-nav-bar>
<!--
The views will be rendered in the <ion-nav-view> directive below
Templates are in the /templates folder (but you could also
have templates inline in this html file if you'd like).
-->
<ion-view ng-controller="HomeCtrl">
<ion-content class="splash">
</ion-content>
<ion-footer-bar class="bar-balanced">
<button ng-click="displayNav('on')" class="button-large button-full button-clear">
<a class="button button-icon icon ion-log-in" href="#/login">
Login
</a>
</button>
</ion-footer-bar>
</ion-view>
</body>
You should use the ng-click directive to change a value like this:
.controller('HomeCtrl', function($scope) {
$scope.displayItem = false;
$scope.display = function (x) {
if (x == 'on'){
$scope.displayItem = true;
}
else if (x == 'off'){
$scope.displayItem = false;
}
}
})
And then inside your View:
<ion-nav-bar ng-show="displayItem" class="bar-balanced">
<ion-content>
<ion-nav-back-button class="bar-balanced">
</ion-nav-back-button>
</ion-content>
</ion-nav-bar>
Your View, will still the same
<ion-footer-bar class="bar-balanced" ng-controller="HomeCtrl as home">
<button ng-click="display('on')" class="button-large button-full button-clear">
<a class="button button-icon icon ion-log-in"href="#/login" >
</a>
</button>
</ion-footer-bar>
Make sure that both html refers to the same controller. Otherwise you will not have access to the $scope.displayItem property.
In case yo want to share data between different controllers, you should look for another alternative, like a Factory/service or property inside the $rootScope.

Using Angular controller inside Bootstrap Modal

[html]
<div class="modal fade" id="proj-edit" tabindex="-1" role="dialog" aria-hidden="true" data-remote="update.html">
<div class="modal-dialog">
<div class="modal-content" ng-controller="UpdateProjectController"></div>
</div>
</div>
[javascript]
var ProjectApp = angular.module('ProjectApp', ["ui.bootstrap"]);
ProjectApp.controller('UpdateProjectController', ["$scope","$http", function($scope, $http){
$scope.message = 'Please enter valid case number';
$scope.UpdateProject = function(){..do something..};
}]);
[update.html]
<div class="modal-header" >
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
<h4 id="myModalLabel" class="modal-title">Update Project</h4>
</div>
<div class="modal-body">
{{message}}
</div>
<div class="modal-footer">
<button type="submit" class="btn blue-soft" ng-click="UpdateProject()">Update</button>
<button type="button" class="btn default" data-dismiss="modal">Cancel</button>
</div>
Issue: Modal is being invoked from JQuery using .modal('show') method. My intention is to render the controller whenever the modal is opened. However, it seems that the modal does not recognise the controller and no message nor function from the controller can be executed. Appreciate your help on this matter. TQ.
HI please check the example
index.html
<!doctype html>
<html ng-app="plunker">
<head>
<script src="https://code.angularjs.org/1.2.18/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>
<form ng-submit="submit()">
<div class="modal-body">
<label>User name</label>
<input type="text" ng-model="user.user" />
<label>Password</label>
<input type="password" ng-model="user.password" />
<label>Add some notes</label>
<textarea rows="4" cols="50" ng-model="user.notes">
</textarea>
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
<input type="submit" class="btn primary-btn" value="Submit" />
</div>
</form>
</script>
<button class="btn" ng-click="open()">Open me!</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>
</body>
</html>
example.js
angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.user = {
user: 'name',
password: null,
notes: null
};
$scope.open = function () {
$modal.open({
templateUrl: 'myModalContent.html', // loads the template
backdrop: true, // setting backdrop allows us to close the modal window on clicking outside the modal window
windowClass: 'modal', // windowClass - additional CSS class(es) to be added to a modal window template
controller: function ($scope, $modalInstance, $log, user) {
$scope.user = user;
$scope.submit = function () {
$log.log('Submiting user info.'); // kinda console logs this statement
$log.log(user);
$modalInstance.dismiss('cancel'); // dismiss(reason) - a method that can be used to dismiss a modal, passing a reason
}
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
},
resolve: {
user: function () {
return $scope.user;
}
}
});//end of modal.open
}; // end of scope.open function
};
for reference http://embed.plnkr.co/As959V/
The reason is update.html is quite a massive form and preferred not to
include inside main html file. So, the modal is basically calling the
remote html file.
Your remote html file and your modal file maybe using 2 different instances of the UpdateProjectController.
As said by Martijn, you coud use ui-bootstrap for this but if you don't want to, you could solve it by using a directive.
// directive to open the modal
var app = angular.module('myApp', []);
app.directive('myModal', myModal);
myModal.$inject = [];
function myModal() {
return {
restrict: 'A',
link: link
}
function link($scope, $element, $attributes) {
$element.click(function (event) {
angular.element($attributes.modalId).modal();
});
}
}
app.controller('ModalCtrl', ModalCtrl);
ModalCtrl.$inject = [];
function ModalCtrl() {
$scope.message = 'Please enter valid case number';
$scope.UpdateProject = function(){..do something..};
}
Modal is being invoked from JQuery using .modal('show') method.
So in case you use a button to do this render the modal, you could easily include the directive as an attribute to the modal instead of ng-click()
Lastly, include the modal file in your template file
<body>
<div ng-controller="UpdateProjectController">
// So in case you use a button to do this render the modal,
// you could easily include the directive as an attribute to the modal instead of ng-click()
<a href="javascript:;" my-modal modal-id="#modalUpdateProject">
Update Project
</a>
</div>
<!-- modals -->
<div ng-controller="ModalCtrl">
<ng-include src="'path/to/modal.html'"></ng-include>
</div>
<!-- end modals -->
</body>

Customizing Modals with angular-modal-service (AngularJS)

I'm using (angular-modal-service) to create popups and modals via a service but I would like to know how it is possible to customize them? For instance, how can I change the modal-header color or remove the "by default" lines between the header, body and footer? Thank you.
Sample of the controllers:
var app = angular.module('app', ['angularModalService']);
app.controller('Controller', function($scope, ModalService) {
$scope.show = function() {
ModalService.showModal({
templateUrl: 'modal.html',
controller: "ModalController"
}).then(function(modal) {
modal.element.modal();
modal.close.then(function(result) {
$scope.message = "You said " + result;
});
});
};
});
app.controller('ModalController', function($scope, close) {
$scope.close = function(result) {
close(result, 500); // close, but give 500ms for bootstrap to animate
};
});
Sample of the html:
<script src="https://code.angularjs.org/1.4.9/angular.min.js"></script>
<script src="https://rawgit.com/dwmkerr/angular-modal-service/master/dst/angular-modal-service.js"></script>
<div class="container" ng-app="app" ng-controller="Controller">
<h3>Angular Modal Service</h3>
<a class="btn btn-default" href ng-click="show()">Show a Modal</a>
<p>{{message}}</p>
<!-- The actual modal template, just a bit o bootstrap -->
<script type="text/ng-template" id="modal.html">
<div class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" ng-click="close('Cancel')" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Yes or No?</h4>
</div>
<div class="modal-body">
<p>It's your call...</p>
</div>
<div class="modal-footer">
<button type="button" ng-click="close('No')" class="btn btn-default" data-dismiss="modal">No</button>
<button type="button" ng-click="close('Yes')" class="btn btn-primary" data-dismiss="modal">Yes</button>
</div>
</div>
</div>
</div>
</script>
</div>
Your question is a CSS question.
To change modal colors or borders you have to add a custom CSS.
You can play with google dev tool to change styles and see the results in real-time so you don't have to reload the page.
To change header color:
.modal-header {
background-color: red;
}
To hide border in footer:
.modal-footer {
border-top: 0px!important;
}
You can use css for that otherwise convert it into custom directive

Display dynamic content in Angular Modal from parent controller

I am using angular-modal-service. I wish to modify the content of modal body as custom input text from the user. My index.html looks like :
<head>
<link rel="import" href="notify.html">
<script type="text/javascript" src="app.js"></script>
</head>
<body>
<input type="text" ng-model="custom_text" />
<input type="button" value="Click here for notification" ng- click="showNotification()" />
</body>
</html>
My app.js :
var app = angular.module("someApp", ['angularModalService']);
app.controller("mainController", function($scope, ModalService){
$scope.showNotification = function(){
document.getElementById('my_text').innerHTML = $scope.custom_text;
alert($scope.custom_text);
ModalService.showModal({
templateUrl: "notify.html",
controller: "YesNoController"
}).then(function(modal) {
modal.element.modal();
modal.close.then(function(result) {
$scope.message = result ? "You said Yes" : "You said No";
});
});
}
});
app.controller('YesNoController', ['$scope', 'close', function($scope, close) {
$scope.close = function(result) {
close(result, 500); // close, but give 500ms for bootstrap to animate
};
}]);
My notify.html has :
<div class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" ng-click="close(false)" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Yes or No?</h4>
</div>
<div class="modal-body">
<p><span id="my_text"></span></p>
</div>
<div class="modal-footer">
<button type="button" ng-click="close(false)" class="btn btn-default" data-dismiss="modal">No</button>
<button type="button" ng-click="close(true)" class="btn btn-primary" data-dismiss="modal">Yes</button>
</div>
</div>
I am actually trying to modify notify.html modal body in the controller by accessing it through DOM. But it is giving me the error : Cannot set property 'innerHTML' of null.
How can I do this. Please help.
First you should only manipulate the DOM in angular with directives. So your approach of accessing the DOM in this way would probably cause you problems even if it was working.
That being said. You just pass the scope value to the Modal and bind the value directly to the template with handlebars {{custom_text}}
Update .showModal Method to pass scope values:
ModalService.showModal({
templateUrl: "notify.html",
controller: "YesNoController",
inputs: {
'custom_text': $scope.custom_text
}
}).then(function(modal) {
modal.element.modal();
modal.close.then(function(result) {
$scope.message = result ? "You said Yes" : "You said No";
});
});
Modal HTML:
<div class="modal-body">
<p><span id="my_text">{{custom_text}}</span></p>
</div>

Categories