Recreate HTML on click using angular 1.x - angularjs

I am creating an album where I can store images. I have attached a simple HTML for sample album. I was hoping, once the user finishes creating an album and he wants to create another one, he simply presses a plus sign. That way another template appears which is same as the one I have included in the snippet. Again, once the user clicks plus another template generates. Is there any way I can achieve this functionality? I can think of doing this with Jquery but I have to write the whole divs which is not efficient I guess. For instance, here is an example : using jquery . I was thinking if there is an efficient way of doing. That way I dont need to code the HTML each time. I am doing this using angularJs 1.x for that. Any suggestion or help is appreciated. Thank you for your time.
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<div style="background-color: yellow; width: 40%">
<div>
<h1>1st Album </h1>
<input type="text" name="albumName">
<input type="submit">
</div>
<div style="margin-top: 20px">
<input type="file" name="photos">
</div>
<div style="margin-top: 20px; font-size: 40px; font-weight: bold; padding: 20px; background-color: aqua; width: 20%">
+
</div>
</div>
</body>
</html>

One thing you can do is create a object array and loop the array using ng-repeat directive in the html.
create a object array like this
$scope.items = [{
name : "1 Album",
albumName : ""
} ]
Then use ng repeat in the DOM like this
<div ng-app="app" ng-controller="ctrl" style="background-color: yellow;width: 40%">
<div ng-repeat="item in items">
<div>
<h1> {{item.name}}</h1>
<input type="text" name="item.albumName">
<input type="submit">
</div>
<div style="margin-top: 20px">
<input type="file" name="photos">
</div>
</div>
<div style="margin-top: 20px; font-size: 40px; font-weight: bold; padding: 20px; background-color: aqua; width: 20%" ng-click="addItem()">
+
</div>
In the plus button create a function that add new object to the array
$scope.addItem = function(){
$scope.items.push({
name : $scope.items.length+1 +" Album",
albumName : ""
})
}
angular.module("app",[])
.controller("ctrl",function($scope){
$scope.items = [{
name : "1 Album",
albumName : ""
} ]
$scope.addItem = function(){
$scope.items.push({
name : $scope.items.length+1 +" Album",
albumName : ""
})
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl" style="background-color: yellow;width: 40%">
<div ng-repeat="item in items">
<div>
<h1> {{item.name}}</h1>
<input type="text" name="item.albumName">
<input type="submit">
</div>
<div style="margin-top: 20px">
<input type="file" name="photos">
</div>
</div>
<div style="margin-top: 20px; font-size: 40px; font-weight: bold; padding: 20px; background-color: aqua; width: 20%" ng-click="addItem()">
+
</div>
</div>

Related

Angularjs material design input not working even after loading css and js files

This my code.... in this material css is not geting applied to input fields and they are appearing as normal html inputs.
I have used material css and js cdns and both of them are same versions. I dont know why its not working. I checked other posts in stackoverflow but i didn't got the solution. so, Somebody please help me with this thing...
var app = angular.module('sdp', ['ngMaterial']).config(function ($mdThemingProvider) {
$mdThemingProvider.theme('custom')
.primaryPalette('blue')
.accentPalette('indigo');
}).controller('MyCtrl', function ($scope) {
});
.header {
text-align: center;
height: 80px;
margin-left: 555px !important;
line-height: 80px;
color:white;
}
body {
width: 100%;
height: 100%;
margin: 0;
font-family: Verdana,sans-serif;
font-size: 12px;
color: #111;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #94bddb), color-stop(100%, #d9edf9));
background-size: cover;
}
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Login to Data Portal</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-aria.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script>
</head>
<body>
<div ng-app="sdp" ng-controller="MyCtrl">
<md-toolbar style="background: #174a7a;">
<div class="md-toolbar-tools">
<h1 class="header">LOGIN</h1>
</div>
</md-toolbar>
</div>
<div>
<md-card >
<md-card-content>
<md-card-title>
<md-card-title-text>
<span class="md-headline">Card</span>
</md-card-title-text>
</md-card-title>
<ng-form name="colorForm">
<div layout-gt-xs="row">
<md-input-container>
<label> Username </label>
<input ng-model="un" required>
</md-input-container>
<md-input-container>
<label> Password </label>
<input ng-model="pswd" required>
</md-input-container>
</div>
</ng-form>
</md-card-content>
</md-card>
</div>
</body>
</html>
You've placed the ng-app on your toolbar div, so your AngularJS app is only working inside that part of the page.
Remove it from there and add it to your body tag to have it affect all of your page, like so:
<body ng-app="sdp">
<div ng-controller="MyCtrl">
...
Here's the full code with the change:
var app = angular.module('sdp', ['ngMaterial']).config(function ($mdThemingProvider) {
$mdThemingProvider.theme('custom')
.primaryPalette('blue')
.accentPalette('indigo');
}).controller('MyCtrl', function ($scope) {
});
.header {
text-align: center;
height: 80px;
margin-left: 555px !important;
line-height: 80px;
color:white;
}
body {
width: 100%;
height: 100%;
margin: 0;
font-family: Verdana,sans-serif;
font-size: 12px;
color: #111;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #94bddb), color-stop(100%, #d9edf9));
background-size: cover;
}
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Login to Data Portal</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-aria.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script>
</head>
<body ng-app="sdp">
<div ng-controller="MyCtrl">
<md-toolbar style="background: #174a7a;">
<div class="md-toolbar-tools">
<h1 class="header">LOGIN</h1>
</div>
</md-toolbar>
</div>
<div>
<md-card >
<md-card-content>
<md-card-title>
<md-card-title-text>
<span class="md-headline">Card</span>
</md-card-title-text>
</md-card-title>
<ng-form name="colorForm">
<div layout-gt-xs="row">
<md-input-container>
<label> Username </label>
<input ng-model="un" required>
</md-input-container>
<md-input-container>
<label> Password </label>
<input ng-model="pswd" required>
</md-input-container>
</div>
</ng-form>
</md-card-content>
</md-card>
</div>
</body>
</html>

angular app animations not working with ng-repeat and bootstrap panel

I am trying to work with the ngAnimate directive of angular but it is not working and also not showing any problem..
I had tried almost every thing but it didn't worked out..
the link to the my code is :
// Code goes here
var ngTodo = angular.module('ngTodo', ['ngAnimate','ngStorage']);
ngTodo.controller('mainController',function($scope,$localStorage){
$scope.todoArray = [];
if($localStorage.todoArray == undefined){
$localStorage.todoArray = $scope.todoArray;
}
else{
$scope.todoArray = $localStorage.todoArray;
}
$scope.addTodo = function(newTodo){
$scope.todoArray.splice(0,0, { title : newTodo.name, details : newTodo.details});
$localStorage.todoArray = $scope.todoArray;
}
$scope.removeTodo = function(index){
$scope.todoArray.splice(index,1);
$localStorage.todoArray = $scope.todoArray;
}
});
/* Styles go here */
body, html {
height: 100%;
}
body{
font-family: sans-serif;
line-height: 1.428;
font-size: 14px;
background-image: url(../../images/bg-image.jpg);
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
/* navbar top styles starts here */
input.search-todo-list{
margin-top: 20px;
}
.navbar-fixed-top{
background-color: #80bfff;
}
/* navbar top styles ends here */
/* content section starts here */
.content{
margin-top: 64px;
margin-bottom: 50px;
}
.empty-todo-list-message{
height: 200px;
margin-top: 30px;
text-align: center;
}
.todo-item{
margin-top: 10px;
}
.panel-heading,
.panel-footer{
padding: 5px 5px;
}
.panel-body{
padding: 7px;
}
.panel-default>.panel-heading,
.panel-body,
.panel-footer{
background-color: yellow;
}
/* content section starts here */
/* navbar bottom styles starts here */
.navbar-fixed-bottom input{
width: 100%;
margin-right: 20px;
}
.navbar-fixed-bottom input,
button{
margin-top: 10px;
}
.navbar-fixed-bottom{
background-color: #80bfff;
}
/* navbar bottom styles ends here */
/* animation styles */
.move-animation.ng-move {
transition: 1.75s;
opacity: 0;
}
.move-animation.ng-move.ng-move-active {
opacity: 1;
}
<!DOCTYPE html>
<html lang="en" ng-app="ngTodo">
<head>
<meta charset="UTF-8">
<link href="assets/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="assets/font-awesome-4.7.0/font-awesome-4.7.0/css/font-awesome.min.css" type="text/css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-animate.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.11/ngStorage.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div class="container-fluid" ng-controller="mainController">
<!-- navbar top starts here -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="row">
<div class="col-sm-2">
<div class="navbar-header">
<a class="navbar-brand" href="#">
<img width="40px" alt="Todo App Icon" class="img-circle img-responsive" src="assets/icon/icon.jpg">
</a>
</div>
</div>
<div class="col-sm-8">
<h2 class="text-center">Today's Todo List</h2>
</div>
<div class="col-sm-2">
<input type="text" placeholder="search..." ng-model="query" class="search-todo-list">
</div>
</div>
</div>
</nav>
<!-- navbar top ends here -->
<!-- content section starts here -->
<div class="row">
<div class="col-sm-12 content">
<div class="row">
<div class="col-sm-6 col-sm-offset-3 empty-todo-list-message" ng-if="todoArray.length == 0">
<div class="panel panel-default ">
<div class="panel-body">
<h1><strong>Your Todo List is EMPTY</strong></h1>
</div>
</div>
</div>
<!-- item starts here -->
<div class="col-sm-6 col-sm-offset-3 todo-item" ng-repeat="todo in todoArray | filter : query" ng-animate=" 'animate' ">
<div class="panel panel-default ">
<div class="panel-heading text-center">
<h3><strong>{{ todo.title + " : " }}</strong></h3>
</div>
<div class="panel-body">
<strong>{{ todo.details}}</strong>
</div>
<div class="panel-footer text-center">
<button ng-click="removeTodo($index)"><i class="fa fa-trash-o fa-2x" aria-hidden="true"></i>
delete</button>
</div>
</div>
</div>
<!-- item ends here -->
</div>
</div>
</div>
<!-- content section ends here -->
<!-- navbar bottom starts here -->
<nav class="navbar navbar-default navbar-fixed-bottom">
<div class="container-fluid">
<div class="row">
<div class="col-sm-4">
<input type="text" placeholder="Add Todo Item" required ng-model="newTodo.name" >
</div>
<div class=" col-sm-4">
<input type="text" placeholder="Add Todo Item Details" required ng-model="newTodo.details">
</div>
<div class=" col-sm-2">
<button ng-click="addTodo(newTodo)" ><i class="fa fa-plus" aria-hidden="true"></i> Add ToDo</button>
</div>
</div>
</div>
</nav>
<!-- navbar bottom ends here -->
</div>
</body>
</html>

Loose Scope in angular JS

I have a multiple tab Html page . On one tab i have add 3 input box and an add button. Whenever the add button is clicked the data to be added into a grid below. But scope is not accessing these variables. Attaching my code below :
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div id="tabs">
<ul>
<li ng-repeat="tab in tabs"
ng-class="{active:isActiveTab(tab.url)}"
ng-click="onClickTab(tab)">{{tab.title}}</li>
</ul>
<div id="mainView">
<div ng-include="currentTab"></div>
</div>
</div>
<script type ="text/javascript" id="one.tpl.html">
<div class="form-group">
<label class="col-md-2 control-label">Name</label>
<div class="col-md-4">
<input type="text" class="form-control" name="name"
ng-model="names" />{{name}}
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Employees</label>
<div class="col-md-4">
<input type="text" class="form-control" name="employees"
ng-model="employeess" />
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Headoffice</label>
<div class="col-md-4">
<input type="text" class="form-control" name="headoffice"
ng-model="headoffices" />
</div>
</div>
<div class="form-group">
<div style="padding-left:110px">
<input type="button" value="Add" ng-click="addRow()" class="btn btn-primary"/>
</div>
</div>
<div>
<table class="table">
<tr>
<th>Name
</th>
<th>Employees
</th>
<th>Head Office
</th>
</tr>
<tr ng-repeat="company in companies">
<td>{{company.name}}
</td>
<td>{{company.employees}}
</td>
<td>{{company.headoffice}}
</td>
</tr>
</table>
</div>
</script>
<script type="text/ng-template" id="two.tpl.html">
<div id="viewTwo">
<h1>View Two</h1>
<p>Test 2</p>
</div>
</script>
<script type="text/ng-template" id="three.tpl.html">
<div id="viewThree">
<h1>View Three</h1>
<p>Test 3</p>
</div>
</script>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.companies = [];
$scope.tabs = [{
title: 'One',
url: 'one.tpl.html'
}, {
title: 'Two',
url: 'two.tpl.html'
}, {
title: 'Three',
url: 'three.tpl.html'
}];
$scope.currentTab = 'one.tpl.html';
$scope.onClickTab = function(tab) {
$scope.currentTab = tab.url;
}
$scope.isActiveTab = function(tabUrl) {
return tabUrl == $scope.currentTab;
}
$scope.addRow = function(){
$scope.companies.push({ 'name':$scope.names, 'employees': $scope.employeess, 'headoffice':$scope.headoffices });
$scope.names='';
$scope.employeess='';
$scope.headoffices='';
}
});
</script>
<style>
#tabs ul {
list-style: none;
padding: 0;
margin: 0;
}
#tabs li {
float: left;
border: 1px solid #000;
border-bottom-width: 0;
margin: 3px 3px 0px 3px;
padding: 5px 5px 0px 5px;
background-color: #CCC;
color: #696969;
}
#mainView {
border: 1px solid black;
clear: both;
padding: 0 1em;
}
.active {
background-color: #FFF;
color: #000;
}
</style>
</body>
</html>
Following variables are not accessible in scope :
$scope.names
$scope.employeess
$scope.headoffices
That's because ng-template creates child scope, so you can basically do one of 2 things:
Access properties via $parent (like $parent.employeess). Example:https://plnkr.co/edit/2LLakRumEB25wyNhNmDg?p=preview)
Define object for new item like below.
Example:
https://plnkr.co/edit/sFkim5WwN5ffPsWtdcDP?p=preview
$scope.newRow = {
names: '',
employeess: '',
headoffices: ''
}
And access them via the same prefix:
ng-model="newRow.employeess"
Explanation:
Scopes have common structure, where $parent property is the parent scope e.t.c up to $rootScope.
When you're using ng-template it creates a new child scope, so the values, assigned within it are stored in the child scope and not in $parent (your controllers scope). The values you're searching for are in child scope because ng-model works in current scope. So you need to make sure that ng-model knows which scope to write. It can be done via $parent parameter or within object. As for 2nd option - the reason is simple. Object value can't be assigned when object is undefined, so search goes to upper level and so on.

