Angular JS hide / show both per item and for all items - javascript

I have a repeater with a headline and a description for each item. I want to be able to hide all descriptions at once with the help of a checkbox. This was easily done. Then i want to be able to hide or show each of the descriptions separately too. And i have almost got it working, except for one problem: if i hide all descriptions with the checkbox, and then click on one description to show it nothing happens until i click it a second time.
Is there any way around it?
Here is my code:
<div id="container" ng-app="" ng-controller="myController">
<input type="checkbox" ng-model="MinAllDescriptions" /> <span>Minimize all descriptions</span><br /><br />
<div class="itemContainer" ng-repeat="item in ItemList">
<span class="itemHeadline">{{item.Headline}}</span>
Hide / Show
<div class="itemDescription" ng-hide="MinAllDescriptions || MinThisDescription" ng-show="!MinAllDescriptions || !MinThisDescription">{{item.Description}}</div>
</div>
</div>
<script>
function myController($scope) {
$scope.MinAllDescriptions = false;
$scope.ItemList = [
{Headline: "Item one", Description: "This is item one"},
{Headline: "Item two", Description: "This is item two"},
{Headline: "Item three", Description: "This is item three"},
{Headline: "Item four", Description: "This is item four"},
{Headline: "Item five", Description: "This is item five"}
];
}
</script>
Check out jsfiddle here: http://jsfiddle.net/195k2e9n/1/

Try this - http://jsfiddle.net/7Lbgjvz7/
Html
<div id="container" ng-app="" ng-controller="myController">
<input type="checkbox" ng-click="minimizeAll()" ng-model="MinAllDescriptions" /> <span>Minimize all descriptions</span><br /><br />
<div class="itemContainer" ng-repeat="item in ItemList">
<span class="itemHeadline">{{item.Headline}}</span>
Hide / Show
<div class="itemDescription" ng-hide="item.MinThisDescription">{{item.Description}}</div>
</div>
</div>
Angular
function myController($scope) {
$scope.MinAllDescriptions = false;
$scope.ItemList = [
{Headline: "Item one", Description: "This is item one"},
{Headline: "Item two", Description: "This is item two"},
{Headline: "Item three", Description: "This is item three"},
{Headline: "Item four", Description: "This is item four"},
{Headline: "Item five", Description: "This is item five"}
];
$scope.minimizeAll = function(){
angular.forEach($scope.ItemList, function(item, i){
item.MinThisDescription = !$scope.MinAllDescriptions;
});
}
}

Add an event into checkbox and set $scope.MinAllDescriptions = !$scope.MinAllDescriptions

Related

Hide group on filter in Angular

My REST API is returning grouped data,
{
"Homer Simpson": [
{
"name": "First article",
"type": "text"
},
{
"name": "Second article",
"type": "text"
}
],
"Marge Simpson": [
{
"name": "Third article"
"type": "text
}
]
}
Articles can be filtered:
<input type="text" placeholder="Quicksearch" ng-model="quicksearch">
...
<div class="article-group" ng-repeat="(author, articles) in articles">
<h3>{{author}} ({{filtered.length}})</h3>
<div class="article" ng-repeat="article in articles | filter: { name: quicksearch } as filtered">
The important thing here is the ({{filtered.length}}). After applying a filter by typing something into the quicksearch input the length changes. Everything works fine, but I'd like hide "empty" authors; if you type in "third" you should no longer see Homer Simpson.
Tried ng-if="filtered.length > 0" on the article-group div, but that doesn't work.
You can simply put ng-show="filtered.length" on .article-group container:
<div class="article-group" ng-show="filtered.length" ng-repeat="(author, articles) in articles">
<h3>{{author}} ({{filtered.length}})</h3>
<div class="article" ng-repeat="article in articles | filter: { name: quicksearch } as filtered">
<pre>{{ article | json }}</pre>
</div>
</div>

Adding Checkboxs into angular js Accordion

