JSFiddle - React, Tailwind, and code Playground
by Romel Herrera
HTML
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular-messages.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/danialfarid-angular-file-upload/7.2.0/ng-file-upload-shim.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/danialfarid-angular-file-upload/7.2.0/ng-file-upload.js"></script>
<section ng-app="publications" ng-controller="PublicationsController" style="padding: 10px">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">New Publication</h3>
</div>
<div class="panel-body">
<form name="publicationForm" novalidate="" ng-submit="submit()">
<button class="btn btn-primary" type="submit"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span> Publish</button>
<hr>
<div class="form-group">
<label class="control-label"><span class="glyphicon glyphicon-bookmark"></span> Title <sup style="color: red;">*</sup>
</label>
<input type="text" name="title" ng-model="model.title" required minlength="7" class="form-control" placeholder="">
<div data-ng-messages="publicationForm.$submitted && publicationForm.title.$error" class="help-block">
<div data-ng-message="required">- The <b>title</b> is required.</div>
<div data-ng-message="minlength">- The <b>title</b> must be at least 7 characters long.</div>
</div>
</div>
<hr class="hr-xs">
...
CSS
.alert-xs {
padding: 1px 5px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
}
/* FileUpload START */
.file-name {
white-space: nowrap;
//font-weight: bold;
width: 300px;
margin-bottom: 2px;
}
.file-name:not(:hover) {
overflow: hidden;
text-overflow: ellipsis;
}
.remove-button {
padding-top: 10px;
}
.img-preview {
height:100px;
max-height: 250px;
max-width: 250px;
margin-bottom: 5px;
}
.file-input {
visibility: hidden;
position: absolute;
top: 0;
left: 0;
height: 0;
width: 0;
}
/* FileUpload END */
.hr-xs {
margin-top: 10px;
margin-bottom: 10px;
}
JavaScript
'use strict';
angular.module('publications', ['ngMessages', 'ngFileUpload'])
.controller('PublicationsController', ['$scope', '$filter', '$log', function ($scope, $filter, $log) {
$scope.model = {
files: []
};
$scope.submit = function () {
if ($scope.publicationForm.$valid) {
$log.info('Submit the form');
} else {
$log.info('something missing')
}
};
$scope.inQueue = function () {
var queue = 0;
angular.forEach($scope.model.files, function (value) {
if (!angular.isDefined(value.inServer) && !angular.isDefined(value.$error)) {
queue += 1;
}
});
return queue;
};
$scope.removeAllQueueFiles = function () {
// TODO remove only the queue and the invalids files, kept the those they are on the server
angular.copy([], $scope.model.files);
};
$scope.removeFile = function (fileIndex) {
$scope.model.files = $filter('filter')($scope.model.files, function(value, index) { return index !== fileIndex;});
};
}])
/**
* AngularJS byte format filter
* Source: https://gist.github.com/thomseddon/3511330
*/
.filter('bytes', [function () {
return function (bytes, precision) {
if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) {
return '-';
}
if (typeof precision === 'undefined') {
precision = 1;
}
var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
number = Math.floor(Math.log(bytes) / Math.log(1024));
return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + ' ' + units[number];
};
}]);