Angular Material: Layout Containers to fill parent

I'm using Angularjs 1.5 with Angular Material 1.0.5 to create a mock table. The issue I have is I can't get the child component 'cell' background-color to fill out 100% in height of the parent. Here is my jsfiddle. Any help on how to do this is appreciated?
JSFIDDLE
HTML
<div ng-app="myApp" ng-controller="mainCtrl">
<style>
.table-row{
border-top: 1px solid black;
border-left: 1px solid black;
border-bottom: 1px solid black;
}
.table-cell{
border-right:1px solid black;
}
</style>
<script type="text/ng-template" id="/table">
<div layout='column'>
<div ng-repeat='col in [0,1,2]'>
<div layout="row" class='table-row'>
<div layout-align='center center' ng-repeat='row in [0,1,2]' flex class='table-cell'>
<div ng-if='$odd' flex>
<cell></cell>
</div>
<div ng-if='$even'flex>
TEST</br>
TEST</br>
</div>
</div>
</div>
</div>
</div>
</script>
<script type="text/ng-template" id="/cell">
<div style='background-color:red'>
CELL
</div>
</script>
<h3>
{{name}}
</h3>
<table>
</table>
</div><!--end app-->
You need to add a hierarchy of layout="column/row" attributes. They are the containers forflex`, otherwise your flex won't have any effect.
https://jsfiddle.net/t8pssapu/

AngularJS Bootstrap make the datetimer picker responsive

I am trying to make the datetimepicker responsive for bootstrap but having issues.
I have seen this plugin:
https://github.com/niftylettuce/bootstrap-datepicker-mobile#requirements
which would be great to use in my application, but the problem is my application doesn't use jQuery (nor do I want it to).
I have the datepicker set up like this:
<div class="col-md-4">
<div ng-model="controller.today" datepicker ng-change="controller.getArchive()"></div>
</div>
Does anyone know how I can make the datetimepicker responsive without using jQuery?
Well I managed to fix this myself.
I created my own templates which looked like this:
<script id="template/datepicker/datepicker.html" type="text/ng-template">
<div class="datepicker" ng-switch="datepickerMode" role="application" ng-keydown="keydown($event)">
<daypicker ng-switch-when="day" tabindex="0"></daypicker>
<monthpicker ng-switch-when="month" tabindex="0"></monthpicker>
<yearpicker ng-switch-when="year" tabindex="0"></yearpicker>
</div>
</script>
<script id="template/datepicker/day.html" type="text/ng-template">
<div>
<div class="row">
<div class="col-xs-2">
<button class="btn btn-default btn-block" ng-click="move(-1)" tabindex="-1"><span class="fa fa-chevron-left"></span></button>
</div>
<div class="col-xs-8">
<button class="btn btn-default btn-block" ng-click="toggleMode()" ng-disabled="datepickerMode === maxMode" tabindex="-1">{{ title }}</button>
</div>
<div class="col-xs-2">
<button class="btn btn-default btn-block"><span class="fa fa-chevron-right"></span></button>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="flexbox">
<div ng-repeat="label in labels track by $index">
<small aria-label="{{ label.full }}">{{ label.abbr }}</small>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="flexbox" ng-repeat="row in rows track by $index">
<div ng-repeat="dt in row track by dt.date">
<button class="btn btn-default btn-block" ng-class="{'btn-info': dt.selected, active isactive(dt)}" ng-click="select(dt.date)" ng-disabled="dt.disabled" tabindex="-1"><span ng-class="{'text-muted': dt.secondary, 'text-info' dt.current}">{{ dt.label }}</span></button>
</div>
</div>
</div>
</div>
</div>
</script>
Then I created 2 SASS files, one for the actual datepicker:
.datepicker {
text-align: center;
.row {
> div {
padding-left: 1px;
padding-right: 1px;
&:first-child {
padding-left: 15px;
}
&:last-child {
padding-right: 15px;
}
}
> .col-xs-12,
> .col-sm-12,
> .col-md-12,
> .col-lg-12 {
padding-left: 15px;
padding-right: 15px;
}
}
.flexbox {
margin-top: -1px;
&:first-child {
margin-top: 2px;
}
}
}
and a flexbox one:
.flexbox {
display: flex;
> div {
-ms-flex: 1 auto;
flex: 1 auto;
margin-left: -1px;
&:first-child {
margin-left: 0;
}
}
}
This solved my issue.
I will update this when I have all templates replaced and I will add a jsfiddle.

Resources