Files added
0
__init__.py
Normal file
11
app.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
application: qrconvert
|
||||
version: 1
|
||||
runtime: python
|
||||
api_version: 1
|
||||
|
||||
handlers:
|
||||
- url: /html
|
||||
static_dir: html
|
||||
|
||||
- url: /.*
|
||||
script: index.py
|
||||
0
auth/__init__.py
Normal file
34
auth/rpxtokenurl.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import logging
|
||||
import urllib
|
||||
import urllib2
|
||||
import json
|
||||
import pdb
|
||||
|
||||
def rpx_response(token):
|
||||
api_params = {
|
||||
'token': token,
|
||||
'apiKey': 'e58e8ad7f740831452c51e3ad40b80eba388a551',
|
||||
'format': 'json',
|
||||
}
|
||||
|
||||
# make the api call
|
||||
http_response = urllib2.urlopen(
|
||||
'https://rpxnow.com/api/v2/auth_info',
|
||||
urllib.urlencode(api_params))
|
||||
|
||||
# read the json response
|
||||
auth_info_json = http_response.read()
|
||||
|
||||
# Step 3) process the json response
|
||||
auth_info = json.loads(auth_info_json)
|
||||
|
||||
# Step 4) use the response to sign the user in
|
||||
if auth_info['stat'] == 'ok':
|
||||
logging.debug( 'Signed in succesfully' )
|
||||
return auth_info
|
||||
else:
|
||||
logging.debug( 'An error occured: ' + auth_info['err']['msg'] )
|
||||
return 'An error occured: ' + auth_info['err']['msg']
|
||||
|
||||
|
||||
|
||||
24
gae_index.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from google.appengine.ext import webapp
|
||||
from google.appengine.ext.webapp.util import run_wsgi_app
|
||||
|
||||
from qrmaker import QRMaker
|
||||
from qrmaker import QRPageHandler
|
||||
|
||||
class MainPage(webapp.RequestHandler):
|
||||
def get(self):
|
||||
self.response.headers['Content-Type'] = 'text/plain'
|
||||
self.response.out.write('Hello, webapp World!')
|
||||
|
||||
application = webapp.WSGIApplication(
|
||||
[
|
||||
('/', MainPage),
|
||||
('/qrmaker', QRPageHandler.QRPageHandler)
|
||||
],
|
||||
debug=True)
|
||||
|
||||
def main():
|
||||
run_wsgi_app(application)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
166
html/index.html
Normal file
@@ -0,0 +1,166 @@
|
||||
<!DOCTYPE HTML>
|
||||
|
||||
<html>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="Content-Type" content="text/html" />
|
||||
|
||||
<title>QR vCard Generator</title>
|
||||
|
||||
<link media="screen" href="css/default.uni-form.css" rel="stylesheet">
|
||||
<link href="css/default.uni-form.css" title="Default Style" media="screen" rel="stylesheet"/>
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
|
||||
@import "css/uni-form.css";
|
||||
|
||||
/* You don't need these, they are here to tune up the page */
|
||||
html{ color: #343434; background: #bcc2c6 url(bg.png); font-size: 14px; line-height: 1.5; font-family: "Lucida Sans Unicode", "Lucida Grande", Arial, Verdana, sans-serif; }
|
||||
body{}
|
||||
|
||||
a:link,
|
||||
a:visited{ text-decoration: none; color: #254a86; }
|
||||
a:hover,
|
||||
a:focus { text-decoration: underline; }
|
||||
|
||||
h1,h2,h3,ul,ol,p{ margin: 1.5em 0; }
|
||||
|
||||
h1{ margin: 42px auto 28px auto; width: 284px; }
|
||||
h2{ font-size: 1.25em; }
|
||||
.uniForm h2{ margin: 1em 0 1em 1.15em; }
|
||||
fieldset h3{ margin: 1.5em -28px; padding: 14px 28px; line-height: 1; background: #efefef; color: #343434; }
|
||||
|
||||
.uniForm{ width: 55%; background: #fff; margin: 28px auto; padding: 28px;
|
||||
/* CSS3 */
|
||||
border-radius: 12px;
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
-o-border-radius: 12px;
|
||||
-khtml-border-radius: 12px;
|
||||
}
|
||||
|
||||
.header{ margin: -28px -28px 28px -28px; padding: 1px 28px; background: #efefef; border-bottom: 1px solid #dfdfdf; position: relative;
|
||||
/* CSS3 */
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
-webkit-border-top-left-radius: 10px;
|
||||
-webkit-border-top-right-radius: 10px;
|
||||
-moz-border-radius-topleft: 10px;
|
||||
-moz-border-radius-topright: 10px;
|
||||
}
|
||||
.header h2{ margin: 1.5em 0 0 0; color: #343434; color: #777; }
|
||||
.header p { margin-top: 0; font-size: 12px; color: #777; }
|
||||
.header .cta{ position: absolute; bottom: 26px; right: 28px; text-align: right; font-weight: bold; background: #194789; padding: 7px 14px;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
text-shadow: -1px -1px 0 rgba(0,0,0,.25);
|
||||
}
|
||||
.header .cta:link,
|
||||
.header .cta:visited{ color: #fff; }
|
||||
.header .cta:focus,
|
||||
.header .cta:hover{ text-decoration: none;
|
||||
/* CSS3 */
|
||||
box-shadow: 0 0 9px rgba(0,163,255,1);
|
||||
-webkit-box-shadow: 0 0 9px rgba(0,163,255,1);
|
||||
-moz-box-shadow: 0 0 9px rgba(0,163,255,1);
|
||||
}
|
||||
.header .cta:active{ bottom: 25px; }
|
||||
|
||||
.browse{ margin: 0; position: fixed; top: 28px; right: 28px; width: 84px; padding: 28px 28px 14px 28px; font-size: 12px; background: #97a2b0;
|
||||
/* CSS3 */
|
||||
border-radius: 12px;
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
-o-border-radius: 12px;
|
||||
-khtml-border-radius: 12px;
|
||||
}
|
||||
.browse h2{ font-size: 12px; margin: 0 0 14px 0; }
|
||||
.browse ul{ margin: 0; padding: 0; }
|
||||
.browse li{ margin: 0 0 14px 0; padding: 0; list-style: none; }
|
||||
.download{ float: right; position: relative; top: 2px; }
|
||||
.intro { width: 55%; margin: 28px auto; text-align: center; font-size: 1.15em; }
|
||||
#footer{ width: 55%; margin: 28px auto; text-align: center; font-size: .75em; color: #777; }
|
||||
|
||||
/* IE6 fixes for the page */
|
||||
* html form.uniForm{ overflow: hidden; }
|
||||
* html .header{ zoom: 1; overflow: hidden;}
|
||||
* html .browse{ position: absolute; }
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
|
||||
<script src="js/uni-form.jquery.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$(".browse a").click(function() {
|
||||
$("link").attr("href",$(this).attr('rel'));
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--[if lte ie 7]>
|
||||
<style type="text/css" media="screen">
|
||||
/* Move these to your IE6/7 specific stylesheet if possible */
|
||||
.uniForm, .uniForm fieldset, .uniForm .ctrlHolder, .uniForm .formHint, .uniForm .buttonHolder, .uniForm .ctrlHolder ul{ zoom:1; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h2>QR Code vCard Generator</h2>
|
||||
<p>Author: <a href="http://fergalmoran.com/">Fergal Moran</a> <a href="http://blog.fergalmoran.com/qrcodegenerator/" class="cta">Blog article</a></p>
|
||||
</div>
|
||||
|
||||
<div id="errorMsg">
|
||||
</div>
|
||||
|
||||
<div id="okMsg">
|
||||
</div>
|
||||
|
||||
<form action="#" class="uniForm">
|
||||
<fieldset class="inlineLabels">
|
||||
<h3>vCard Details</h3>
|
||||
<div class="ctrlHolder">
|
||||
<label for="">First name</label>
|
||||
<input id="firstname" name="FIRSTNAME" value="" size="35" class="textInput" type="text">
|
||||
</div>
|
||||
<div class="ctrlHolder">
|
||||
<label for="">Surname</label>
|
||||
<input id="surname" name="SURNAME" value="" size="35" class="textInput" type="text">
|
||||
</div>
|
||||
<div class="ctrlHolder">
|
||||
<label for="">Email address</label>
|
||||
<input id="email" name="EMAIL" value="" size="35" class="textInput" type="text">
|
||||
</div>
|
||||
<div class="ctrlHolder">
|
||||
<label for="">Organisation</label>
|
||||
<input id="organisation" name="ORGANISATION" value="" size="35" class="textInput" type="text">
|
||||
</div>
|
||||
<div class="ctrlHolder">
|
||||
<label for="">Telephone (home):</label>
|
||||
<input id="telhome" name="TELHOME" value="" size="35" class="textInput" type="text">
|
||||
</div>
|
||||
<div class="ctrlHolder">
|
||||
<label for="">Telephone (work):</label>
|
||||
<input id="telhome" name="TELWORK" value="" size="35" class="textInput" type="text">
|
||||
</div>
|
||||
<div class="ctrlHolder">
|
||||
<label for="">Address (home):</label>
|
||||
<textarea id="addrhome" name="ADDRHOME" rows="5" cols="25"></textarea>
|
||||
<p class="formHint">Please end lines with a , </p>
|
||||
</div>
|
||||
<div class="ctrlHolder">
|
||||
<label for="">Address (work):</label>
|
||||
<textarea id="addrwork" name="ADDRWORK" rows="5" cols="25"></textarea>
|
||||
<p class="formHint">Please end lines with a , </p>
|
||||
</div>
|
||||
<div class="buttonHolder"><button type="submit" class="primaryAction">Submit</button></div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
124
html/qrcode.html
Normal file
@@ -0,0 +1,124 @@
|
||||
<!DOCTYPE HTML>
|
||||
|
||||
<html>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="Content-Type" content="text/html" />
|
||||
|
||||
<title>QR vCard Generator</title>
|
||||
|
||||
<link media="screen" href="css/default.uni-form.css" rel="stylesheet">
|
||||
<link href="css/default.uni-form.css" title="Default Style" media="screen" rel="stylesheet"/>
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
|
||||
@import "css/uni-form.css";
|
||||
|
||||
/* You don't need these, they are here to tune up the page */
|
||||
html{ color: #343434; background: #bcc2c6 url(bg.png); font-size: 14px; line-height: 1.5; font-family: "Lucida Sans Unicode", "Lucida Grande", Arial, Verdana, sans-serif; }
|
||||
body{}
|
||||
|
||||
a:link,
|
||||
a:visited{ text-decoration: none; color: #254a86; }
|
||||
a:hover,
|
||||
a:focus { text-decoration: underline; }
|
||||
|
||||
h1,h2,h3,ul,ol,p{ margin: 1.5em 0; }
|
||||
|
||||
h1{ margin: 42px auto 28px auto; width: 284px; }
|
||||
h2{ font-size: 1.25em; }
|
||||
.uniForm h2{ margin: 1em 0 1em 1.15em; }
|
||||
fieldset h3{ margin: 1.5em -28px; padding: 14px 28px; line-height: 1; background: #efefef; color: #343434; }
|
||||
|
||||
.uniForm{ width: 55%; background: #fff; margin: 28px auto; padding: 28px;
|
||||
/* CSS3 */
|
||||
border-radius: 12px;
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
-o-border-radius: 12px;
|
||||
-khtml-border-radius: 12px;
|
||||
}
|
||||
|
||||
.header{ margin: -28px -28px 28px -28px; padding: 1px 28px; background: #efefef; border-bottom: 1px solid #dfdfdf; position: relative;
|
||||
/* CSS3 */
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
-webkit-border-top-left-radius: 10px;
|
||||
-webkit-border-top-right-radius: 10px;
|
||||
-moz-border-radius-topleft: 10px;
|
||||
-moz-border-radius-topright: 10px;
|
||||
}
|
||||
.header h2{ margin: 1.5em 0 0 0; color: #343434; color: #777; }
|
||||
.header p { margin-top: 0; font-size: 12px; color: #777; }
|
||||
.header .cta{ position: absolute; bottom: 26px; right: 28px; text-align: right; font-weight: bold; background: #194789; padding: 7px 14px;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
text-shadow: -1px -1px 0 rgba(0,0,0,.25);
|
||||
}
|
||||
.header .cta:link,
|
||||
.header .cta:visited{ color: #fff; }
|
||||
.header .cta:focus,
|
||||
.header .cta:hover{ text-decoration: none;
|
||||
/* CSS3 */
|
||||
box-shadow: 0 0 9px rgba(0,163,255,1);
|
||||
-webkit-box-shadow: 0 0 9px rgba(0,163,255,1);
|
||||
-moz-box-shadow: 0 0 9px rgba(0,163,255,1);
|
||||
}
|
||||
.header .cta:active{ bottom: 25px; }
|
||||
|
||||
.browse{ margin: 0; position: fixed; top: 28px; right: 28px; width: 84px; padding: 28px 28px 14px 28px; font-size: 12px; background: #97a2b0;
|
||||
/* CSS3 */
|
||||
border-radius: 12px;
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
-o-border-radius: 12px;
|
||||
-khtml-border-radius: 12px;
|
||||
}
|
||||
.browse h2{ font-size: 12px; margin: 0 0 14px 0; }
|
||||
.browse ul{ margin: 0; padding: 0; }
|
||||
.browse li{ margin: 0 0 14px 0; padding: 0; list-style: none; }
|
||||
.download{ float: right; position: relative; top: 2px; }
|
||||
.intro { width: 55%; margin: 28px auto; text-align: center; font-size: 1.15em; }
|
||||
#footer{ width: 55%; margin: 28px auto; text-align: center; font-size: .75em; color: #777; }
|
||||
|
||||
/* IE6 fixes for the page */
|
||||
* html form.uniForm{ overflow: hidden; }
|
||||
* html .header{ zoom: 1; overflow: hidden;}
|
||||
* html .browse{ position: absolute; }
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
|
||||
<script src="js/uni-form.jquery.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$(".browse a").click(function() {
|
||||
$("link").attr("href",$(this).attr('rel'));
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--[if lte ie 7]>
|
||||
<style type="text/css" media="screen">
|
||||
/* Move these to your IE6/7 specific stylesheet if possible */
|
||||
.uniForm, .uniForm fieldset, .uniForm .ctrlHolder, .uniForm .formHint, .uniForm .buttonHolder, .uniForm .ctrlHolder ul{ zoom:1; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h2>QR Code vCard Generator</h2>
|
||||
<p>Author: <a href="http://fergalmoran.com/">Fergal Moran</a> <a href="http://blog.fergalmoran.com/qrcodegenerator/" class="cta">Blog article</a></p>
|
||||
</div>
|
||||
|
||||
<div id="okMsg">
|
||||
<img src="qrcode.png" alt="QRCode should be here" />
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
BIN
html/qrcode.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
27
html/style.css
Normal file
@@ -0,0 +1,27 @@
|
||||
<style type="text/css">
|
||||
*{
|
||||
margin:0;
|
||||
padding:0;
|
||||
font:bold 12px "Lucida Grande", Arial, sans-serif;
|
||||
}
|
||||
body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.inputfield{
|
||||
width:50%;
|
||||
padding:10px;
|
||||
outline:none;
|
||||
height:36px;
|
||||
}
|
||||
.focusField{
|
||||
border:solid 2px #73A6FF;
|
||||
background:#EFF5FF;
|
||||
color:#000;
|
||||
}
|
||||
.idleField{
|
||||
background:#EEE;
|
||||
color: #6F6F6F;
|
||||
border: solid 2px #DFDFDF;
|
||||
}
|
||||
</style>
|
||||
82
index.py
Normal file
@@ -0,0 +1,82 @@
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
|
||||
def initLogging():
|
||||
logging.basicConfig(level=logging.DEBUG
|
||||
,format='%(asctime)s [[%(levelname)s]] %(message)s'
|
||||
,datefmt='%d %b %y %H:%M'
|
||||
,filename='/tmp/qrmaker.log'
|
||||
,filemode='a')
|
||||
import bottle
|
||||
from bottle import route, request, redirect, run, template, static_file
|
||||
from qrmaker import QRMaker
|
||||
from auth import rpxtokenurl
|
||||
from model import user
|
||||
|
||||
initLogging()
|
||||
logging.debug("Path: " + os.path.dirname(__file__) + '/views/')
|
||||
bottle.TEMPLATE_PATH.insert(0, os.path.dirname(__file__) + '/views/')
|
||||
|
||||
@route('/favicon.ico')
|
||||
def favicon():
|
||||
return static_file('favicon.ico', root=os.path.dirname(__file__) + '/static/images')
|
||||
|
||||
@route('/static/:directory/:filename')
|
||||
def server_static(directory, filename):
|
||||
return static_file(filename, root=os.path.dirname(__file__) + '/static/%s' % directory)
|
||||
|
||||
@route('/css/:filename')
|
||||
def server_static(filename):
|
||||
return static_file(filename, root=os.path.dirname(__file__) + '/views/css')
|
||||
|
||||
@route('/js/:filename')
|
||||
def server_static(filename):
|
||||
return static_file(filename, root=os.path.dirname(__file__) + '/views/js')
|
||||
|
||||
@route('auth_proxy', method='POST')
|
||||
def auth_proxy():
|
||||
ret = rpxtokenurl.rpx_response(request.forms.get('token'))
|
||||
if type(ret).__name__ == 'dict':
|
||||
newUser = user.UserController(ret)
|
||||
newUser.generatePermalink()
|
||||
return template('qrcode')
|
||||
else:
|
||||
return ret
|
||||
|
||||
@route('/permalink/:id')
|
||||
def permalink(id=''):
|
||||
if id == '':
|
||||
return template('qrcode', id='', linkurl='Invalid qrcode id')
|
||||
else:
|
||||
qr = QRMaker.QRMaker()
|
||||
linkUrl = 'Here is your permalink for this vcard <br /> <a href="http://%s/%s">Link</a>' % (request['HTTP_HOST'], qr.generatePermalink(id))
|
||||
return template(
|
||||
'qrcode',
|
||||
id=id,
|
||||
linkurl=linkUrl
|
||||
)
|
||||
|
||||
@route('/qrcode')
|
||||
def index():
|
||||
if id == '':
|
||||
return 'Invalid qrcode id specified'
|
||||
else:
|
||||
return template('qrcode', id='', linkurl='')
|
||||
|
||||
@route('/:name')
|
||||
def index(name='World'):
|
||||
return template('qrform')
|
||||
|
||||
@route('/')
|
||||
def index():
|
||||
return template('qrform')
|
||||
|
||||
@route('/genqr', method='POST')
|
||||
def gen_qrvcard():
|
||||
qr = QRMaker.QRMaker()
|
||||
uid = qr.createVCard(request.forms)
|
||||
return template('qrcode', id=uid, linkurl='')
|
||||
|
||||
application = bottle.default_app()
|
||||
0
model/__init__.py
Normal file
9
model/controller.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from pymongo import Connection
|
||||
import logging
|
||||
|
||||
class Controller:
|
||||
def __init__(self):
|
||||
self._cn = Connection()
|
||||
self.DB = self._cn.qrmaker
|
||||
logging.debug("Created database connection")
|
||||
|
||||
27
model/user.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import logging
|
||||
import pymongo
|
||||
import gridfs
|
||||
import pdb
|
||||
import controller
|
||||
class UserController():
|
||||
def __init__(self, items):
|
||||
logging.debug("Created a user")
|
||||
self._controller = controller.Controller()
|
||||
|
||||
self._profile = items['profile']
|
||||
self._id = self._profile['identifier']
|
||||
|
||||
|
||||
def generatePermalink(self):
|
||||
fs = gridfs.GridFS(self._controller.DB)
|
||||
|
||||
logging.debug("Generating permalink")
|
||||
self._write()
|
||||
|
||||
def _write(self):
|
||||
pdb.set_trace()
|
||||
blob = {
|
||||
"_id" : self._id,
|
||||
"profile" : self._profile
|
||||
}
|
||||
self._controller.DB.users.insert(blob)
|
||||
46
qrmaker/QRMaker.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from pygooglechart import QRChart
|
||||
import logging
|
||||
import re
|
||||
import uuid
|
||||
import shutil
|
||||
|
||||
HEIGHT = 220
|
||||
WIDTH = 220
|
||||
|
||||
vCardTemplate = """BEGIN:VCARD
|
||||
N:{SURNAME};{FIRSTNAME}
|
||||
TEL;CELL:{TELMOBILE}
|
||||
TEL;HOME:{TELHOME}
|
||||
EMAIL:{EMAIL}
|
||||
URL:{URL}
|
||||
END:VCARD"""
|
||||
|
||||
class QRMaker:
|
||||
def __init__(self):
|
||||
self._templateData = vCardTemplate
|
||||
|
||||
def createVCard(self, data):
|
||||
logging.debug("In createVCard")
|
||||
chart = QRChart(HEIGHT, WIDTH)
|
||||
templateData = ""
|
||||
|
||||
for k, v in data.items():
|
||||
templateData = self._templateData.replace("{%s}" % k, v)
|
||||
self._templateData = templateData
|
||||
|
||||
match = re.sub(r'{\w*\w}', '', templateData)
|
||||
|
||||
chart.add_data(match)
|
||||
|
||||
chart.set_ec('H', 0)
|
||||
uid = uuid.uuid1()
|
||||
|
||||
chart.download('static/cache/%s.png' % uid)
|
||||
return uid
|
||||
|
||||
def generatePermalink(self, id):
|
||||
shutil.copyfile(
|
||||
'static/cache/%s.png' % id,
|
||||
'static/images/permalinked/%s.png' % id
|
||||
)
|
||||
return 'static/images/permalinked/%s.png' % id
|
||||
7
qrmaker/QRPageHandler.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from google.appengine.ext import webapp
|
||||
from google.appengine.ext.webapp.util import run_wsgi_app
|
||||
|
||||
class QRPageHandler(webapp.RequestHandler):
|
||||
def get(self):
|
||||
self.response.headers['Content-Type'] = 'text/plain'
|
||||
self.response.out.write('Hello, qrmaker')
|
||||
0
qrmaker/__init__.py
Normal file
1161
qrmaker/pygooglechart.py
Normal file
BIN
static/cache/07968d7c-1a57-11e0-b3ab-001ec9ff1126.png
vendored
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
static/cache/0891e970-19cf-11e0-a16e-001ec9ff1126.png
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/cache/322fcf7a-1a53-11e0-8a59-001ec9ff1126.png
vendored
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/cache/3526ee82-19ce-11e0-ab4b-001ec9ff1126.png
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/cache/3582b2e6-1a53-11e0-8a59-001ec9ff1126.png
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/cache/3ba09c50-19cd-11e0-b1fb-001ec9ff1126.png
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/cache/4318653c-1a57-11e0-92f9-001ec9ff1126.png
vendored
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
static/cache/519ad578-19cf-11e0-b288-001ec9ff1126.png
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/cache/6ef91b96-1a53-11e0-97bd-001ec9ff1126.png
vendored
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/cache/a69fb7ae-1a52-11e0-8a59-001ec9ff1126.png
vendored
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/cache/ca163ebc-19ce-11e0-a16e-001ec9ff1126.png
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/cache/e0a25cc6-19cc-11e0-8480-001ec9ff1126.png
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/images/favicon.ico
Executable file
|
After Width: | Height: | Size: 318 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/images/qrcode.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
149
views/css/blue.uni-form.css
Executable file
@@ -0,0 +1,149 @@
|
||||
/* ------------------------------------------------------------------------------
|
||||
|
||||
UNI-FORM BLUE by DRAGAN BABIC (v2) | Wed, 31 Mar 10
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2010, Dragan Babic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
------------------------------------------------------------------------------ */
|
||||
|
||||
.uniForm{ background: #dde8ec; }
|
||||
|
||||
.uniForm legend{ font-weight: bold; font-size: 100%; margin: 0; padding: 1.5em 0; }
|
||||
|
||||
.uniForm .ctrlHolder{ padding: 1em; border-bottom: 1px solid #c4ced1; }
|
||||
.uniForm .ctrlHolder.focused{ background: #e1f0f6; }
|
||||
|
||||
.uniForm .buttonHolder{ background: #c4ced1; text-align: right; margin: 1.5em 0 0 0; padding: 1.5em;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm .buttonHolder .primaryAction{ padding: 10px 22px; line-height: 1; background: #254a86; border: 1px solid #163362; font-size: 12px; font-weight: bold; color: #fff;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
box-shadow: 1px 1px 0 #d5e2e7;
|
||||
-webkit-box-shadow: 1px 1px 0 #d5e2e7;
|
||||
-moz-box-shadow: 1px 1px 0 #d5e2e7;
|
||||
text-shadow: -1px -1px 0 rgba(0,0,0,.25);
|
||||
}
|
||||
.uniForm .buttonHolder .primaryAction:active{ position: relative; top: 1px; }
|
||||
.uniForm .secondaryAction { text-align: left; }
|
||||
.uniForm button.secondaryAction { background: transparent; border: none; color: #777; margin: 1.25em 0 0 0; padding: 0; }
|
||||
|
||||
.uniForm .inlineLabels label em,
|
||||
.uniForm .inlineLabels .label em{ font-style: normal; font-weight: bold; }
|
||||
.uniForm label small{ font-size: .75em; color: #777; }
|
||||
|
||||
.uniForm .textInput,
|
||||
.uniForm textarea { padding: 4px 2px; border: 1px solid #b2babe; background: #fff;
|
||||
/* CSS3 */
|
||||
border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-o-border-radius: 3px;
|
||||
-khtml-border-radius: 3px;
|
||||
}
|
||||
.uniForm textarea { height: 12em; }
|
||||
|
||||
.uniForm .ctrlHolder ul li label{ font-size: .85em; }
|
||||
|
||||
/* Get rid of the 'glow' effect in WebKit, optional */
|
||||
.uniForm .ctrlHolder .textInput:focus,
|
||||
.uniForm .ctrlHolder textarea:focus{ outline: none; }
|
||||
|
||||
.uniForm .formHint { font-size: .85em; color: #777; }
|
||||
.uniForm .inlineLabels .formHint { padding-top: .5em; }
|
||||
.uniForm .ctrlHolder.focused .formHint{ color: #333; }
|
||||
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
/* ############################### Messages #################################### */
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
|
||||
/* Error message at the top of the form */
|
||||
.uniForm #errorMsg{ background: #c20f2e; color: #fff; margin: 0 0 1.5em 0; padding: 1px 1.5em;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
box-shadow: 0 0 14px rgba(0,0,0,.25);
|
||||
-webkit-box-shadow: 0 0 14px rgba(0,0,0,.25);
|
||||
-moz-box-shadow: 0 0 14px rgba(0,0,0,.25);
|
||||
}
|
||||
.uniForm #errorMsg ol{ margin: 0 0 1.5em 0; padding: 0; }
|
||||
.uniForm #errorMsg ol li{ margin: 0 0 3px 1.5em; padding: 7px; background: #a20d27; position: relative; font-size: .85em;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
|
||||
.uniForm .ctrlHolder.error,
|
||||
.uniForm .ctrlHolder.focused.error{ color: #c20f2e;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm .ctrlHolder.error input.error,
|
||||
.uniForm .ctrlHolder.error select.error,
|
||||
.uniForm .ctrlHolder.error textarea.error{ border-color: #c20f2e; }
|
||||
|
||||
/* Success messages at the top of the form */
|
||||
.uniForm #okMsg{ background: #59a20e; color: #343434; margin: 0 0 1.5em 0; padding: 1.5em; text-align: center;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
box-shadow: 0 0 14px rgba(0,0,0,.25);
|
||||
-webkit-box-shadow: 0 0 14px rgba(0,0,0,.25);
|
||||
-moz-box-shadow: 0 0 14px rgba(0,0,0,.25);
|
||||
text-shadow: 1px 1px 0 rgba(255,255,255,.25);
|
||||
}
|
||||
.uniForm #okMsg p{ margin: 0; }
|
||||
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
/* ############################### Columns ##################################### */
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
|
||||
.uniForm .col{ margin-bottom: 1.5em; }
|
||||
/* Use .first and .last classes to control the layout/spacing of your columns */
|
||||
.uniForm .col.first{ width: 49%; float: left; clear: none; }
|
||||
.uniForm .col.last { width: 49%; float: right; clear: none; margin-right: 0; }
|
||||
137
views/css/dark.uni-form.css
Executable file
@@ -0,0 +1,137 @@
|
||||
/* ------------------------------------------------------------------------------
|
||||
|
||||
UNI-FORM DARK by DRAGAN BABIC (v2) | Wed, 31 Mar 10
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2010, Dragan Babic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
------------------------------------------------------------------------------ */
|
||||
|
||||
.uniForm{ background: #343434; color: #ccc; }
|
||||
|
||||
.uniForm legend{ font-weight: bold; font-size: 100%; margin: 0; padding: 1.5em 0; }
|
||||
|
||||
.uniForm .ctrlHolder{ padding: 1em; border-bottom: 1px solid #232323; }
|
||||
.uniForm .ctrlHolder.focused{ background: #232323; }
|
||||
|
||||
.uniForm .buttonHolder{ background: #232323; text-align: right; margin: 1.5em 0 0 0; padding: 1.5em;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm .buttonHolder .primaryAction{ padding: 10px 22px; line-height: 1; background: #59a20e; border: 1px solid #232323; font-size: 12px; font-weight: bold; color: #fff;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
box-shadow: 1px 1px 0 #232323;
|
||||
-webkit-box-shadow: 1px 1px 0 #232323;
|
||||
-moz-box-shadow: 1px 1px 0 #232323;
|
||||
text-shadow: -1px -1px 0 rgba(0,0,0,.25);
|
||||
}
|
||||
.uniForm .buttonHolder .primaryAction:active{ position: relative; top: 1px; }
|
||||
.uniForm .secondaryAction { text-align: left; }
|
||||
.uniForm button.secondaryAction { background: transparent; border: none; color: #777; margin: 1.25em 0 0 0; padding: 0; }
|
||||
|
||||
.uniForm .inlineLabels label em,
|
||||
.uniForm .inlineLabels .label em{ font-style: normal; font-weight: bold; }
|
||||
.uniForm label small{ font-size: .75em; color: #777; }
|
||||
|
||||
.uniForm .textInput,
|
||||
.uniForm textarea { padding: 4px 2px; border: 1px solid #232323; background: #555; color: #dfdfdf; }
|
||||
.uniForm textarea { height: 12em; }
|
||||
.uniForm .textInput:focused,
|
||||
.uniForm textarea:focused{ border-color: #fff; }
|
||||
|
||||
/* Get rid of the 'glow' effect in WebKit, optional */
|
||||
.uniForm .ctrlHolder .textInput:focus,
|
||||
.uniForm .ctrlHolder textarea:focus{ outline: none; }
|
||||
|
||||
.uniForm .formHint { font-size: .85em; color: #777; }
|
||||
.uniForm .inlineLabels .formHint { padding-top: .5em; }
|
||||
.uniForm .ctrlHolder.focused .formHint{ color: #fff; }
|
||||
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
/* ############################### Messages #################################### */
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
|
||||
/* Error message at the top of the form */
|
||||
.uniForm #errorMsg{ background: #c20f2e; border: 1px solid #232323; color: #fff; margin: 0 0 1.5em 0; padding: 0 1.5em;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm #errorMsg ol{ margin: 0 0 1.5em 0; padding: 0; }
|
||||
.uniForm #errorMsg ol li{ margin: 0 0 3px 1.5em; padding: 7px; background: #a20d27; position: relative; font-size: .85em;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
|
||||
.uniForm .ctrlHolder.error,
|
||||
.uniForm .ctrlHolder.focused.error{ background: #c20f2e; border: 1px solid #232323; color: #fff;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm .ctrlHolder.error input.error,
|
||||
.uniForm .ctrlHolder.error select.error,
|
||||
.uniForm .ctrlHolder.error textarea.error{ color: #af4c4c; margin: 0 0 6px 0; padding: 4px; background: #ffbfbf; }
|
||||
|
||||
.uniForm .ctrlHolder.error .formHint{ color: #fff; }
|
||||
|
||||
/* Success messages at the top of the form */
|
||||
.uniForm #okMsg{ background: #59a20e; border: 1px solid #232323; color: #fff; margin: 0 0 1.5em 0; padding: 1.5em; text-align: center;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm #okMsg p{ margin: 0; }
|
||||
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
/* ############################### Columns ##################################### */
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
|
||||
.uniForm .col{ margin-bottom: 1.5em; }
|
||||
/* Use .first and .last classes to control the layout/spacing of your columns */
|
||||
.uniForm .col.first{ width: 49%; float: left; clear: none; }
|
||||
.uniForm .col.last { width: 49%; float: right; clear: none; margin-right: 0; }
|
||||
153
views/css/default.uni-form.css
Executable file
@@ -0,0 +1,153 @@
|
||||
/* ------------------------------------------------------------------------------
|
||||
|
||||
UNI-FORM DEFAULT by DRAGAN BABIC (v2) | Wed, 31 Mar 10
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2010, Dragan Babic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
------------------------------------------------------------------------------ */
|
||||
|
||||
.uniForm{}
|
||||
|
||||
.uniForm legend{ font-weight: bold; font-size: 100%; margin: 0; padding: 1.5em 0; }
|
||||
|
||||
.uniForm .ctrlHolder{ padding: 1em; border-bottom: 1px solid #efefef; }
|
||||
.uniForm .ctrlHolder.focused{ background: #fffcdf; }
|
||||
|
||||
.uniForm .inlineLabels .noLabel{}
|
||||
|
||||
.uniForm .buttonHolder{ background: #efefef; text-align: right; margin: 1.5em 0 0 0; padding: 1.5em;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm .buttonHolder .primaryAction{ padding: 10px 22px; line-height: 1; background: #254a86; border: 1px solid #163362; font-size: 12px; font-weight: bold; color: #fff;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
box-shadow: 1px 1px 0 #fff;
|
||||
-webkit-box-shadow: 1px 1px 0 #fff;
|
||||
-moz-box-shadow: 1px 1px 0 #fff;
|
||||
text-shadow: -1px -1px 0 rgba(0,0,0,.25);
|
||||
}
|
||||
.uniForm .buttonHolder .primaryAction:active{ position: relative; top: 1px; }
|
||||
.uniForm .secondaryAction { text-align: left; }
|
||||
.uniForm button.secondaryAction { background: transparent; border: none; color: #777; margin: 1.25em 0 0 0; padding: 0; }
|
||||
|
||||
.uniForm .inlineLabels label em,
|
||||
.uniForm .inlineLabels .label em{ font-style: normal; font-weight: bold; }
|
||||
.uniForm label small{ font-size: .75em; color: #777; }
|
||||
|
||||
.uniForm .textInput,
|
||||
.uniForm textarea { padding: 4px 2px; border: 1px solid #aaa; background: #fff; }
|
||||
.uniForm textarea { height: 12em; }
|
||||
.uniForm select {}
|
||||
.uniForm .fileUpload {}
|
||||
|
||||
.uniForm ul{}
|
||||
.uniForm li{}
|
||||
.uniForm ul li label{ font-size: .85em; }
|
||||
|
||||
.uniForm .small {}
|
||||
.uniForm .medium{}
|
||||
.uniForm .large {} /* Large is default and should match the value you set for .textInput, textarea or select */
|
||||
.uniForm .auto {}
|
||||
.uniForm .small,
|
||||
.uniForm .medium,
|
||||
.uniForm .auto{}
|
||||
|
||||
/* Get rid of the 'glow' effect in WebKit, optional */
|
||||
.uniForm .ctrlHolder .textInput:focus,
|
||||
.uniForm .ctrlHolder textarea:focus{ outline: none; }
|
||||
|
||||
.uniForm .formHint { font-size: .85em; color: #777; }
|
||||
.uniForm .inlineLabels .formHint { padding-top: .5em; }
|
||||
.uniForm .ctrlHolder.focused .formHint{ color: #333; }
|
||||
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
/* ############################### Messages #################################### */
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
|
||||
/* Error message at the top of the form */
|
||||
.uniForm #errorMsg{ background: #ffdfdf; border: 1px solid #f3afb5; margin: 0 0 1.5em 0; padding: 0 1.5em;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm #errorMsg h3{} /* Feel free to use a heading level suitable to your page structure */
|
||||
.uniForm #errorMsg ol{ margin: 0 0 1.5em 0; padding: 0; }
|
||||
.uniForm #errorMsg ol li{ margin: 0 0 3px 1.5em; padding: 7px; background: #f6bec1; position: relative; font-size: .85em;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
|
||||
.uniForm .ctrlHolder.error,
|
||||
.uniForm .ctrlHolder.focused.error{ background: #ffdfdf; border: 1px solid #f3afb5;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm .ctrlHolder.error input.error,
|
||||
.uniForm .ctrlHolder.error select.error,
|
||||
.uniForm .ctrlHolder.error textarea.error{ color: #af4c4c; margin: 0 0 6px 0; padding: 4px; }
|
||||
|
||||
/* Success messages at the top of the form */
|
||||
.uniForm #okMsg{ background: #c8ffbf; border: 1px solid #a2ef95; margin: 0 0 1.5em 0; padding: 1.5em; text-align: center;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm #okMsg p{ margin: 0; }
|
||||
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
/* ############################### Columns ##################################### */
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
|
||||
.uniForm .col{}
|
||||
.uniForm .col.first{}
|
||||
.uniForm .col.last{}
|
||||
.uniForm .col{ margin-bottom: 1.5em; }
|
||||
/* Use .first and .last classes to control the layout/spacing of your columns */
|
||||
.uniForm .col.first{ width: 49%; float: left; clear: none; }
|
||||
.uniForm .col.last { width: 49%; float: right; clear: none; margin-right: 0; }
|
||||
155
views/css/ready.uni-form.css
Executable file
@@ -0,0 +1,155 @@
|
||||
/* ------------------------------------------------------------------------------
|
||||
|
||||
UNI-FORM DARK by DRAGAN BABIC (v2) | Wed, 31 Mar 10
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2010, Dragan Babic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
------------------------------------------------------------------------------ */
|
||||
|
||||
.uniForm{ background: #EFF3E2; color: #000;}
|
||||
.uniForm fieldset h3{background:#187193; color: #FFFFFF; border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm legend{ font-weight: bold; font-size: 100%; margin: 0; padding: 1.5em 0; }
|
||||
.uniForm .ctrlHolder.focused label {color:#FFFFFF;}
|
||||
.uniForm .ctrlHolder.focused.error label {color:#000000;}
|
||||
.uniForm .ctrlHolder{ padding: 1em; border-bottom: 1px solid #232323; }
|
||||
.uniForm .ctrlHolder.focused{ background: #96B343; }
|
||||
|
||||
.uniForm .buttonHolder{ background: #187193; color:#ffffff; text-align: right; margin: 1.5em 0 0 0; padding: 1.5em;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm .buttonHolder .primaryAction{ padding: 10px 22px; line-height: 1; background: #59a20e; border: 1px solid #232323; font-size: 12px; font-weight: bold; color: #fff;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
box-shadow: 1px 1px 0 #232323;
|
||||
-webkit-box-shadow: 1px 1px 0 #232323;
|
||||
-moz-box-shadow: 1px 1px 0 #232323;
|
||||
text-shadow: -1px -1px 0 rgba(0,0,0,.25);
|
||||
}
|
||||
.uniForm .buttonHolder .primaryAction:active{ position: relative; top: 1px; }
|
||||
.uniForm .secondaryAction { text-align: left; }
|
||||
.uniForm button.secondaryAction { background: transparent; border: none; color: #FFFFFF; margin: 1.25em 0 0 0; padding: 0; }
|
||||
|
||||
.uniForm .inlineLabels label em,
|
||||
.uniForm .inlineLabels .label em{ font-style: normal; font-weight: bold; }
|
||||
.uniForm label small{ font-size: .75em; color: #777; }
|
||||
|
||||
.uniForm .textInput,
|
||||
.uniForm textarea { padding: 4px 2px; border: 1px solid #187193; background: #FFFFFF; color: #dfdfdf; border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px; }
|
||||
.uniForm textarea { height: 12em;}
|
||||
.uniForm .textInput:focused,
|
||||
.uniForm textarea:focused{ border: 3px solid #187193;}
|
||||
|
||||
.uniForm .ctrlHolder.error textarea,
|
||||
.uniForm .ctrlHolder.error .textInput{border: 1px solid #c20f2e;}
|
||||
.uniForm .ctrlHolder.focused.error textarea,
|
||||
.uniForm .ctrlHolder.focused.error .textInput{border: 3px solid #c20f2e;}
|
||||
|
||||
.uniForm .ctrlHolder.focused textarea,
|
||||
.uniForm .ctrlHolder.focused .textInput{border: 3px solid #187193;}
|
||||
|
||||
/* Get rid of the 'glow' effect in WebKit, optional */
|
||||
.uniForm .ctrlHolder .textInput:focus,
|
||||
.uniForm .ctrlHolder textarea:focus{ outline: none; }
|
||||
|
||||
.uniForm .formHint { font-size: .85em; color: #777; }
|
||||
.uniForm .inlineLabels .formHint { padding-top: .5em; }
|
||||
.uniForm .ctrlHolder.focused .formHint{ color: #fff; }
|
||||
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
/* ############################### Messages #################################### */
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
|
||||
/* Error message at the top of the form */
|
||||
.uniForm #errorMsg{ background: #c20f2e; border: 1px solid #232323; color: #fff; margin: 0 0 1.5em 0; padding: 0 1.5em;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm #errorMsg ol{ margin: 0 0 1.5em 0; padding: 0; }
|
||||
.uniForm #errorMsg ol li{ margin: 0 0 3px 1.5em; padding: 7px; background: #a20d27; position: relative; font-size: .85em;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
|
||||
.uniForm .ctrlHolder.error,
|
||||
.uniForm .ctrlHolder.focused.error{ background: #FFDFDF; border: 1px solid #c20f2e; color: #000000;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm .ctrlHolder.error input.error,
|
||||
.uniForm .ctrlHolder.error select.error,
|
||||
.uniForm .ctrlHolder.error textarea.error{ color: #af4c4c; margin: 0 0 6px 0; padding: 4px; background: #ffbfbf; }
|
||||
|
||||
.uniForm .ctrlHolder.error .formHint{ color: #000000; }
|
||||
|
||||
/* Success messages at the top of the form */
|
||||
.uniForm #okMsg{ background: #59a20e; border: 1px solid #232323; color: #fff; margin: 0 0 1.5em 0; padding: 0 1.5em; text-align: center;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
}
|
||||
.uniForm #okMsg p{ margin: 0; }
|
||||
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
/* ############################### Columns ##################################### */
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
|
||||
.uniForm .col{ margin-bottom: 1.5em; }
|
||||
/* Use .first and .last classes to control the layout/spacing of your columns */
|
||||
.uniForm .col.first{ width: 49%; float: left; clear: none; }
|
||||
.uniForm .col.last { width: 49%; float: right; clear: none; margin-right: 0; }
|
||||
164
views/css/uni-form.css
Executable file
@@ -0,0 +1,164 @@
|
||||
/* ------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2010, Dragan Babic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
------------------------------------------------------------------------------ */
|
||||
/* ############################# GENERALS ################################### */
|
||||
/* ------------------------------------------------------------------------------ */
|
||||
|
||||
.uniForm{ margin: 0; padding: 0; position: relative; z-index: 1; } /* reset stuff */
|
||||
|
||||
/* Some generals and more resets */
|
||||
.uniForm fieldset{ border: none; margin: 0; padding: 0; }
|
||||
.uniForm fieldset legend{ margin: 0; padding: 0; }
|
||||
|
||||
/* This are the main units that contain form elements */
|
||||
.uniForm .ctrlHolder,
|
||||
.uniForm .buttonHolder{ margin: 0; padding: 0; clear: both; }
|
||||
|
||||
/* Clear all floats */
|
||||
.uniForm:after,
|
||||
.uniForm .buttonHolder:after,
|
||||
.uniForm .ctrlHolder:after,
|
||||
.uniForm .ctrlHolder .multiField:after,
|
||||
.uniForm .inlineLabel:after{ content: "."; display: block; height: 0; line-height: 0; font-size: 0; clear: both; min-height: 0; visibility: hidden; }
|
||||
|
||||
.uniForm label,
|
||||
.uniForm button{ cursor: pointer; }
|
||||
|
||||
/* ------------------------------------------------------------------------------ */
|
||||
/* ########################## DEFAULT LAYOUT ################################ */
|
||||
/* ------------------------------------------------------------------------------ */
|
||||
/* Styles for form controls where labels are above the input elements */
|
||||
/* ------------------------------------------------------------------------------ */
|
||||
|
||||
.uniForm label,
|
||||
.uniForm .label{ display: block; float: none; margin: 0 0 .5em 0; padding: 0; line-height: 100%; width: auto; }
|
||||
|
||||
/* Float the input elements */
|
||||
.uniForm .textInput,
|
||||
.uniForm .fileUpload,
|
||||
.uniForm .selectInput,
|
||||
.uniForm select,
|
||||
.uniForm textarea{ float: left; width: 53%; margin: 0; }
|
||||
|
||||
/* Read-Only output */
|
||||
.uniForm .readOnlyLabel{ margin: 0; font-size: 1em; font-weight: bold; }
|
||||
.uniForm .readOnly{ font-size: .85em; }
|
||||
.uniForm .readOnly .choiceLabel{ color: #777; text-transform: uppercase; font-size: .75em; letter-spacing: .15em; }
|
||||
|
||||
/* Postition the hints */
|
||||
.uniForm .formHint{ float: right; width: 43%; margin: 0; clear: none; }
|
||||
|
||||
/* Position the elements inside combo boxes (multiple inputs/selects/checkboxes/radio buttons per unit) */
|
||||
.uniForm ul{ float: left; width: 53%; margin: 0; padding: 0; }
|
||||
.uniForm ul li{ margin: 0 0 .5em 0; list-style: none; }
|
||||
.uniForm ul li label{ margin: 0; float: none; display: block; overflow: visible; }
|
||||
/* Alternate layout */
|
||||
.uniForm ul.alternate li{ float: left; width: 30%; margin-right: 3%; }
|
||||
.uniForm ul.alternate li label{ float: none; display: block; width: 98%; }
|
||||
.uniForm ul .textInput,
|
||||
.uniForm ul .selectInput,
|
||||
.uniForm ul select,
|
||||
.uniForm ul.alternate .textInput,
|
||||
.uniForm ul.alternate .selectInput,
|
||||
.uniForm ul.alternate select{ width: 98%; margin-top: .5em; display: block; float: none; }
|
||||
|
||||
/* Required fields asterisk styling */
|
||||
.uniForm label em,
|
||||
.uniForm .label em{ float: left; width: 1em; margin: 0 0 0 -1em; }
|
||||
|
||||
/* ------------------------------------------------------------------------------ */
|
||||
/* ######################### ALTERNATE LAYOUT ############################### */
|
||||
/* ------------------------------------------------------------------------------ */
|
||||
/* Styles for form controls where labels are in line with the input elements */
|
||||
/* Set the class of the parent (preferably to a fieldset) to .inlineLabels */
|
||||
/* ------------------------------------------------------------------------------ */
|
||||
|
||||
.uniForm .inlineLabels label,
|
||||
.uniForm .inlineLabels .label,
|
||||
.uniForm .inlineLabels .readOnlyLabel{ float: left; margin: .3em 2% 0 0; padding: 0; line-height: 1; position: relative; width: 32%; }
|
||||
|
||||
.uniForm .inlineLabels .readOnlyLabel{ margin: 0; }
|
||||
|
||||
/* Float the input elements */
|
||||
.uniForm .inlineLabels .textInput,
|
||||
.uniForm .inlineLabels .fileUpload,
|
||||
.uniForm .inlineLabels .selectInput,
|
||||
.uniForm .inlineLabels select,
|
||||
.uniForm .inlineLabels textarea{ float: left; width: 64%; }
|
||||
|
||||
/* Postition the hints */
|
||||
.uniForm .inlineLabels .formHint{ clear: both; float: none; width: auto; margin-left: 34%; position: static; }
|
||||
|
||||
/* Position the elements inside combo boxes (multiple inputs/selects/checkboxes/radio buttons per unit) */
|
||||
.uniForm .inlineLabels ul{ float: left; width: 66%; }
|
||||
.uniForm .inlineLabels ul li{ margin: .5em 0; }
|
||||
.uniForm .inlineLabels ul li label{ float: none; display: block; width: 100%; }
|
||||
/* Alternate layout */
|
||||
.uniForm .inlineLabels ul.alternate li{ margin-right: 3%; margin-top: .25em; }
|
||||
.uniForm .inlineLabels ul li label .textInput,
|
||||
.uniForm .inlineLabels ul li label textarea,
|
||||
.uniForm .inlineLabels ul li label select{ float: none; display: block; width: 98%; }
|
||||
|
||||
.uniForm .inlineLabels .readOnly{ float: right; width: 66%; }
|
||||
|
||||
/* Required fields asterisk styling */
|
||||
.uniForm .inlineLabels label em,
|
||||
.uniForm .inlineLabels .label em{ display: block; float: none; margin: 0; position: absolute; right: 0; }
|
||||
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
/* ########################### Additional Stuff ################################ */
|
||||
/* ----------------------------------------------------------------------------- */
|
||||
|
||||
/* Generals */
|
||||
.uniForm legend{ color: inherit; }
|
||||
|
||||
.uniForm .secondaryAction{ float: left; }
|
||||
|
||||
/* .inlineLabel is used for inputs within labels - checkboxes and radio buttons */
|
||||
.uniForm .inlineLabel input,
|
||||
.uniForm .inlineLabels .inlineLabel input,
|
||||
.uniForm .blockLabels .inlineLabel input,
|
||||
/* class .inlineLabel is depreciated */
|
||||
.uniForm label input{ float: none; display: inline; margin: 0; padding: 0; border: none; }
|
||||
|
||||
.uniForm .buttonHolder .inlineLabel,
|
||||
.uniForm .buttonHolder label{ float: left; margin: .5em 0 0 0; width: auto; max-width: 60%; text-align: left; }
|
||||
|
||||
/* When you don't want to use a label */
|
||||
.uniForm .inlineLabels .noLabel ul{ margin-left: 34%; /* Match to width of label + gap to field */ }
|
||||
|
||||
/* Classes for control of the widths of the fields */
|
||||
.uniForm .small { width: 30% !important; }
|
||||
.uniForm .medium{ width: 45% !important; }
|
||||
.uniForm .large { } /* Large is default and should match the value you set for .textInput, textarea or select */
|
||||
.uniForm .auto { width: auto !important; height: auto !important; }
|
||||
.uniForm .small,
|
||||
.uniForm .medium,
|
||||
.uniForm .auto{ margin-right: 4px; }
|
||||
|
||||
/* Columns */
|
||||
.uniForm .col{ float: left; }
|
||||
.uniForm .col{ width: 50%; }
|
||||
607
views/js/uni-form-validation.jquery.js
Executable file
@@ -0,0 +1,607 @@
|
||||
/**
|
||||
* Uni-Form jQuery Plugin
|
||||
*
|
||||
* Provides form actions for use with the Uni-Form markup style
|
||||
* This version adds additional support for client side validation
|
||||
*
|
||||
* Author: Ilija Studen for the purposes of Uni-Form
|
||||
*
|
||||
* Modified by Aris Karageorgos to use the parents function
|
||||
*
|
||||
* Modified by Toni Karlheinz to support input fields' text
|
||||
* coloring and removal of their initial values on focus
|
||||
*
|
||||
* Modified by Jason Brumwell for optimization, addition
|
||||
* of valid and invalid states and default data attribues
|
||||
*
|
||||
* Modified by LearningStation to add support for client
|
||||
* side validation routines. The validation routines based on an
|
||||
* open source library of unknown authorship.
|
||||
*
|
||||
* @see http://sprawsm.com/uni-form/
|
||||
* @license MIT http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
jQuery.fn.uniform = function(settings) {
|
||||
/**
|
||||
* prevent_submit : enable with either true or class on form of "preventSubmit"
|
||||
* ask_on_leave : enable with either true or class on form of "askOnLeave"
|
||||
*/
|
||||
settings = jQuery.extend({
|
||||
prevent_submit : false,
|
||||
ask_on_leave : false,
|
||||
valid_class : 'valid',
|
||||
invalid_class : 'invalid',
|
||||
error_class : 'error',
|
||||
focused_class : 'focused',
|
||||
holder_class : 'ctrlHolder',
|
||||
field_selector : 'input, textarea, select',
|
||||
default_value_color: "#AFAFAF"
|
||||
}, settings);
|
||||
|
||||
/**
|
||||
* Internationalized language strings for validation messages
|
||||
*
|
||||
* @var Object
|
||||
*/
|
||||
var i18n_en = {
|
||||
required : '%s is required',
|
||||
minlength : '%s should be at least %d characters long',
|
||||
min : '%s should be greater than or equal to %d',
|
||||
maxlength : '%s should not be longer than %d characters',
|
||||
max : '%s should be less than or equal to %d',
|
||||
same_as : '%s is expected to be same as %s',
|
||||
email : '%s is not a valid email address',
|
||||
url : '%s is not a valid URL',
|
||||
number : '%s needs to be a number',
|
||||
integer : '%s needs to be a whole number',
|
||||
alpha : '%s should contain only letters (without special characters or numbers)',
|
||||
alphanum : '%s should contain only numbers and letters (without special characters)',
|
||||
phrase : '%s should contain only alphabetic characters, numbers, spaces, and the following: . , - _ () * # :',
|
||||
phone : '%s should be a phone number',
|
||||
date : '%s should be a date (mm/dd/yyyy)',
|
||||
callback : 'Failed to validate %s field. Validator function (%s) is not defined!',
|
||||
on_leave : 'Are you sure you want to leave this page without saving this form?'
|
||||
};
|
||||
|
||||
/**
|
||||
* Supported validators
|
||||
*
|
||||
* @var Object
|
||||
*/
|
||||
var validators = {
|
||||
|
||||
/**
|
||||
* Get the value for a validator that takes parameters
|
||||
*
|
||||
* @param string name
|
||||
* @param string all classes on element
|
||||
*
|
||||
* @return mixed || null
|
||||
*/
|
||||
get_val : function(name, classes, default_value) {
|
||||
var value = default_value;
|
||||
classes = classes.split(' ');
|
||||
for(var i = 0; i < classes.length; i++) {
|
||||
if(classes[i] == name) {
|
||||
if((classes[i + 1] != 'undefined') && ('val-' === classes[i + 1].substr(0,4))) {
|
||||
value = parseInt(classes[i + 1].substr(4),10);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if value of specific field is present, whitespace will be counted as empty
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param string caption
|
||||
*/
|
||||
required : function(field, caption) {
|
||||
if(jQuery.trim(field.val()) == '') {
|
||||
return i18n('required', caption);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Validate is value of given field is shorter than supported
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param sting caption
|
||||
*/
|
||||
validateMinLength : function(field, caption) {
|
||||
var min_length = this.get_val('validateMinLength', field.attr('class'), 0);
|
||||
|
||||
if((min_length > 0) && (field.val().length < min_length)) {
|
||||
return i18n('minlength', caption, min_length);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Validate is if value is lesser than min
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param sting caption
|
||||
*/
|
||||
validateMin : function(field, caption) {
|
||||
var min_val = this.get_val('validateMin', field.attr('class'), 0);
|
||||
|
||||
if((parseInt(field.val(),10) < min_val)) {
|
||||
return i18n('min', caption, min_val);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Validate if field value is longer than allowed
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param string caption
|
||||
*/
|
||||
validateMaxLength : function(field, caption) {
|
||||
var max_length = this.get_val('validateMaxLength', field.attr('class'), 0);
|
||||
|
||||
if((max_length > 0) && (field.val().length > max_length)) {
|
||||
return i18n('maxlength', caption, max_length);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Validate is if value is lesser than min
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param sting caption
|
||||
*/
|
||||
validateMax : function(field, caption) {
|
||||
var max_val = this.get_val('validateMax', field.attr('class'), 0);
|
||||
|
||||
if((parseInt(field.val(),10) > max_val)) {
|
||||
return i18n('max', caption, max_val);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Make sure that field has same value as the value of target field
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param string caption
|
||||
*/
|
||||
validateSameAs : function(field, caption) {
|
||||
var classes = field.attr('class').split(' ');
|
||||
var target_field_name = '';
|
||||
|
||||
for(var i = 0; i < classes.length; i++) {
|
||||
if(classes[i] == 'validateSameAs') {
|
||||
if(classes[i + 1] != 'undefined') {
|
||||
target_field_name = classes[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(target_field_name) {
|
||||
var target_field = jQuery('#' + target_field_name);
|
||||
if(target_field.length > 0) {
|
||||
//var target_field_caption = field_caption(field);
|
||||
var target_field_caption = field_caption(target_field);
|
||||
|
||||
if(target_field.val() != field.val()) {
|
||||
return i18n('same_as', caption, target_field_caption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Validate if provided value is valid email address
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param string caption
|
||||
*/
|
||||
validateEmail : function(field, caption) {
|
||||
if(field.val().match(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/)) {
|
||||
return true;
|
||||
} else {
|
||||
return i18n('email', caption)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Validate if provided value is valid URL
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param string caption
|
||||
*/
|
||||
validateUrl : function(field, caption) {
|
||||
if(field.val().match(/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i)) {
|
||||
return true;
|
||||
} else {
|
||||
return i18n('url', caption);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Number is only valid value (integers and floats)
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param string caption
|
||||
*/
|
||||
validateNumber : function(field, caption) {
|
||||
if(field.val().match(/(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/) || field.val() == '') {
|
||||
return true;
|
||||
} else {
|
||||
return i18n('number', caption);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Whole numbers are allowed
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param string caption
|
||||
*/
|
||||
validateInteger : function(field, caption) {
|
||||
if(field.val().match(/(^-?\d\d*$)/) || field.val() == '') {
|
||||
return true;
|
||||
} else {
|
||||
return i18n('integer', caption);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Letters only
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param string caption
|
||||
*/
|
||||
validateAlpha : function(field, caption) {
|
||||
if(field.val().match(/^[a-zA-Z]+$/)) {
|
||||
return true;
|
||||
} else {
|
||||
return i18n('alpha', caption);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Letters and numbers
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param string caption
|
||||
*/
|
||||
validateAlphaNum : function(field, caption) {
|
||||
if(field.val().match(/\W/)) {
|
||||
return i18n('alphanum', caption);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Simple phrases
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param string caption
|
||||
*/
|
||||
validatePhrase : function(field, caption) {
|
||||
if((field.val() == '') || field.val().match(/^[\w\d\.\-_\(\)\*'# :,]+$/i)) {
|
||||
return true;
|
||||
} else {
|
||||
return i18n('phrase', caption);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Phone number
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param string caption
|
||||
*/
|
||||
validatePhone : function(field, caption) {
|
||||
if(field.val().match('/^1?-?(\d{3})?-?(\d{2})?\d-?(\d{4})$/')) {
|
||||
return true;
|
||||
} else {
|
||||
return i18n('phone', caption);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Phone number
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param string caption
|
||||
*/
|
||||
validateDate : function(field, caption) {
|
||||
if(field.val().match('(1[0-9]|[1-9])/([1-3][0-9]|[1-9])/((19|20)[0-9][0-9]|[0-9][0-9])')) {
|
||||
return true;
|
||||
} else {
|
||||
return i18n('date', caption);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback validator
|
||||
*
|
||||
* Lets you define your own validators. Usage:
|
||||
*
|
||||
* <input name="myinput" class="validateCallback my_callback" />
|
||||
*
|
||||
* This will result in UniForm searching for window.my_callback funciton and
|
||||
* executing it with field and caption arguments. Sample implementation:
|
||||
*
|
||||
* window.my_callback = function(field, caption) {
|
||||
* if(field.val() == '34') {
|
||||
* return true;
|
||||
* } else {
|
||||
* return caption + ' value should be "34"';
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @param jQuery field
|
||||
* @param caption
|
||||
*/
|
||||
validateCallback : function(field, caption) {
|
||||
var classes = field.attr('class').split(' ');
|
||||
var callback_function = '';
|
||||
|
||||
for(var i = 0; i < classes.length; i++) {
|
||||
if(classes[i] == 'validateCallback') {
|
||||
if(classes[i + 1] != 'undefined') {
|
||||
callback_function = classes[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(window[callback_function] != 'undefined' && (typeof window[callback_function] == 'function')) {
|
||||
return window[callback_function](field, caption);
|
||||
}
|
||||
|
||||
return i18n('callback', caption, callback_function);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple replacement for i18n + sprintf
|
||||
*
|
||||
* @param string language for for the local i18n object
|
||||
* @param mixed substitution vars
|
||||
*
|
||||
* @return internationalized string
|
||||
*/
|
||||
var i18n = function(lang_key) {
|
||||
var lang_string = i18n_en[lang_key];
|
||||
var bits = lang_string.split('%');
|
||||
var out = bits[0];
|
||||
var re = /^([ds])(.*)$/;
|
||||
for (var i=1; i<bits.length; i++) {
|
||||
p = re.exec(bits[i]);
|
||||
if (!p || arguments[i] == null) continue;
|
||||
if (p[1] == 'd') {
|
||||
out += parseInt(arguments[i], 10);
|
||||
} else if (p[1] == 's') {
|
||||
out += arguments[i];
|
||||
}
|
||||
out += p[2];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Uni-Form bahaviours to the form
|
||||
*
|
||||
*/
|
||||
return this.each(function() {
|
||||
var form = jQuery(this);
|
||||
|
||||
/**
|
||||
* Set the results of form validation on the form element
|
||||
*
|
||||
* @param object $input jQuery form element
|
||||
* @param bool valid true if the form value passed all validation
|
||||
* @param string text validation error message to display
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
var validate = function($input,valid,text) {
|
||||
var $p = $input.closest('div.' + settings.holder_class)
|
||||
.andSelf()
|
||||
.toggleClass(settings.invalid_class, !valid)
|
||||
.toggleClass(settings.error_class, !valid)
|
||||
.toggleClass(settings.valid_class, valid)
|
||||
.find('p.formHint');
|
||||
|
||||
if (! valid && ! $p.data('info-text')) {
|
||||
$p.data('info-text', $p.html());
|
||||
}
|
||||
else if (valid) {
|
||||
text = $p.data('info-text');
|
||||
}
|
||||
|
||||
if (text) {
|
||||
$p.html(text);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Select form fields and attach them higlighter functionality
|
||||
*
|
||||
*/
|
||||
form.find(settings.field_selector).each(function(){
|
||||
var $input = $(this),
|
||||
value = $input.val();
|
||||
|
||||
$input.data('default-color',$input.css('color'));
|
||||
|
||||
if (value === $input.data('default-value') || ! value) {
|
||||
$input.not('select').css("color", settings.default_value_color);
|
||||
$input.val($input.data('default-value'));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* If we've set ask_on_leave we'll register a handler here
|
||||
*
|
||||
* We need to seriaze the form data, wait for a beforeunload,
|
||||
* then serialize and compare for changes
|
||||
*
|
||||
* If they changed things, and haven't submitted, we'll let them
|
||||
* know about it
|
||||
*
|
||||
*/
|
||||
if(settings.ask_on_leave || form.hasClass('askOnLeave')) {
|
||||
var initial_values = form.serialize();
|
||||
$(window).bind("beforeunload", function(e) {
|
||||
if(initial_values != form.serialize()) {
|
||||
var leave_page = confirm(i18n('on_leave'));
|
||||
// Return focus or something?
|
||||
return leave_page;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the submission of the form
|
||||
*
|
||||
* Tasks
|
||||
* * Remove any default values from the form
|
||||
* * If prevent_submit is set true, return false if
|
||||
* there are outstanding errors in the form
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
form.submit(function(){
|
||||
form.find(settings.field_selector).each(function(){
|
||||
if($(this).val() === $(this).data('default-value')) { $(this).val(""); }
|
||||
});
|
||||
|
||||
// it would be novel to use prevent_submit to disable the submit button
|
||||
// in the blur handler
|
||||
//
|
||||
// here we could traverse and revalidate, but instead, we check for
|
||||
// invalid and error class markers
|
||||
if((settings.prevent_submit || form.hasClass('preventSubmit'))
|
||||
&& form.find('.' + settings.invalid_class)
|
||||
.add('.' + settings.error_class).length
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
/**
|
||||
* Set the form focus class
|
||||
*
|
||||
* Remove any classes other than the focus class and hide the default label text
|
||||
*
|
||||
*/
|
||||
form.delegate(settings.field_selector, 'focus', function() {
|
||||
form.find('.' + settings.focused_class).removeClass(settings.focused_class);
|
||||
|
||||
var $input = $(this);
|
||||
|
||||
$input.parents().filter('.'+settings.holder_class+':first').addClass(settings.focused_class);
|
||||
|
||||
if($input.val() === $input.data('default-value')){
|
||||
$input.val("");
|
||||
}
|
||||
|
||||
$input.not('select').css('color',$input.data('default-color'));
|
||||
});
|
||||
|
||||
/**
|
||||
* Validate a form field on the blur event
|
||||
*
|
||||
* Search the classnames on the element for the names of
|
||||
* validators, and run them as we find them
|
||||
*
|
||||
* If the validators fail, we trigger either 'success' or 'error' events
|
||||
*
|
||||
*/
|
||||
form.delegate(settings.field_selector, 'blur', function() {
|
||||
var $input = $(this);
|
||||
var label = $(this)
|
||||
.closest('div.'+settings.holder_class)
|
||||
.find('label').text();
|
||||
|
||||
// remove focus from form element
|
||||
form.find('.' + settings.focused_class).removeClass(settings.focused_class);
|
||||
|
||||
// (if empty or equal to default value) AND not required
|
||||
if(($input.val() === "" || $input.val() === $input.data('default-value'))
|
||||
&& !$input.hasClass('required')
|
||||
){
|
||||
$input.not('select').css("color",settings.default_value_color);
|
||||
$input.val($input.data('default-value'));
|
||||
return;
|
||||
}
|
||||
|
||||
// run the validation and if they all pass, we mark the color and move on
|
||||
var has_validation = false;
|
||||
for(validator in validators) {
|
||||
if($input.hasClass(validator)){
|
||||
has_validation = true;
|
||||
var validation_result = validators[validator]($input, label);
|
||||
if(typeof(validation_result) == 'string') {
|
||||
$input.trigger('error', validation_result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if it had validation and we didn't return above,
|
||||
// then all validation passed
|
||||
if (has_validation) {
|
||||
$input.trigger('success');
|
||||
}
|
||||
|
||||
// return the color to the default
|
||||
$input.css('color', $input.data('default-color'));
|
||||
return;
|
||||
});
|
||||
|
||||
/**
|
||||
* Handle a validation error in the form element
|
||||
*
|
||||
* This will set the field to have the error marker
|
||||
* and update the warning text
|
||||
*
|
||||
* @param event e
|
||||
* @param string validation message
|
||||
*/
|
||||
form.delegate(settings.field_selector,'error',function(e,text) {
|
||||
validate($(this), false, text);
|
||||
});
|
||||
|
||||
/**
|
||||
* Handle a succesfull validation in the form element
|
||||
*
|
||||
* Remove any error messages and set the validation
|
||||
* marker to be success
|
||||
*
|
||||
* @param event e
|
||||
* @param string unused
|
||||
*/
|
||||
form.delegate(settings.field_selector,'success',function(e,text) {
|
||||
validate($(this), true);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Auto set on page load
|
||||
$(document).ready(function() {
|
||||
jQuery('form').uniform({ask_on_leave : true});
|
||||
});
|
||||
|
||||
101
views/js/uni-form.jquery.js
Executable file
@@ -0,0 +1,101 @@
|
||||
// Author: Ilija Studen for the purposes of Uni–Form
|
||||
|
||||
// Modified by Aris Karageorgos to use the parents function
|
||||
|
||||
// Modified by Toni Karlheinz to support input fields' text
|
||||
// coloring and removal of their initial values on focus
|
||||
|
||||
// Modified by Jason Brumwell for optimization, addition
|
||||
// of valid and invalid states and default data attribues
|
||||
|
||||
jQuery.fn.uniform = function(settings) {
|
||||
settings = jQuery.extend({
|
||||
valid_class : 'valid',
|
||||
invalid_class : 'invalid',
|
||||
error_class : 'error',
|
||||
focused_class : 'focused',
|
||||
holder_class : 'ctrlHolder',
|
||||
field_selector : 'input, textarea, select',
|
||||
default_value_color: "#AFAFAF"
|
||||
}, settings);
|
||||
|
||||
return this.each(function() {
|
||||
var form = jQuery(this),
|
||||
validate = function($input,valid,text) {
|
||||
var $p = $input.closest('div.'+settings.holder_class)
|
||||
.andSelf()
|
||||
.toggleClass(settings.invalid_class,!valid)
|
||||
.toggleClass(settings.error_class,!valid)
|
||||
.toggleClass(settings.valid_class,valid)
|
||||
.find('p.formHint');
|
||||
|
||||
if (! valid && ! $p.data('info-text')) {
|
||||
$p.data('info-text',$p.html());
|
||||
} else if (valid) {
|
||||
text = $p.data('info-text');
|
||||
}
|
||||
|
||||
if (text) {
|
||||
$p.html(text);
|
||||
}
|
||||
};
|
||||
|
||||
form.submit(function(){
|
||||
form.find(settings.field_selector).each(function(){
|
||||
if($(this).val() == $(this).data('default-value')) $(this).val("");
|
||||
});
|
||||
})
|
||||
|
||||
// Select form fields and attach them higlighter functionality
|
||||
form.find(settings.field_selector).each(function(){
|
||||
var $input = $(this),
|
||||
value = $input.val();
|
||||
|
||||
$input.data('default-color',$input.css('color'));
|
||||
|
||||
if (value == $input.data('default-value') || ! value) {
|
||||
$input.not('select').css("color",settings.default_value_color);
|
||||
$input.val($input.data('default-value'));
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
form.delegate(settings.field_selector,'focus',function() {
|
||||
form.find('.' + settings.focused_class).removeClass(settings.focused_class);
|
||||
|
||||
var $input = $(this);
|
||||
|
||||
$input.parents().filter('.'+settings.holder_class+':first').addClass(settings.focused_class);
|
||||
|
||||
if($input.val() == $input.data('default-value')){
|
||||
$input.val("");
|
||||
}
|
||||
|
||||
$input.not('select').css('color',$input.data('default-color'));
|
||||
});
|
||||
|
||||
form.delegate(settings.field_selector,'blur',function() {
|
||||
var $input = $(this);
|
||||
form.find('.' + settings.focused_class).removeClass(settings.focused_class);
|
||||
if($input.val() == "" || $input.val() == $input.data('default-value')){
|
||||
$input.not('select').css("color",settings.default_value_color);
|
||||
$input.val($input.data('default-value'));
|
||||
} else {
|
||||
$input.css('color',$input.data('default-color'));
|
||||
}
|
||||
});
|
||||
|
||||
form.delegate(settings.field_selector,'error',function(e,text) {
|
||||
validate($(this),false,text);
|
||||
});
|
||||
|
||||
form.delegate(settings.field_selector,'success',function(e,text) {
|
||||
validate($(this),true);
|
||||
});
|
||||
});
|
||||
};
|
||||
// Auto set on page load...
|
||||
$(document).ready(function() {
|
||||
jQuery('form').uniform();
|
||||
});
|
||||
|
||||
144
views/qrcode.tpl
Normal file
@@ -0,0 +1,144 @@
|
||||
<!DOCTYPE HTML>
|
||||
|
||||
<html>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="Content-Type" content="text/html" />
|
||||
|
||||
<title>QR vCard Generator</title>
|
||||
|
||||
<link media="screen" href="css/default.uni-form.css" rel="stylesheet">
|
||||
<link href="css/default.uni-form.css" title="Default Style" media="screen" rel="stylesheet"/>
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
|
||||
@import "css/uni-form.css";
|
||||
|
||||
/* You don't need these, they are here to tune up the page */
|
||||
html{ color: #343434; background: #bcc2c6 url(bg.png); font-size: 14px; line-height: 1.5; font-family: "Lucida Sans Unicode", "Lucida Grande", Arial, Verdana, sans-serif; }
|
||||
body{}
|
||||
|
||||
a:link,
|
||||
a:visited{ text-decoration: none; color: #254a86; }
|
||||
a:hover,
|
||||
a:focus { text-decoration: underline; }
|
||||
|
||||
h1,h2,h3,ul,ol,p{ margin: 1.5em 0; }
|
||||
|
||||
h1{ margin: 42px auto 28px auto; width: 284px; }
|
||||
h2{ font-size: 1.25em; }
|
||||
.uniForm h2{ margin: 1em 0 1em 1.15em; }
|
||||
fieldset h3{ margin: 1.5em -28px; padding: 14px 28px; line-height: 1; background: #efefef; color: #343434; }
|
||||
|
||||
.uniForm{ width: 55%; background: #fff; margin: 28px auto; padding: 28px;
|
||||
/* CSS3 */
|
||||
border-radius: 12px;
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
-o-border-radius: 12px;
|
||||
-khtml-border-radius: 12px;
|
||||
}
|
||||
|
||||
.header{ margin: -28px -28px 28px -28px; padding: 1px 28px; background: #efefef; border-bottom: 1px solid #dfdfdf; position: relative;
|
||||
/* CSS3 */
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
-webkit-border-top-left-radius: 10px;
|
||||
-webkit-border-top-right-radius: 10px;
|
||||
-moz-border-radius-topleft: 10px;
|
||||
-moz-border-radius-topright: 10px;
|
||||
}
|
||||
.header h2{ margin: 1.5em 0 0 0; color: #343434; color: #777; }
|
||||
.header p { margin-top: 0; font-size: 12px; color: #777; }
|
||||
.header .cta{ position: absolute; bottom: 26px; right: 28px; text-align: right; font-weight: bold; background: #194789; padding: 7px 14px;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
text-shadow: -1px -1px 0 rgba(0,0,0,.25);
|
||||
}
|
||||
.header .cta:link,
|
||||
.header .cta:visited{ color: #fff; }
|
||||
.header .cta:focus,
|
||||
.header .cta:hover{ text-decoration: none;
|
||||
/* CSS3 */
|
||||
box-shadow: 0 0 9px rgba(0,163,255,1);
|
||||
-webkit-box-shadow: 0 0 9px rgba(0,163,255,1);
|
||||
-moz-box-shadow: 0 0 9px rgba(0,163,255,1);
|
||||
}
|
||||
.header .cta:active{ bottom: 25px; }
|
||||
|
||||
.browse{ margin: 0; position: fixed; top: 28px; right: 28px; width: 84px; padding: 28px 28px 14px 28px; font-size: 12px; background: #97a2b0;
|
||||
/* CSS3 */
|
||||
border-radius: 12px;
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
-o-border-radius: 12px;
|
||||
-khtml-border-radius: 12px;
|
||||
}
|
||||
.browse h2{ font-size: 12px; margin: 0 0 14px 0; }
|
||||
.browse ul{ margin: 0; padding: 0; }
|
||||
.browse li{ margin: 0 0 14px 0; padding: 0; list-style: none; }
|
||||
.download{ float: right; position: relative; top: 2px; }
|
||||
.intro { width: 55%; margin: 28px auto; text-align: center; font-size: 1.15em; }
|
||||
#footer{ width: 55%; margin: 28px auto; text-align: center; font-size: .75em; color: #777; }
|
||||
|
||||
/* IE6 fixes for the page */
|
||||
* html form.uniForm{ overflow: hidden; }
|
||||
* html .header{ zoom: 1; overflow: hidden;}
|
||||
* html .browse{ position: absolute; }
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
|
||||
<script src="js/uni-form.jquery.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$(".browse a").click(function() {
|
||||
$("link").attr("href",$(this).attr('rel'));
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--[if lte ie 7]>
|
||||
<style type="text/css" media="screen">
|
||||
/* Move these to your IE6/7 specific stylesheet if possible */
|
||||
.uniForm, .uniForm fieldset, .uniForm .ctrlHolder, .uniForm .formHint, .uniForm .buttonHolder, .uniForm .ctrlHolder ul{ zoom:1; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
<script type="text/javascript">
|
||||
var rpxJsHost = (("https:" == document.location.protocol) ? "https://" : "http://static.");
|
||||
document.write(unescape("%3Cscript src='" + rpxJsHost +
|
||||
"rpxnow.com/js/lib/rpx.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
RPXNOW.overlay = true;
|
||||
RPXNOW.language_preference = 'en';
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h2>QR Code vCard Generator</h2>
|
||||
<p>Author: <a href="http://fergalmoran.com/">Fergal Moran</a> <a href="http://blog.fergalmoran.com/qrcodegenerator/" class="cta">Blog article</a></p>
|
||||
</div>
|
||||
|
||||
<div id="okMsg" style="padding-left: 100px">
|
||||
<p>
|
||||
Here is your qrcode vCard. Right click the image below and select "Save as" to download it. <br />
|
||||
Alternatively, you may click "Permalink" below to generate a permanent URL for this image (please note, this requires signing in and may not always be available).
|
||||
</p>
|
||||
<span align="centre">
|
||||
<img align="middle" src="static/cache/{{id}}.png" alt="QRCode should be here" />
|
||||
</span>
|
||||
<div id="auth_widget">
|
||||
<!-- <a class="rpxnow" onclick="return false;" href="https://fm-qrcodes.rpxnow.com/openid/v2/signin?token_url=http%3A%2F%2Fdev.fergalmoran.com%3A8080%2Fauth_proxy"> Permalink </a> -->
|
||||
<a class="" href="/permalink/{{id}}"> Permalink </a>
|
||||
</div>
|
||||
<div id="permalink">
|
||||
{{!linkurl}}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
167
views/qrform.tpl
Normal file
@@ -0,0 +1,167 @@
|
||||
<!DOCTYPE HTML>
|
||||
|
||||
<html>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="Content-Type" content="text/html" />
|
||||
|
||||
<title>QR vCard Generator</title>
|
||||
|
||||
<link media="screen" href="css/default.uni-form.css" rel="stylesheet">
|
||||
<link href="css/default.uni-form.css" title="Default Style" media="screen" rel="stylesheet"/>
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
|
||||
@import "css/uni-form.css";
|
||||
|
||||
/* You don't need these, they are here to tune up the page */
|
||||
html{ color: #343434; background: #bcc2c6 url(bg.png); font-size: 14px; line-height: 1.5; font-family: "Lucida Sans Unicode", "Lucida Grande", Arial, Verdana, sans-serif; }
|
||||
body{}
|
||||
|
||||
a:link,
|
||||
a:visited{ text-decoration: none; color: #254a86; }
|
||||
a:hover,
|
||||
a:focus { text-decoration: underline; }
|
||||
|
||||
h1,h2,h3,ul,ol,p{ margin: 1.5em 0; }
|
||||
|
||||
h1{ margin: 42px auto 28px auto; width: 284px; }
|
||||
h2{ font-size: 1.25em; }
|
||||
.uniForm h2{ margin: 1em 0 1em 1.15em; }
|
||||
fieldset h3{ margin: 1.5em -28px; padding: 14px 28px; line-height: 1; background: #efefef; color: #343434; }
|
||||
|
||||
.uniForm{ width: 55%; background: #fff; margin: 28px auto; padding: 28px;
|
||||
/* CSS3 */
|
||||
border-radius: 12px;
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
-o-border-radius: 12px;
|
||||
-khtml-border-radius: 12px;
|
||||
}
|
||||
|
||||
.header{ margin: -28px -28px 28px -28px; padding: 1px 28px; background: #efefef; border-bottom: 1px solid #dfdfdf; position: relative;
|
||||
/* CSS3 */
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
-webkit-border-top-left-radius: 10px;
|
||||
-webkit-border-top-right-radius: 10px;
|
||||
-moz-border-radius-topleft: 10px;
|
||||
-moz-border-radius-topright: 10px;
|
||||
}
|
||||
.header h2{ margin: 1.5em 0 0 0; color: #343434; color: #777; }
|
||||
.header p { margin-top: 0; font-size: 12px; color: #777; }
|
||||
.header .cta{ position: absolute; bottom: 26px; right: 28px; text-align: right; font-weight: bold; background: #194789; padding: 7px 14px;
|
||||
/* CSS3 */
|
||||
border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
text-shadow: -1px -1px 0 rgba(0,0,0,.25);
|
||||
}
|
||||
.header .cta:link,
|
||||
.header .cta:visited{ color: #fff; }
|
||||
.header .cta:focus,
|
||||
.header .cta:hover{ text-decoration: none;
|
||||
/* CSS3 */
|
||||
box-shadow: 0 0 9px rgba(0,163,255,1);
|
||||
-webkit-box-shadow: 0 0 9px rgba(0,163,255,1);
|
||||
-moz-box-shadow: 0 0 9px rgba(0,163,255,1);
|
||||
}
|
||||
.header .cta:active{ bottom: 25px; }
|
||||
|
||||
.browse{ margin: 0; position: fixed; top: 28px; right: 28px; width: 84px; padding: 28px 28px 14px 28px; font-size: 12px; background: #97a2b0;
|
||||
/* CSS3 */
|
||||
border-radius: 12px;
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
-o-border-radius: 12px;
|
||||
-khtml-border-radius: 12px;
|
||||
}
|
||||
.browse h2{ font-size: 12px; margin: 0 0 14px 0; }
|
||||
.browse ul{ margin: 0; padding: 0; }
|
||||
.browse li{ margin: 0 0 14px 0; padding: 0; list-style: none; }
|
||||
.download{ float: right; position: relative; top: 2px; }
|
||||
.intro { width: 55%; margin: 28px auto; text-align: center; font-size: 1.15em; }
|
||||
#footer{ width: 55%; margin: 28px auto; text-align: center; font-size: .75em; color: #777; }
|
||||
|
||||
/* IE6 fixes for the page */
|
||||
* html form.uniForm{ overflow: hidden; }
|
||||
* html .header{ zoom: 1; overflow: hidden;}
|
||||
* html .browse{ position: absolute; }
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
|
||||
<script src="js/uni-form.jquery.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$(".browse a").click(function() {
|
||||
$("link").attr("href",$(this).attr('rel'));
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--[if lte ie 7]>
|
||||
<style type="text/css" media="screen">
|
||||
/* Move these to your IE6/7 specific stylesheet if possible */
|
||||
.uniForm, .uniForm fieldset, .uniForm .ctrlHolder, .uniForm .formHint, .uniForm .buttonHolder, .uniForm .ctrlHolder ul{ zoom:1; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h2>QR Code vCard Generator</h2>
|
||||
<p>Author: <a href="http://fergalmoran.com/">Fergal Moran</a> <a href="http://blog.fergalmoran.com/qrcodegenerator/" class="cta">Blog article</a></p>
|
||||
</div>
|
||||
|
||||
<div id="errorMsg">
|
||||
</div>
|
||||
|
||||
<div id="okMsg">
|
||||
</div>
|
||||
|
||||
<form action="/qrmaker" method="POST" enctype="multipart/form-data" class="uniForm">
|
||||
<fieldset class="inlineLabels">
|
||||
<h3>vCard Details</h3>
|
||||
<div class="ctrlHolder">
|
||||
<label for="">First name</label>
|
||||
<input id="firstname" name="FIRSTNAME" value="" size="35" class="textInput" type="text">
|
||||
</div>
|
||||
<div class="ctrlHolder">
|
||||
<label for="">Surname</label>
|
||||
<input id="surname" name="SURNAME" value="" size="35" class="textInput" type="text">
|
||||
</div>
|
||||
<div class="ctrlHolder">
|
||||
<label for="">Email address</label>
|
||||
<input id="email" name="EMAIL" value="" size="35" class="textInput" type="text">
|
||||
</div>
|
||||
<!--
|
||||
<div class="ctrlHolder">
|
||||
<label for="">Organisation</label>
|
||||
<input id="organisation" name="ORGANISATION" value="" size="35" class="textInput" type="text">
|
||||
</div>
|
||||
-->
|
||||
<div class="ctrlHolder">
|
||||
<label for="">Telephone (mobile):</label>
|
||||
<input id="telmobile" name="TELMOBILE" value="" size="35" class="textInput" type="text">
|
||||
</div>
|
||||
<div class="ctrlHolder">
|
||||
<label for="">Telephone (home):</label>
|
||||
<input id="telhome" name="TELHOME" value="" size="35" class="textInput" type="text">
|
||||
</div>
|
||||
<div class="ctrlHolder">
|
||||
<label for="">Website Address:</label>
|
||||
<input id="url" name="URL" value="" size="35" class="textInput" type="text">
|
||||
</div>
|
||||
<div class="ctrlHolder">
|
||||
<label for="">Address:</label>
|
||||
<input id="addrhome" name="ADDRHOME" value="" size="35" class="textInput" type="text">
|
||||
<p class="formHint">Please seperate lines with a comma</p>
|
||||
</div>
|
||||
<div class="buttonHolder"><button type="submit" class="primaryAction">Submit</button></div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||