Accordian in angularjs - angularjs

I want to add accordian in my angularjs app. I have to show some details on button click "Additional Information". Not sure how to toggle class panel with button click.
Here is my html:
<button ng-click="showPanel()" class="accordian">Additional Information</button>
<br>
<div class="panel" style="width: 750px;">
<div class="panel-heading">Attributes</div>
<table class="table table-bordered">
<tbody>
<tr >
<td>{{room.allowFecc}}</td>
</tr>
</tbody>
</table>
</div>
CSS:
button.accordian {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
button.accordion.active, button.accordion:hover {
background-color: #ddd;
}
div.panel {
padding: 0 18px;
display: none;
background-color: white;
}
div.panel.show {
display: block;
}

You can drop the class that simply does a display: block - Angular has built in directives like ngShow and ngHide which will take care of this for you. Basically in Angular, you want to manipulate the data, and then let the view bind back to the data.
For your basic example above, you want to toggle a variable from true to false to show the accordian or hide it, and then based on the variable, add a class:
The Angular:
$scope.toggleAccordian = function() {
$scope.showAccordian = !$scope.showAccordian; //our toggle variable
}
The HTML:
<button ng-click="toggleAccordian()" class="accordian">Additional Information</button>
<br>
<div class="panel" ng-show="showAccordian" ng-class="{'accordianActiveClass': showAccordian }" style="width: 750px;">
<div class="panel-heading">Attributes</div>
<table class="table table-bordered">
<tbody>
<tr >
<td>{{room.allowFecc}}</td>
</tr>
</tbody>
</table>
</div>
The ng-class="{'accordianActiveClass': showAccordian }" is the class magic, replace accordianActiveClass with the class you want to show, and when the condition is satisfied (showAccordian) the class will be added.

Related

layout design suggestion for modal popup

I am looking for layout design suggestion for one of my screens.
I have a modal popup window which displays the customers information in tabbed layout which means one tab per customer. each tab has 3 accordions out of which 2 accordions have tables(grid).
Now the requirement is to compare the customer data side by side instead of using tabs. we can have maximum of 4 customers.
I assume this is what you are going for:
Layout diagram
I suggest you use the <table> tag for that. Each table column (<td>) will represent one customer.
I provided you with my example below.
body {
background-color: #ccc;
}
#modal {
width: 80%;
min-width: 100px;
height: 80%;
min-height: 100px;
background-color: white;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
padding: 15px;
text-align: center;
}
#customer_table {
position: absolute;
bottom: 10px;
width: 100%;
height: 75%;
vertical-align: top;
border-spacing: 0;
}
tr:first-child td {
height: 20px;
background-color: #5a5a5a;
color: white;
}
td {
border-left: solid #5a5a5a 1px;
border-right: solid #5a5a5a 1px;
border-bottom: solid #5a5a5a 1px;
}
<html>
<body>
<div id="modal">
<h2>Customer table</h2>
<table id="customer_table">
<tr>
<td>Customer 1</td>
<td>Customer 2</td>
<td>Customer 3</td>
<td>Customer 4</td>
</tr>
<tr>
<td>Customer data</td>
<td>Customer data</td>
<td>Customer data</td>
<td>Customer data</td>
</tr>
</table>
</div>
</body>
</html>

How to fold table columns into rows on mobile devices?