I am new to angularjs. I am trying to add check boxes into a particular scope.group
Below is the mock-up of what i want to achieve and code.
<accordion close-others="false">
<accordion-group ng-repeat="group in groups" is-open="group.open">
<accordion-heading>
<i ng-class="{'icon-minus-sign':groups[$index].open,'icon-plus-sign':!groups[$index].open }"></i>
<span class="title-pos" >{{group.title}}</span>
</accordion-heading>
{{group.content}}
</accordion-group>
</accordion>
<script>
angular.module('main',['ui.bootstrap'])
.controller('AppCtrl', function($scope){
$scope.groups = [
{
"title":"Series",
"open":true
},
{
"title":"Price Range",
"content":"Content B",
"open":true
},
{
"title":"Engine Type",
"content":"Content C",
"open":false
},
{
"title":"Engine Type",
"content":"Content C",
"open":false
},
{
"title":"Life Style",
"content":"Content C",
"open":false
},
{
"title":"Seats",
"content":"Content C",
"open":false
},
];
})
</script>
I would like to add the check box to Engine type group.
Look forward for any help
Thanks in advance
Replace {{group.content}} with <div ng-bind-html="group.content"></div>
You should then add your checkboxes HTML code inside "content" part of "Engine Type" group, similar to this :
...
{
"title":"Engine Type",
"content":'<input type="checkbox" name="checkbox1" value="Petrol">Petrol',
"open":false
},
...
For each one of the enteries in $scope.groups whatever comes in "content" will appear inside <div ng-bind-html="group.content"></div> block.
Finally, Be sure to add ngSanitize to your module dependencies as in this plunkr
You can add the checkboxes in the content area
<accordion-group ng-repeat="group in groups" is-open="group.open">
<accordion-heading>
<i ng-class="{'icon-minus-sign':groups[$index].open,'icon-plus-sign':!groups[$index].open }"></i>
<span class="title-pos" >{{group.title}}</span>
</accordion-heading>
<div ng-repeat="option in group.options">
<!-- checkbox and text here -->
</div>
</accordion-group>
And reorganize your data to include the checkboxes model
$scope.groups = [
{
"title":"Engine Type",
"content":"Content C",
"open":false,
"options": [
"Petrol", // or if you have id for them: {id:engine_petrol, name:"Petrol"}
"Diesel",
"Hybrid"
]
}
];

Angular ng-switch inside select option

