I have a problem with the code, all I need is to hide the "NotesText" the arrow is pointing up, and after showing the "NotesText" arrow must be pointing down. I can not find the way to make this happen, please, I need help.
Basically, I need is to change the direction of the arrow agree if I need to show or hide
This is what I have .
This is HTML:
<div id="notes-controller" class="collapse in" ng-controller="NotesController">
<fieldset>
<legend class="translatable" data-i18n="Notes">Notes</legend>
<form novalidate class="simple-form">
<div class="container col-md-12" ng-show="$ctrl.param.note.visible">
<textarea class="col-md-12" ng-readonly="$ctrl.param.note.readonly" type="text" id="Notes" ng-model="$ctrl.notes.note" ng-model-options="{ getterSetter: true }" />
</div>
</form>
</fieldset>
</div>
<span type="button" class="glyphicon glyphicon-chevron-up" data-toggle="collapse" data-target="#notes-controller"></span>
This is Controller
angular.
module('notesText').
component('notesText', {
templateUrl: '/Scripts/test/notes-text/notes-text.template.html',
bindings: {
notes: '=',
param: '='
}
}).controller('NotesController', ['$scope', function ($scope) {
$scope.master = {};
$scope.update = function (user) {
$scope.master = angular.copy(user);
};
$scope.reset = function () {
$scope.user = angular.copy($scope.master);
};
$scope.reset();
}]);
This is how it looks:
enter image description here
A very Minimalistic Soln:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container" ng-app="">
<textarea id="myTextArea" ng-hide="isHidden">MY TEXT</textarea>
<br>
<span class="glyphicon" ng-class="isHidden ? 'glyphicon-chevron-down' : 'glyphicon-chevron-up'" ng-click="isHidden = !isHidden;">
</span>
</div>
A more verbose Soln:
Have a look at the working example below:
Simply using ng-class to attach glyphicon-chevron-up or glyphicon-chevron-down based on expression returned by a function that checks if the textarea is visible.
angular.module("myApp", [])
.controller("myCtrl", function($scope) {
$scope.isShown = function() {
return $('#myTextArea').is(':visible');
}
$scope.hideIt = function() {
$('#myTextArea').toggle();
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container" ng-app="myApp" ng-controller="myCtrl">
<textarea id="myTextArea">MY TEXT</textarea>
<br>
<span class="glyphicon"
ng-class="isShown() ? 'glyphicon-chevron-up' : 'glyphicon-chevron-down'"
ng-click="hideIt()">
</span>
</div>
Using the ng-show and ng-hide directive might be the best way to achieve this. That way you can have a scoped variable you can point to. You could also do an ng-class that if true, rotates the icon 180 degs. Either way it's up to you.
<span ng-show="$ctrl.IsToggled" type="button" class="glyphicon glyphicon-chevron-up" data-toggle="collapse" data-target="#notes-controller"></span>
<span ng-hide="$ctrl.IsToggled" type="button" class="glyphicon glyphicon-chevron-down" data-toggle="collapse" data-target="#notes-controller"></span>
Related
I am trying to make a generic "List of Values", a searchable modal with a natural identifier and a description. I have managed to create an angularjs app that does this in SpringBoot but it is not callable as a modal.
I want to use nothing but angularjs, bootstrap and springboot mvc, I don't want to get into node as the backend.
I attempted to follow the instructions here:
https://www.uibootstrap.net/angular-ui-bootstrap/angular-bootstrap-modal-example-demo/
But they are incomplete, code fragments. I have tried to put it all together and have the following three files:
At this point I am getting
Error: [$injector:modulerr] Failed to instantiate module TestApp due to:
[$injector:modulerr] Failed to instantiate module ui.bootstrap due to:
[$injector:nomod] Module 'ui.bootstrap' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
I don't even know where this would get ui.bootstrap and the installation instructions for it say to use npm, I want to know what files are being used and place them in my springboot project. Npm and node are not in the architectural plans.
index.html:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Model</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.js"></script>
<script src="./app.js"></script>
</head>
<body>
<div ng-app="TestApp">
<div class="well">
<button type="button" class="btn btn-primary" ng-click="openModal()">Click
to Open Modal Window!</button>
</div>
</div>
</body>
app.js:
var modalInstance = '';
var app = angular.module('TestApp', ['ui.bootstrap']);
app.controller('TestCtrl', function($scope, $http) {
function modalOpenCtrl($scope, payload){
console.log('fgfdfd');
$scope.datas = payload;
console.log($scope.datas);
$scope.closeModal = function(){
$scope.cancelModal();
}
}
$scope.openModal = function(task){
modalInstance = $uibModal.open({
animation: false,
templateUrl: './modal_window.html',
controller: 'modalOpenCtrl',
scope: $scope,
size: 'md',
backdrop: 'static',
resolve: {
payload: function () {
return {
msg_body : 'Hello! I am payload msg',
title : 'Hello! Title',
body_title : 'UiBootstrap.net'
};
}
}
});
}
function modalOpenCtrl($scope, payload){
console.log('fgfdfd');
$scope.datas = payload;
console.log($scope.datas);
$scope.closeModal = function(){
$scope.cancelModal();
}
}
})
modal_window.html:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Model</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.css">
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.js"></script>
<script>
src="./app.js"
</script>
</head>
<body>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-label="Close" ng-click="closeModal()">
<span aria-hidden="true">×</span>
</button>
<div class="modal-title">
<h4>{{datas.title}}</h4>
</div>
</div>
<div class="modal-body log-view">
<div class="clearfix">
<h2>{{datas.body_title}}</h2>
<div>{{datas.msg_body}}</div>
</div>
</div>
<div class="modal-footer model-grey-color">
<div class="clearfix">
<div>
<button class="btn btn-success" ng-click="closeModal()">
<i class="ace-icon fa fa-ok"></i> Ok
</button>
<button class="btn btn-danger" ng-click="closeModal()">
<i class="fa fa-close"></i> Close
</button>
</div>
</div>
</div>
</body>
It seems you haven't connected linking between controller and view
The error Failed to instantiate module ui.bootstrap due to: you are getting due to it's not loaded and you are trying to use this module.
Please check below for how to show modal using ui.bootstrap
First you need to create proper directory structure in order to load files when application run in browser.
Directory structure example:
Now let's jump to index.html
index.html:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Model</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<div ng-app="TestApp" ng-controller="TestCtrl">
<div class="well">
<button type="button" class="btn btn-primary" ng-click="openModal('abc')">Click
to Open Modal Window!</button>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.3.3.js"></script>
<script src="js/app.js"></script>
</body>
</html>
app.js
var modalInstance = '';
var app = angular.module('TestApp', ['ui.bootstrap']);
app.controller('TestCtrl', function($scope, $http,$uibModal) {
$scope.modalOpenCtrl = function($scope, payload){
console.log('fgfdfd');
$scope.datas = payload;
console.log($scope.datas);
$scope.closeModal = function(){
console.log("this is close modal")
$scope.cancelModal();
}
}
$scope.openModal = function(task){
modalInstance = $uibModal.open({
animation: false,
templateUrl: './main_window.html',
controller: 'modalOpenCtrl',
scope: $scope,
size: 'md',
backdrop: 'static',
resolve: {
payload: function () {
return {
msg_body : 'Hello! I am payload msg',
title : 'Hello! Title',
body_title : 'UiBootstrap.net'
};
}
}
});
}
$scope.cancelModal = function(){
console.log("this is final called");
modalInstance.close();
}
});
main_window.html
<div>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-label="Close" ng-click="closeModal()">
<span aria-hidden="true">×</span>
</button>
<div class="modal-title">
<h4>{{datas.title}}</h4>
</div>
</div>
<div class="modal-body log-view">
<div class="clearfix">
<h2>{{datas.body_title}}</h2>
<div>{{datas.msg_body}}</div>
</div>
</div>
<div class="modal-footer model-grey-color">
<div class="clearfix">
<div>
<button class="btn btn-success" ng-click="closeModal()">
<i class="ace-icon fa fa-ok"></i> Ok
</button>
<button class="btn btn-danger" ng-click="closeModal()">
<i class="fa fa-close"></i> Close
</button>
</div>
</div>
</div>
</div>
That's it run this code and it will be open modal on button click
Note: This is just basic setup of angularjs. We can still improve this code if you have more features to built like routing, api calls, mvc pattern
Here is medium blog which explains some basics features of angularjs.
You need to add bootstrap script to your index.html file like <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.min.js"></script>
Can anyone explain to me why when I print console.log($scope.inputvalue) the variable is not updated with the values that I enter in the input?
Maybe I just misunderstood the meaning of ng-model, in this case, how do I pass a value from the view to controller?
(function () {
'use strict';
angular.module('LunchCheck', [])
.controller('checkiftoomuch', ['$scope', checkiftoomuch]);
function checkiftoomuch($scope){
$scope.inputvalue = "";
console.log($scope.inputvalue);
}
})();
<!doctype html>
<html lang="en" ng-app="LunchCheck">
<head>
<title>Lunch Checker</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="app.js"></script>
<link rel="stylesheet" href="styles/bootstrap.min.css">
<style>
.message { font-size: 1.3em; font-weight: bold; }
</style>
</head>
<body>
<div class="container" ng-controller="checkiftoomuch">
<h1>Lunch Checker</h1>
<div class="form-group">
<input id="lunch-menu"
type="text"
placeholder="list comma separated dishes you usually have for lunch"
class="form-control"
ng-model="inputvalue">
</div>
<div class="form-group">
<button class="btn btn-default">Check If Too Much</button>
</div>
<div class="form-group message">
Total number of disches: {{ inputvalue }}
</div>
</div>
</body>
</html>
You're setting $scope.inputvalue = ""; before the console.log. But after you change the value, you need to console.log it again.
Try using:
function checkiftoomuch($scope){
$scope.inputvalue = "";
console.log($scope.inputvalue);
$scope.$watch('inputvalue', function(newValue, oldValue){
console.log(newValue);
})
}
Or add a function on your button click like:
<div class="form-group">
<button class="btn btn-default" ng-click="showValue()>Check If Too Much</button>
</div>
And in JS:
function checkiftoomuch($scope){
$scope.inputvalue = "";
console.log($scope.inputvalue);
$scope.showValue = function(){
console.log($scope.inputvalue);
}
}
AngularJS has 2-way data binding which means, the values in the view and controller are in sync always, they do not have to be passed back and forth.
I have a directive in my angular website that builds a page header, in that page header I am wanting to show the user's first and last name. I am wrapping my entire application in a MainController. My rendered HTML looks like this,
<html ng-app="app" ng-controller="MainController as main" class="fa-events-icons-failed ng-scope">
<head>
<style type="text/css">#charset "UTF-8";[ng\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-anchor{position:absolute;}</style>
<meta charset="utf-8">
<title ng-bind="main.windowTitle" class="ng-binding">App School Management</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="dist/css/generic.css">
<link rel="stylesheet" type="text/css" href="dist/css/styles.min.css">
<script src="https://use.fontawesome.com/2a6c262d81.js"></script><script src="https://cdn.fontawesome.com:443/js/stats.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/2a6c262d81.css" media="all">
</head>
<body cz-shortcut-listen="true">
<div id="page-wrapper">
<div id="page-header" class="bg-gradient-9 ng-isolate-scope" header="" user="userModel">
<div id="mobile-navigation">
<button id="nav-toggle" class="collapsed" data-toggle="collapse" data-target="#page-sidebar"><span></span></button>
</div>
<div id="header-logo" class="logo-bg">
<a ui-sref="dashboard.home" class="branding" title="Schoozle">
App Logo
</a>
<a id="close-sidebar" href="#" title="Close sidebar">
<i class="fa fa-chevron-left" aria-hidden="true"></i>
</a>
</div>
<div id="header-nav-left">
<div class="user-account-btn dropdown">
<a href="#" title="My Account" class="user-profile clearfix" data-toggle="dropdown">
<img width="28" src="http://placehold.it/40x40" alt="Profile image">
<span ng-bind="$scope.user.first_name" class="ng-binding"></span>
<i class="fa fa-chevron-down" aria-hidden="true"></i>
</a>
</div>
</div>
<!-- #header-nav-left -->
<div id="header-nav-right">
<div class="dropdown" id="notifications-btn">
<a data-toggle="dropdown" href="#" title="">
<span class="small-badge bg-yellow"></span>
<i class="fa fa-bell" aria-hidden="true"></i>
</a>
<div class="dropdown-menu box-md float-right">
<!-- Notifications Dropdown -->
</div>
</div>
</div>
</div>
My non directive HTML looks like this,
<div header user="userModel"></div>
And my controller code, and directive code looks this,
app.directive('header', [function () {
return {
restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
replace: true,
scope: {user: '='}, // This is one of the cool things :). Will be explained in post.
templateUrl: "/templates/partials/header.html",
controller: ['$scope', '$filter', function ($scope, $filter) {
// Your behaviour goes here :)
}]
}
}]);
app.controller('MainController', ['$scope', 'UserService', function($scope, UserService){
var self = this;
this.windowTitle = "App School Management";
this.loading = true;
this.user = {};
UserService.authenticatedUser()
.then(function(response){
self.loading = false;
self.userModel = response.message;
}, function(error) {
self.hasError = true;
self.errors = error.message;
});
}]);
How do I get my user object from the controller into the directive?
Since you are using MainController as main, add main to your directive:
<div header user="main.userModel"></div>
than user data will be available through your isolated scope two way binding within your 'templates/partials/header.html' as user object, something like user.firstName and user.lastName.
You can avoid using $scope by adding to your directive definition
controllerAs: 'ctrl';
bindToController: true;
than your user data will be available witin HTML as ctrl.user object
I've seen a similar question asked around here and the answer seems to be that the variable managing whether or not the datepicker is opened should be on the parent scope. I thought I had done that here, but it's still not working. The difference between my code and all the others I've seen is that I'm using controller as and everyone else is using $scope. How should this be working with controller as?
Full Plnkr Here
Here is the main page
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />'); </script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="style.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular.min.js" data-semver="1.4.6"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.1/ui-bootstrap-tpls.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl as main">
<button class="btn btn-primary" ng-click="main.openModal()">Open Modal</button>
</body>
</html>
Here is the modal
<div class="modal-header">
{{modal.title}}
</div>
<div class="modal-body">
<p class="input-group">
<input type="date"
class="form-control"
ng-model="modal.dt"
is-open="main.opened"
close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="main.opened = true">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</p>
</div>
Here are the controllers
var app = angular.module('plunker', ['ui.bootstrap']);
app.controller('MainCtrl', function($modal) {
var main = this;
main.openModal = function() {
var modalInstance = $modal.open({
templateUrl: 'modal.html',
controller: 'ModalInstanceCtrl as modal',
size: 'sm'
});
};
});
app.controller('ModalInstanceCtrl', function($modalInstance) {
var modal = this;
modal.title = 'Modal Title';
});
You've forgotten the datepicker-popup attribute on the input element:
<input type="date" datepicker-popup
class="form-control"
ng-model="main.dt"
is-open="main.opened"
close-text="Close" />
Also, you need to add the following code into your ng-click in order to stop the click event from propagating to the button's parent elements (clicking the parent div would immediately close the datepicker popup):
$event.preventDefault(); $event.stopPropagation();
e.g.
ng-click="$event.preventDefault(); $event.stopPropagation(); main.opened = true"
or put it into a method if you prefer.
Updated Plunker
Here is a small self-contained html todo application using routes...
It has two views - list.html and add.html
list.html:
<div>
Add Task
<br />
<br />
<div class="container" id="tasks">
<ul>
<li ng-repeat="task in tasks">
<button ng-show="!task.done" ng-click="markTaskAsDone(task)" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-ok-circle"></span></button>
<button ng-show="task.done" ng-click="markTaskAsNotDone(task)" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-pushpin"></span></button>
<button ng-click="removeTask(task)" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-remove-circle"></span></button>
<s ng-show="task.done">{{task.desc}}</s>
<span ng-show="!task.done">{{task.desc}}</span>
</li>
</ul>
<p ng-show="tasks.length == 0">Add few tasks</p>
</div>
</div>
add.html:
<div>
<span class="glyphicon glyphicon-arrow-left"></span> Back
<h2>Add a task</h2>
<div class="form-inline">
<input type="text" data-ng-model="newTask.desc" placeholder="Enter Task..." class="form-control" />
Add
</div>
</div>
I only have one controller.
controllers = {
ToDoController: function ($scope, $timeout, $location) {
//two items in by default...
$scope.tasks = [
{ desc: 'Buy milk', done: false },
{ desc: 'Collect newspaper', done: false }
];
$scope.newTask = { desc: '', done: false };
$scope.addNewTask = function () {
$location.path('/');
console.log('a');
$scope.tasks.push($scope.newTask);
}
$scope.markTaskAsDone = function (task) {
task.done = true;
console.log($scope.tasks);
}
$scope.markTaskAsNotDone = function (task) {
task.done = false;
};
$scope.removeTask = function (task) {
$scope.tasks.splice($scope.tasks.indexOf(task), 1);
};
//called to set newTask
$scope.setNewTask = function () {
$scope.newTask = { desc: '', done: false };
};
}
};
My shell page looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ToDo List</title>
<!-- Bootstrap -->
<link href="Content/bootstrap.min.css" rel="stylesheet">
<link href="Content/bootstrap-theme.min.css" rel="stylesheet">
<style>
#tasks ul {
margin: 0px;
padding: 0px;
list-style: none;
font-size: large;
}
</style>
</head>
<body>
<h1>TODO App</h1>
<div data-ng-app="todoApp">
<div data-ng-view=""></div>
</div>
<script src="Scripts/jquery-1.9.0.min.js"></script>
<script src="Scripts/bootstrap.min.js"></script>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/angular-route.min.js"></script>
<script src="Scripts/todo.js"></script>
<script>
var app = angular.module('todoApp', ['ngRoute']);
app.controller(controllers);
app.config(function ($routeProvider) {
$routeProvider
.when('/list', {
controller: 'ToDoController',
templateUrl: 'partials/list.html'
})
.when('/add', {
controller: 'ToDoController',
templateUrl: 'partials/add.html'
})
.otherwise({ redirectTo: '/list' });
});
</script>
</body>
</html>
Issue:
When I load index.html its shows the list.html. The two default items I've put shows up. I click on Add and navigate to the second view (add.html), enter details and click on the Add button in that page...I navigate to the list.html view, but its still showing the old list...not the updated list...
Surely missing some api call to do the update to the view...else this page is coming from some cache. What is the correct way to do this?
ToDoController is instantiated twice and separately for your two views. To maintain 1 instance of the controller to control both views, don't declare it in your routing, but declare it on a parent tag of the views.
For instance, like this:
<div data-ng-app="todoApp" data-ng-controller="ToDoController">
<div data-ng-view></div>
</div>
Even better is to write separate controllers for each view to put the view-specific logic into, and have 1 parent controller to store values that both controllers should have access to.
Another way to share scope among isolated controllers is using $rootScope, but you should normally try to avoid using that (like you would try to avoid using global variables in any programming language).