I'm developing a website featuring a restaurant's menu. Each item is available in different sizes, each at a different price. This is displayed on medium and large devices using a table, with a column for each price:
On mobile devices, the screen is too narrow to properly display up to 4 different sizes per product.
So I would like to fold columns into rows, having each row starting with the column name:
Is there anything like this possible using a responsive design? I'm trying to avoid maintaining two different HTML versions of the content, one visible only on mobile, and one visible only on larger screens.
I'm using Foundation 5, so I'm ideally looking for a solution using this grid system, but I'm open to any solution really.
The solution involves making table cells display: block on mobile devices, and adding a data-* attribute to each cell, matching the column name.
This data attribute is injected in the cell's ::before pseudo-element with content: attr().
Example:
<table>
<thead>
<tr>
<th>Pasta</th>
<th>Small</th>
<th>Regular</th>
</tr>
</thead>
<tbody>
<tr>
<td>Spaghetti Bolognese</td>
<td data-th="Small">£5.00</td>
<td data-th="Regular">£7.00</td>
</tr>
<tr>
<td>Lasagna</td>
<td data-th="Small">£5.00</td>
<td data-th="Regular">£7.00</td>
</tr>
</tbody>
</table>
CSS:
#media only screen and (max-width: 40em) {
thead th:not(:first-child) {
display: none;
}
td, th {
display: block;
}
td[data-th]:before {
content: attr(data-th);
}
}
You'll need to add some extra float to make it pretty.
Working example: http://codepen.io/anon/pen/medrZo
CSS changes for the above results
table {
border-spacing: 0;
}
td,
th {
padding: 0.5em;
}
th {
font-weight: bold;
text-align: left;
}
thead th {
background-color: #999;
color: white;
}
td > div {
float: right;
}
#media screen and (max-width: 885px) {
thead th:not(:first-child) {
display: none;
}
thead th:first-child:after {
content: "'s";
}
td, th {
display: block;
width: 100% !important;
}
td:first-child {
font-weight: bold;
}
td[data-th]:before {
content: attr(data-th);
border-radius: 10px 0px 0px 10px;
font-weight: bold;
min-width: 10rem;
display: inline-block;
}
}

onsen-ui gestures not working

I need to implement a menu with the exact same looks as onsen sliding-menu,but that slides from top. I was thinking to use onsen gestures to be able to drag the menu, but the gestures sample provided in the onsen guide does not work. Am I missing something?
<ons-gesture-detector>
<div id="detect-area" style="width: 300px; height: 300px;background-color:blue;">
Swipe Here
</div>
</ons-gesture-detector>
<script>
alert("in");
$(document).on('swipeleft', '#detect-area', function() {
alert("swipe");
})
</script>
Try this, it should work. Don't forget to add jquery first.
<ons-gesture-detector style="height: 300px; margin: 50px 50px;">
<div id="hoge" style="border: 1px solid #ccc; background-color: #f9f9f9; width: 100%; height: 300px; line-height: 300px; text-align: center; color: #999;">
...
</div>
</ons-gesture-detector>
<script>
var eventName =
'drag dragleft dragright dragup dragdown hold release swipe swipeleft swiperight ' +
'swipeup swipedown tap doubletap touch transform pinch pinchin pinchout rotate';
$(document).on(eventName, '#hoge', function(event) {
if (event.type !== 'release') {
$(this).text(event.type);
}
});
</script>

How to get div to stop blinking for a split second when its ng-if is false?

