Skip to content

Instantly share code, notes, and snippets.

@qgustavor
Last active August 29, 2015 14:24
Show Gist options
  • Select an option

  • Save qgustavor/09db2171c4eb351771e7 to your computer and use it in GitHub Desktop.

Select an option

Save qgustavor/09db2171c4eb351771e7 to your computer and use it in GitHub Desktop.
Permeabilidade dos Solos
<!DOCTYPE html>
<html manifest="manifest.appcache">
<head>
<meta charset="UTF-8">
<title>Permeabilidade dos Solos</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet prefetch" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.0/css/materialize.min.css">
<link rel="stylesheet prefetch" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet prefetch" href="pen.css">
<meta name="mobile-web-app-capable" content="yes">
<meta name="theme-color" content="#009688">
<meta name="application-name" content="Permeabilidade dos Solos">
<!-- Don't complain with new HTML5 features, they aren't even done -->
</head>
<body>
<!-- Menu superior -->
<nav>
<div class="nav-wrapper teal"> <a href="#" class="brand-logo">Coeficiente de Permeabilidade</a>
<ul id="nav-mobile" class="right hide-on-small-only">
<li><a href="#info" class="tooltipped" data-position="bottom" data-delay="50" data-tooltip="Informações sobre o aplicativo"><i class="material-icons">info</i></a></li>
<li><a href="#ensaio/novo" class="tooltipped" data-position="bottom" data-delay="50" data-tooltip="Nova obra"><i class="material-icons">add</i></a></li>
</ul>
</div>
</nav>
<div class="container">
<!-- Tela principal -->
<div class="row state-page" id="main">
<div class="col s12">
<ul class="ensaios-collection collection with-header">
<li class="collection-header"> Obras </li>
<li class="collection-item no-data center-align">
<div><i class="material-icons teal-text text-lighten-1 big-icon">assignment</i>Ainda não há obras cadastradas</div>
</li>
</ul>
<div class="hide-on-med-and-up center-align"> <a href="#info">Informações sobre o aplicativo</a> </div>
<div class="fixed-action-btn hide-on-med-and-up" style="bottom: 45px; right: 24px;">
<a href="#ensaio/novo" class="btn-floating btn-large teal tooltipped" data-position="top" data-delay="50" data-tooltip="Nova obra"> <i class="large material-icons">add</i> </a>
</div>
</div>
</div>
<!-- Tela de ensaios -->
<div class="row state-page" id="ensaio">
<div class="col s12">
<!-- Guias mostradas na parte superior -->
<ul class="tabs">
<li class="tab col s3"><a class="active" data-href="dados">Dados</a></li>
<li class="tab col s3"><a data-href="amostras">Amostras</a></li>
<li class="tab col s3"><a data-href="norma">Norma</a></li>
<li class="tab col s3"><a data-href="manual">Manual</a></li>
</ul>
</div>
<!-- Formulário de entrada de dados gerais -->
<div data-id="dados" class="col s12">
<div class="row">
<div class="input-field col s12 m6">
<input id="obra" type="text" class="validate">
<label for="obra">Obra</label>
</div>
<div class="input-field col s12 m6">
<input id="local" type="text" class="validate">
<label for="local">Local</label>
</div>
<div class="input-field col s4 m3">
<input id="trecho" type="text" class="validate">
<label for="trecho">Trecho</label>
</div>
<div class="input-field col s4 m3">
<input id="subtrecho" type="text" class="validate">
<label for="subtrecho">Sub-trecho</label>
</div>
<div class="input-field col s4 m6">
<input id="furo" type="text" class="validate">
<label for="furo">Furo</label>
</div>
<div class="input-field col s6">
<input id="profundidade" type="number" step="any" class="validate">
<label for="profundidade">Profundidade</label>
</div>
<div class="input-field col s6">
<input id="data" type="date" class="validate datepicker">
<label for="data" class="active">Data</label>
</div>
<div class="input-field col s6 m4">
<input id="areaBureta" type="number" step="any" class="validate">
<label for="areaBureta">Área da bureta</label>
</div>
<div class="input-field col s6 m4">
<input id="areaCorpoProva" type="number" step="any" class="validate">
<label for="areaCorpoProva">Área do corpo de prova</label>
</div>
<div class="input-field col s12 m4">
<input id="alturaCorpoProva" type="number" step="any" class="validate">
<label for="alturaCorpoProva">Altura do corpo de prova</label>
</div>
</div>
</div>
<!-- Formulário de entrada dos dados das amostras -->
<div data-id="amostras" class="col s12">
<div class="row">
<div class="col s12">
<ul class="pagination">
<li class="active"><a href="#!">1</a></li>
<li class="waves-effect"><a href="#!"><i class="material-icons">add</i></a></li>
</ul>
</div>
</div>
<div class="row">
<div class="input-field col s9 m3 l4">
<input id="horaInicio" type="text" class="validate">
<label for="horaInicio">Hora de Início</label>
</div>
<div class="input-field col s3 m3 l2">
<button id="marcarHoraInicio" class="btn">Agora</button>
</div>
<div class="input-field col s9 m3 l4">
<input id="horaFim" type="text" class="validate">
<label for="horaFim">Hora do Fim</label>
</div>
<div class="input-field col s3 m3 l2">
<button id="marcarHoraFim" class="btn">Agora</button>
</div>
<div class="input-field col s6 m4">
<input id="alturaInicial" type="number" step="any" class="validate">
<label for="alturaInicial">h1 (cm)</label>
</div>
<div class="input-field col s6 m4">
<input id="alturaFinal" type="number" step="any" class="validate">
<label for="alturaFinal">h2 (cm)</label>
</div>
<div class="input-field col s12 m4">
<!-- Infelizmente a especificação para determinar temperatura não foi implementada:
https://dvcs.w3.org/hg/dap/raw-file/default/temperature/Overview.html -->
<input id="temperatura" type="number" step="any" class="validate">
<label for="temperatura">Temperatura</label>
</div>
</div>
<div class="row">
<div class="input-field col s4">
<input id="tempo" type="text" readonly>
<label for="tempo">Tempo (s)</label>
</div>
<div class="input-field col s4">
<input id="kt" type="text" readonly>
<label for="kt">kt (cm/s)</label>
</div>
<div class="input-field col s4">
<input id="k20" type="text" readonly>
<label for="k20">k20 (cm/s)</label>
</div>
</div>
</div>
<!-- Espaço para mostrar a norma -->
<div data-id="norma" class="col s12 center-align"><div class="card-panel teal">
<i class="material-icons white-text big-icon">warning</i><i class="white-text">Em construção</i>
</div></div>
<!-- Espaço para mostrar o manual do permeâmetro -->
<div data-id="manual" class="col s12 center-align"> <img class="responsive-img" src="https://i.imgur.com/qQnFjab.jpg" alt="Manual do permeâmetro. Infelizmente não vou escrever o que está escrito." /> </div>
</div>
<!-- Página onde é mostrada as informações dos desenvolvedores -->
<div class="row state-page" id="info">
<div class="col s12">
<ul class="collection with-header">
<li class="collection-header">Desenvolvedores</li>
<li class="collection-item avatar">
<img src="https://secure.gravatar.com/avatar/4039a864f60bdb71f6b8ad64f0b94f87" alt="Avatar do Gustavo" class="circle">
<span class="title">Gustavo Rodrigues</span>
<p>Desenvolvimento do aplicativo web<br>
<a class="orange-text" href="mailto:メエル@qgustavor.tk" title="E-mail">メエル</a><a class="green-text" href="https://twitter.com/qgustavor" title="Twitter">@qgustavor</a><a class="indigo-text" href="http://qgustavor.tk" title="Website">.tk</a>
</p>
</li>
<li class="collection-item avatar">
<img src="https://secure.gravatar.com/avatar/none?d=mm" alt="Avatar do Jonathan" class="circle">
<span class="title">Johnattan Pereira</span>
<p>Desenvolvimento da planilha que baseou o aplicativo<br>
© Johnattan Pereira - All rights reserved<br>
<!-- Por mim você não precisa de colocar ano, o que você precisa mostrar é que há "dono".
Algums discordam disso, por exemplo: http://stackoverflow.com/q/2390230/1850091
Caso escolha usar então coloque o ano de publicação, como mostrado no link acima. -->
Contato: [email protected]
</p>
</li>
</ul>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.0/js/materialize.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.3/moment.min.js"></script>
<script src="https://cdn.rawgit.com/chrisdavies/rlite/7a2be52119cf3f482e0d751a7d677a88bad58c1c/rlite.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/localforage/1.2.3/localforage.min.js"></script>
<script src="pen.js"></script>
</body>
</html>
CACHE MANIFEST
# 2015-07-10T16:40-03:00
# Explicitly cached entries
index.html
pen.css
pen.js
# External resources:
https://cdn.rawgit.com/chrisdavies/rlite/7a2be52119cf3f482e0d751a7d677a88bad58c1c/rlite.min.js
https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.0/css/materialize.min.css
https://cdnjs.cloudflare.com/ajax/libs/localforage/1.2.3/localforage.min.js
https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.3/moment.min.js
https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js
https://fonts.googleapis.com/icon?family=Material+Icons
https://i.imgur.com/qQnFjab.jpg
FALLBACK:
https://secure.gravatar.com/avatar/* https://secure.gravatar.com/avatar/none?d=mm
# All other resources (e.g. sites) require the user to be online.
NETWORK:
*
html {
width: 100vw;
overflow-x: hidden;
}
.state-page {
display: none;
}
.big-icon {
font-size: 5em;
display: block;
}
.no-data {
font-size: 1.5em;
}
nav .brand-logo {
font-size: 1.5rem;
padding-left: 1em;
max-width: 100%;
overflow: hidden;
}
.tabs {
background: transparent;
}
.tabs .tab {
overflow: hidden;
}
nav, nav .nav-wrapper i, nav a.button-collapse, nav a.button-collapse i {
height: 64px;
line-height: 64px;
}
/* global Rlite, Materialize, $, localforage */
var r = Rlite();
var itemsAmostras = [];
var amostraAtual = 0;
var relacaoViscosidade = [ // O primeiro item é 10°C
13.36, 12.99, 12.63, 12.30, 11.98, 11.68, 11.38, 11.09, 10.81, 10.54, 10.29,
10.03, 9.80, 9.56, 9.34, 9.13, 8.92, 8.72, 8.52, 8.34, 8.16, 7.98, 7.82, 7.66,
7.50, 7.45, 7.20, 7.06, 6.92, 6.79 ];
if (window.applicationCache) {
window.applicationCache.addEventListener('cached', function () {
setTimeout(function () {
Materialize.toast('O aplicativo foi salvo e agora funciona mesmo sem conexão a internet.', 4e3);
}, 5000);
});
window.applicationCache.addEventListener('updateready', function () {
Materialize.toast('Uma atualização do aplicativo foi recebida <a href="." class="btn">atualizar</a>', 10e3);
});
}
$(function () {
// Hash-based routing
function processHash() {
var hash = location.hash || '#';
r.run(hash.slice(1));
}
window.addEventListener('hashchange', processHash);
processHash();
$('.datepicker').pickadate();
$('#marcarHoraInicio, #marcarHoraFim').click(function () {
$('#' + this.id.replace('marcarH', 'h'))
.val(moment().format('HH:mm:ss'))
.addClass('valid').trigger('change')
.next('label').addClass('active');
});
itemsAmostras = $('[data-id="amostras"] input').map(function () {
return this.id;
}).get();
});
// Default route
r.add('', function () {
document.title = 'Início';
$('.state-page').slideUp(1000);
$('#main').stop().slideDown(1000);
var collection = $('.ensaios-collection');
collection.find('li').css('opacity', 0);
var ensaios = [];
var noDataEl = collection.find('.no-data').hide();
localforage.iterate(function (value, key) {
if (key.indexOf('CP_') === 0) {
ensaios.push([key, value]);
}
}, function () {
collection.find('.collection-item')
.not('.no-data')
.remove();
if (ensaios.length) {
collection.append(ensaios.map(function (ensaio) {
return $('<li>', {
class: 'collection-item'
}).css('opacity', 0)
.append($('<a>', {
text: ensaio[1].obra.trim() || 'Sem nome',
href: '#ensaio/' + ensaio[0].substr(3)
}), $('<a>', {
class: 'secondary-content tooltipped',
href: '#delete/' + ensaio[0].substr(3),
'data-position': 'left',
'data-tooltip': 'Apagar obra'
}).html('<i class="material-icons">delete</i>'));
}));
// Need to refresh all tooltiped items
$('.tooltipped').tooltip();
} else {
noDataEl.show();
}
Materialize.showStaggeredList('.ensaios-collection');
});
});
r.add('ensaio/:id', function (r) {
$('.state-page').slideUp(1000);
amostraAtual = 0;
var id = r.params.id;
localforage.getItem('CP_' + id, function (err, state) {
if (err || !state) {
abrirEnsaio(Date.now().toString(36), {
amostras: []
});
} else {
state.amostras = state.amostras || [];
abrirEnsaio(id, state);
}
});
});
r.add('delete/:id', function (r) {
document.tile = 'Removendo ensaio';
var id = r.params.id;
localforage.removeItem('CP_' + id, function () {
location.hash = '#';
});
});
function saveData(el, state) {
var alterouAmostra = false;
var amostra = state.amostras[amostraAtual] = state.amostras[amostraAtual] || {};
el.find('input').each(function () {
var $this = $(this),
id = $this.attr('id');
if (itemsAmostras.indexOf(id) === -1) {
state[id] = $this.val();
} else {
amostra[id] = $this.val();
alterouAmostra = true;
}
});
if (alterouAmostra) {
amostra.tempo =
moment(amostra.horaFim, ['hh:mm:ss a', 'HH:mm:ss', 'YYYY-MM-DD HH:mm:ss']).diff(
moment(amostra.horaInicio, ['hh:mm:ss a', 'HH:mm:ss', 'YYYY-MM-DD HH:mm:ss']),
'seconds'
);
if (amostra.tempo < 0) {
amostra.tempo += 86400;
}
if (amostra.tempo) {
amostra.tempo = amostra.tempo.toFixed(0);
} else {
amostra.tempo = '';
}
$('#tempo').val(amostra.tempo)
.toggleClass('valid', !!amostra.tempo)
.next('label').toggleClass('active', !!amostra.tempo);
amostra.kt =
state.areaBureta * state.alturaCorpoProva *
// O logaritmo normalmente é em base euleriana
// ... ao menos em JavaScript e Wolfram|Alpha:
Math.log(amostra.alturaInicial / amostra.alturaFinal) /
state.areaCorpoProva / amostra.tempo;
if (amostra.kt) {
amostra.kt = amostra.kt.toFixed(3).replace(/\.0+$/, '');
} else {
amostra.kt = '';
}
$('#kt').val(amostra.kt)
.toggleClass('valid', !!amostra.kt)
.next('label').toggleClass('active', !!amostra.kt);
amostra.k20 = relacaoViscosidade[Math.round(amostra.temperatura) - 10] / relacaoViscosidade[10];
if (amostra.k20) {
amostra.k20 = amostra.k20.toFixed(3).replace(/\.0+$/, '');
} else {
amostra.k20 = '';
}
$('#k20').val(amostra.k20)
.toggleClass('valid', !!amostra.k20)
.next('label').toggleClass('active', !!amostra.k20);
}
}
function abrirEnsaio(id, state) {
var el = $('#ensaio')
.stop().slideDown(1000);
var tabs = el.find('[data-id]').hide();
tabs.first().show();
document.title = 'Ensaio ' + (state.obra || 'Sem nome');
loadData(el, state);
el.find('[data-href]').each(function () {
var $this = $(this);
$this.attr(
'href',
'ensaio/' + id + '/' + $this.attr('data-href')
);
}).off('click').on('click', function () {
tabs.slideUp(200)
.filter('[data-id="' + $(this).data('href') + '"]')
.stop().slideDown(200);
});
el.find('ul.tabs').tabs()
.find('li a').first()
.trigger('click');
el.find('input').off('change').on('change', function () {
saveData(el, state);
localforage.setItem('CP_' + id, state);
});
}
function populateAmostras(el, state){
if (state.amostras.length === 0) {
state.amostras.push({});
}
$('[data-id="amostras"] .pagination')
.empty()
.append(
$.map(state.amostras, function (element, index) {
return $('<li>').append($('<a>', {
href: '#',
text: index + 1
}).click(function () {
loadAmostra(el, state, index);
return false;
}));
}),
$('<li>', {class: 'waves-effect'})
.append($('<a>', {
href: '#',
html: '<i class="material-icons">add</i>'
}).click(function(){
state.amostras.push({});
populateAmostras(el, state);
loadAmostra(el, state, state.amostras.length - 1);
return false;
}))
);
}
function loadAmostra(el, state, amostra) {
$('[data-id="amostras"] .pagination li').removeClass('active')
.eq(amostra).addClass('active');
amostraAtual = amostra;
var state = state.amostras[amostra] = state.amostras[amostra] || {};
$.each(itemsAmostras, function (index, key) {
el.find('input[id="' + key + '"]')
.val(state[key] || '')
.toggleClass('valid', !!state[key])
.next('label').toggleClass('active', !!state[key]);
});
}
function loadData(el, state) {
el.find('input')
.val('')
.trigger('blur');
$.each(state, function (key, value) {
el.find('[id="' + key + '"]')
.val(value || '');
});
populateAmostras(el, state);
loadAmostra(el, state, 0);
$('label[for]').each(function () {
var $this = $(this);
$this.toggleClass(
'active', !!$('#' + $this.attr('for')).val()
);
});
}
r.add('info', function () {
document.title = 'Informações';
$('.state-page').slideUp(1000);
$('#info').stop().slideDown(1000);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment