@ -1,2 +1,4 @@
@@ -1,2 +1,4 @@
|
||||
node_modules |
||||
.DS_Store |
||||
.DS_Store |
||||
*.sqlite |
||||
.#* |
||||
|
||||
@ -0,0 +1,175 @@
@@ -0,0 +1,175 @@
|
||||
package main |
||||
|
||||
import ( |
||||
"database/sql" |
||||
"fmt" |
||||
_ "github.com/mattn/go-sqlite3" |
||||
"log" |
||||
"net/http" |
||||
"strconv" |
||||
) |
||||
|
||||
type Response struct { |
||||
FirstName, Name string |
||||
Answer string |
||||
NumAdult, NumKids uint |
||||
Vegi, Vegan bool |
||||
NumVegi, NumVegan uint |
||||
Allerien bool |
||||
Allergene string |
||||
Accumodation bool |
||||
NumRooms uint |
||||
Arrival string |
||||
Musik string |
||||
Email string |
||||
Permission bool |
||||
} |
||||
|
||||
func newRespose(db *sql.DB, row *Response) error { |
||||
sqlStmt := fmt.Sprintf(`INSERT INTO response |
||||
(fName, lName, answer, numAdult, numKids, vegi, numVegi, vegan, numVegan, allergiger, allergene, accommodation, numRooms, arrival, musik, email, permission) |
||||
VALUES |
||||
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`) |
||||
|
||||
tx, err := db.Begin() |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
stmt, err := tx.Prepare(sqlStmt) |
||||
defer tx.Commit() |
||||
if err != nil { |
||||
return err |
||||
} |
||||
defer stmt.Close() |
||||
|
||||
log.Printf("Add new response: %s", *row) |
||||
_, err = stmt.Exec( |
||||
row.FirstName, row.Name, |
||||
row.Answer, |
||||
row.NumAdult, row.NumKids, |
||||
row.Vegi, row.NumVegi, |
||||
row.Vegan, row.NumVegan, |
||||
row.Allerien, row.Allergene, |
||||
row.Accumodation, row.NumRooms, |
||||
row.Arrival, |
||||
row.Musik, |
||||
row.Email, row.Permission) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
return nil |
||||
} |
||||
|
||||
func initDB(dbS string) (*sql.DB, error) { |
||||
db, err := sql.Open("sqlite3", dbS) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
sqlStmt := fmt.Sprintf(`CREATE TABLE IF NOT EXISTS response |
||||
(id INTEGER NOT NULL PRIMARY KEY, |
||||
fName TEXT NOT NULL, lName TEXT NOT NULL, |
||||
answer TEXT NOT NULL, |
||||
numAdult INTEGER NOT NULL, numKids INTEGER NOT NULL, |
||||
vegi BOOLEAN, numVegi INTEGER, |
||||
vegan BOOLEAN, numVegan INTEGER, |
||||
allergiger BOOLEAN, allergene TEXT, |
||||
accommodation BOOLEAN, numRooms INTEGER, |
||||
arrival TEXT, |
||||
musik TEXT, |
||||
email TEXT, permission BOOLEAN, |
||||
created DATETIME DEFAULT CURRENT_TIMESTAMP);`) |
||||
_, err = db.Exec(sqlStmt) |
||||
if err != nil { |
||||
return db, err |
||||
} |
||||
|
||||
log.Printf("DB %s is up and running", dbS) |
||||
return db, nil |
||||
} |
||||
|
||||
func main() { |
||||
// init database
|
||||
db, err := initDB("response.sqlite") |
||||
if err != nil { |
||||
if db != nil { |
||||
db.Close() |
||||
} |
||||
log.Panic(err) |
||||
} |
||||
defer db.Close() |
||||
|
||||
// init http server with two routes for onepage website and endpoint for sending the response
|
||||
http.Handle("/", httpLogHandler(http.FileServer(http.Dir("../../../../frontend")))) |
||||
http.HandleFunc("/process", func(w http.ResponseWriter, r *http.Request) { |
||||
processAnmeldung(w, r, db) |
||||
}) |
||||
|
||||
http.ListenAndServe(":8080", nil) |
||||
} |
||||
|
||||
func parseBool(s string) bool { |
||||
return s == "on" |
||||
} |
||||
|
||||
func parseUInt(s string) uint { |
||||
u64, err := strconv.ParseUint(s, 10, 32) |
||||
if err != nil { |
||||
return 0 |
||||
} |
||||
return uint(u64) |
||||
} |
||||
|
||||
func httpLogHandler(h http.Handler) http.Handler { |
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
||||
log.Printf("Webseiten Aufruf: '%v:%v' %v", r.Method, r.URL, r.Header) |
||||
h.ServeHTTP(w, r) |
||||
}) |
||||
} |
||||
|
||||
func processAnmeldung(w http.ResponseWriter, r *http.Request, db *sql.DB) { |
||||
log.Printf("Process Endpoint Aufruf: '%v:%v' %v", r.Method, r.URL, r.Header) |
||||
|
||||
if r.Method != http.MethodPost { |
||||
http.Redirect(w, r, "/", http.StatusSeeOther) |
||||
return |
||||
} |
||||
|
||||
// Call ParseForm() to parse the raw query and update r.PostForm and r.Form.
|
||||
if err := r.ParseForm(); err != nil { |
||||
fmt.Fprintf(w, "ParseForm() err: %v", err) |
||||
return |
||||
} |
||||
log.Printf("Post from website: %v", r.PostForm) |
||||
|
||||
response := Response{ |
||||
FirstName: r.FormValue("firstname"), |
||||
Name: r.FormValue("name"), |
||||
Answer: r.FormValue("rueckmeldung"), |
||||
NumAdult: parseUInt(r.FormValue("numAdult")), |
||||
NumKids: parseUInt(r.FormValue("numKids")), |
||||
Vegi: parseBool(r.FormValue("vegi")), |
||||
Vegan: parseBool(r.FormValue("vegan")), |
||||
NumVegi: parseUInt(r.FormValue("numVegi")), |
||||
NumVegan: parseUInt(r.FormValue("numVegan")), |
||||
Allergene: r.FormValue("allagene"), |
||||
Allerien: parseBool(r.FormValue("allergiger")), |
||||
Accumodation: parseBool(r.FormValue("unterkunft")), |
||||
Arrival: r.FormValue("arrival"), |
||||
NumRooms: parseUInt(r.FormValue("numUnterkunft")), |
||||
Musik: r.FormValue("musik"), |
||||
Email: r.FormValue("email"), |
||||
Permission: parseBool(r.FormValue("weitergabe")), |
||||
} |
||||
log.Printf("Form values parsed: %v", response) |
||||
|
||||
err := newRespose(db, &response) |
||||
if err != nil { |
||||
log.Print("Fehler beim einfügen in die DB: %v", err) |
||||
} |
||||
|
||||
//TODO return json
|
||||
fmt.Fprintf(w, "Post from website!\n %v\n", response) |
||||
} |
||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 333 B After Width: | Height: | Size: 333 B |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 233 KiB After Width: | Height: | Size: 233 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 379 KiB After Width: | Height: | Size: 379 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 356 KiB After Width: | Height: | Size: 356 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 4.8 MiB After Width: | Height: | Size: 4.8 MiB |
@ -1,52 +0,0 @@
@@ -1,52 +0,0 @@
|
||||
{ |
||||
"title": "Agency", |
||||
"name": "startbootstrap-agency", |
||||
"version": "6.0.2", |
||||
"scripts": { |
||||
"build": "npm run clean && npm run build:pug && npm run build:scss && npm run build:scripts && npm run build:assets", |
||||
"build:assets": "node scripts/build-assets.js", |
||||
"build:pug": "node scripts/build-pug.js", |
||||
"build:scripts": "node scripts/build-scripts.js", |
||||
"build:scss": "node scripts/build-scss.js", |
||||
"clean": "node scripts/clean.js", |
||||
"start": "npm run build && node scripts/start.js", |
||||
"start:debug": "npm run build && node scripts/start-debug.js" |
||||
}, |
||||
"description": "Agency is a one page HTML theme for Bootstrap.", |
||||
"keywords": [ |
||||
"css", |
||||
"sass", |
||||
"html", |
||||
"responsive", |
||||
"theme", |
||||
"template" |
||||
], |
||||
"homepage": "https://startbootstrap.com/template-overviews/agency", |
||||
"bugs": { |
||||
"url": "https://github.com/StartBootstrap/startbootstrap-agency/issues", |
||||
"email": "feedback@startbootstrap.com" |
||||
}, |
||||
"license": "MIT", |
||||
"author": "Start Bootstrap", |
||||
"contributors": [ |
||||
"David Miller (http://davidmiller.io/)" |
||||
], |
||||
"repository": { |
||||
"type": "git", |
||||
"url": "https://github.com/StartBootstrap/startbootstrap-agency.git" |
||||
}, |
||||
"dependencies": { |
||||
"bootstrap": "4.5.0" |
||||
}, |
||||
"devDependencies": { |
||||
"autoprefixer": "9.8.0", |
||||
"browser-sync": "2.26.7", |
||||
"chokidar": "3.4.0", |
||||
"concurrently": "5.2.0", |
||||
"postcss": "7.0.32", |
||||
"prettier": "2.0.5", |
||||
"pug": "3.0.0", |
||||
"sass": "1.26.8", |
||||
"shelljs": "0.8.4" |
||||
} |
||||
} |
||||
@ -1,5 +0,0 @@
@@ -1,5 +0,0 @@
|
||||
'use strict'; |
||||
|
||||
const renderAssets = require('./render-assets'); |
||||
|
||||
renderAssets(); |
||||
@ -1,19 +0,0 @@
@@ -1,19 +0,0 @@
|
||||
'use strict'; |
||||
const path = require('path'); |
||||
const sh = require('shelljs'); |
||||
const renderPug = require('./render-pug'); |
||||
|
||||
const srcPath = path.resolve(path.dirname(__filename), '../src'); |
||||
|
||||
sh.find(srcPath).forEach(_processFile); |
||||
|
||||
function _processFile(filePath) { |
||||
if ( |
||||
filePath.match(/\.pug$/) |
||||
&& !filePath.match(/include/) |
||||
&& !filePath.match(/mixin/) |
||||
&& !filePath.match(/\/pug\/layouts\//) |
||||
) { |
||||
renderPug(filePath); |
||||
} |
||||
} |
||||
@ -1,5 +0,0 @@
@@ -1,5 +0,0 @@
|
||||
'use strict'; |
||||
|
||||
const renderScripts = require('./render-scripts'); |
||||
|
||||
renderScripts(); |
||||
@ -1,5 +0,0 @@
@@ -1,5 +0,0 @@
|
||||
'use strict'; |
||||
|
||||
const renderSCSS = require('./render-scss'); |
||||
|
||||
renderSCSS(); |
||||
@ -1,7 +0,0 @@
@@ -1,7 +0,0 @@
|
||||
const sh = require('shelljs'); |
||||
const path = require('path'); |
||||
|
||||
const destPath = path.resolve(path.dirname(__filename), '../dist'); |
||||
|
||||
sh.rm('-rf', `${destPath}/*`) |
||||
|
||||
@ -1,11 +0,0 @@
@@ -1,11 +0,0 @@
|
||||
'use strict'; |
||||
const fs = require('fs'); |
||||
const path = require('path'); |
||||
const sh = require('shelljs'); |
||||
|
||||
module.exports = function renderAssets() { |
||||
const sourcePath = path.resolve(path.dirname(__filename), '../src/assets'); |
||||
const destPath = path.resolve(path.dirname(__filename), '../dist/.'); |
||||
|
||||
sh.cp('-R', sourcePath, destPath) |
||||
}; |
||||
@ -1,35 +0,0 @@
@@ -1,35 +0,0 @@
|
||||
'use strict'; |
||||
const fs = require('fs'); |
||||
const path = require('path'); |
||||
const pug = require('pug'); |
||||
const sh = require('shelljs'); |
||||
const prettier = require('prettier'); |
||||
|
||||
module.exports = function renderPug(filePath) { |
||||
const destPath = filePath.replace(/src\/pug\//, 'dist/').replace(/\.pug$/, '.html'); |
||||
const srcPath = path.resolve(path.dirname(__filename), '../src'); |
||||
|
||||
console.log(`### INFO: Rendering ${filePath} to ${destPath}`); |
||||
const html = pug.renderFile(filePath, { |
||||
doctype: 'html', |
||||
filename: filePath, |
||||
basedir: srcPath |
||||
}); |
||||
|
||||
const destPathDirname = path.dirname(destPath); |
||||
if (!sh.test('-e', destPathDirname)) { |
||||
sh.mkdir('-p', destPathDirname); |
||||
} |
||||
|
||||
const prettified = prettier.format(html, { |
||||
printWidth: 1000, |
||||
tabWidth: 4, |
||||
singleQuote: true, |
||||
proseWrap: 'preserve', |
||||
endOfLine: 'lf', |
||||
parser: 'html', |
||||
htmlWhitespaceSensitivity: 'ignore' |
||||
}); |
||||
|
||||
fs.writeFileSync(destPath, prettified); |
||||
}; |
||||
@ -1,25 +0,0 @@
@@ -1,25 +0,0 @@
|
||||
'use strict'; |
||||
const fs = require('fs'); |
||||
const packageJSON = require('../package.json'); |
||||
const path = require('path'); |
||||
const sh = require('shelljs'); |
||||
|
||||
module.exports = function renderScripts() { |
||||
const sourcePath = path.resolve(path.dirname(__filename), '../src/js/scripts.js'); |
||||
const destPath = path.resolve(path.dirname(__filename), '../dist/js/scripts.js'); |
||||
|
||||
const copyright = `/*!
|
||||
* Start Bootstrap - ${packageJSON.title} v${packageJSON.version} (${packageJSON.homepage}) |
||||
* Copyright 2013-${new Date().getFullYear()} ${packageJSON.author} |
||||
* Licensed under ${packageJSON.license} (https://github.com/StartBootstrap/${packageJSON.name}/blob/master/LICENSE)
|
||||
*/ |
||||
` |
||||
const scriptsJS = fs.readFileSync(sourcePath); |
||||
const destPathDirname = path.dirname(destPath); |
||||
|
||||
if (!sh.test('-e', destPathDirname)) { |
||||
sh.mkdir('-p', destPathDirname); |
||||
} |
||||
|
||||
fs.writeFileSync(destPath, copyright + scriptsJS); |
||||
}; |
||||
@ -1,42 +0,0 @@
@@ -1,42 +0,0 @@
|
||||
'use strict'; |
||||
const autoprefixer = require('autoprefixer') |
||||
const fs = require('fs'); |
||||
const packageJSON = require('../package.json'); |
||||
const path = require('path'); |
||||
const postcss = require('postcss') |
||||
const sass = require('sass'); |
||||
const sh = require('shelljs'); |
||||
|
||||
const stylesPath = '../src/scss/styles.scss'; |
||||
const destPath = path.resolve(path.dirname(__filename), '../dist/css/styles.css'); |
||||
|
||||
module.exports = function renderSCSS() { |
||||
|
||||
const results = sass.renderSync({ |
||||
data: entryPoint, |
||||
includePaths: [ |
||||
path.resolve(path.dirname(__filename), '../node_modules') |
||||
], |
||||
}); |
||||
|
||||
const destPathDirname = path.dirname(destPath); |
||||
if (!sh.test('-e', destPathDirname)) { |
||||
sh.mkdir('-p', destPathDirname); |
||||
} |
||||
|
||||
postcss([ autoprefixer ]).process(results.css, {from: 'styles.css', to: 'styles.css'}).then(result => { |
||||
result.warnings().forEach(warn => { |
||||
console.warn(warn.toString()) |
||||
}) |
||||
fs.writeFileSync(destPath, result.css.toString()); |
||||
}) |
||||
|
||||
}; |
||||
|
||||
const entryPoint = `/*!
|
||||
* Start Bootstrap - ${packageJSON.title} v${packageJSON.version} (${packageJSON.homepage}) |
||||
* Copyright 2013-${new Date().getFullYear()} ${packageJSON.author} |
||||
* Licensed under ${packageJSON.license} (https://github.com/StartBootstrap/${packageJSON.name}/blob/master/LICENSE)
|
||||
*/ |
||||
@import "${stylesPath}" |
||||
` |
||||
@ -1,86 +0,0 @@
@@ -1,86 +0,0 @@
|
||||
'use strict'; |
||||
|
||||
const _ = require('lodash'); |
||||
const chokidar = require('chokidar'); |
||||
const path = require('path'); |
||||
const renderAssets = require('./render-assets'); |
||||
const renderPug = require('./render-pug'); |
||||
const renderScripts = require('./render-scripts'); |
||||
const renderSCSS = require('./render-scss'); |
||||
|
||||
const watcher = chokidar.watch('src', { |
||||
persistent: true, |
||||
}); |
||||
|
||||
let READY = false; |
||||
|
||||
process.title = 'pug-watch'; |
||||
process.stdout.write('Loading'); |
||||
let allPugFiles = {}; |
||||
|
||||
watcher.on('add', filePath => _processFile(filePath, 'add')); |
||||
watcher.on('change', filePath => _processFile(filePath, 'change')); |
||||
watcher.on('ready', () => { |
||||
READY = true; |
||||
console.log(' READY TO ROLL!'); |
||||
}); |
||||
|
||||
_handleSCSS(); |
||||
|
||||
function _processFile(filePath, watchEvent) { |
||||
|
||||
if (!READY) { |
||||
if (filePath.match(/\.pug$/)) { |
||||
if (!filePath.match(/includes/) && !filePath.match(/mixins/) && !filePath.match(/\/pug\/layouts\//)) { |
||||
allPugFiles[filePath] = true; |
||||
} |
||||
} |
||||
process.stdout.write('.'); |
||||
return; |
||||
} |
||||
|
||||
console.log(`### INFO: File event: ${watchEvent}: ${filePath}`); |
||||
|
||||
if (filePath.match(/\.pug$/)) { |
||||
return _handlePug(filePath, watchEvent); |
||||
} |
||||
|
||||
if (filePath.match(/\.scss$/)) { |
||||
if (watchEvent === 'change') { |
||||
return _handleSCSS(filePath, watchEvent); |
||||
} |
||||
return; |
||||
} |
||||
|
||||
if (filePath.match(/src\/js\//)) { |
||||
return renderScripts(); |
||||
} |
||||
|
||||
if (filePath.match(/src\/assets\//)) { |
||||
return renderAssets(); |
||||
} |
||||
|
||||
} |
||||
|
||||
function _handlePug(filePath, watchEvent) { |
||||
if (watchEvent === 'change') { |
||||
if (filePath.match(/includes/) || filePath.match(/mixins/) || filePath.match(/\/pug\/layouts\//)) { |
||||
return _renderAllPug(); |
||||
} |
||||
return renderPug(filePath); |
||||
} |
||||
if (!filePath.match(/includes/) && !filePath.match(/mixins/) && !filePath.match(/\/pug\/layouts\//)) { |
||||
return renderPug(filePath); |
||||
} |
||||
} |
||||
|
||||
function _renderAllPug() { |
||||
console.log('### INFO: Rendering All'); |
||||
_.each(allPugFiles, (value, filePath) => { |
||||
renderPug(filePath); |
||||
}); |
||||
} |
||||
|
||||
function _handleSCSS() { |
||||
renderSCSS(); |
||||
} |
||||
@ -1,24 +0,0 @@
@@ -1,24 +0,0 @@
|
||||
const concurrently = require('concurrently'); |
||||
const path = require('path'); |
||||
|
||||
const browserSyncPath = path.resolve(path.dirname(__filename), '../node_modules/.bin/browser-sync'); |
||||
|
||||
concurrently([ |
||||
{ command: 'node --inspect scripts/sb-watch.js', name: 'SB_WATCH', prefixColor: 'bgBlue.bold' }, |
||||
{ |
||||
command: `${browserSyncPath} dist -w --no-online`, |
||||
name: 'SB_BROWSER_SYNC', |
||||
prefixColor: 'bgBlue.bold', |
||||
} |
||||
], { |
||||
prefix: 'name', |
||||
killOthers: ['failure', 'success'], |
||||
}).then(success, failure); |
||||
|
||||
function success() { |
||||
console.log('Success'); |
||||
} |
||||
|
||||
function failure() { |
||||
console.log('Failure'); |
||||
} |
||||
@ -1,24 +0,0 @@
@@ -1,24 +0,0 @@
|
||||
const concurrently = require('concurrently'); |
||||
const path = require('path'); |
||||
|
||||
const browserSyncPath = path.resolve(path.dirname(__filename), '../node_modules/.bin/browser-sync'); |
||||
|
||||
concurrently([ |
||||
{ command: 'node scripts/sb-watch.js', name: 'SB_WATCH', prefixColor: 'bgBlue.bold' }, |
||||
{ |
||||
command: `"${browserSyncPath}" --reload-delay 2000 --reload-debounce 2000 dist -w --no-online`, |
||||
name: 'SB_BROWSER_SYNC', |
||||
prefixColor: 'bgGreen.bold', |
||||
} |
||||
], { |
||||
prefix: 'name', |
||||
killOthers: ['failure', 'success'], |
||||
}).then(success, failure); |
||||
|
||||
function success() { |
||||
console.log('Success'); |
||||
} |
||||
|
||||
function failure() { |
||||
console.log('Failure'); |
||||
} |
||||
|
Before Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 233 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 356 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 73 KiB |
@ -1,88 +0,0 @@
@@ -1,88 +0,0 @@
|
||||
$(function () { |
||||
$( |
||||
"#contactForm input,#contactForm textarea,#contactForm button" |
||||
).jqBootstrapValidation({ |
||||
preventSubmit: true, |
||||
submitError: function ($form, event, errors) { |
||||
// additional error messages or events
|
||||
}, |
||||
submitSuccess: function ($form, event) { |
||||
event.preventDefault(); // prevent default submit behaviour
|
||||
// get values from FORM
|
||||
var name = $("input#name").val(); |
||||
var email = $("input#email").val(); |
||||
var phone = $("input#phone").val(); |
||||
var message = $("textarea#message").val(); |
||||
var firstName = name; // For Success/Failure Message
|
||||
// Check for white space in name for Success/Fail message
|
||||
if (firstName.indexOf(" ") >= 0) { |
||||
firstName = name.split(" ").slice(0, -1).join(" "); |
||||
} |
||||
$this = $("#sendMessageButton"); |
||||
$this.prop("disabled", true); // Disable submit button until AJAX call is complete to prevent duplicate messages
|
||||
$.ajax({ |
||||
url: "/assets/mail/contact_me.php", |
||||
type: "POST", |
||||
data: { |
||||
name: name, |
||||
phone: phone, |
||||
email: email, |
||||
message: message, |
||||
}, |
||||
cache: false, |
||||
success: function () { |
||||
// Success message
|
||||
$("#success").html("<div class='alert alert-success'>"); |
||||
$("#success > .alert-success") |
||||
.html( |
||||
"<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×" |
||||
) |
||||
.append("</button>"); |
||||
$("#success > .alert-success").append( |
||||
"<strong>Your message has been sent. </strong>" |
||||
); |
||||
$("#success > .alert-success").append("</div>"); |
||||
//clear all fields
|
||||
$("#contactForm").trigger("reset"); |
||||
}, |
||||
error: function () { |
||||
// Fail message
|
||||
$("#success").html("<div class='alert alert-danger'>"); |
||||
$("#success > .alert-danger") |
||||
.html( |
||||
"<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×" |
||||
) |
||||
.append("</button>"); |
||||
$("#success > .alert-danger").append( |
||||
$("<strong>").text( |
||||
"Sorry " + |
||||
firstName + |
||||
", it seems that my mail server is not responding. Please try again later!" |
||||
) |
||||
); |
||||
$("#success > .alert-danger").append("</div>"); |
||||
//clear all fields
|
||||
$("#contactForm").trigger("reset"); |
||||
}, |
||||
complete: function () { |
||||
setTimeout(function () { |
||||
$this.prop("disabled", false); // Re-enable submit button when AJAX call is complete
|
||||
}, 1000); |
||||
}, |
||||
}); |
||||
}, |
||||
filter: function () { |
||||
return $(this).is(":visible"); |
||||
}, |
||||
}); |
||||
|
||||
$('a[data-toggle="tab"]').click(function (e) { |
||||
e.preventDefault(); |
||||
$(this).tab("show"); |
||||
}); |
||||
}); |
||||
|
||||
/*When clicking on Full hide fail/success boxes */ |
||||
$("#name").focus(function () { |
||||
$("#success").html(""); |
||||
}); |
||||
@ -1,26 +0,0 @@
@@ -1,26 +0,0 @@
|
||||
<?php |
||||
// Check for empty fields |
||||
if(empty($_POST['name']) || |
||||
empty($_POST['email']) || |
||||
empty($_POST['phone']) || |
||||
empty($_POST['message']) || |
||||
!filter_var($_POST['email'],FILTER_VALIDATE_EMAIL)) |
||||
{ |
||||
echo "No arguments Provided!"; |
||||
return false; |
||||
} |
||||
|
||||
$name = strip_tags(htmlspecialchars($_POST['name'])); |
||||
$email_address = strip_tags(htmlspecialchars($_POST['email'])); |
||||
$phone = strip_tags(htmlspecialchars($_POST['phone'])); |
||||
$message = strip_tags(htmlspecialchars($_POST['message'])); |
||||
|
||||
// Create the email and send the message |
||||
$to = 'yourname@yourdomain.com'; // Add your email address in between the '' replacing yourname@yourdomain.com - This is where the form will send a message to. |
||||
$email_subject = "Website Contact Form: $name"; |
||||
$email_body = "You have received a new message from your website contact form.\n\n"."Here are the details:\n\nName: $name\n\nEmail: $email_address\n\nPhone: $phone\n\nMessage:\n$message"; |
||||
$headers = "From: noreply@yourdomain.com\n"; // This is the email address the generated message will be from. We recommend using something like noreply@yourdomain.com. |
||||
$headers .= "Reply-To: $email_address"; |
||||
mail($to,$email_subject,$email_body,$headers); |
||||
return true; |
||||
?> |
||||
@ -1,937 +0,0 @@
@@ -1,937 +0,0 @@
|
||||
/* jqBootstrapValidation |
||||
* A plugin for automating validation on Twitter Bootstrap formatted forms. |
||||
* |
||||
* v1.3.6 |
||||
* |
||||
* License: MIT <http://opensource.org/licenses/mit-license.php> - see LICENSE file
|
||||
* |
||||
* http://ReactiveRaven.github.com/jqBootstrapValidation/
|
||||
*/ |
||||
|
||||
(function($) { |
||||
|
||||
var createdElements = []; |
||||
|
||||
var defaults = { |
||||
options: { |
||||
prependExistingHelpBlock: false, |
||||
sniffHtml: true, // sniff for 'required', 'maxlength', etc
|
||||
preventSubmit: true, // stop the form submit event from firing if validation fails
|
||||
submitError: false, // function called if there is an error when trying to submit
|
||||
submitSuccess: false, // function called just before a successful submit event is sent to the server
|
||||
semanticallyStrict: false, // set to true to tidy up generated HTML output
|
||||
autoAdd: { |
||||
helpBlocks: true |
||||
}, |
||||
filter: function() { |
||||
// return $(this).is(":visible"); // only validate elements you can see
|
||||
return true; // validate everything
|
||||
} |
||||
}, |
||||
methods: { |
||||
init: function(options) { |
||||
|
||||
var settings = $.extend(true, {}, defaults); |
||||
|
||||
settings.options = $.extend(true, settings.options, options); |
||||
|
||||
var $siblingElements = this; |
||||
|
||||
var uniqueForms = $.unique( |
||||
$siblingElements.map(function() { |
||||
return $(this).parents("form")[0]; |
||||
}).toArray() |
||||
); |
||||
|
||||
$(uniqueForms).bind("submit", function(e) { |
||||
var $form = $(this); |
||||
var warningsFound = 0; |
||||
var $inputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter); |
||||
$inputs.trigger("submit.validation").trigger("validationLostFocus.validation"); |
||||
|
||||
$inputs.each(function(i, el) { |
||||
var $this = $(el), |
||||
$controlGroup = $this.parents(".form-group").first(); |
||||
if ( |
||||
$controlGroup.hasClass("warning") |
||||
) { |
||||
$controlGroup.removeClass("warning").addClass("error"); |
||||
warningsFound++; |
||||
} |
||||
}); |
||||
|
||||
$inputs.trigger("validationLostFocus.validation"); |
||||
|
||||
if (warningsFound) { |
||||
if (settings.options.preventSubmit) { |
||||
e.preventDefault(); |
||||
} |
||||
$form.addClass("error"); |
||||
if ($.isFunction(settings.options.submitError)) { |
||||
settings.options.submitError($form, e, $inputs.jqBootstrapValidation("collectErrors", true)); |
||||
} |
||||
} else { |
||||
$form.removeClass("error"); |
||||
if ($.isFunction(settings.options.submitSuccess)) { |
||||
settings.options.submitSuccess($form, e); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
return this.each(function() { |
||||
|
||||
// Get references to everything we're interested in
|
||||
var $this = $(this), |
||||
$controlGroup = $this.parents(".form-group").first(), |
||||
$helpBlock = $controlGroup.find(".help-block").first(), |
||||
$form = $this.parents("form").first(), |
||||
validatorNames = []; |
||||
|
||||
// create message container if not exists
|
||||
if (!$helpBlock.length && settings.options.autoAdd && settings.options.autoAdd.helpBlocks) { |
||||
$helpBlock = $('<div class="help-block" />'); |
||||
$controlGroup.find('.controls').append($helpBlock); |
||||
createdElements.push($helpBlock[0]); |
||||
} |
||||
|
||||
// =============================================================
|
||||
// SNIFF HTML FOR VALIDATORS
|
||||
// =============================================================
|
||||
|
||||
// *snort sniff snuffle*
|
||||
|
||||
if (settings.options.sniffHtml) { |
||||
var message = ""; |
||||
// ---------------------------------------------------------
|
||||
// PATTERN
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("pattern") !== undefined) { |
||||
message = "Not in the expected format<!-- data-validation-pattern-message to override -->"; |
||||
if ($this.data("validationPatternMessage")) { |
||||
message = $this.data("validationPatternMessage"); |
||||
} |
||||
$this.data("validationPatternMessage", message); |
||||
$this.data("validationPatternRegex", $this.attr("pattern")); |
||||
} |
||||
// ---------------------------------------------------------
|
||||
// MAX
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) { |
||||
var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax")); |
||||
message = "Too high: Maximum of '" + max + "'<!-- data-validation-max-message to override -->"; |
||||
if ($this.data("validationMaxMessage")) { |
||||
message = $this.data("validationMaxMessage"); |
||||
} |
||||
$this.data("validationMaxMessage", message); |
||||
$this.data("validationMaxMax", max); |
||||
} |
||||
// ---------------------------------------------------------
|
||||
// MIN
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) { |
||||
var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin")); |
||||
message = "Too low: Minimum of '" + min + "'<!-- data-validation-min-message to override -->"; |
||||
if ($this.data("validationMinMessage")) { |
||||
message = $this.data("validationMinMessage"); |
||||
} |
||||
$this.data("validationMinMessage", message); |
||||
$this.data("validationMinMin", min); |
||||
} |
||||
// ---------------------------------------------------------
|
||||
// MAXLENGTH
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("maxlength") !== undefined) { |
||||
message = "Too long: Maximum of '" + $this.attr("maxlength") + "' characters<!-- data-validation-maxlength-message to override -->"; |
||||
if ($this.data("validationMaxlengthMessage")) { |
||||
message = $this.data("validationMaxlengthMessage"); |
||||
} |
||||
$this.data("validationMaxlengthMessage", message); |
||||
$this.data("validationMaxlengthMaxlength", $this.attr("maxlength")); |
||||
} |
||||
// ---------------------------------------------------------
|
||||
// MINLENGTH
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("minlength") !== undefined) { |
||||
message = "Too short: Minimum of '" + $this.attr("minlength") + "' characters<!-- data-validation-minlength-message to override -->"; |
||||
if ($this.data("validationMinlengthMessage")) { |
||||
message = $this.data("validationMinlengthMessage"); |
||||
} |
||||
$this.data("validationMinlengthMessage", message); |
||||
$this.data("validationMinlengthMinlength", $this.attr("minlength")); |
||||
} |
||||
// ---------------------------------------------------------
|
||||
// REQUIRED
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) { |
||||
message = settings.builtInValidators.required.message; |
||||
if ($this.data("validationRequiredMessage")) { |
||||
message = $this.data("validationRequiredMessage"); |
||||
} |
||||
$this.data("validationRequiredMessage", message); |
||||
} |
||||
// ---------------------------------------------------------
|
||||
// NUMBER
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") { |
||||
message = settings.builtInValidators.number.message; |
||||
if ($this.data("validationNumberMessage")) { |
||||
message = $this.data("validationNumberMessage"); |
||||
} |
||||
$this.data("validationNumberMessage", message); |
||||
} |
||||
// ---------------------------------------------------------
|
||||
// EMAIL
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") { |
||||
message = "Not a valid email address<!-- data-validator-validemail-message to override -->"; |
||||
if ($this.data("validationValidemailMessage")) { |
||||
message = $this.data("validationValidemailMessage"); |
||||
} else if ($this.data("validationEmailMessage")) { |
||||
message = $this.data("validationEmailMessage"); |
||||
} |
||||
$this.data("validationValidemailMessage", message); |
||||
} |
||||
// ---------------------------------------------------------
|
||||
// MINCHECKED
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("minchecked") !== undefined) { |
||||
message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required<!-- data-validation-minchecked-message to override -->"; |
||||
if ($this.data("validationMincheckedMessage")) { |
||||
message = $this.data("validationMincheckedMessage"); |
||||
} |
||||
$this.data("validationMincheckedMessage", message); |
||||
$this.data("validationMincheckedMinchecked", $this.attr("minchecked")); |
||||
} |
||||
// ---------------------------------------------------------
|
||||
// MAXCHECKED
|
||||
// ---------------------------------------------------------
|
||||
if ($this.attr("maxchecked") !== undefined) { |
||||
message = "Too many options checked; Maximum of '" + $this.attr("maxchecked") + "' required<!-- data-validation-maxchecked-message to override -->"; |
||||
if ($this.data("validationMaxcheckedMessage")) { |
||||
message = $this.data("validationMaxcheckedMessage"); |
||||
} |
||||
$this.data("validationMaxcheckedMessage", message); |
||||
$this.data("validationMaxcheckedMaxchecked", $this.attr("maxchecked")); |
||||
} |
||||
} |
||||
|
||||
// =============================================================
|
||||
// COLLECT VALIDATOR NAMES
|
||||
// =============================================================
|
||||
|
||||
// Get named validators
|
||||
if ($this.data("validation") !== undefined) { |
||||
validatorNames = $this.data("validation").split(","); |
||||
} |
||||
|
||||
// Get extra ones defined on the element's data attributes
|
||||
$.each($this.data(), function(i, el) { |
||||
var parts = i.replace(/([A-Z])/g, ",$1").split(","); |
||||
if (parts[0] === "validation" && parts[1]) { |
||||
validatorNames.push(parts[1]); |
||||
} |
||||
}); |
||||
|
||||
// =============================================================
|
||||
// NORMALISE VALIDATOR NAMES
|
||||
// =============================================================
|
||||
|
||||
var validatorNamesToInspect = validatorNames; |
||||
var newValidatorNamesToInspect = []; |
||||
|
||||
do // repeatedly expand 'shortcut' validators into their real validators
|
||||
{ |
||||
// Uppercase only the first letter of each name
|
||||
$.each(validatorNames, function(i, el) { |
||||
validatorNames[i] = formatValidatorName(el); |
||||
}); |
||||
|
||||
// Remove duplicate validator names
|
||||
validatorNames = $.unique(validatorNames); |
||||
|
||||
// Pull out the new validator names from each shortcut
|
||||
newValidatorNamesToInspect = []; |
||||
$.each(validatorNamesToInspect, function(i, el) { |
||||
if ($this.data("validation" + el + "Shortcut") !== undefined) { |
||||
// Are these custom validators?
|
||||
// Pull them out!
|
||||
$.each($this.data("validation" + el + "Shortcut").split(","), function(i2, el2) { |
||||
newValidatorNamesToInspect.push(el2); |
||||
}); |
||||
} else if (settings.builtInValidators[el.toLowerCase()]) { |
||||
// Is this a recognised built-in?
|
||||
// Pull it out!
|
||||
var validator = settings.builtInValidators[el.toLowerCase()]; |
||||
if (validator.type.toLowerCase() === "shortcut") { |
||||
$.each(validator.shortcut.split(","), function(i, el) { |
||||
el = formatValidatorName(el); |
||||
newValidatorNamesToInspect.push(el); |
||||
validatorNames.push(el); |
||||
}); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
validatorNamesToInspect = newValidatorNamesToInspect; |
||||
|
||||
} while (validatorNamesToInspect.length > 0) |
||||
|
||||
// =============================================================
|
||||
// SET UP VALIDATOR ARRAYS
|
||||
// =============================================================
|
||||
|
||||
var validators = {}; |
||||
|
||||
$.each(validatorNames, function(i, el) { |
||||
// Set up the 'override' message
|
||||
var message = $this.data("validation" + el + "Message"); |
||||
var hasOverrideMessage = (message !== undefined); |
||||
var foundValidator = false; |
||||
message = |
||||
( |
||||
message ? |
||||
message : |
||||
"'" + el + "' validation failed <!-- Add attribute 'data-validation-" + el.toLowerCase() + "-message' to input to change this message -->" |
||||
); |
||||
|
||||
$.each( |
||||
settings.validatorTypes, |
||||
function(validatorType, validatorTemplate) { |
||||
if (validators[validatorType] === undefined) { |
||||
validators[validatorType] = []; |
||||
} |
||||
if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) { |
||||
validators[validatorType].push( |
||||
$.extend( |
||||
true, { |
||||
name: formatValidatorName(validatorTemplate.name), |
||||
message: message |
||||
}, |
||||
validatorTemplate.init($this, el) |
||||
) |
||||
); |
||||
foundValidator = true; |
||||
} |
||||
} |
||||
); |
||||
|
||||
if (!foundValidator && settings.builtInValidators[el.toLowerCase()]) { |
||||
|
||||
var validator = $.extend(true, {}, settings.builtInValidators[el.toLowerCase()]); |
||||
if (hasOverrideMessage) { |
||||
validator.message = message; |
||||
} |
||||
var validatorType = validator.type.toLowerCase(); |
||||
|
||||
if (validatorType === "shortcut") { |
||||
foundValidator = true; |
||||
} else { |
||||
$.each( |
||||
settings.validatorTypes, |
||||
function(validatorTemplateType, validatorTemplate) { |
||||
if (validators[validatorTemplateType] === undefined) { |
||||
validators[validatorTemplateType] = []; |
||||
} |
||||
if (!foundValidator && validatorType === validatorTemplateType.toLowerCase()) { |
||||
$this.data("validation" + el + formatValidatorName(validatorTemplate.name), validator[validatorTemplate.name.toLowerCase()]); |
||||
validators[validatorType].push( |
||||
$.extend( |
||||
validator, |
||||
validatorTemplate.init($this, el) |
||||
) |
||||
); |
||||
foundValidator = true; |
||||
} |
||||
} |
||||
); |
||||
} |
||||
} |
||||
|
||||
if (!foundValidator) { |
||||
$.error("Cannot find validation info for '" + el + "'"); |
||||
} |
||||
}); |
||||
|
||||
// =============================================================
|
||||
// STORE FALLBACK VALUES
|
||||
// =============================================================
|
||||
|
||||
$helpBlock.data( |
||||
"original-contents", |
||||
( |
||||
$helpBlock.data("original-contents") ? |
||||
$helpBlock.data("original-contents") : |
||||
$helpBlock.html() |
||||
) |
||||
); |
||||
|
||||
$helpBlock.data( |
||||
"original-role", |
||||
( |
||||
$helpBlock.data("original-role") ? |
||||
$helpBlock.data("original-role") : |
||||
$helpBlock.attr("role") |
||||
) |
||||
); |
||||
|
||||
$controlGroup.data( |
||||
"original-classes", |
||||
( |
||||
$controlGroup.data("original-clases") ? |
||||
$controlGroup.data("original-classes") : |
||||
$controlGroup.attr("class") |
||||
) |
||||
); |
||||
|
||||
$this.data( |
||||
"original-aria-invalid", |
||||
( |
||||
$this.data("original-aria-invalid") ? |
||||
$this.data("original-aria-invalid") : |
||||
$this.attr("aria-invalid") |
||||
) |
||||
); |
||||
|
||||
// =============================================================
|
||||
// VALIDATION
|
||||
// =============================================================
|
||||
|
||||
$this.bind( |
||||
"validation.validation", |
||||
function(event, params) { |
||||
|
||||
var value = getValue($this); |
||||
|
||||
// Get a list of the errors to apply
|
||||
var errorsFound = []; |
||||
|
||||
$.each(validators, function(validatorType, validatorTypeArray) { |
||||
if (value || value.length || (params && params.includeEmpty) || (!!settings.validatorTypes[validatorType].blockSubmit && params && !!params.submitting)) { |
||||
$.each(validatorTypeArray, function(i, validator) { |
||||
if (settings.validatorTypes[validatorType].validate($this, value, validator)) { |
||||
errorsFound.push(validator.message); |
||||
} |
||||
}); |
||||
} |
||||
}); |
||||
|
||||
return errorsFound; |
||||
} |
||||
); |
||||
|
||||
$this.bind( |
||||
"getValidators.validation", |
||||
function() { |
||||
return validators; |
||||
} |
||||
); |
||||
|
||||
// =============================================================
|
||||
// WATCH FOR CHANGES
|
||||
// =============================================================
|
||||
$this.bind( |
||||
"submit.validation", |
||||
function() { |
||||
return $this.triggerHandler("change.validation", { |
||||
submitting: true |
||||
}); |
||||
} |
||||
); |
||||
$this.bind( |
||||
[ |
||||
"keyup", |
||||
"focus", |
||||
"blur", |
||||
"click", |
||||
"keydown", |
||||
"keypress", |
||||
"change" |
||||
].join(".validation ") + ".validation", |
||||
function(e, params) { |
||||
|
||||
var value = getValue($this); |
||||
|
||||
var errorsFound = []; |
||||
|
||||
$controlGroup.find("input,textarea,select").each(function(i, el) { |
||||
var oldCount = errorsFound.length; |
||||
$.each($(el).triggerHandler("validation.validation", params), function(j, message) { |
||||
errorsFound.push(message); |
||||
}); |
||||
if (errorsFound.length > oldCount) { |
||||
$(el).attr("aria-invalid", "true"); |
||||
} else { |
||||
var original = $this.data("original-aria-invalid"); |
||||
$(el).attr("aria-invalid", (original !== undefined ? original : false)); |
||||
} |
||||
}); |
||||
|
||||
$form.find("input,select,textarea").not($this).not("[name=\"" + $this.attr("name") + "\"]").trigger("validationLostFocus.validation"); |
||||
|
||||
errorsFound = $.unique(errorsFound.sort()); |
||||
|
||||
// Were there any errors?
|
||||
if (errorsFound.length) { |
||||
// Better flag it up as a warning.
|
||||
$controlGroup.removeClass("success error").addClass("warning"); |
||||
|
||||
// How many errors did we find?
|
||||
if (settings.options.semanticallyStrict && errorsFound.length === 1) { |
||||
// Only one? Being strict? Just output it.
|
||||
$helpBlock.html(errorsFound[0] + |
||||
(settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "")); |
||||
} else { |
||||
// Multiple? Being sloppy? Glue them together into an UL.
|
||||
$helpBlock.html("<ul role=\"alert\"><li>" + errorsFound.join("</li><li>") + "</li></ul>" + |
||||
(settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "")); |
||||
} |
||||
} else { |
||||
$controlGroup.removeClass("warning error success"); |
||||
if (value.length > 0) { |
||||
$controlGroup.addClass("success"); |
||||
} |
||||
$helpBlock.html($helpBlock.data("original-contents")); |
||||
} |
||||
|
||||
if (e.type === "blur") { |
||||
$controlGroup.removeClass("success"); |
||||
} |
||||
} |
||||
); |
||||
$this.bind("validationLostFocus.validation", function() { |
||||
$controlGroup.removeClass("success"); |
||||
}); |
||||
}); |
||||
}, |
||||
destroy: function() { |
||||
|
||||
return this.each( |
||||
function() { |
||||
|
||||
var |
||||
$this = $(this), |
||||
$controlGroup = $this.parents(".form-group").first(), |
||||
$helpBlock = $controlGroup.find(".help-block").first(); |
||||
|
||||
// remove our events
|
||||
$this.unbind('.validation'); // events are namespaced.
|
||||
// reset help text
|
||||
$helpBlock.html($helpBlock.data("original-contents")); |
||||
// reset classes
|
||||
$controlGroup.attr("class", $controlGroup.data("original-classes")); |
||||
// reset aria
|
||||
$this.attr("aria-invalid", $this.data("original-aria-invalid")); |
||||
// reset role
|
||||
$helpBlock.attr("role", $this.data("original-role")); |
||||
// remove all elements we created
|
||||
if (createdElements.indexOf($helpBlock[0]) > -1) { |
||||
$helpBlock.remove(); |
||||
} |
||||
|
||||
} |
||||
); |
||||
|
||||
}, |
||||
collectErrors: function(includeEmpty) { |
||||
|
||||
var errorMessages = {}; |
||||
this.each(function(i, el) { |
||||
var $el = $(el); |
||||
var name = $el.attr("name"); |
||||
var errors = $el.triggerHandler("validation.validation", { |
||||
includeEmpty: true |
||||
}); |
||||
errorMessages[name] = $.extend(true, errors, errorMessages[name]); |
||||
}); |
||||
|
||||
$.each(errorMessages, function(i, el) { |
||||
if (el.length === 0) { |
||||
delete errorMessages[i]; |
||||
} |
||||
}); |
||||
|
||||
return errorMessages; |
||||
|
||||
}, |
||||
hasErrors: function() { |
||||
|
||||
var errorMessages = []; |
||||
|
||||
this.each(function(i, el) { |
||||
errorMessages = errorMessages.concat( |
||||
$(el).triggerHandler("getValidators.validation") ? $(el).triggerHandler("validation.validation", { |
||||
submitting: true |
||||
}) : [] |
||||
); |
||||
}); |
||||
|
||||
return (errorMessages.length > 0); |
||||
}, |
||||
override: function(newDefaults) { |
||||
defaults = $.extend(true, defaults, newDefaults); |
||||
} |
||||
}, |
||||
validatorTypes: { |
||||
callback: { |
||||
name: "callback", |
||||
init: function($this, name) { |
||||
return { |
||||
validatorName: name, |
||||
callback: $this.data("validation" + name + "Callback"), |
||||
lastValue: $this.val(), |
||||
lastValid: true, |
||||
lastFinished: true |
||||
}; |
||||
}, |
||||
validate: function($this, value, validator) { |
||||
if (validator.lastValue === value && validator.lastFinished) { |
||||
return !validator.lastValid; |
||||
} |
||||
|
||||
if (validator.lastFinished === true) { |
||||
validator.lastValue = value; |
||||
validator.lastValid = true; |
||||
validator.lastFinished = false; |
||||
|
||||
var rrjqbvValidator = validator; |
||||
var rrjqbvThis = $this; |
||||
executeFunctionByName( |
||||
validator.callback, |
||||
window, |
||||
$this, |
||||
value, |
||||
function(data) { |
||||
if (rrjqbvValidator.lastValue === data.value) { |
||||
rrjqbvValidator.lastValid = data.valid; |
||||
if (data.message) { |
||||
rrjqbvValidator.message = data.message; |
||||
} |
||||
rrjqbvValidator.lastFinished = true; |
||||
rrjqbvThis.data("validation" + rrjqbvValidator.validatorName + "Message", rrjqbvValidator.message); |
||||
// Timeout is set to avoid problems with the events being considered 'already fired'
|
||||
setTimeout(function() { |
||||
rrjqbvThis.trigger("change.validation"); |
||||
}, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
|
||||
} |
||||
} |
||||
); |
||||
} |
||||
|
||||
return false; |
||||
|
||||
} |
||||
}, |
||||
ajax: { |
||||
name: "ajax", |
||||
init: function($this, name) { |
||||
return { |
||||
validatorName: name, |
||||
url: $this.data("validation" + name + "Ajax"), |
||||
lastValue: $this.val(), |
||||
lastValid: true, |
||||
lastFinished: true |
||||
}; |
||||
}, |
||||
validate: function($this, value, validator) { |
||||
if ("" + validator.lastValue === "" + value && validator.lastFinished === true) { |
||||
return validator.lastValid === false; |
||||
} |
||||
|
||||
if (validator.lastFinished === true) { |
||||
validator.lastValue = value; |
||||
validator.lastValid = true; |
||||
validator.lastFinished = false; |
||||
$.ajax({ |
||||
url: validator.url, |
||||
data: "value=" + value + "&field=" + $this.attr("name"), |
||||
dataType: "json", |
||||
success: function(data) { |
||||
if ("" + validator.lastValue === "" + data.value) { |
||||
validator.lastValid = !!(data.valid); |
||||
if (data.message) { |
||||
validator.message = data.message; |
||||
} |
||||
validator.lastFinished = true; |
||||
$this.data("validation" + validator.validatorName + "Message", validator.message); |
||||
// Timeout is set to avoid problems with the events being considered 'already fired'
|
||||
setTimeout(function() { |
||||
$this.trigger("change.validation"); |
||||
}, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
|
||||
} |
||||
}, |
||||
failure: function() { |
||||
validator.lastValid = true; |
||||
validator.message = "ajax call failed"; |
||||
validator.lastFinished = true; |
||||
$this.data("validation" + validator.validatorName + "Message", validator.message); |
||||
// Timeout is set to avoid problems with the events being considered 'already fired'
|
||||
setTimeout(function() { |
||||
$this.trigger("change.validation"); |
||||
}, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
|
||||
} |
||||
}); |
||||
} |
||||
|
||||
return false; |
||||
|
||||
} |
||||
}, |
||||
regex: { |
||||
name: "regex", |
||||
init: function($this, name) { |
||||
return { |
||||
regex: regexFromString($this.data("validation" + name + "Regex")) |
||||
}; |
||||
}, |
||||
validate: function($this, value, validator) { |
||||
return (!validator.regex.test(value) && !validator.negative) || |
||||
(validator.regex.test(value) && validator.negative); |
||||
} |
||||
}, |
||||
required: { |
||||
name: "required", |
||||
init: function($this, name) { |
||||
return {}; |
||||
}, |
||||
validate: function($this, value, validator) { |
||||
return !!(value.length === 0 && !validator.negative) || |
||||
!!(value.length > 0 && validator.negative); |
||||
}, |
||||
blockSubmit: true |
||||
}, |
||||
match: { |
||||
name: "match", |
||||
init: function($this, name) { |
||||
var element = $this.parents("form").first().find("[name=\"" + $this.data("validation" + name + "Match") + "\"]").first(); |
||||
element.bind("validation.validation", function() { |
||||
$this.trigger("change.validation", { |
||||
submitting: true |
||||
}); |
||||
}); |
||||
return { |
||||
"element": element |
||||
}; |
||||
}, |
||||
validate: function($this, value, validator) { |
||||
return (value !== validator.element.val() && !validator.negative) || |
||||
(value === validator.element.val() && validator.negative); |
||||
}, |
||||
blockSubmit: true |
||||
}, |
||||
max: { |
||||
name: "max", |
||||
init: function($this, name) { |
||||
return { |
||||
max: $this.data("validation" + name + "Max") |
||||
}; |
||||
}, |
||||
validate: function($this, value, validator) { |
||||
return (parseFloat(value, 10) > parseFloat(validator.max, 10) && !validator.negative) || |
||||
(parseFloat(value, 10) <= parseFloat(validator.max, 10) && validator.negative); |
||||
} |
||||
}, |
||||
min: { |
||||
name: "min", |
||||
init: function($this, name) { |
||||
return { |
||||
min: $this.data("validation" + name + "Min") |
||||
}; |
||||
}, |
||||
validate: function($this, value, validator) { |
||||
return (parseFloat(value) < parseFloat(validator.min) && !validator.negative) || |
||||
(parseFloat(value) >= parseFloat(validator.min) && validator.negative); |
||||
} |
||||
}, |
||||
maxlength: { |
||||
name: "maxlength", |
||||
init: function($this, name) { |
||||
return { |
||||
maxlength: $this.data("validation" + name + "Maxlength") |
||||
}; |
||||
}, |
||||
validate: function($this, value, validator) { |
||||
return ((value.length > validator.maxlength) && !validator.negative) || |
||||
((value.length <= validator.maxlength) && validator.negative); |
||||
} |
||||
}, |
||||
minlength: { |
||||
name: "minlength", |
||||
init: function($this, name) { |
||||
return { |
||||
minlength: $this.data("validation" + name + "Minlength") |
||||
}; |
||||
}, |
||||
validate: function($this, value, validator) { |
||||
return ((value.length < validator.minlength) && !validator.negative) || |
||||
((value.length >= validator.minlength) && validator.negative); |
||||
} |
||||
}, |
||||
maxchecked: { |
||||
name: "maxchecked", |
||||
init: function($this, name) { |
||||
var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); |
||||
elements.bind("click.validation", function() { |
||||
$this.trigger("change.validation", { |
||||
includeEmpty: true |
||||
}); |
||||
}); |
||||
return { |
||||
maxchecked: $this.data("validation" + name + "Maxchecked"), |
||||
elements: elements |
||||
}; |
||||
}, |
||||
validate: function($this, value, validator) { |
||||
return (validator.elements.filter(":checked").length > validator.maxchecked && !validator.negative) || |
||||
(validator.elements.filter(":checked").length <= validator.maxchecked && validator.negative); |
||||
}, |
||||
blockSubmit: true |
||||
}, |
||||
minchecked: { |
||||
name: "minchecked", |
||||
init: function($this, name) { |
||||
var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); |
||||
elements.bind("click.validation", function() { |
||||
$this.trigger("change.validation", { |
||||
includeEmpty: true |
||||
}); |
||||
}); |
||||
return { |
||||
minchecked: $this.data("validation" + name + "Minchecked"), |
||||
elements: elements |
||||
}; |
||||
}, |
||||
validate: function($this, value, validator) { |
||||
return (validator.elements.filter(":checked").length < validator.minchecked && !validator.negative) || |
||||
(validator.elements.filter(":checked").length >= validator.minchecked && validator.negative); |
||||
}, |
||||
blockSubmit: true |
||||
} |
||||
}, |
||||
builtInValidators: { |
||||
email: { |
||||
name: "Email", |
||||
type: "shortcut", |
||||
shortcut: "validemail" |
||||
}, |
||||
validemail: { |
||||
name: "Validemail", |
||||
type: "regex", |
||||
regex: "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\.[A-Za-z]{2,4}", |
||||
message: "Not a valid email address<!-- data-validator-validemail-message to override -->" |
||||
}, |
||||
passwordagain: { |
||||
name: "Passwordagain", |
||||
type: "match", |
||||
match: "password", |
||||
message: "Does not match the given password<!-- data-validator-paswordagain-message to override -->" |
||||
}, |
||||
positive: { |
||||
name: "Positive", |
||||
type: "shortcut", |
||||
shortcut: "number,positivenumber" |
||||
}, |
||||
negative: { |
||||
name: "Negative", |
||||
type: "shortcut", |
||||
shortcut: "number,negativenumber" |
||||
}, |
||||
number: { |
||||
name: "Number", |
||||
type: "regex", |
||||
regex: "([+-]?\\\d+(\\\.\\\d*)?([eE][+-]?[0-9]+)?)?", |
||||
message: "Must be a number<!-- data-validator-number-message to override -->" |
||||
}, |
||||
integer: { |
||||
name: "Integer", |
||||
type: "regex", |
||||
regex: "[+-]?\\\d+", |
||||
message: "No decimal places allowed<!-- data-validator-integer-message to override -->" |
||||
}, |
||||
positivenumber: { |
||||
name: "Positivenumber", |
||||
type: "min", |
||||
min: 0, |
||||
message: "Must be a positive number<!-- data-validator-positivenumber-message to override -->" |
||||
}, |
||||
negativenumber: { |
||||
name: "Negativenumber", |
||||
type: "max", |
||||
max: 0, |
||||
message: "Must be a negative number<!-- data-validator-negativenumber-message to override -->" |
||||
}, |
||||
required: { |
||||
name: "Required", |
||||
type: "required", |
||||
message: "This is required<!-- data-validator-required-message to override -->" |
||||
}, |
||||
checkone: { |
||||
name: "Checkone", |
||||
type: "minchecked", |
||||
minchecked: 1, |
||||
message: "Check at least one option<!-- data-validation-checkone-message to override -->" |
||||
} |
||||
} |
||||
}; |
||||
|
||||
var formatValidatorName = function(name) { |
||||
return name |
||||
.toLowerCase() |
||||
.replace( |
||||
/(^|\s)([a-z])/g, |
||||
function(m, p1, p2) { |
||||
return p1 + p2.toUpperCase(); |
||||
} |
||||
); |
||||
}; |
||||
|
||||
var getValue = function($this) { |
||||
// Extract the value we're talking about
|
||||
var value = $this.val(); |
||||
var type = $this.attr("type"); |
||||
if (type === "checkbox") { |
||||
value = ($this.is(":checked") ? value : ""); |
||||
} |
||||
if (type === "radio") { |
||||
value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? value : ""); |
||||
} |
||||
return value; |
||||
}; |
||||
|
||||
function regexFromString(inputstring) { |
||||
return new RegExp("^" + inputstring + "$"); |
||||
} |
||||
|
||||
/** |
||||
* Thanks to Jason Bunting via StackOverflow.com |
||||
* |
||||
* http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string#answer-359910
|
||||
* Short link: http://tinyurl.com/executeFunctionByName
|
||||
**/ |
||||
function executeFunctionByName(functionName, context /*, args*/ ) { |
||||
var args = Array.prototype.slice.call(arguments).splice(2); |
||||
var namespaces = functionName.split("."); |
||||
var func = namespaces.pop(); |
||||
for (var i = 0; i < namespaces.length; i++) { |
||||
context = context[namespaces[i]]; |
||||
} |
||||
return context[func].apply(this, args); |
||||
} |
||||
|
||||
$.fn.jqBootstrapValidation = function(method) { |
||||
|
||||
if (defaults.methods[method]) { |
||||
return defaults.methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); |
||||
} else if (typeof method === 'object' || !method) { |
||||
return defaults.methods.init.apply(this, arguments); |
||||
} else { |
||||
$.error('Method ' + method + ' does not exist on jQuery.jqBootstrapValidation'); |
||||
return null; |
||||
} |
||||
|
||||
}; |
||||
|
||||
$.jqBootstrapValidation = function(options) { |
||||
$(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this, arguments); |
||||
}; |
||||
|
||||
})(jQuery); |
||||
@ -1,51 +0,0 @@
@@ -1,51 +0,0 @@
|
||||
(function ($) { |
||||
"use strict"; // Start of use strict
|
||||
|
||||
// Smooth scrolling using jQuery easing
|
||||
$('a.js-scroll-trigger[href*="#"]:not([href="#"])').click(function () { |
||||
if ( |
||||
location.pathname.replace(/^\//, "") == |
||||
this.pathname.replace(/^\//, "") && |
||||
location.hostname == this.hostname |
||||
) { |
||||
var target = $(this.hash); |
||||
target = target.length |
||||
? target |
||||
: $("[name=" + this.hash.slice(1) + "]"); |
||||
if (target.length) { |
||||
$("html, body").animate( |
||||
{ |
||||
scrollTop: target.offset().top - 72, |
||||
}, |
||||
1000, |
||||
"easeInOutExpo" |
||||
); |
||||
return false; |
||||
} |
||||
} |
||||
}); |
||||
|
||||
// Closes responsive menu when a scroll trigger link is clicked
|
||||
$(".js-scroll-trigger").click(function () { |
||||
$(".navbar-collapse").collapse("hide"); |
||||
}); |
||||
|
||||
// Activate scrollspy to add active class to navbar items on scroll
|
||||
$("body").scrollspy({ |
||||
target: "#mainNav", |
||||
offset: 74, |
||||
}); |
||||
|
||||
// Collapse Navbar
|
||||
var navbarCollapse = function () { |
||||
if ($("#mainNav").offset().top > 100) { |
||||
$("#mainNav").addClass("navbar-shrink"); |
||||
} else { |
||||
$("#mainNav").removeClass("navbar-shrink"); |
||||
} |
||||
}; |
||||
// Collapse now if page is not at top
|
||||
navbarCollapse(); |
||||
// Collapse the navbar when page is scrolled
|
||||
$(window).scroll(navbarCollapse); |
||||
})(jQuery); // End of use strict
|
||||
@ -1,459 +0,0 @@
@@ -1,459 +0,0 @@
|
||||
doctype html |
||||
html(lang='en') |
||||
|
||||
head |
||||
|
||||
meta(charset='utf-8') |
||||
meta(name='viewport', content='width=device-width, initial-scale=1, shrink-to-fit=no') |
||||
meta(name='description', content='') |
||||
meta(name='author', content='') |
||||
|
||||
title Agency - Start Bootstrap Theme |
||||
|
||||
link(rel='icon', type='image/x-icon', href='assets/img/favicon.ico') |
||||
|
||||
// Font Awesome icons (free version) |
||||
script(src='https://use.fontawesome.com/releases/v5.13.0/js/all.js', crossorigin='anonymous') |
||||
|
||||
// Google fonts |
||||
link(href='https://fonts.googleapis.com/css?family=Montserrat:400,700', rel='stylesheet', type='text/css') |
||||
link(href='https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic,700italic', rel='stylesheet', type='text/css') |
||||
link(href='https://fonts.googleapis.com/css?family=Roboto+Slab:400,100,300,700', rel='stylesheet', type='text/css') |
||||
|
||||
// Core theme CSS (includes Bootstrap) |
||||
link(href='css/styles.css', rel='stylesheet') |
||||
|
||||
body#page-top |
||||
|
||||
// Navigation |
||||
nav#mainNav.navbar.navbar-expand-lg.navbar-dark.fixed-top |
||||
.container |
||||
a.navbar-brand.js-scroll-trigger(href='#page-top') |
||||
img(src='assets/img/navbar-logo.svg', alt='') |
||||
button.navbar-toggler.navbar-toggler-right(type='button', data-toggle='collapse', data-target='#navbarResponsive', aria-controls='navbarResponsive', aria-expanded='false', aria-label='Toggle navigation') |
||||
| Menu |
||||
i.fas.fa-bars.ml-1 |
||||
#navbarResponsive.collapse.navbar-collapse |
||||
ul.navbar-nav.text-uppercase.ml-auto |
||||
li.nav-item |
||||
a.nav-link.js-scroll-trigger(href='#services') Services |
||||
li.nav-item |
||||
a.nav-link.js-scroll-trigger(href='#portfolio') Portfolio |
||||
li.nav-item |
||||
a.nav-link.js-scroll-trigger(href='#about') About |
||||
li.nav-item |
||||
a.nav-link.js-scroll-trigger(href='#team') Team |
||||
li.nav-item |
||||
a.nav-link.js-scroll-trigger(href='#contact') Contact |
||||
// Masthead |
||||
header.masthead |
||||
.container |
||||
.masthead-subheading Welcome To Our Studio! |
||||
.masthead-heading.text-uppercase It's Nice To Meet You |
||||
a.btn.btn-primary.btn-xl.text-uppercase.js-scroll-trigger(href='#services') Tell Me More |
||||
|
||||
// Services |
||||
section#services.page-section |
||||
.container |
||||
.text-center |
||||
h2.section-heading.text-uppercase Services |
||||
h3.section-subheading.text-muted Lorem ipsum dolor sit amet consectetur. |
||||
.row.text-center |
||||
.col-md-4 |
||||
span.fa-stack.fa-4x |
||||
i.fas.fa-circle.fa-stack-2x.text-primary |
||||
i.fas.fa-shopping-cart.fa-stack-1x.fa-inverse |
||||
h4.my-3 E-Commerce |
||||
p.text-muted |
||||
| Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima maxime quam architecto quo inventore harum ex magni, dicta impedit. |
||||
.col-md-4 |
||||
span.fa-stack.fa-4x |
||||
i.fas.fa-circle.fa-stack-2x.text-primary |
||||
i.fas.fa-laptop.fa-stack-1x.fa-inverse |
||||
h4.my-3 Responsive Design |
||||
p.text-muted |
||||
| Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima maxime quam architecto quo inventore harum ex magni, dicta impedit. |
||||
.col-md-4 |
||||
span.fa-stack.fa-4x |
||||
i.fas.fa-circle.fa-stack-2x.text-primary |
||||
i.fas.fa-lock.fa-stack-1x.fa-inverse |
||||
h4.my-3 Web Security |
||||
p.text-muted |
||||
| Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima maxime quam architecto quo inventore harum ex magni, dicta impedit. |
||||
|
||||
// Portfolio Grid |
||||
section#portfolio.page-section.bg-light |
||||
.container |
||||
.text-center |
||||
h2.section-heading.text-uppercase Portfolio |
||||
h3.section-subheading.text-muted Lorem ipsum dolor sit amet consectetur. |
||||
.row |
||||
.col-lg-4.col-sm-6.mb-4 |
||||
.portfolio-item |
||||
a.portfolio-link(data-toggle='modal', href='#portfolioModal1') |
||||
.portfolio-hover |
||||
.portfolio-hover-content |
||||
i.fas.fa-plus.fa-3x |
||||
img.img-fluid(src='assets/img/portfolio/01-thumbnail.jpg', alt='') |
||||
.portfolio-caption |
||||
.portfolio-caption-heading Threads |
||||
.portfolio-caption-subheading.text-muted Illustration |
||||
.col-lg-4.col-sm-6.mb-4 |
||||
.portfolio-item |
||||
a.portfolio-link(data-toggle='modal', href='#portfolioModal2') |
||||
.portfolio-hover |
||||
.portfolio-hover-content |
||||
i.fas.fa-plus.fa-3x |
||||
img.img-fluid(src='assets/img/portfolio/02-thumbnail.jpg', alt='') |
||||
.portfolio-caption |
||||
.portfolio-caption-heading Explore |
||||
.portfolio-caption-subheading.text-muted Graphic Design |
||||
.col-lg-4.col-sm-6.mb-4 |
||||
.portfolio-item |
||||
a.portfolio-link(data-toggle='modal', href='#portfolioModal3') |
||||
.portfolio-hover |
||||
.portfolio-hover-content |
||||
i.fas.fa-plus.fa-3x |
||||
img.img-fluid(src='assets/img/portfolio/03-thumbnail.jpg', alt='') |
||||
.portfolio-caption |
||||
.portfolio-caption-heading Finish |
||||
.portfolio-caption-subheading.text-muted Identity |
||||
.col-lg-4.col-sm-6.mb-4.mb-lg-0 |
||||
.portfolio-item |
||||
a.portfolio-link(data-toggle='modal', href='#portfolioModal4') |
||||
.portfolio-hover |
||||
.portfolio-hover-content |
||||
i.fas.fa-plus.fa-3x |
||||
img.img-fluid(src='assets/img/portfolio/04-thumbnail.jpg', alt='') |
||||
.portfolio-caption |
||||
.portfolio-caption-heading Lines |
||||
.portfolio-caption-subheading.text-muted Branding |
||||
.col-lg-4.col-sm-6.mb-4.mb-sm-0 |
||||
.portfolio-item |
||||
a.portfolio-link(data-toggle='modal', href='#portfolioModal5') |
||||
.portfolio-hover |
||||
.portfolio-hover-content |
||||
i.fas.fa-plus.fa-3x |
||||
img.img-fluid(src='assets/img/portfolio/05-thumbnail.jpg', alt='') |
||||
.portfolio-caption |
||||
.portfolio-caption-heading Southwest |
||||
.portfolio-caption-subheading.text-muted Website Design |
||||
.col-lg-4.col-sm-6 |
||||
.portfolio-item |
||||
a.portfolio-link(data-toggle='modal', href='#portfolioModal6') |
||||
.portfolio-hover |
||||
.portfolio-hover-content |
||||
i.fas.fa-plus.fa-3x |
||||
img.img-fluid(src='assets/img/portfolio/06-thumbnail.jpg', alt='') |
||||
.portfolio-caption |
||||
.portfolio-caption-heading Window |
||||
.portfolio-caption-subheading.text-muted Photography |
||||
|
||||
// About |
||||
section#about.page-section |
||||
.container |
||||
.text-center |
||||
h2.section-heading.text-uppercase About |
||||
h3.section-subheading.text-muted Lorem ipsum dolor sit amet consectetur. |
||||
ul.timeline |
||||
li |
||||
.timeline-image |
||||
img.rounded-circle.img-fluid(src='assets/img/about/1.jpg', alt='') |
||||
.timeline-panel |
||||
.timeline-heading |
||||
h4 2009-2011 |
||||
h4.subheading Our Humble Beginnings |
||||
.timeline-body |
||||
p.text-muted |
||||
| Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sunt ut voluptatum eius sapiente, totam reiciendis temporibus qui quibusdam, recusandae sit vero unde, sed, incidunt et ea quo dolore laudantium consectetur! |
||||
li.timeline-inverted |
||||
.timeline-image |
||||
img.rounded-circle.img-fluid(src='assets/img/about/2.jpg', alt='') |
||||
.timeline-panel |
||||
.timeline-heading |
||||
h4 March 2011 |
||||
h4.subheading An Agency is Born |
||||
.timeline-body |
||||
p.text-muted |
||||
| Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sunt ut voluptatum eius sapiente, totam reiciendis temporibus qui quibusdam, recusandae sit vero unde, sed, incidunt et ea quo dolore laudantium consectetur! |
||||
li |
||||
.timeline-image |
||||
img.rounded-circle.img-fluid(src='assets/img/about/3.jpg', alt='') |
||||
.timeline-panel |
||||
.timeline-heading |
||||
h4 December 2012 |
||||
h4.subheading Transition to Full Service |
||||
.timeline-body |
||||
p.text-muted |
||||
| Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sunt ut voluptatum eius sapiente, totam reiciendis temporibus qui quibusdam, recusandae sit vero unde, sed, incidunt et ea quo dolore laudantium consectetur! |
||||
li.timeline-inverted |
||||
.timeline-image |
||||
img.rounded-circle.img-fluid(src='assets/img/about/4.jpg', alt='') |
||||
.timeline-panel |
||||
.timeline-heading |
||||
h4 July 2014 |
||||
h4.subheading Phase Two Expansion |
||||
.timeline-body |
||||
p.text-muted |
||||
| Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sunt ut voluptatum eius sapiente, totam reiciendis temporibus qui quibusdam, recusandae sit vero unde, sed, incidunt et ea quo dolore laudantium consectetur! |
||||
li.timeline-inverted |
||||
.timeline-image |
||||
h4 |
||||
| Be Part |
||||
br |
||||
| Of Our |
||||
br |
||||
| Story! |
||||
|
||||
// Team |
||||
section#team.page-section.bg-light |
||||
.container |
||||
.text-center |
||||
h2.section-heading.text-uppercase Our Amazing Team |
||||
h3.section-subheading.text-muted Lorem ipsum dolor sit amet consectetur. |
||||
.row |
||||
.col-lg-4 |
||||
.team-member |
||||
img.mx-auto.rounded-circle(src='assets/img/team/1.jpg', alt='') |
||||
h4 Kay Garland |
||||
p.text-muted Lead Designer |
||||
a.btn.btn-dark.btn-social.mx-2(href='#!') |
||||
i.fab.fa-twitter |
||||
a.btn.btn-dark.btn-social.mx-2(href='#!') |
||||
i.fab.fa-facebook-f |
||||
a.btn.btn-dark.btn-social.mx-2(href='#!') |
||||
i.fab.fa-linkedin-in |
||||
.col-lg-4 |
||||
.team-member |
||||
img.mx-auto.rounded-circle(src='assets/img/team/2.jpg', alt='') |
||||
h4 Larry Parker |
||||
p.text-muted Lead Marketer |
||||
a.btn.btn-dark.btn-social.mx-2(href='#!') |
||||
i.fab.fa-twitter |
||||
a.btn.btn-dark.btn-social.mx-2(href='#!') |
||||
i.fab.fa-facebook-f |
||||
a.btn.btn-dark.btn-social.mx-2(href='#!') |
||||
i.fab.fa-linkedin-in |
||||
.col-lg-4 |
||||
.team-member |
||||
img.mx-auto.rounded-circle(src='assets/img/team/3.jpg', alt='') |
||||
h4 Diana Petersen |
||||
p.text-muted Lead Developer |
||||
a.btn.btn-dark.btn-social.mx-2(href='#!') |
||||
i.fab.fa-twitter |
||||
a.btn.btn-dark.btn-social.mx-2(href='#!') |
||||
i.fab.fa-facebook-f |
||||
a.btn.btn-dark.btn-social.mx-2(href='#!') |
||||
i.fab.fa-linkedin-in |
||||
.row |
||||
.col-lg-8.mx-auto.text-center |
||||
p.large.text-muted |
||||
| Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut eaque, laboriosam veritatis, quos non quis ad perspiciatis, totam corporis ea, alias ut unde. |
||||
|
||||
// Clients |
||||
div.py-5 |
||||
.container |
||||
.row |
||||
.col-md-3.col-sm-6.my-3 |
||||
a(href='#!') |
||||
img.img-fluid.d-block.mx-auto(src='assets/img/logos/envato.jpg', alt='') |
||||
.col-md-3.col-sm-6.my-3 |
||||
a(href='#!') |
||||
img.img-fluid.d-block.mx-auto(src='assets/img/logos/designmodo.jpg', alt='') |
||||
.col-md-3.col-sm-6.my-3 |
||||
a(href='#!') |
||||
img.img-fluid.d-block.mx-auto(src='assets/img/logos/themeforest.jpg', alt='') |
||||
.col-md-3.col-sm-6.my-3 |
||||
a(href='#!') |
||||
img.img-fluid.d-block.mx-auto(src='assets/img/logos/creative-market.jpg', alt='') |
||||
|
||||
// Contact |
||||
section#contact.page-section |
||||
.container |
||||
.text-center |
||||
h2.section-heading.text-uppercase Contact Us |
||||
h3.section-subheading.text-muted Lorem ipsum dolor sit amet consectetur. |
||||
form#contactForm(name='sentMessage', novalidate='novalidate') |
||||
.row.align-items-stretch.mb-5 |
||||
.col-md-6 |
||||
.form-group |
||||
input#name.form-control(type='text', placeholder='Your Name *', required='required', data-validation-required-message='Please enter your name.') |
||||
p.help-block.text-danger |
||||
.form-group |
||||
input#email.form-control(type='email', placeholder='Your Email *', required='required', data-validation-required-message='Please enter your email address.') |
||||
p.help-block.text-danger |
||||
.form-group.mb-md-0 |
||||
input#phone.form-control(type='tel', placeholder='Your Phone *', required='required', data-validation-required-message='Please enter your phone number.') |
||||
p.help-block.text-danger |
||||
.col-md-6 |
||||
.form-group.form-group-textarea.mb-md-0 |
||||
textarea#message.form-control(placeholder='Your Message *', required='required', data-validation-required-message='Please enter a message.') |
||||
p.help-block.text-danger |
||||
.text-center |
||||
#success |
||||
button#sendMessageButton.btn.btn-primary.btn-xl.text-uppercase(type='submit') Send Message |
||||
|
||||
// Footer |
||||
footer.footer.py-4 |
||||
.container |
||||
.row.align-items-center |
||||
.col-lg-4.text-lg-left |
||||
| Copyright © Your Website 2020 |
||||
.col-lg-4.my-3.my-lg-0 |
||||
a.btn.btn-dark.btn-social.mx-2(href='#!') |
||||
i.fab.fa-twitter |
||||
a.btn.btn-dark.btn-social.mx-2(href='#!') |
||||
i.fab.fa-facebook-f |
||||
a.btn.btn-dark.btn-social.mx-2(href='#!') |
||||
i.fab.fa-linkedin-in |
||||
.col-lg-4.text-lg-right |
||||
a.mr-3(href='#!') Privacy Policy |
||||
a(href='#!') Terms of Use |
||||
|
||||
// Portfolio Modals |
||||
// Modal 1 |
||||
#portfolioModal1.portfolio-modal.modal.fade(tabindex='-1', role='dialog', aria-hidden='true') |
||||
.modal-dialog |
||||
.modal-content |
||||
.close-modal(data-dismiss='modal') |
||||
img(src="assets/img/close-icon.svg", alt='Close modal') |
||||
.container |
||||
.row.justify-content-center |
||||
.col-lg-8 |
||||
.modal-body |
||||
// Project Details Go Here |
||||
h2.text-uppercase Project Name |
||||
p.item-intro.text-muted Lorem ipsum dolor sit amet consectetur. |
||||
img.img-fluid.d-block.mx-auto(src='assets/img/portfolio/01-full.jpg', alt='') |
||||
p Use this area to describe your project. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est blanditiis dolorem culpa incidunt minus dignissimos deserunt repellat aperiam quasi sunt officia expedita beatae cupiditate, maiores repudiandae, nostrum, reiciendis facere nemo! |
||||
ul.list-inline |
||||
li Date: January 2020 |
||||
li Client: Threads |
||||
li Category: Illustration |
||||
button.btn.btn-primary(data-dismiss='modal', type='button') |
||||
i.fas.fa-times.mr-1 |
||||
| Close Project |
||||
// Modal 2 |
||||
#portfolioModal2.portfolio-modal.modal.fade(tabindex='-1', role='dialog', aria-hidden='true') |
||||
.modal-dialog |
||||
.modal-content |
||||
.close-modal(data-dismiss='modal') |
||||
img(src="assets/img/close-icon.svg", alt='Close modal') |
||||
.container |
||||
.row.justify-content-center |
||||
.col-lg-8 |
||||
.modal-body |
||||
// Project Details Go Here |
||||
h2.text-uppercase Project Name |
||||
p.item-intro.text-muted Lorem ipsum dolor sit amet consectetur. |
||||
img.img-fluid.d-block.mx-auto(src='assets/img/portfolio/02-full.jpg', alt='') |
||||
p Use this area to describe your project. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est blanditiis dolorem culpa incidunt minus dignissimos deserunt repellat aperiam quasi sunt officia expedita beatae cupiditate, maiores repudiandae, nostrum, reiciendis facere nemo! |
||||
ul.list-inline |
||||
li Date: January 2020 |
||||
li Client: Explore |
||||
li Category: Graphic Design |
||||
button.btn.btn-primary(data-dismiss='modal', type='button') |
||||
i.fas.fa-times.mr-1 |
||||
| Close Project |
||||
// Modal 3 |
||||
#portfolioModal3.portfolio-modal.modal.fade(tabindex='-1', role='dialog', aria-hidden='true') |
||||
.modal-dialog |
||||
.modal-content |
||||
.close-modal(data-dismiss='modal') |
||||
img(src="assets/img/close-icon.svg", alt='Close modal') |
||||
.container |
||||
.row.justify-content-center |
||||
.col-lg-8 |
||||
.modal-body |
||||
// Project Details Go Here |
||||
h2.text-uppercase Project Name |
||||
p.item-intro.text-muted Lorem ipsum dolor sit amet consectetur. |
||||
img.img-fluid.d-block.mx-auto(src='assets/img/portfolio/03-full.jpg', alt='') |
||||
p Use this area to describe your project. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est blanditiis dolorem culpa incidunt minus dignissimos deserunt repellat aperiam quasi sunt officia expedita beatae cupiditate, maiores repudiandae, nostrum, reiciendis facere nemo! |
||||
ul.list-inline |
||||
li Date: January 2020 |
||||
li Client: Finish |
||||
li Category: Identity |
||||
button.btn.btn-primary(data-dismiss='modal', type='button') |
||||
i.fas.fa-times.mr-1 |
||||
| Close Project |
||||
// Modal 4 |
||||
#portfolioModal4.portfolio-modal.modal.fade(tabindex='-1', role='dialog', aria-hidden='true') |
||||
.modal-dialog |
||||
.modal-content |
||||
.close-modal(data-dismiss='modal') |
||||
img(src="assets/img/close-icon.svg", alt='Close modal') |
||||
.container |
||||
.row.justify-content-center |
||||
.col-lg-8 |
||||
.modal-body |
||||
// Project Details Go Here |
||||
h2.text-uppercase Project Name |
||||
p.item-intro.text-muted Lorem ipsum dolor sit amet consectetur. |
||||
img.img-fluid.d-block.mx-auto(src='assets/img/portfolio/04-full.jpg', alt='') |
||||
p Use this area to describe your project. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est blanditiis dolorem culpa incidunt minus dignissimos deserunt repellat aperiam quasi sunt officia expedita beatae cupiditate, maiores repudiandae, nostrum, reiciendis facere nemo! |
||||
ul.list-inline |
||||
li Date: January 2020 |
||||
li Client: Lines |
||||
li Category: Branding |
||||
button.btn.btn-primary(data-dismiss='modal', type='button') |
||||
i.fas.fa-times.mr-1 |
||||
| Close Project |
||||
// Modal 5 |
||||
#portfolioModal5.portfolio-modal.modal.fade(tabindex='-1', role='dialog', aria-hidden='true') |
||||
.modal-dialog |
||||
.modal-content |
||||
.close-modal(data-dismiss='modal') |
||||
img(src="assets/img/close-icon.svg", alt='Close modal') |
||||
.container |
||||
.row.justify-content-center |
||||
.col-lg-8 |
||||
.modal-body |
||||
// Project Details Go Here |
||||
h2.text-uppercase Project Name |
||||
p.item-intro.text-muted Lorem ipsum dolor sit amet consectetur. |
||||
img.img-fluid.d-block.mx-auto(src='assets/img/portfolio/05-full.jpg', alt='') |
||||
p Use this area to describe your project. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est blanditiis dolorem culpa incidunt minus dignissimos deserunt repellat aperiam quasi sunt officia expedita beatae cupiditate, maiores repudiandae, nostrum, reiciendis facere nemo! |
||||
ul.list-inline |
||||
li Date: January 2020 |
||||
li Client: Southwest |
||||
li Category: Website Design |
||||
button.btn.btn-primary(data-dismiss='modal', type='button') |
||||
i.fas.fa-times.mr-1 |
||||
| Close Project |
||||
// Modal 6 |
||||
#portfolioModal6.portfolio-modal.modal.fade(tabindex='-1', role='dialog', aria-hidden='true') |
||||
.modal-dialog |
||||
.modal-content |
||||
.close-modal(data-dismiss='modal') |
||||
img(src="assets/img/close-icon.svg", alt='Close modal') |
||||
.container |
||||
.row.justify-content-center |
||||
.col-lg-8 |
||||
.modal-body |
||||
// Project Details Go Here |
||||
h2.text-uppercase Project Name |
||||
p.item-intro.text-muted Lorem ipsum dolor sit amet consectetur. |
||||
img.img-fluid.d-block.mx-auto(src='assets/img/portfolio/06-full.jpg', alt='') |
||||
p Use this area to describe your project. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est blanditiis dolorem culpa incidunt minus dignissimos deserunt repellat aperiam quasi sunt officia expedita beatae cupiditate, maiores repudiandae, nostrum, reiciendis facere nemo! |
||||
ul.list-inline |
||||
li Date: January 2020 |
||||
li Client: Window |
||||
li Category: Photography |
||||
button.btn.btn-primary(data-dismiss='modal', type='button') |
||||
i.fas.fa-times.mr-1 |
||||
| Close Project |
||||
|
||||
// Bootstrap core JS |
||||
script(src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js') |
||||
script(src='https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.bundle.min.js') |
||||
|
||||
// Third party plugin JS |
||||
script(src='https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.min.js') |
||||
|
||||
// Contact form JS |
||||
script(src='assets/mail/jqBootstrapValidation.js') |
||||
script(src='assets/mail/contact_me.js') |
||||
|
||||
// Core theme JS |
||||
script(src='js/scripts.js') |
||||