Thanks to the answer to this question, I don't get a JavaScript error when AngularJS gets a 401 error back from AJAX since I replaced ng-show with ng-if.
However, even with ng-if, when AJAX returns a 401 error and the hasNoAccess div is displayed, I notice that when the page loads, the hasAccess div blinks quickly on the screen and then disappears.
How can I get the hasAccess div to stop displaying for a split second on page load when its ng-if condition is false?
ADDENDUM: I can put a style="display:none" in the hasAccess div, which solves the problem, but then, when the ng-if if true, it doesn't display the div at all.
EDIT: Added ng-cloak to the hasAccess element, but it still blinks.
<div class="pageContent">
<h2>Showcase AngularJS 4: Interactivity with Bootstrap</h2>
<div ng-app="mainApp">
<div ng-controller="projectManagerController">
<div class="projectManagerContainer">
<div ng-cloak class="hasAccess" ng-if="projectManagers != '[noAccess]'">
<div class="projectManagerArea">
<h3>Project Managers</h3>
<table class="table table-striped table-bordered">
<tr>
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
<tr ng-repeat="projectManager in projectManagers| orderBy: 'surname'">
<td class="text-right">{{projectManager.id}}</td>
<td>{{projectManager.givenname}}</td>
<td>{{projectManager.surname}}</td>
</tr>
</table>
<button class="btn btn-success">
<span class="glyphicon glyphicon-pencil"></span> Edit
</button>
</div>
</div>
<div class="hasNoAccess" ng-if="projectManagers == '[noAccess]'">
<div class="alert alert-warning">No access to project managers.</div>
</div>
</div>
</div>
</div>
<script>
var app = angular.module('mainApp', []);
app.controller('projectManagerController', function ($scope, $http) {
$scope.message = 'Here are the project managers:';
$http.get("<?= qsys::getFullUrl("task/showcaseAngularjs3") ?>")
.success(function (response) {
$scope.projectManagers = response;
})
.error(function (error) {
$scope.projectManagers = '[noAccess]';
});
});
</script>
<style type="text/css" scoped>
.pageContent {
margin: 10px;
}
.projectManagerContainer {
width: 500px;
}
.projectManagerArea {
border: 1px solid #ddd;
background-color: #eee;
padding: 20px;
border-radius: 5px;
}
.projectManagerArea h3 {
font-size: 22px;
margin: 0 0 10px 0;
}
</style>

How to hide a div by clicking a button?

In my angular.js learning project I want to hide one div and show another when I click a button.
In this code, I'd like the first div to be hidden at the click (or even destroyed?) and the second div to be shown.
Basically I want the user experience of going from page 1 to page 2 in my app.
How do I make this happen?
Index.html
<ion-content ng-controller="StartpageCtrl">
<div class="list card" id="startCard" ng-show="showstartCard">
<div class="item item-image item item-text-wrap">
Card 1
</div>
</div>
<div class="list card" id="secondCard" ng-show="showsecondCard">
<div class="item item-image item item-text-wrap">
Card 2
</div>
</div>
<button ng-click="hideCard()" class="button button-full button-calm button icon-right ion-chevron-right">
Start now
</button>
</ion-content>
controllers.js
.controller("StartpageCtrl", funcion($scope){
$scope.showstartCard = true;
$scope.showsecondCard = false;
$scope.hideCard = function() {
$scope.showstartCard = false;
$scope.showsecondCard = true;
};
});
When I run the page I see "Card 2" and nothing happens when I click the button.
What I wanted to see was "Card 1" and for it to switch to "Card 2" as I click the button...
Solved
I had forgotten to add references to controllers.js in the app.js angular.module as well as the script tag in index.html. It works fine now.
Using angular:
HTML file:
<td>Source Doc..
<div id="mydiv" ng-show="showDetails">
<div id="mydiv-container">
<div id="mydiv-content">
Close
<br>
hello
</div>
</div>
</div>
</td>
css file:
body {
height: 100%;
background-color: #F0F0F0;
font-family: Arial, sans-serif;
}
#mydiv {
width: 100%;
height: 100%;
overflow: hidden;
left: 100px;
top: 150px;
position: absolute;
opacity: 0.95;
}
#mydiv-container {
margin-left: auto;
margin-right: auto;
}
#mydiv-content {
width: 70%;
padding: 20px;
background-color: white;
border: 1px solid #6089F7;
}
a {
color: #5874BF;
text-decoration: none;
}
a:hover {
color: #112763;
}
If you are looking for toggle, then this code might help as there is no need to have any extra CSS or JS functions needed.
<button ng-click="isDetailOpen = !isDetailOpen"
ng-class="!isDetailOpen ? 'ion-ios-arrow-down' : 'ion-ios-arrow-up'"
class="button button-clear button-positive icon-right">
<span ng-show="!isDetailOpen">More Detail</span>
<span ng-show="isDetailOpen">Less Detail</span>
</button>
<div ng-show="isDetailOpen">
<p>Per ad ferri dicta, omnis laudem dicunt duo an. Ex pri solum definitiones.</p>
</div>
I figured it out while working on Angular-Ionic project.

Resources