I want the [Data Presentation Format] applied to [Dropdown Box]. I need the "parent" to be presented as is inside the dropdown box, but I need the "child" to be presented with with a [tab], to show the parent-child relationship.
$scope.itemlist will be prepared in order (i.e. parenta, childa1, childa2, parentb, childb1, childb2)
The HTML:
<div ng-controller="MyCtrl">
<h1>-- Data Presentation Format --</h1>
<ul>
<li ng-repeat="item in itemlist">
<div ng-switch on="item[1]">
<div ng-switch-when="Parent">{{item[0]}}</div>
<div ng-switch-default> {{item[0]}}</div>
</div>
</li>
</ul>
<br/>
<h1>-- Dropdown Box --</h1>
<select ng-model="loc1" ng-options="item[0] for item in itemlist">
<option value="">Item</option>
</select>
<br/><br/>
<h1>-- What I Got --</h1>
<select ng-model="loc2">
<option ng-repeat="item in itemlist">
<div ng-switch on="item[1]">
<div ng-switch-when="Parent">{{item[0]}}</div>
<div ng-switch-default> {{item[0]}}</div>
</div>
</option>
</select>
The javascript:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.itemlist =
[
["Unit A", "Parent"],
["Room A", "Child"],
["Room B", "Child"],
["Room C", "Child"],
["Room D", "Child"],
["Room E", "Child"],
["Unit 1", "Parent"],
["Room 1", "Child"],
["Room 2", "Child"],
["Room 3", "Child"]
];
}
JsFiddle here: http://jsfiddle.net/HB7LU/11174/
I don't think you can use   inside the option element, as its not rendered as html. If you insist on using the element instead of something like a jQuery dropdown (which basically is a ), then i'd suggest using dashes or similar to illustrate parent/child relationship.
http://jsfiddle.net/HB7LU/11177/
I solved it using a formatting function i placed on the scope
$scope.formattedItem = function(item) {
return item[1] === 'Parent' ? item[0] : '--' + item[0];
<select ng-model="loc2">
<option ng-repeat="item in itemlist" >
{{formattedItem(item)}}
</option>
</select>

How to hide an element in angular js if this is repeatable?

I have created a code and I'm repeatable in text with icon.
You see the img but I want to hide to this actually I show this image if I have a anchor link than show if I have no link than not show this image. Is this possible in angular js?
My code is:
Angular Code is
var myAppMy = angular.module('myFapp', []);
myAppMy.controller('myControler', function($scope) {
$scope.items = [
{
"title":"Book" ,"subtitle":[
{"subtitle":"PanchTantra ",
"description":"Kids Books",
"authorName":"Kisna"
}
],
"description": "Some Book is very Good."
},
{
"title":"Mediciane Book" , "subtitle":[
{"subtitle":"Pharmacy", "description":"This book is related to Docotrs"}
],
"description": "This book is very hard"
},
{
"title":"Reciape Book" , "subtitle":[
{"subtitle":"Khana Khajana", "description":"This book is related to Foods"}
],
"description": "This book is nice..."
},
{
"title":"Computer Book" , "subtitle":[
{"subtitle":"BCA MCA", "description":"This book is related to Education"}
],
"description": "This book is very beautiful."
}
];
});
HTML Code is
<body ng-app="myFapp">
<ul ng-controller="myControler">
<li ng-repeat= "item in items">
<div>{{item.title}} </div>
<div>{{item.description}}</div>
<ul>
<li ng-repeat="subtitle in item.subtitle">
<div>{{subtitle.subtitle }} <img src="https://www.gravatar.com/avatar/76e03db06bb6dcf24f95bf4d354486db?s=32&d=identicon&r=PG" />{{ subtitle.authorName}} </div>
<div>{{subtitle.description}} this is </div>
</li>
</ul>
</li>
</ul>
</body>
Plunkr link is
Is this what you want to do ?
<div>{{subtitle.subtitle }} <img src="https://www.gravatar.com/avatar/76e03db06bb6dcf24f95bf4d354486db?s=32&d=identicon&r=PG" />{{ subtitle.authorName}} </div>
http://plnkr.co/edit/6tnGlTLeLUZdiGCUHDFV?p=preview
The ng-show directive allows you to show or hide the given HTML element based on the expression provided.
See the Official doc

AngularJS Multiple Dynamic Views based on Single Route

Forgive me if I don't explain this well. I'm having a hard time getting my mind around the real problem I'm having. I'm hoping that someone will be able to make sense of my ideas and probably correct my misunderstandings of MVC, the way Angular works, or the structure of my controllers and which components I have tied a controller to. Sorry for the long question, but I've included as many screenshots and as much code as I thought might be helpful in understanding my current predicament. I've been stuck on this for weeks.
I'm building the initial stages of an EHR (Electronic Health Record) application that doctors would use in the office when visiting with patients. Obviously I'm not done styling everything or putting in content to make it look good. I'm also not finished making all of the data dynamic - which is what I'm having a hard time with. The piece I'm working on allows the doctor to select a patient, view information from their past visits, start a visit, and fill in the information for all of their symptoms, diagnoses, and prescription information.
The left menu bar is a controller, the header is a controller, and the bottom part (patient summary) is a controller. I want it to function as you might expect - it loads the header initially and then swaps out the bottom 2/3 of the site (from summary to symptoms, diagnosis, and prescriptions). So, after clicking on Start Visit, it should load the piece below.
As you can see from the first screenshot, the URL is localhost:8080/#/patientSummary/1 where the 1 is the patient ID. Everything must be based off of that ID. So, when a doctor initially selects a patient, it should load that page and base the information in the header and the patient summary off of the ID (using a query to the DB that works just fine). Then in the transition to second screenshot, and all transitions within that page, the header should stay constant.
In each of my views, patientSummary, symptoms, diagnosis, and prescriptions-tests, at the top I have <ng-include src="'templates/header.html'"></ng-include> to get the header. I know this is not good practice. So obviously every time I change a page it re-renders the header. As stated above, I don't want to do it this way, but this is the only way that I could get it to work.
Any ideas on what I could do differently? It needs to work like I've described above, so that the header will stay constant on every page but also will be populated dynamically based off of the patient ID at the same time as the patient summary, but I can't figure out how. I've looked into Services/Cache to share the patient ID between the header and patient summary controllers, but that doesn't seem like the best way to do it, either (and every time I try it comes back as undefined even after I've injected it into the controller).
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Patient Summary</title>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
<link rel="stylesheet" type="text/css" href="css/common.css"/>
</head>
<body>
<div id="content" ng-app="osmosisApp" ng-controller="MainCtrl">
<!-- Left Menu -->
<div id="left-menu-wrapper" ng-controller="MenuCtrl">
<div class="left-menu-button" ng-click="showLeftMenu = !showLeftMenu"></div>
<nav id="left-menu" class="left-menu" ng-class="{'open' : showLeftMenu}">
<h3>Patient List</h3>
<block class="patient-button" ng-repeat="patient in patients" ng-click="go('/patientSummary/' + patient.id)">
<img class="patient-button-image" ng-src="{{patient.picture}}"/>
<div id="patient-name-and-status" class="patient-name-and-status">
<h4 class="patient-button-name">{{patient.name}}</h4>
<p class="patient-button-status">{{patient.status}}</p>
</div>
</block>
</nav>
<div id="content-cover" ng-click="showLeftMenu = !showLeftMenu" ng-class="{'content-cover' : showLeftMenu, 'content-uncover' : !showLeftMenu}"></div>
</div>
<!-- /Left Menu -->
<!-- Content -->
<div id="content-frame" ng-view></div>
<!-- /Content -->
</div>
<script src="http://maps.googleapis.com/maps/api/js?libraries=places&sensor=true"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular.js"></script>
<script src="lib/angular/angular-route.js"></script>
<script src="js/controllers.js"></script>
</body>
</html>
header.html
<!-- Header -->
<div id="header-wrapper">
<div id="patient-summary-header" class="header-row" ng-controller="HeaderCtrl">
<div id="pic-and-info" class="column-1">
<img id="patient-picture" ng-src="{{patient.picture}}" />
<h2 id="patient-name">{{patient.name}}</h2>
<div id="patient-info">
<p>{{patient.age}}, {{patient.sex}}</p>
</div>
</div>
<div id="patient-vitals-graph" class="column-2">
<canvas id="vitals-graph"></canvas>
</div>
<div id="logo-div" class="column-3">
<img id="logo" ng-src="{{'http://placehold.it/400x150'}}" />
</div>
</div>
</div>
<!-- /Header -->
patientSummary.html (one of the views)
<ng-include src="'templates/header.html'"></ng-include>
<!-- Patient Summary -->
<!-- Nav Buttons -->
<div id="start-visit" class="start-visit-button" ng-click="go('/symptoms')">Start Visit</div>
<!-- /Nav Buttons -->
<div id="patient-summary" class="section group">
<div id="column1" class="column span-2-of-3 height-5-of-5">
<h2>Past Visits</h2>
<div id="past-visits-info" class="info-section height-5-of-5">
<div class="past-visits-display" ng-repeat="pastVisit in patientSummary.pastVisits">
<h5>Diagnosis</h5>
<p>{{pastVisit.diagnosis}}</p>
<h5>Symptoms</h5>
<ul>
<li ng-repeat="symptom in pastVisit.symptoms">{{symptom}}</li>
</ul>
<div class="past-visits-display-date">{{pastVisit.date}}</div>
</div>
</div>
</div>
<div id="column2" class="column span-1-of-3 height-5-of-5">
<h2>Current Conditions</h2>
<div class="info-section height-1-of-5">
<ul>
<li ng-repeat="condition in patientSummary.currentConditions">{{condition}}</li>
</ul>
</div>
<h2>Current Prescriptions</h2>
<div class="info-section height-2-of-5">
<ul>
<li ng-repeat="prescription in prescriptions | currentPrescriptions">{{prescription.name}}</li>
</ul>
</div>
<h2>Expired Prescriptions</h2>
<div class="info-section height-2-of-5">
<ul>
<li ng-repeat="prescription in prescriptions | expiredPrescriptions">{{prescription.name}}</li>
</ul>
</div>
<h2>Patient Questions</h2>
<div class="info-section height-1-of-5">
<ul>
<li ng-repeat="question in patientSummary.questions">{{question}}</li>
</ul>
</div>
</div>
</div>
<!-- /Patient Summary -->
Routes in controllers.js
var osmosisApp = angular.module('osmosisApp', ['ngRoute'], function($routeProvider, $httpProvider) {
$routeProvider
.when('/select-news', {
templateUrl:'templates/select-news.html'
})
.when('/select-news/end-visit', {
templateUrl:'templates/select-news.html',
controller:'EndVisitCtrl'
})
.when('/patientSummary/:id', {
templateUrl:'templates/patientSummary.html',
controller:'SummaryCtrl'
})
.when('/symptoms', {
templateUrl:'templates/symptoms.html',
controller:'SymptomsCtrl'
})
.when('/prescriptions-tests', {
templateUrl:'templates/prescriptions-tests.html',
controller:'PrescriptionsTestsCtrl'
})
.when('/diagnosis', {
templateUrl:'templates/diagnosis.html',
controller:'DiagnosisCtrl'
})
.otherwise({redirectTo:'/select-news'});
// Other magic to make POST stuff work
Controllers in controllers.js
// Main Controller
osmosisApp.controller('MainCtrl', ['$scope', '$location', function ($scope, $location) {
$scope.showHeader = false;
$scope.go = function(path) {
$location.path(path);
};
$scope.$on('$routeChangeSuccess', function() {
$.getScript("lib/chart/Chart.js", function() {
$.getScript("js/chart.js");
});
});
}]);
// Header Controller
osmosisApp.controller('HeaderCtrl', ['$scope', '$http', function ($scope, $http, cacheService) {
//sharedProperties.getId();
//cacheService.get('id');
// Needs to grab the ID from the SummaryCtrl
/*$http.post("/patient/getPatientInfo", {"patient_id" : 1})
.success(function(response) {
console.log("Server response: " + JSON.stringify(response));
});*/
$scope.patient = {
"id" : 1,
"name" : "Mike DeMille",
"age" : "23",
"sex" : "Male",
"picture" : "images/MikeDeMille.png"
};
}]);
// Patient Summary Controller
osmosisApp.controller('SummaryCtrl', ['$scope', '$routeParams', function ($scope, $routeParams, cacheService) {
//sharedProperties.setId($routeParams.id);
//cacheService.put('id', $routeParams.id);
$scope.patientSummary = {
"currentConditions" : ["Lung cancer", "Another awful, life-threatening condition"],
"pastVisits" : [{
"date" : "9/1/2013",
"symptoms" : ["Old age", "Mortality"],
"diagnosis" : "The patient is going to die... Again",
"prescriptions" : [{
"name" : "Prescription name",
"dose" : "Once daily",
"form" : "tablet",
"duration" : "30 days",
"refills" : "3",
"expiration" : "9/1/2014"
},{
"name" : "Prescription name 2",
"dose" : "Twice daily",
"form" : "capsule",
"duration" : "60 days",
"refills" : "3",
"expiration" : "9/1/2014"
}],
"tests" : [{
"name" : "Test name",
"results" : "Blah blah blah, results"
},{
"name" : "Test name 2",
"results" : "Blah blah blah, results 2"
}]
},{
"date" : "7/3/2011",
"symptoms" : ["Promiscuity", "Risk taking"],
"diagnosis" : "The patient is going to die",
"prescriptions" : [{
"name" : "Prescription name 3",
"dose" : "Once daily",
"form" : "tablet",
"duration" : "30 days",
"refills" : "3",
"expiration" : "7/3/2012"
},{
"name" : "Prescription name 4",
"dose" : "Twice daily",
"form" : "capsule",
"duration" : "10 days",
"refills" : "3",
"expiration" : "7/3/2012"
}],
"tests" : [{
"name" : "Test name 3",
"results" : "Blah blah blah, results 3"
},{
"name" : "Test name 4",
"results" : "Blah blah blah, results 4"
}]
}],
"questions" : ["When am I going to die?", "Why am I going to die?"]
}
$scope.prescriptions = [{
"name" : "Prescription name",
"dose" : "Once daily",
"form" : "tablet",
"duration" : "30 days",
"refills" : "3",
"expiration" : "9/1/2014"
},{
"name" : "Prescription name 2",
"dose" : "Twice daily",
"form" : "capsule",
"duration" : "60 days",
"refills" : "3",
"expiration" : "9/1/2014"
},{
"name" : "Prescription name 3",
"dose" : "Once daily",
"form" : "tablet",
"duration" : "30 days",
"refills" : "3",
"expiration" : "7/3/2012"
},{
"name" : "Prescription name 4",
"dose" : "Twice daily",
"form" : "capsule",
"duration" : "10 days",
"refills" : "3",
"expiration" : "7/3/2012"
}
];
}]);
You may want to take a look at ui-router. ui-router supports a more complex templating structure including multiple views in one page.
You could put header template out of ng-view and the data linked with globals $rootScope, and when you change the page, you should remove data from $rootScope to change in the header.
For example, to view only the ID from param....
'index.html'
<ng-include src="'templates/header.html'"></ng-include>
<div id="content-frame" ng-view></div>
'controllers.js'
osmosisApp.controller('SummaryCtrl', ['$scope', '$routeParams', '$rootScope', function ($scope, $routeParams, $rootScope) {
$rootScope.pacientId = $routeParams.id;
.........................
$scope.$on("$destroy", function(){
delete $rootScope.pacientId;
});
'headers.html'
{{pacientId}}
You can see this working in Plunkr

Categories

Resources