I am newbie with angularjs
I want to use modal with bootstrap
but there is no any effect on my page
and there is no error message
here is my code
<div ng-controller="MainCtrl">
<button class="btn" ng-click="open()">Open me!</button>
<div modal="shouldBeOpen" close="close()" options="opts">
<div class="modal-header">
<h3>I'm a modal!</h3>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button class="btn btn-warning cancel" ng-click="close()">Cancel</button>
</div>
</div>
'use strict';
angular.module('yeomanContactsAppApp')
.controller('MainCtrl', function ($scope) {
$scope.open = function () {
$scope.shouldBeOpen = true;
};
$scope.close = function () {
$scope.closeMsg = 'I was closed at: ' + new Date();
$scope.shouldBeOpen = false;
};
$scope.items = ['item1', 'item2'];
$scope.opts = {
backdropFade: true,
dialogFade:true
};});
it result in directly show modal content , not click button to show modal ?
I am so confused , please help
thanks a lot !
Which bootstrap version are you using? If the html is the full bootstrap it looks like you are missing some parts like role='dialog' etc.
default set $scope.shouldBeOpen to false and then toggle it in your functions. Then it shouldn't open directly I think.
angular.module('yeomanContactsAppApp')
.controller('MainCtrl', function ($scope) {
$scope.shouldBeOpen = false;
...
});
The script works fine maybe its the html that is wrong. I used angular with bootstrap without any trouble.
Related
I have a list of products and you want to display a modal window to edit the parameters of these products
for this you have in each row a button that calls the modal ....
my Edit button in Index.cshtml:
<td>
Editar
</td>
my script in Index.cshtml:
<script>
var EditarProducto = function (codigoProducto) {
var url = "/Productoes/EditarProducto?Kn_CodigoProducto="+codigoProducto;
$("#EditModalBody").load(url, function () {
$("#myModalEditar").modal("show");
})
}
</script>
my modal Bootstrap in Index view:
<div class="modal fade" id="myModalEditar">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Editar Producto</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="EditModalBody">
</div>
</div>
</div>
</div>
my ActionResult in controller:
public ActionResult EditarProducto (int Kn_CodigoProducto)
{
Producto model = new Producto();
if(Kn_CodigoProducto >= 0)
{
var producto = db.Productoes.Where(c => c.Kn_CodigoProducto == Kn_CodigoProducto).FirstOrDefault();
model.v_Nombre = producto.v_Nombre;
}
return PartialView("_PartialEditar", model);
}
and my partial view that receives the model sent from the controller:
#model Dominio.Producto
<div class="jumbotron">
<label>Esto es una prueba #Model.v_Nombre</label>
</div>
I have the partial view inside the folder along with the Index.cshtml view
Also I have referenced the corresponding scripts, what is happening? What is missing? It is the first time that I work with partial and modal views ... am I doing it correctly?
Expected behavior: when you click on the edit button, the modal opens
Behavior obtained: although when clicking on the edit button it enters the action of my controller, it does not show the modal
any help for me?
Instead of this:
<script>
var EditarProducto = function (codigoProducto) {
var url = "/Productoes/EditarProducto?Kn_CodigoProducto="+codigoProducto;
$("#EditModalBody").load(url, function () {
$("#myModalEditar").modal("show");
})
}
</script>
Can you try this:
<script>
var EditarProducto = function (codigoProducto) {
var url = "/Productoes/EditarProducto?Kn_CodigoProducto="+codigoProducto;
$.ajax({
url: url,
type: 'GET',
success: function (result) {
$('#EditModalBody').html(result);
$("#myModalEditar").modal("show");
},
error: function (xhr, status) {
alert(status);
}
});
}
</script>
You don't need to write jquery to invoke modal popup, instead you can use data-toggle and data-target attribuites.
Editar
I am new in this field and want to write a app, now I meet some problems. Here is a simple version of my code, what I want is the API only show signUp first. After I press signUp and press submit the button shown should be only signout
I think my way is not all right, because after I change the value in service, another controller can't update its value. Could you tell me that?
please use this.logged if possible, thanks!
The process is not necessary to be same to my title. OK if it can implement my function.
https://plnkr.co/edit/1ptaVzmD7EwPZ6dU23gR?p=preview
(function(){
angular.module('myApp',['myApp.dashboard','myApp.value','myApp.signUp']);
})();
(function(){
angular.module('myApp.dashboard',[]);
})();
(function(){
angular.module('myApp.value',[]);
})();
(function(){
angular.module('myApp.signUp',[]);
})();
(function(){
'use strict';
angular.module('myApp.dashboard').controller('mainControl',mainControl);
mainControl.$inject = ['whichToShow'];
function mainControl(whichToShow){
this.logged=whichToShow.getVar();
alert(this.logged);
}
})();
(function(){
'use strict';
angular.module('myApp.value').factory('whichToShow',function(){
alert("running2");
var logged=false;
return {
getVar: function(){
return logged;
},
setVar: function(value){
logged=value;
}
};
});
})();
(function(){
'use strict';
angular.module('myApp.signUp').controller('signUpControl',signUpControl);
signUpControl.$inject = ['whichToShow'];
function signUpControl(whichToShow){
alert("haha");
this.logIn=function(){
whichToShow.setVar(true);
alert("running set!");
};
};
})();
partial html:
<body ng-controller="mainControl as mc">
<div>
<div ng-hide="mc.logged">
<button type="button" class="btn" data-toggle="modal" data-target=".signUp">Sign Up</button>
</div>
<div ng-show="mc.logged">
<button>Sign Out</button>
</div>
</div>
<div class="signUp modal fade" id="signUp" ng-controller='signUpControl as sc'>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">sigh up</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
</div>
<div class="modal-body">
<form id="signUpForm" name="signUpForm" ng-submit="sc.logIn()">
<label for="email">
<span>email:</span>
<input type="email" name="email">
</label>
<button class="submit" id="signUpSubmit" type="submit" value="signUp">submit</button>
</form>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
</body>
Basically you are setting values in factory object after user clicks on submit but that doesn't reflect in UI as you have not updated the scope object this.logged.So to tell main controller fromsign up controller that change the this.logged $scope value we can use $emit or $broadcast
Apart from $watch approach you can even use $broadcast to achieve this.
Working DEMO
Just add this below code in your JS file controllers
signUpControl
(function(){
'use strict';
angular.module('myApp.signUp').controller('signUpControl',signUpControl);
signUpControl.$inject = ['whichToShow','$rootScope'];
function signUpControl(whichToShow,$rootScope){
alert("haha");
this.logIn=function(){
whichToShow.setVar(true);
$rootScope.$broadcast('login');//broadcasting that user has logged in
//alert("running set!");
};
};
})
mainControl
(function(){
'use strict';
angular.module('myApp.dashboard').controller('mainControl',mainControl);
mainControl.$inject = ['whichToShow','$rootScope'];
function mainControl(whichToShow,$rootScope){
var mc = this;
mc.main ={};
mc.main.logged=whichToShow.getVar();
alert(mc.main.logged);
// below code will listen to the broadcast and do the necessary process..
$rootScope.$on('login',function(event,args){
mc.main.logged=whichToShow.getVar();
});
}
})
You need watch for the changes on the logged value from the service.
That is all you need to do.
(function() {
angular.module('myApp', ['myApp.dashboard', 'myApp.value', 'myApp.signUp']);
})();
(function() {
angular.module('myApp.dashboard', []);
})();
(function() {
angular.module('myApp.value', []);
})();
(function() {
angular.module('myApp.signUp', []);
})();
(function() {
'use strict';
angular.module('myApp.dashboard').controller('mainControl', mainControl);
mainControl.$inject = ['$scope', 'whichToShow'];
function mainControl($scope, whichToShow) {
$scope.$watch(() => whichToShow.getVar(), (newValue, oldValue) => this.logged = newValue)
}
})();
(function() {
'use strict';
angular.module('myApp.value').factory('whichToShow', function() {
var logged = false;
var service = {};
return {
getVar: function() {
return logged;
},
setVar: function(value) {
logged = value;
}
}
});
})();
(function() {
'use strict';
angular.module('myApp.signUp').controller('signUpControl', signUpControl);
signUpControl.$inject = ['whichToShow'];
function signUpControl(whichToShow) {
this.logIn = function() {
whichToShow.setVar(true);
};
};
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div ng-app="myApp">
<div ng-controller="mainControl as mc">
<div>
<div ng-hide="mc.logged">
<button type="button" class="btn" data-toggle="modal" data-target=".signUp">Sign Up</button>
</div>
<div ng-show="mc.logged">
<button>Sign Out</button>
</div>
</div>
<div class="signUp modal fade" id="signUp" ng-controller='signUpControl as sc'>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">sigh up</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
</div>
<div class="modal-body">
<form id="signUpForm" name="signUpForm" ng-submit="sc.logIn()">
<label for="email">
<span>email:</span>
<input type="email" name="email">
</label>
<button class="submit" id="signUpSubmit" type="submit" value="signUp">submit</button>
</form>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
</div>
</div>
Working solution on Codepen
You are still trying to set the value of primitives here, rather than object properties. In JavaScript, primitives are passed byValue, not byReference, so whichToShow.getVar(); is returning true or false rather than returning a reference to logged. Therefore, you won't see changes to logged unless you call .getVar() again, to get the new value. This is why most answers you have seen so far have had some form of $watch, $broadcast, or similar, to alert your mc that it should ask again for the logged variable's current value.
If you want to avoid using a $watch, you should use an object instead of a primitive. by using an object, you can pass the object byReference, which will allow angular to see the changes to the properties wherever there is a reference set.
In your factory, return an object:
(function() {
'use strict';
angular.module('myApp.value').factory('whichToShow', function() {
alert("running2");
var status = {
logged: false
};
var logged = false;
return {
getVar: function() {
return status;
},
setVar: function(value) {
status.logged = value;
}
};
});
})();
In mainControl, use a reference to this object:
(function() {
'use strict';
angular.module('myApp.value').factory('whichToShow', function() {
alert("running2");
var status = {
logged: false
};
return {
getVar: function() {
return status;
},
setVar: function(value) {
status.logged = value;
}
};
});
})();
And finally, use the object property in the HTML:
<div ng-hide="mc.status.logged">
...
<div ng-show="mc.status.logged">
...
https://plnkr.co/edit/Pindt2LYxDxyk8C5Axp1?p=preview
I might even go one step further and just return the object directly by the service, and skip the getVar and setVar functions.
You can put some variable globally or in your rootcontroller,lets says isLoggedIn
now with one service you can set this variable on signingIn
and use it like this
{
}<span data-ng-if="!isLoggedIn">Sign In</span>
<span data-ng-if="isLoggedIn">Sign Out</span>
[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>
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>
I have a form with additional data fields displayed in a modal:
<form class="form-horizontal" name="newForm" ng-controller="FormCtrl" ng-submit="submit()">
<label>Test</label>
<div ng-controller="ModalCtrl">
<a class="btn btn-link" ng-click="open()">Open</a>
<ng-include src="'partials/modal.html'"></ng-include>
</div>
</form>
includes:
<div modal="shouldBeOpen" close="close()" options="opts">
<div class="modal-header">
<h4>I'm a modal!</h4>
</div>
<div class="modal-body">
<ul>
<input type="text" tabindex="16" ng-model="someinput" name="someinput" size="32" class="validate[someinput]" />
</ul>
</div>
<div class="modal-footer">
<button class="btn btn-warning cancel" ng-click="close()">Cancel</button>
</div>
</div>
JS:
var ModalCtrl = function ($scope) {
$scope.open = function () {
$scope.shouldBeOpen = true;
};
$scope.close = function () {
$scope.shouldBeOpen = false;
};
$scope.opts = {
backdropFade: true,
dialogFade:true
};
};
How can I read/inject/transfer the user input from the modal form into the main form?
What you need is to communicate between two controllers and this can be achieved by creating a service.
Using this as reference.
You could create a service as follows:
angular.module('myApp', [])
.service('sharedInput', function () {
var modalInput = "";
return {
getModalInput:function () {
return modalInput;
},
setModalInput:function (value) {
modalInput = value;
}
};
});
Next, in your ModalCtrl() function, I assume that you will have a button to submit the input. Let us say that clicking this button invokes the "submitInput" function in the scope of ModalCtrl. You will write this function as:
$scope.submitInput = function() {
sharedInput.setMOdalInput($scope.someinput);
}
...and in your FormCtrl() you will write the following code to read the modal input:
var input = sharedInput.getModalInput()
You also need to pass the parameter "sharedInput" to the ModalCtrl and FormCtrl just like how you passed $scope. And now you have your two controllers communicating.
I found a comment to an issue on GitHub with a plunker explaining the problem and the solution with angular-ui, without the shared service. Works like a charm.
http://plnkr.co/edit/ktfq0Y?p=preview