This commit is contained in:
friendica 2015-01-01 21:49:01 -08:00
commit 545e47933a
55 changed files with 7071 additions and 5447 deletions

View File

@ -139,7 +139,8 @@ $(document).ready(function() {
var known = {
en: true, // ENGLISH
fr: true, // FRENCH
nl: true // NETHERLANDS
nl: true, // NETHERLANDS
sv: true // SWEDISH
// ADD YOUR LANGUAGE HERE.
};
// Figure out the language, default to English because that's
@ -196,6 +197,55 @@ $(document).ready(function() {
"Code Source Ouvert",
"Gratuit",
null);
else if (lang == "sv") // SWEDISH TRANSLATIONS
terms = new Array("Sekretess skalad för Internet",
"Socialt nätverkande",
"Single Sign-On",
"Fotoalbum",
"Decentraliserat",
"Molnlagring",
"Ditt eget innehåll",
"Blogg",
"End-to-end-kryptering",
"Chattrum",
"Delbara tilläggsprogram",
"Kontrollera behörighet mellan webbplatser",
"Ångra privata meddelanden",
"Skapa webbsidor",
"Innehållshantering",
"Tidsbegränsade meddelanden",
"Spel och verktyg",
"Inte styrt av företag",
"Forum",
"Gilla + Ogilla",
"Dela allt som är digitalt",
"Kommunikation",
"Identitsmedvetet innehåll",
"Pseudonymer",
"Multipla identiteter",
"Reklamfritt",
"Rich Text-inlägg/-kommentarer",
"Händelsekalender",
"Bokmärken",
"Gemensam taggning",
"Speglad katalog",
"Nomadisk identitet",
"Avknoppade kanaler",
"Anpassad kryptering",
"Multipla profiler",
"Sekretessgrupper",
"Fildelning",
"MIT-licens",
"Självständighet",
"Samhörighetsfiltrering",
"Vänförslag",
"Fjärrinloggning",
"Teman",
"Tillägg",
"Externt API",
"Tredjepartsappar",
"Öppen källkod",
null);
// Find all <div>s with a class of "wrapper" and lang attribute equal
// to `lang` and make them visibile.
@ -315,6 +365,33 @@ De RedMatrix is ideaal voor groepen mensen van welke omvang dan ook, van kleine
</div>
<div style="margin-top: 15px; margin-bottom: 15px;"><a href="pubsites">Andere openbare hubs</a> | <a href="https://redmatrix.me">Projectwebsite</a> | <a href="https://github.com/friendica/red">Broncode</a> | <a href="https://zothub.com/channel/one">Ontwikkelaars</a></div>
</div>
<!-- SWEDISH FRONTPAGE TRANSLATION STARTS HERE -->
<div lang="sv" class="wrapper" style="display: none;">
<div class="tr" style="font-size: 1.4em; color: #666; margin-left: 75px; margin-right: 75px;">
Ett av de vanliga problemen med oberoende publicering p&aring; n&auml;tet har alltid varit det faktum att oberoende f&ouml;rfattare ofta &auml;r isolerade fr&aring;n varandra p&aring; sin egen webbplats och l&auml;gger det mesta av energin p&aring; att locka och attrahera bes&ouml;kare. Uppkomsten av vinstdrivande tj&auml;nster och s&aring; kallade sociala n&auml;tverk erbj&ouml;d en l&ouml;sning till m&aring;nga av dessa problem. Centraliseringen som p&aring;g&aring;tt har dock lett till att ditt inneh&aring;ll inte l&auml;ngre &auml;r under din direkta kontroll. Det &auml;r delat fullt ut med vinstdrivande annons&ouml;rer och myndigheter, men ironiskt nog uppmanas du ofta att betala pengar f&ouml;r att s&auml;kerst&auml;lla att dina v&auml;nner kan se ditt inneh&aring;ll. F&ouml;rest&auml;ll dig en situation d&auml;r du har f&ouml;rdelarna av den skalbarhet, kontakt och spridning som centraliseringen typiskt erbjuder, samtidigt som du inte ger avkall p&aring; kontroll &ouml;ver din egen n&auml;rvaro p&aring; Internet.
</div>
<br />
<div class="tr" style="font-size: 1.4em; color: #666; margin-left: 75px; margin-right: 75px;">
RedMatrix &auml;r ett n&auml;tverk sammansatt av ett stort antal mindre, oberoende och sj&auml;lvst&auml;ndiga webbplatser, sammankopplade till en samverkande publicerings- och kommunikationsplattform. Mjukvaran best&aring;r av en webbapplikation sl&auml;ppt som &ouml;ppen k&auml;llkod, som tillhandah&aring;ller ett <strong>decentraliserat</strong> fleranv&auml;ndarsystem f&ouml;r kommunikation, publicering och delning, och n&auml;r den k&ouml;rs utg&ouml;r en nod i n&auml;tverket. Varje nod erbjuder s&aring;v&auml;l kommunikationsverktyg (privata meddelanden, chatt, blogg, forum och traditionellt socialt n&auml;tverkande) som filhantering (foton, kalenderh&auml;ndelser, filer, webbsidor, delbara till&auml;ggsprogram) f&ouml;r alla medlemmar; alltihop i en sammanknuten plattform. Dessa noder tar automatiskt kontakt med varandra och resten av n&auml;tverket. Sekretess och inneh&aring;llsstyrning &auml;r alltid under din direkta personliga kontroll, och beh&ouml;righet till inl&auml;gg eller filer kan ges eller nekas vem som helst i n&auml;tverket.
</div>
<br />
<div class="tr" style="font-size: 1.4em; color: #666; margin-left: 75px; margin-right: 75px;">
Det som g&ouml;r RedMatrix unikt &auml;r vad vi kallar "magisk fj&auml;rrinloggning" - som &auml;r baserad p&aring; v&aring;rt banbrytande arbete med en decentraliserad identitetshantering. Ingen annan plattform vi k&auml;nner till erbjuder i dagsl&auml;get n&aring;got liknande. Inom n&auml;tverket &auml;r gr&auml;nserna mellan de olika noderna utsuddade eller till synes icke-existerande. En identitet i n&auml;tverket kan vara &ouml;verg&aring;ende och potentiellt nomadisk. "Vem du &auml;r" har inget att g&ouml;ra med "vilken dator du ansluter till inom n&auml;tverket" och webbsidornas inneh&aring;ll kan skapas s&aring; att det anpassar sig utifr&aring;n vem som tittar p&aring; det. Du har m&ouml;jlighet att "klona" din identitet till andra noder, vilket l&aring;ter dig forts&auml;tta att kommunicera med dina v&auml;nner utan avbrott om din prim&auml;ra nod skulle bli otillg&auml;nglig (tillf&auml;lligt eller permanent).
</div>
<br />
<div class="tr" style="font-size: 1.4em; color: #666; margin-left: 75px; margin-right: 75px;">
RedMatrix passar f&ouml;r grupper av vilken storlek som helst - alltifr&aring;n privatpersoner och familjer till n&auml;tforum, f&ouml;retagswebbplatser och organisationer. Det kan anv&auml;ndas av alla som har inneh&aring;ll de &ouml;nskar dela med sig av och samtidigt ha full kontroll &ouml;ver vem de delar det med.
</div>
<br />
<div style="margin-bottom: 15px; color: #808080; font-size: 1.8em;"><strong>RedMatrix - "N&auml;tverket"</strong></div>
<div style="font-size: 1.4em;">
<a href="register" style="color: white; padding:10px; background-color: #c60032; border-radius: 10px;">Registrera dig nu!</a>
<a href="donate" style="color: white; padding:10px; background-color: #c60032; border-radius: 10px;">Ge ett bidrag / Sponsra</a>
</div>
<div style="margin-top: 15px; margin-bottom: 15px;"><a href="pubsites">Offentliga noder</a> | <a href="https://redmatrix.me">Projektets hemsida</a> | <a href="https://github.com/friendica/red">Kod</a> | <a href="https://zothub.com/channel/one">Utvecklare</a></div>
</div>
<!-- INSERT NEW TRANSLATIONS HERE -->
<!-- DO NOT REMOVE THE 2 LINES BELOW -->

View File

@ -14,25 +14,17 @@ function timezone_cmp($a, $b) {
return ( t($a) < t($b)) ? -1 : 1;
}
// emit a timezone selector grouped (primarily) by continent
function select_timezone($current = 'America/Los_Angeles') {
// Return timezones grouped (primarily) by continent
function get_timezones( ){
$timezone_identifiers = DateTimeZone::listIdentifiers();
$o ='<select id="timezone_select" name="timezone">';
usort($timezone_identifiers, 'timezone_cmp');
$continent = '';
$continents = array();
foreach($timezone_identifiers as $value) {
$ex = explode("/", $value);
if(count($ex) > 1) {
if($ex[0] != $continent) {
if($continent != '')
$o .= '</optgroup>';
$continent = $ex[0];
$o .= '<optgroup label="' . t($continent) . '">';
}
$continent = t($ex[0]);
if(count($ex) > 2)
$city = substr($value,strpos($value,'/')+1);
else
@ -40,35 +32,14 @@ function select_timezone($current = 'America/Los_Angeles') {
}
else {
$city = $ex[0];
if($continent != t('Miscellaneous')) {
$o .= '</optgroup>';
$continent = t('Miscellaneous');
$o .= '<optgroup label="' . t($continent) . '">';
}
$continent = t('Miscellaneous');
}
$city = str_replace('_', ' ', t($city));
$selected = (($value == $current) ? " selected=\"selected\" " : "");
$o .= "<option value=\"$value\" $selected >$city</option>";
}
$o .= '</optgroup></select>';
return $o;
}
// return a select using 'field_select_raw' template, with timezones
// groupped (primarily) by continent
// arguments follow convetion as other field_* template array:
// 'name', 'label', $value, 'help'
function field_timezone($name='timezone', $label='', $current = 'America/Los_Angeles', $help){
$options = select_timezone($current);
$options = str_replace('<select id="timezone_select" name="timezone">','', $options);
$options = str_replace('</select>','', $options);
$tpl = get_markup_template('field_select_raw.tpl');
return replace_macros($tpl, array(
'$field' => array($name, $label, $current, $help, $options),
));
if(!x($continents,$ex[0])) $continents[$ex[0]] = array();
$continents[$continent][$value] = $city;
}
return $continents;
}
// General purpose date parse/convert function.

View File

@ -800,38 +800,18 @@ function get_role_perms($role) {
}
/**
* @brief Creates a HTML select field with all available roles.
* @brief Returns a list or roles, grouped by type
*
* @param string $current The current role
* @return string Returns the complete HTML code for this privacy-role-select field.
* @return string Returns an array of roles, grouped by type
*/
function role_selector($current) {
if(! $current)
$current = 'custom';
function get_roles() {
$roles = array(
'social' => array( t('Social Networking'),
array('social' => t('Mostly Public'), 'social_restricted' => t('Restricted'), 'social_private' => t('Private'))),
'forum' => array( t('Community Forum'),
array('forum' => t('Mostly Public'), 'forum_restricted' => t('Restricted'), 'forum_private' => t('Private'))),
'feed' => array( t('Feed Republish'),
array('feed' => t('Mostly Public'), 'feed_restricted' => t('Restricted'))),
'special' => array( t('Special Purpose'),
array('soapbox' => t('Celebrity/Soapbox'), 'repository' => t('Group Repository'))),
'other' => array( t('Other'),
array('custom' => t('Custom/Expert Mode'))));
t('Social Networking') => array('social' => t('Mostly Public'), 'social_restricted' => t('Restricted'), 'social_private' => t('Private')),
t('Community Forum') => array('forum' => t('Mostly Public'), 'forum_restricted' => t('Restricted'), 'forum_private' => t('Private')),
t('Feed Republish') => array('feed' => t('Mostly Public'), 'feed_restricted' => t('Restricted')),
t('Special Purpose') => array('soapbox' => t('Celebrity/Soapbox'), 'repository' => t('Group Repository')),
t('Other') => array('custom' => t('Custom/Expert Mode')));
$o = '<select name="permissions_role" id="privacy-role-select">';
foreach($roles as $k => $v) {
$o .= '<optgroup label="'. htmlspecialchars($v[0]) . '">';
foreach($v[1] as $kk => $vv) {
$selected = (($kk === $current) ? ' selected="selected"' : '');
$o .= '<option value="' . $kk . '"' . $selected . '>' . htmlspecialchars($vv) . '</option>';
}
$o .= '</optgroup>';
}
$o .= '</select>';
return $o;
return $roles;
}

166
library/jquery.AreYouSure/.gitignore vendored Normal file
View File

@ -0,0 +1,166 @@
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.vspscc
.builds
*.dotCover
## TODO: If you have NuGet Package Restore enabled, uncomment this
#packages/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
# Visual Studio profiler
*.psess
*.vsp
# ReSharper is a .NET coding add-in
_ReSharper*
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
# Others
[Bb]in
[Oo]bj
sql
TestResults
*.Cache
ClientBin
stylecop.*
~$*
*.dbmdl
Generated_Code #added for RIA/Silverlight projects
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
############
## Windows
############
# Windows image file caches
Thumbs.db
# Folder config file
Desktop.ini
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
# Mac crap
.DS_Store
bower_components/
node_modules/

View File

@ -0,0 +1,26 @@
module.exports = function(grunt) {
grunt.config.init({
karma: {
options: {
browsers: [ 'Chrome', 'Firefox', 'Safari', 'IE' ],
frameworks: [ 'jasmine' ],
reportSlowerThan: 500,
singleRun: true
},
unit: {
files: [
{ pattern: 'bower_components/jquery/dist/jquery.min.js' },
{ pattern: 'bower_components/jasmine-jquery/lib/jasmine-jquery.js' },
{ pattern: 'jquery.are-you-sure.js' },
{ pattern: 'spec/javascripts/*.js' },
{ pattern: 'spec/javascripts/fixtures/**/*.html', included: false }
]
}
}
});
grunt.registerTask('test', 'Run tests.', [ 'karma' ]);
grunt.registerTask('default', [ 'test' ]);
grunt.loadNpmTasks('grunt-karma');
};

View File

@ -0,0 +1,297 @@
Are You Sure? - A light "dirty forms" JQuery Plugin
======
**Version:** 1.9
*Are-you-sure* (```jquery.are-you-sure.js```) is simple light-weight "dirty
form" JQuery Plugin for modern browsers. It helps prevent users from losing
unsaved HTML Form changes by promoting the user to save/submit.
It's simple to use. Just add the following line to your page's ready
function:
```javascript
$('form').areYouSure();
```
*Are-you-sure* is a minimal plugin for modern browsers. There are plenty of
"dirty forms" implementations out there, however they all seemed very
heavyweight and over-engineered...! Most were written some time back and
contain many 'hacks' to support legacy browsers, and/or rely on other fat
dependencies such as FaceBox or jQueryUI. *Are-you-sure* solves this by
doing this simple task in the simplest possible way.
*Are-you-sure* is as simple as it gets:
* 100% JS with zero dependencies and no external CSS.
* Leverages `onBeforeUnload` to detect all page/browser exit events.
* Works on forms of any size.
* Correct state management - if a user edits then restores a value, the form
is not considered dirty.
* Easy to understand - less than a "terminal screen" of code!
* Graceful degradation on legacy browsers (i.e. if you're running an old
browser... remember to save :-)
###Basic Usage
```javascript
$(function() {
// Enable on all forms
$('form').areYouSure();
// Enable on selected forms
$('form.dirty-check').areYouSure();
// With a custom message
$('form').areYouSure( {'message':'Your profile details are not saved!'} );
}
```
To ignore selected fields from the dirtyness check:
```html
<form id="myForm" name="myform" action="/post" method="post">
Field 1: (checked) <input type="text" name="field1"> <br />
Field 2: (ignored): <input type="text" name="field2" data-ays-ignore="true"> <br />
Field 3: (ignored): <input type="text" name="field3" class="ays-ignore"> <br />
<input type="submit" value="Submit">
</form>
```
###Advanced Usage
```javascript
$(function() {
/*
* Make Are-You-Sure "silent" by disabling the warning message
* (tracking/monitoring only mode). This option is useful when you wish to
* use the dirty/save events and/or use the dirtyness tracking in your own
* beforeunload handler.
*/
$('form').areYouSure( {'silent':true} );
/*
* Dirtyness Change Events
* Are-You-Sure fires off "dirty" and "clean" events when the form's state
* changes. You can bind() or on(), these events to implement your own form
* state logic. A good example is enabling/disabling a Save button.
*
* "this" refers to the form that fired the event.
*/
$('form').on('dirty.areYouSure', function() {
// Enable save button only as the form is dirty.
$(this).find('input[type="submit"]').removeAttr('disabled');
});
$('form').on('clean.areYouSure', function() {
// Form is clean so nothing to save - disable the save button.
$(this).find('input[type="submit"]').attr('disabled', 'disabled');
});
/*
* It's easy to test if a form is dirty in your own code - just check
* to see if it has a "dirty" CSS class.
*/
if ($('#my-form').hasClass('dirty')) {
// Do something
}
/*
* If you're dynamically adding new fields/inputs, and would like to track
* their state, trigger Are-You-Sure to rescan the form like this:
*/
$('#my-form').trigger('rescan.areYouSure');
/*
* If you'd like to reset/reinitialize the form's state as clean and
* start tracking again from this new point onwards, trigger the
* reinitalize as follows. This is handy if say you've managing your
* own form save/submit via asyc AJAX.
*/
$('#my-form').trigger('reinitialize.areYouSure');
/*
* In some situations it may be desirable to look for other form
* changes such as adding/removing fields. This is useful for forms that
* can change their field count, such as address/phone contact forms.
* Form example, you might remove a phone number from a contact form
* but update nothing else. This should mark the form as dirty.
*/
$('form').areYouSure( {'addRemoveFieldsMarksDirty':true} );
/*
* Sometimes you may have advanced forms that change their state via
* custom JavaScript or 3rd-party component JavaScript. Are-You-Sure may
* not automatically detect these state changes. Examples include:
* - Updating a hidden input field via background JS.
* - Using a [rich WYSIWYG edit control](https://github.com/codedance/jquery.AreYouSure/issues/17).
* One solution is to manually trigger a form check as follows:
*/
$('#my-form').trigger('checkform.areYouSure');
/*
* As an alternative to using events, you can pass in a custom change
* function.
*/
$('#my-adv-form').areYouSure({
change: function() {
// Enable save button only if the form is dirty. i.e. something to save.
if ($(this).hasClass('dirty')) {
$(this).find('input[type="submit"]').removeAttr('disabled');
} else {
$(this).find('input[type="submit"]').attr('disabled', 'disabled');
}
}
});
/*
* Mixing in your own logic into the warning.
*/
$('#my-form').areYouSure( {'silent':true} );
$(window).on('beforeunload', function() {
isSunday = (0 == (new Date()).getDay());
if ($('#my-form').hasClass('dirty') && isSunday) {
return "Because it's Sunday, I'll be nice and let you know you forgot to save!";
}
}
}
```
The [demo page](http://www.papercut.com/products/free_software/are-you-sure/demo/are-you-sure-demo.html)
shows the advanced usage options in more detail.
###Install
Are-You-Sure is a light-weight jQuery plugin - it's a single standalone
JavaScript file. You can download the
[jquery.are-you-sure.js](https://raw.github.com/codedance/jquery.AreYouSure/master/jquery.are-you-sure.js)
file and include it in your page. Because it's so simple it seems a shame
to add an extra browser round trip. It's recommended that you consider
concatenating it with other common JS lib files, and/or even cut-n-pasting
the code (and license header) into one of your existing JS files.
For experimental Mobile Safari support, also include ```ays-beforeunload-shim.js```
(see Known Issues below).
*Are-you-sure* may also be installed with [Bower](http://twitter.github.com/bower/):
```bash
$ bower install jquery.are-you-sure
```
If you're using, or like, *Are-you-sure* make sure you **star/watch** this project
so you can stay up-to-date with updates.
###Demo
This [demo page](http://www.papercut.com/products/free_software/are-you-sure/demo/are-you-sure-demo.html)
hosts a number of example forms.
###Supported Browsers
*Are-you-sure* has been tested on and fully supports the following browsers:
* IE 9 through 11
* Google Chrome (versions since 2012)
* Firefox (versions since 2012)
* Safari (versions since 2012)
Experimental support is available on iOS and Opera via the *beforeunload* shim (see below).
###Known Issues & Limitations
####Mobile Safari and Opera
The ```windows.beforeunload``` event is not supported on iOS (iPhone, iPad, and iPod). An
experimental shim offering partial *beforeunload* emulation is provided to help plug this gap.
It works by scanning the page for anchor links and augments the default behaviour to first
check with *Are-you-sure* before navigating away. To use, simply include
```ays-beforeunload-shim.js``` in your page.
####Firefox
The custom message option may not work on Firefox ([Firefox bug 588292](https://bugzilla.mozilla.org/show_bug.cgi?id=588292)).
###Development
The aim is to keep *Are-you-sure* simple and light. If you think you have
a good idea which is aligned with this objective, please voice your thoughts
in the issues list.
####Pull Requests
If possible, please submit your pull request against the most recent ```dev-*``` branch rather than master. This will make it easier to merge your code into the next planned release.
####Running tests
```bash
$ npm install
$ npm test
```
###Release History
**2014-08-13** (1.9) - This is a minor bugfix release:
* Addressed issue [#45](https://github.com/codedance/jquery.AreYouSure/issues/55) seen with empty select fields.
* Thanks [valgen](https://github.com/valgen) and [tus124](https://github.com/tus124) for the contribution.
**2014-06-22** (1.8) - This is a minor bugfix release:
* Fixed NPE that may occur when using a 'multiple' option field.
* Minor timing tweak to help mitigate bypass issue raised in [#45](https://github.com/codedance/jquery.AreYouSure/issues/45)
* Thanks [apassant](https://github.com/apassant) and [amatenkov](https://github.com/amatenkov) for the contribution.
**2014-05-28** (1.7)
* Fixed multiple warning dialogs that may appear on IE and recent versions of Chrome
* Experimental support for iOS Mobile Safari (via a *beforeunload* shim)
* Various minor fixes (e.g. support input fields with no type=)
* Minor performance improvements on pages with multiple forms
* Improved documentation and examples
* Thanks to [lfjeff](https://github.com/lfjeff) and [aqlong](https://github.com/aqlong) for the contribution and ideas!
**2014-02-07** (1.6)
* Add field count tracking (```addRemoveFieldsMarksDirty```) (contrib *jonegerton*)
* Added event to manually trigger a form check/recheck (contrib *jonegerton*)
* Thanks to [jonegerton](https://github.com/jonegerton) for the contribution!
**2013-11-15** (1.5)
* Added support for HTML5 input field types. (contrib *albinsunnanbo*)
* New option to reinitialize/reset the dirty state. This is handy if you're managing your own async submit/save using AJAX. (contrib *albinsunnanbo*)
* Thanks to [albinsunnanbo](https://github.com/albinsunnanbo) for the contribution!
**2013-10-2** (1.4)
* Added dirty and clean "events"
* Added an option to disable the message (dirty tracking only)
* Added an option to rescan a form to look/detect any new fields
**2013-07-24** - Minor fix - don't fail if form elements have no "name" attribute.
**2013-05-14** - Added support for form reset buttons (contributed by codev).
**2013-05-01** - Added support for hidden and disabled form fields.
**2013-02-03** - Add demo page.
**2013-01-28** - Add ```change``` event support and a demo page.
**2012-10-26** - Use dashes in class names rather than camel case.
**2012-10-24** - Initial public release.
###Prerequisites
jQuery version 1.4.2 or higher. 2.0+ or 1.10+ recommended.
###License
The same as JQuery...
jQuery Plugin: Are-You-Sure (Dirty Form Detection)
https://github.com/codedance/jquery.AreYouSure/
Copyright (c) 2012-2014, Chris Dance - PaperCut Software http://www.papercut.com/
Dual licensed under the MIT or GPL Version 2 licenses.
http://jquery.org/license

View File

@ -0,0 +1,39 @@
{
"name": "are-you-sure",
"title": "Are You Sure? - a dirty forms check plugin",
"description": "Are-you-sure is simple light-weight dirty forms JQuery Plugin for modern browsers. It helps prevent users from loosing unsaved form changes by prompting the user to save/submit. It's dependency free and designed for modern browsers... just the features you need and nothing more! See the project page and demo for usage and examples.",
"keywords": [
"form",
"dirty",
"field",
"change",
"save",
"save-check",
"save-warning"
],
"version": "1.9.0",
"author": {
"name": "Chris Dance (codedance) at PaperCut Software",
"url": "https://github.com/codedance"
},
"maintainers": [
{
"name": "Chris Dance",
"email": "chris.dance@papercut.com",
"url": "http://www.papercut.com/"
}
],
"licenses": [
{
"type": "MIT",
"url": "https://github.com/codedance/jquery.AreYouSure/blob/master/README.md"
}
],
"bugs": "https://github.com/codedance/jquery.AreYouSure/issues",
"homepage": "https://github.com/codedance/jquery.AreYouSure",
"docs": "https://github.com/codedance/jquery.AreYouSure",
"demo": "http://www.papercut.com/products/free_software/are-you-sure/demo/are-you-sure-demo.html",
"dependencies": {
"jquery": ">=1.4.2"
}
}

View File

@ -0,0 +1,31 @@
/*!
* An experimental shim to partially emulate onBeforeUnload on iOS.
* Part of https://github.com/codedance/jquery.AreYouSure/
*
* Copyright (c) 2012-2014, Chris Dance and PaperCut Software http://www.papercut.com/
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Author: chris.dance@papercut.com
* Date: 19th May 2014
*/
$(function() {
if (!navigator.userAgent.toLowerCase().match(/iphone|ipad|ipod|opera/)) {
return;
}
$('a').bind('click', function(evt) {
var href = $(evt.target).closest('a').attr('href');
if (href !== undefined && !(href.match(/^#/) || href.trim() == '')) {
var response = $(window).triggerHandler('beforeunload', response);
if (response && response != "") {
var msg = response + "\n\n"
+ "Press OK to leave this page or Cancel to stay.";
if (!confirm(msg)) {
return false;
}
}
window.location.href = href;
return false;
}
});
});

View File

@ -0,0 +1,30 @@
{
"name": "jquery.are-you-sure",
"version": "1.9.0",
"homepage": "https://github.com/codedance/jquery.AreYouSure",
"authors": [
"CodeDance <chris.dance@papercut.com>"
],
"description": "A light-weight jQuery 'dirty forms' Plugin - it monitors html forms and alerts users to unsaved changes if they attempt to close the browser or navigate away from the page. (Are you sure?)",
"main": "jquery.are-you-sure.js",
"keywords": [
"form",
"dirty",
"field",
"change",
"save-check",
"are-you-sure",
"save-warning"
],
"license": "MIT/GPLv2",
"ignore": [
"**/.*",
"demo"
],
"dependencies": {
"jquery": ">=1.4.2"
},
"devDependencies": {
"jasmine-jquery": "~2.0.3"
}
}

View File

@ -0,0 +1,576 @@
<!DOCTYPE html>
<html>
<head>
<title>Demo: Are You Sure? - a dirty forms jQuery Plugin</title>
<!--
We'll use an old version of jQuery to show we're backwards compatible. In
production we recommend using a later version. e.g.
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
-->
<script src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
<script src="../jquery.are-you-sure.js"></script>
<script src="../ays-beforeunload-shim.js"></script>
<script>
$(function() {
// Example 1 - ... in one line of code
$('#example-1-form').areYouSure();
// Example 2 - ignore a dynamic field
$('#example-2-form').areYouSure();
var defaultPickup15min = new Date((new Date()).getTime() + 15 * 60000);
$('#pickup').val(defaultPickup15min.getHours()
+ ':' + defaultPickup15min.getMinutes());
// Example 3 - custom message and hooking the dirty change events
$('#example-3-form').areYouSure(
{
message: "Did you forget to save your standard coffee order?"
}
);
// Enable save button only if the form is dirty - using events.
$('#example-3-form').bind('dirty.areYouSure', function() {
$(this).find('input[type="submit"]').removeAttr('disabled');
});
$('#example-3-form').bind('clean.areYouSure', function() {
$(this).find('input[type="submit"]').attr('disabled', 'disabled');
});
// Example 4 - dynamically change and add form fields.
$('#example-4-form').areYouSure(
{
message: "Did you forget to submit your coffee order?"
}
);
$('#example-4-lastorder').click(function() {
// ... set our saved coffee type.
$('#example-4-coffee').val('espresso');
// Because we've made a change from our own JavaScript, we need to fire
// off manual 'form check'.
$('#example-4-form').trigger('checkform.areYouSure');
});
// If it's warm enough, offer an iced coffee special.
$.getJSON("http://api.openweathermap.org/data/2.5/weather?q=Melbourne,AU&mode=json&units=metric&callback=?",
function(data) {
var temp = data.main.temp;
if (temp > 5) {
$('#example-4-special').append('<p>It\'s currently '
+ temp + 'C in Melbourne. Ice it up!</p>');
$('#example-4-special').append('<input type="checkbox" name="make-it-iced" value="true" />'
+ ' Make it an iced coffee<br />');
// Trigger rescan event on the form so we start tracking the new field.
$('#example-4-form').trigger('rescan.areYouSure');
}
}
);
/*
* Example 5
* - extra shots button to enable/disable shots options
* - like/unlike button (changing hidden form field value)
* - hook dirty change event to enable/disable submit (using method),
* to more easily demonstrate when the form is dirty
*/
$('#example-5-extra-shots').click(function() {
// we trigger a change event on the fields so that the AreYouSure event handler is called
$('#example-5-form input[name=shots]').removeAttr('disabled').change();
$('#example-5-extra-shots').hide();
$('#example-5-shots-options').show();
return false;
});
$('#example-5-like-button').click(function() {
var currentLike = $('#example-5-like').val() == 'true';
var newLike = !currentLike;
// we trigger a change event on the fields so that the areYouSure event handler is called
$('#example-5-like').val(newLike).change();
$('#example-5-like-button').text(newLike ? 'Unlike' : 'Like');
return false;
});
$('#example-5-form').areYouSure({
change: function() {
// Enable save button only if the form is dirty.
if ($(this).hasClass('dirty')) {
$(this).find('input[type="submit"]').removeAttr('disabled');
} else {
$(this).find('input[type="submit"]').attr('disabled', 'disabled');
}
}
});
// Example 6 - HTML5 input types
$('#example-6-form').areYouSure();
// Example 7 - ... in one line of code for the form and some more optional to toggle disabled state of the save button
$('#example-7-form').areYouSure();
$('#example-7-save-button').click(function () {
$('#example-7-form').trigger('reinitialize.areYouSure');
});
// code below is optional to handle disabled state of the save button
$('#example-7-form').bind('dirty.areYouSure', function () {
// Enable save button only as the form is dirty.
$('#example-7-save-button').attr({ 'disabled': false });
});
$('#example-7-form').bind('clean.areYouSure', function () {
// Form is clean so nothing to save - disable the save button.
$('#example-7-save-button').attr({ 'disabled': true });
});
});
</script>
<style type="text/css">
body {
font-family: myriad-pro-1, myriad-pro-2, 'Lucida Grande', 'Arial', sans-serif;
margin: 25px;
}
form {
width: 350px;
border: 1px solid #AA5303;
padding: 10px 20px;
background-image: -webkit-linear-gradient(top, rgba(170,83,3, 0.1), rgba(170,83,3, 0.5));
background-image: -moz-linear-gradient(top, rgba(170,83,3, 0.1), rgba(170,83,3, 0.5));
background-image: -ms-linear-gradient(top, rgba(170,83,3, 0.1), rgba(170,83,3, 0.5));
background-image: -o-linear-gradient(top, rgba(170,83,3, 0.1), rgba(170,83,3, 0.5));
background-image: linear-gradient(top, rgba(170,83,3, 0.1), rgba(170,83,3, 0.5));
border-radius: 5px;
}
/* A bit of custom styling on example 3 */
#example-3-form.dirty, #example-4-form.dirty {
box-shadow: 0 0 8px rgba(255, 0, 0, 1);
-webkit-box-shadow: 0 0 8px rgba(255, 0, 0, 1);
-moz-box-shadow: 0 0 8px rgba(255, 0, 0, 1);
border:1px solid rgba(255,0,0, 0.8);
}
form h2 {
font-size: 22px;
}
form > div {
padding: 8px;
font-size: 12px;
}
form > div input[type="text"],
form > div input[type="color"],
form > div input[type="date"],
form > div input[type="datetime"],
form > div input[type="datetime-local"],
form > div input[type="email"],
form > div input[type="month"],
form > div input[type="number"],
form > div input[type="range"],
form > div input[type="search"],
form > div input[type="tel"],
form > div input[type="time"],
form > div input[type="url"],
form > div input[type="week"],
form > div input:not([type]),
form > div textarea,
form > div select,
form > div button {
float: right;
width: 200px;
}
form > div input[type="radio"],
form > div input[type="checkbox"] {
display: inline-block;
margin-left: 130px;
}
form > div input[type="submit"] {
float: right;
}
form > div.buttons {
clear: both;
padding-bottom: 20px;
}
</style>
</head>
<body>
<h1>jQuery Plugin Demo: Are You Sure?</h1>
<p>
This page hosts a demo of the <a href="https://github.com/codedance/jquery.AreYouSure">jQuery Are-You-Sure</a> plugin (<code>jquery.are-you-sure.js</code>).
</p>
<p>
<i>Are-you-sure</i> is simple light-weight "dirty forms" JQuery Plugin for modern browsers. It helps prevent users from loosing unsaved form changes.
</p>
<p>
<strong>Features:</strong>
<ul>
<li>Light weight - only the features you need!</li>
<li>Dependency free.</li>
<li>Correct state management - if a user edits then restores a value, the form is not considered dirty.</li>
<li>Easy to understand - less than a "terminal screen" of code!</li>
<li>... and <a href="https://github.com/codedance/jquery.AreYouSure">more</a>.</li>
</ul>
</p>
<h2>Example 1: It's simple!</h2>
<p>
This example shows how easy it is to add a dirty check to your form(s) with one line
of code. (View the page's source)
</p>
<form id="example-1-form" name="coffeeOrder1" method="post">
<h2>Enter Your Coffee Order</h2>
<div>
<label for="example-1-coffee">Coffee</label>
<select name="coffee" id="example-1-coffee">
<option value="espresso">Espresso</option>
<option value="dbl-espresso">Caffe Doppio</option>
<option value="latte">Caffe Latte</option>
<option value="macciato">Machhiato</option>
<option value="cappuccino">Cappuccino</option>
</select>
</div>
<div>
<label>Shots</label><br />
<input type="radio" name="shots" value="1" checked /> 1 Shot - Standard<br />
<input type="radio" name="shots" value="2" /> 2 Shots - Morning wakeup!<br />
<input type="radio" name="shots" value="3" /> 3 Shots - Overdrive!<br />
</div>
<div>
<label for="example-1-sugar">Sugar</label> <input type="text" name="sugar" value="0" id="example-1-sugar" />
</div>
<div>
<label for="example-1-instructions">Special Instructions</label>
<textarea name="instructions" rows="5" id="example-1-instructions"></textarea>
</div>
<div class="buttons">
<input type="checkbox" name="remember" value="true" /> Remember my order<br />
<input type="submit" value="Submit">
<input type="reset" value="Reset">
</div>
<div>
<p>... or visit <a href="http://www.google.com/">Google</a> or close the window without saving!</p>
</div>
</form>
<h2>Example 2: Ignore the unimportant!</h2>
<p>
This example highlights how to disregard a field from the dirty check. In this form
the first field is dynamically populated and hence a change on this field should <em>not</em>
mark the form as dirty.
</p>
<form id="example-2-form" name="coffeeOrder2" method="post">
<h2>Enter Your Coffee Order</h2>
<div>
<!-- The ays-ignore class means a change on this field is not considered "dirty" -->
<label for="pickup">Pickup Time</label>
<input class="ays-ignore" type="text" name="pickup" id="pickup" />
<!-- or you can use a data attribute like this:
<label for="pickup">Pickup Time</label> <input data-ays-ignore="true" type="text" name="pickup" id="pickup" />
-->
</div>
<div>
<label for="example-2-coffee">Coffee</label>
<select name="coffee" id="example-2-coffee">
<option value="espresso">Espresso</option>
<option value="dbl-espresso">Caffe Doppio</option>
<option value="latte">Caffe Latte</option>
<option value="macciato">Machhiato</option>
<option value="cappuccino">Cappuccino</option>
</select>
</div>
<div>
<label>Shots</label><br />
<input type="radio" name="shots" value="1" checked /> 1 Shot - Standard<br />
<input type="radio" name="shots" value="2" /> 2 Shots - Morning wakeup!<br />
<input type="radio" name="shots" value="3" /> 3 Shots - Overdrive!<br />
</div>
<div>
<label for="example-2-sugar">Sugar</label> <input type="text" name="sugar" value="0" id="example-2-sugar" />
</div>
<div>
<label for="example-2-instructions">Special Instructions</label>
<textarea name="instructions" rows="5" id="example-2-instructions"></textarea>
</div>
<div class="buttons">
<input type="checkbox" name="remember" value="true" /> Remember my order<br />
<input type="submit" value="Submit">
</div>
<div>
<p>... or visit <a href="http://www.google.com/">Google</a> or close the window without saving!</p>
</div>
</form>
<h2>Example 3: Lets be intelligent!</h2>
<p>
This is a more advanced example. The <code>dirty</code> and <code>clean</code> change events are
intercepted so the save button is only enabled if the form is dirty (i.e. something to save).
It also demonstrates how to customize the warning message and change the style of a dirty
form (CSS styling using the <code>.dirty</code> class).
</p>
<form id="example-3-form" name="coffeeOrder3" method="post">
<h2>Update My Standard Order</h2>
<div>
<label for="example-3-coffee">Coffee</label>
<select name="coffee" id="example-3-coffee">
<option value=""></option>
<option value="cappuccino">Cappuccino</option>
<option value="espresso">Espresso</option>
<option value="dbl-espresso">Caffe Doppio</option>
<option value="latte">Caffe Latte</option>
<option value="macciato">Machhiato</option>
</select>
</div>
<div>
<label>Shots</label><br />
<input type="radio" name="shots" value="1" /> 1 Shot - Standard<br />
<input type="radio" name="shots" value="2" checked /> 2 Shots - Morning wakeup!<br />
<input type="radio" name="shots" value="3" /> 3 Shots - Overdrive!<br />
</div>
<div>
<label for="example-3-sugar">Sugar</label>
<input type="text" name="sugar" value="1" id="example-3-sugar" />
</div>
<div>
<label for="example-3-instructions">Special Instructions</label>
<textarea name="instructions" rows="5" id="example-3-instructions">No chocolate please</textarea>
</div>
<div class="buttons">
<input type="submit" value="Save" disabled="disabled">
</div>
<div>
<p>... or visit <a href="http://www.google.com/">Google</a> or close the window without saving!</p>
</div>
</form>
<h2>Example 4: Lets be dynamic!</h2>
<p>
In this example we'll dymaically add a field and fire off the <code>rescan</code> event. After
the rescan, Are-You-Sure will start looking for changes on the new fields as well.
</p>
<form id="example-4-form" name="coffeeOrder4" method="post">
<h2>Order Coffee For Pickup Now</h2>
<div>
<a id="example-4-lastorder" href="javascript:void(0);">Set my preferences from my last order</a><br />
</div>
<div>
<label for="example-4-coffee">Coffee</label>
<select name="coffee" id="example-4-coffee">
<option value="cappuccino">Cappuccino</option>
<option value="espresso">Espresso</option>
<option value="dbl-espresso">Caffe Doppio</option>
<option value="latte">Caffe Latte</option>
</select>
</div>
<div id="example-4-special"></div>
<div class="buttons">
<input type="submit" value="Place Order">
</div>
<div>
<p>... or visit <a href="http://www.google.com/">Google</a> or close the window without saving!</p>
</div>
</form>
<h2>Example 5: Edge cases</h2>
<p>
This example demonstrates tracking of hidden and disabled form elements that are changed by non-input elements.
E.g.:
</p>
<ul>
<li>clicking a link or non-input button that changes the value of a hidden form field, or</li>
<li>
clicking a link or non-input button that enables or disables some form fields (which has an effect on whether
or not those fields will be submitted with the form, despite the values not changing).
</li>
</ul>
<form id="example-5-form" name="coffeeOrder5" method="post">
<h2>Update My Standard Order</h2>
<div>
<label for="example-5-coffee">Coffee</label>
<select name="coffee" id="example-3-coffee">
<option value="cappuccino">Cappuccino</option>
<option value="espresso">Espresso</option>
<option value="dbl-espresso">Caffe Doppio</option>
<option value="latte">Caffe Latte</option>
<option value="macciato">Machhiato</option>
</select>
</div>
<div>
<label>Shots</label>
<!--
The visually hidden "shots" radio buttons are disabled and would not normally be submitted with the form.
Clicking the following button will visually show and enable these buttons, resulting in a form state change
(and hence the form is considered dirty) without the values having changed.
-->
<button id="example-5-extra-shots">I want extra shots</button>
<div id="example-5-shots-options" style="display: none;">
<input type="radio" name="shots" value="1" disabled /> 1 Shot - Standard<br />
<input type="radio" name="shots" value="2" disabled /> 2 Shots - Morning wakeup!<br />
<input type="radio" name="shots" value="3" disabled /> 3 Shots - Overdrive!<br />
</div>
</div>
<div>
<label>Do you like us?</label>
<input type="hidden" name="like" value="false" id="example-5-like" />
<button id="example-5-like-button">Like</button>
</div>
<div class="buttons">
<input type="submit" value="Save" disabled="disabled">
</div>
<div>
<p>... or visit <a href="http://www.google.com/">Google</a> or close the window without saving!</p>
</div>
</form>
<h2>Example 6: HTML5 inputs!</h2>
<p>
This example shows support for HTML5 input types. It's not a coffee order form,
but you need coffee if you're working with HTML5 :-)
</p>
<form id="example-6-form" name="coffeeOrder6" method="post">
<h2>Doing HTML5? You'll need coffee!</h2>
<div>
<label for="example-6-color">color</label>
<input type="color" name="example-6-color" />
</div>
<div>
<label for="example-6-date">date</label>
<input type="date" name="example-6-date" />
</div>
<div>
<label for="example-6-datetime">datetime</label>
<input type="datetime" name="example-6-datetime" />
</div>
<div>
<label for="example-6-datetime-local">datetime-local</label>
<input type="datetime-local" name="example-6-datetime-local" />
</div>
<div>
<label for="example-6-email">email</label>
<input type="email" name="example-6-email" />
</div>
<div>
<label for="example-6-month">month</label>
<input type="month" name="example-6-month" />
</div>
<div>
<label for="example-6-number">number</label>
<input type="number" name="example-6-number" />
</div>
<div>
<label for="example-6-range">range</label>
<input type="range" name="example-6-range" />
</div>
<div>
<label for="example-6-search">search</label>
<input type="search" name="example-6-search" />
</div>
<div>
<label for="example-6-tel">tel</label>
<input type="tel" name="example-6-tel" />
</div>
<div>
<label for="example-6-time">time</label>
<input type="time" name="example-6-time" />
</div>
<div>
<label for="example-6-url">url</label>
<input type="url" name="example-6-url" />
</div>
<div>
<label for="example-6-week">week</label>
<input type="week" name="example-6-week" />
</div>
<div>
<label for="example-6-select">select/optgroup</label>
<select>
<optgroup label="Beans">
<option value="india">India</option>
<option value="indonesia" selected="selected">Indonesia</option>
<option value="brazil">Brazil</option>
</optgroup>
<optgroup label="Roast">
<option value="l">Light</option>
<option value="m">Medium</option>
<option value="h">Heavy</option>
</optgroup>
</select>
</div>
<div>
<label for="example-6-mselect">multi select</label>
<select multiple>
<option value="arabica">Arabica</option>
<option value="arabica">Peaberry</option>
<option value="malabar " selected="selected">Malabar</option>
<option value="robusta ">Robusta</option>
</select>
</div>
<div style="clear:both;"></div>
<div>
<label for="example-6-plain">plain old field</label>
<input name="example-6-plain" />
</div>
<div class="buttons">
<input type="submit" value="Submit">
<input type="reset" value="Reset">
</div>
<div>
<p>... or visit <a href="http://www.google.com/">Google</a> or close the window without saving!</p>
</div>
</form>
<h2>Example 7: Mark current state as not dirty!</h2>
<p>
This example shows how you can mark the current state as not dirty. Handy for AJAX forms
we're you're managing your own submits.
</p>
<form id="example-7-form" name="coffeeOrder7" method="post">
<h2>Tell us your default coffee</h2>
<div>
<label for="example-7-coffee">Default coffee</label>
<select name="coffee" id="example-7-coffee">
<option value="espresso">Espresso</option>
<option value="dbl-espresso">Caffe Doppio</option>
<option value="latte">Caffe Latte</option>
<option value="macciato">Machhiato</option>
<option value="cappuccino">Cappuccino</option>
</select>
</div>
<div>
<button id="example-7-save-button" disabled="disabled">Save without submit</button>
</div>
<div class="buttons">
<input type="submit" value="Submit">
</div>
<div>
<p>... or visit <a href="http://www.google.com/">Google</a> or close the window without saving!</p>
</div>
</form>
<p>
This jQuery plugin is developed by <a href="https://github.com/codedance">Chris Dance</a>
at <a href="http://www.papercut.com/">PaperCut Software</a> - Are-You-Sure is used in
PaperCut's printing management software and it has been open sourced with help of
Tom, Jack and Matt from PaperCut's dev team.
</p>
</body>
</html>

View File

@ -0,0 +1,192 @@
/*!
* jQuery Plugin: Are-You-Sure (Dirty Form Detection)
* https://github.com/codedance/jquery.AreYouSure/
*
* Copyright (c) 2012-2014, Chris Dance and PaperCut Software http://www.papercut.com/
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Author: chris.dance@papercut.com
* Version: 1.9.0
* Date: 13th August 2014
*/
(function($) {
$.fn.areYouSure = function(options) {
var settings = $.extend(
{
'message' : 'You have unsaved changes!',
'dirtyClass' : 'dirty',
'change' : null,
'silent' : false,
'addRemoveFieldsMarksDirty' : false,
'fieldEvents' : 'change keyup propertychange input',
'fieldSelector': ":input:not(input[type=submit]):not(input[type=button])"
}, options);
var getValue = function($field) {
if ($field.hasClass('ays-ignore')
|| $field.hasClass('aysIgnore')
|| $field.attr('data-ays-ignore')
|| $field.attr('name') === undefined) {
return null;
}
if ($field.is(':disabled')) {
return 'ays-disabled';
}
var val;
var type = $field.attr('type');
if ($field.is('select')) {
type = 'select';
}
switch (type) {
case 'checkbox':
case 'radio':
val = $field.is(':checked');
break;
case 'select':
val = '';
$field.find('option').each(function(o) {
var $option = $(this);
if ($option.is(':selected')) {
val += $option.val();
}
});
break;
default:
val = $field.val();
}
return val;
};
var storeOrigValue = function($field) {
$field.data('ays-orig', getValue($field));
};
var checkForm = function(evt) {
var isFieldDirty = function($field) {
var origValue = $field.data('ays-orig');
if (undefined === origValue) {
return false;
}
return (getValue($field) != origValue);
};
var $form = ($(this).is('form'))
? $(this)
: $(this).parents('form');
// Test on the target first as it's the most likely to be dirty
if (isFieldDirty($(evt.target))) {
setDirtyStatus($form, true);
return;
}
$fields = $form.find(settings.fieldSelector);
if (settings.addRemoveFieldsMarksDirty) {
// Check if field count has changed
var origCount = $form.data("ays-orig-field-count");
if (origCount != $fields.length) {
setDirtyStatus($form, true);
return;
}
}
// Brute force - check each field
var isDirty = false;
$fields.each(function() {
$field = $(this);
if (isFieldDirty($field)) {
isDirty = true;
return false; // break
}
});
setDirtyStatus($form, isDirty);
};
var initForm = function($form) {
var fields = $form.find(settings.fieldSelector);
$(fields).each(function() { storeOrigValue($(this)); });
$(fields).unbind(settings.fieldEvents, checkForm);
$(fields).bind(settings.fieldEvents, checkForm);
$form.data("ays-orig-field-count", $(fields).length);
setDirtyStatus($form, false);
};
var setDirtyStatus = function($form, isDirty) {
var changed = isDirty != $form.hasClass(settings.dirtyClass);
$form.toggleClass(settings.dirtyClass, isDirty);
// Fire change event if required
if (changed) {
if (settings.change) settings.change.call($form, $form);
if (isDirty) $form.trigger('dirty.areYouSure', [$form]);
if (!isDirty) $form.trigger('clean.areYouSure', [$form]);
$form.trigger('change.areYouSure', [$form]);
}
};
var rescan = function() {
var $form = $(this);
var fields = $form.find(settings.fieldSelector);
$(fields).each(function() {
var $field = $(this);
if (!$field.data('ays-orig')) {
storeOrigValue($field);
$field.bind(settings.fieldEvents, checkForm);
}
});
// Check for changes while we're here
$form.trigger('checkform.areYouSure');
};
var reinitialize = function() {
initForm($(this));
}
if (!settings.silent && !window.aysUnloadSet) {
window.aysUnloadSet = true;
$(window).bind('beforeunload', function() {
$dirtyForms = $("form").filter('.' + settings.dirtyClass);
if ($dirtyForms.length == 0) {
return;
}
// Prevent multiple prompts - seen on Chrome and IE
if (navigator.userAgent.toLowerCase().match(/msie|chrome/)) {
if (window.aysHasPrompted) {
return;
}
window.aysHasPrompted = true;
window.setTimeout(function() {window.aysHasPrompted = false;}, 900);
}
return settings.message;
});
}
return this.each(function(elem) {
if (!$(this).is('form')) {
return;
}
var $form = $(this);
$form.submit(function() {
$form.removeClass(settings.dirtyClass);
});
$form.bind('reset', function() { setDirtyStatus($form, false); });
// Add a custom events
$form.bind('rescan.areYouSure', rescan);
$form.bind('reinitialize.areYouSure', reinitialize);
$form.bind('checkform.areYouSure', checkForm);
initForm($form);
});
};
})(jQuery);

View File

@ -0,0 +1,45 @@
{
"name": "jquery.AreYouSure",
"description": "A light-weight jQuery \"dirty forms\" Plugin - it monitors HTML forms and alerts users to unsaved changes if they attempt to close the browser or navigate away from the page. (Are you sure?)",
"homepage": "https://github.com/codedance/jquery.AreYouSure",
"author": "Chris Dance <chris.dance@papercut.com> (https://github.com/codedance)",
"contributors": [
"Tom Clift <tom.clift@papercut.com> (https://github.com/tclift)",
"Jon Egerton <jon@ja2.co.uk> (http://www.jonegerton.com/)",
"Scadoodles (https://github.com/Scadoodles)",
"Albin Sunnanbo (https://github.com/albinsunnanbo)",
"Marc Sutton <ashre@iname.com> (http://www.codev.co.uk)"
],
"version": "1.9.0",
"license": "MIT/GPLv2",
"keywords": [ "dirty", "form", "onbeforeunload", "save", "check" ],
"main": "jquery.are-you-sure.js",
"engines": {
"node": ">=0.8.0"
},
"repository": {
"type": "git",
"url": "https://github.com/codedance/jquery.AreYouSure"
},
"bugs": {
"url": "https://github.com/codedance/jquery.AreYouSure/issues"
},
"dependencies": {
"jquery": ">=1.4.2"
},
"devDependencies": {
"bower": "^1.3.1",
"grunt": "^0.4.5",
"grunt-cli": "^0.1.13",
"grunt-karma": "^0.8.3",
"karma-chrome-launcher": "^0.1.4",
"karma-jasmine": "^0.2.2",
"karma-ie-launcher": "^0.1.5",
"karma-firefox-launcher": "^0.1.3",
"karma-safari-launcher": "^0.1.1"
},
"scripts": {
"postinstall": "node_modules/.bin/bower install",
"test": "node_modules/.bin/grunt test"
}
}

View File

@ -0,0 +1,4 @@
<form>
<input type="text" name="a">
<input type="submit">
</form>

View File

@ -0,0 +1,28 @@
'use strict';
// Karma adds 'base/' to the default path
jasmine.getFixtures().fixturesPath = 'base/spec/javascripts/fixtures';
describe("A form's", function() {
var $form = undefined;
describe('text input', function() {
var $textInput = undefined;
beforeEach(function() {
loadFixtures('input-text.html');
$form = $('form');
$textInput = $('input[type=text]');
$form.areYouSure();
});
it('should cause dirtyness after its value changes', function(done) {
expect($form.hasClass('dirty')).toBe(false);
$textInput.val('new').change();
setTimeout(function() {
expect($form.hasClass('dirty')).toBe(true);
done();
}, 0);
});
});
});

View File

@ -115,11 +115,8 @@ function new_channel_content(&$a) {
'$nick_desc' => t('Your nickname will be used to create an easily remembered channel address (like an email address) which you can share with others.'),
'$label_import' => t('Or <a href="import">import an existing channel</a> from another location'),
'$name' => $name,
'$label_role' => t('Channel Type'),
'$questionmark' => t('?'),
'$what_is_role' => t('What is this?'),
'$help_role' => t('Please choose a channel type (such as social networking or community forum) and privacy requirements so we can select the best permissions for you'),
'$role_select' => role_selector(($privacy_role) ? $privacy_role : 'social'),
'$help_role' => t('Please choose a channel type (such as social networking or community forum) and privacy requirements so we can select the best permissions for you'),
'$role' => array('permissions_role' , t('Channel Type'), ($privacy_role) ? $privacy_role : 'social', '<a href="help/roles" target="_blank">'.t('Read more about roles').'</a>',get_roles()),
'$nickname' => $nickname,
'$submit' => t('Create')
));

View File

@ -596,13 +596,12 @@ function profiles_content(&$a) {
$opt_tpl = get_markup_template("profile_hide_friends.tpl");
$hide_friends = replace_macros($opt_tpl,array(
'$desc' => t('Hide your contact/friend list from viewers of this profile?'),
'$yes_str' => t('Yes'),
'$no_str' => t('No'),
'$yes_selected' => (($r[0]['hide_friends']) ? " checked=\"checked\" " : ""),
'$no_selected' => (($r[0]['hide_friends'] == 0) ? " checked=\"checked\" " : "")
));
$hide_friends = replace_macros($opt_tpl,array('$field' => array(
'hide-friends',
t('Hide your contact/friend list from viewers of this profile?'),
$r[0]['hide_friends'],
'',
)));
$q = q("select * from profdef where true");
if($q) {

View File

@ -122,10 +122,19 @@ function settings_post(&$a) {
if((argc() > 1) && (argv(1) === 'features')) {
check_form_security_token_redirectOnErr('/settings/features', 'settings_features');
foreach($_POST as $k => $v) {
if(strpos($k,'feature_') === 0) {
set_pconfig(local_user(),'feature',substr($k,8),((intval($v)) ? 1 : 0));
}
// Build list of features and check which are set
$features = get_features();
$all_features = array();
foreach($features as $k => $v) {
foreach($v as $f)
$all_features[] = $f[0];
}
foreach($all_features as $k) {
if(x($_POST,"feature_$k"))
set_pconfig(local_user(),'feature',$k, 1);
else
set_pconfig(local_user(),'feature',$k, 0);
}
build_sync_packet();
return;
@ -707,7 +716,6 @@ function settings_content(&$a) {
'$title' => t('Additional Features'),
'$features' => $arr,
'$submit' => t('Submit'),
'$field_yesno' => 'field_yesno.tpl',
));
return $o;
@ -938,7 +946,7 @@ function settings_content(&$a) {
$timezone = date_default_timezone_get();
$opt_tpl = get_markup_template("field_yesno.tpl");
$opt_tpl = get_markup_template("field_checkbox.tpl");
if(get_config('system','publish_all')) {
$profile_in_dir = '<input type="hidden" name="profile_in_directory" value="1" />';
}
@ -1010,12 +1018,10 @@ function settings_content(&$a) {
'$uid' => local_user(),
'$form_security_token' => get_form_security_token("settings"),
'$nickname_block' => $prof_addr,
'$h_basic' => t('Basic Settings'),
'$username' => array('username', t('Full Name:'), $username,''),
'$email' => array('email', t('Email Address:'), $email, ''),
'$timezone' => array('timezone_select' , t('Your Timezone:'), select_timezone($timezone), ''),
'$timezone' => array('timezone_select' , t('Your Timezone:'), $timezone, '', get_timezones()),
'$defloc' => array('defloc', t('Default Post Location:'), $defloc, t('Geographical location to display on your posts')),
'$allowloc' => array('allow_location', t('Use Browser Location:'), ((get_pconfig(local_user(),'system','use_browser_location')) ? 1 : ''), ''),
@ -1044,9 +1050,7 @@ function settings_content(&$a) {
'$aclselect' => populate_acl($perm_defaults,false),
'$suggestme' => $suggestme,
'$group_select' => $group_select,
'$role_lbl' => t('Channel permissions category:'),
'$role_select' => role_selector($permissions_role),
'$role' => array('permissions_role' , t('Channel permissions category:'), $permissions_role, '', get_roles()),
'$profile_in_dir' => $profile_in_dir,
'$hide_friends' => $hide_friends,

View File

@ -349,7 +349,7 @@ function setup_content(&$a) {
'$siteurl' => array('siteurl', t('Website URL'), z_root(), t('Please use SSL (https) URL if available.')),
'$timezone' => field_timezone('timezone', t('Please select a default timezone for your website'), $timezone, ''),
'$timezone' => array('timezone', t('Please select a default timezone for your website'), $timezone, '', get_timezones()),
'$baseurl' => $a->get_baseurl(),

View File

@ -79,3 +79,7 @@ nav .navbar-toggle {
code {
white-space: normal;
}
/* Bootstrap assumes that checkboxes are on the left of labels, while it's usually the opposite in Red */
.field.checkbox input[type="checkbox"] { margin-left: 0px; }
.field.checkbox label { padding-left: 0px; font-weight: 700}

View File

@ -6,6 +6,8 @@
margin-top: 25px;
}
#sellpage-edit label{
/* first-of-type needed to style switches */
#sellpage-edit label.mainlabel,
#sellpage-edit label:first-of-type {
width: 300px;
}
}

View File

@ -3,7 +3,9 @@
margin-top: 30px;
}
#group-edit-form label {
/* first-of-type needed to style switches */
#group-edit-form label.mainlabel,
#group-edit-form label:first-of-type {
float: left;
width: 300px;
}

View File

@ -28,7 +28,9 @@ ul#settings-privacy-macros {
margin-bottom: 10px;
}
#settings-permissions-wrapper .field label{
/* first-of-type needed to be able to style switches */
#settings-permissions-wrapper .field label.mainlabel,
#settings-permissions-wrapper .field label:first-of-type {
width: 350px;
}
@ -41,7 +43,9 @@ ul#settings-privacy-macros {
margin-bottom: 45px;
}
#settings-notifications label {
/* first-of-type needed to be able to style switches */
#settings-notifications .field label.mainlabel,
#settings-notifications .field label:first-of-type {
margin-left: 20px;
width: 330px;
}
@ -63,4 +67,4 @@ ul#settings-privacy-macros {
#settings-channel-menu-end {
clear: both;
margin-bottom: 15px;
}
}

View File

@ -4,8 +4,9 @@
margin-left: 0;
}
.thing-label, .field label, .thing-verb-label, .thing-profile-label{
/* first-of-type needed to style switches */
.field label.mainlabel,
.thing-label, .field label:first-of-type, .thing-verb-label, .thing-profile-label{
float: left;
width: 350px;
}
@ -18,4 +19,4 @@
.thing-field-end {
clear: both;
}
}

3
view/js/mod_admin.js Normal file
View File

@ -0,0 +1,3 @@
$(document).ready(function() {
$('form').areYouSure(); // Warn user about unsaved settings
});

View File

@ -1,5 +1,5 @@
$(document).ready(function() {
// $("#privacy-role-select").sSelect();
// $("#id_permissions_role").sSelect();
$("#newchannel-name").blur(function() {
$("#name-spinner").spin('small');
var zreg_name = $("#newchannel-name").val();

3
view/js/mod_profiles.js Normal file
View File

@ -0,0 +1,3 @@
$(document).ready(function() {
$('form').areYouSure(); // Warn user about unsaved settings
});

View File

@ -2,14 +2,15 @@
var ispublic = aStr['everybody'] ;
$(document).ready(function() {
$('form').areYouSure(); // Warn user about unsaved settings
$("a#settings-default-perms-menu").colorbox({
'inline' : true,
'transition' : 'elastic'
});
$("#privacy-role-select").change(function() {
var role = $("#privacy-role-select").val();
$("#id_permissions_role").change(function() {
var role = $("#id_permissions_role").val();
if(role == 'custom')
$('#advanced-perm').show();
else

View File

@ -44,6 +44,7 @@ head_add_js('docready.js');
head_add_js('library/colorbox/jquery.colorbox-min.js');
head_add_js('library/bootstrap-tagsinput/bootstrap-tagsinput.js');
head_add_js('library/jquery.AreYouSure/jquery.are-you-sure.js');
/**
* Those who require this feature will know what to do with it.
* Those who don't, won't.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -301,14 +301,14 @@ footer {
#main-login #id_remember {
float: left;
padding: 0;
margin-top: 15px;
margin-bottom: 0;
margin-left: 0;
width: 20px;
}
#main-login .field.checkbox label {
margin-top: 15px;
/* first-of-type needed to style switches */
#main-login .field.checkbox label.mainlabel,
#main-login .field.checkbox label:first-of-type {
margin-bottom: 0;
float: left;
width: 100px;
@ -373,13 +373,16 @@ footer {
font-weight: bold;
}
#profile-edit-wrapper .field label {
#profile-edit-wrapper .field {
margin-top: 20px;
}
/* first-of-type needed to style switches */
#profile-edit-wrapper .field label.mainlabel,
#profile-edit-wrapper .field label:first-of-type {
width: 175px;
}
#profile-edit-wrapper .field input[type="text"] {
margin-top: 20px;
width: 220px;
}
@ -1242,7 +1245,9 @@ footer {
width: 100%
}
.field label {
/* first-of-type needed to style switches */
.field label.mainlabel,
.field label:first-of-type {
float: left;
width: 350px;
}
@ -1296,6 +1301,8 @@ footer {
.hidden { display: none!important; }
.field.radio .field_help { margin-left: 0px; }
.field.checkbox .field_help { display: inline; margin-left: 10px; }
/**
* OAuth
@ -2350,3 +2357,70 @@ aside .nav > li > a:hover, aside .nav > li > a:focus {
.jothidden .bootstrap-tagsinput:hover, .jothidden .bootstrap-tagsinput:focus {
border: 1px solid #cccccc;
}
/* Hide the placeholder label which is used for styling switches */
/* Many places give a width to all labels, so need to specifically set these to 0 width */
/* This should probably be moved to core */
.field.checkbox label.switchlabel,
.field.checkbox label:nth-of-type(2) {
width: 0px;
margin: 0px;
float: none;
}
/* Turn checkboxes into switches */
/* Doesn't work with IE<9. */
.field.checkbox input {
position: absolute;
margin-left: -9999px;
visibility: hidden;
}
.field.checkbox input + label.switchlabel,
.field.checkbox input + label:nth-of-type(2) {
display: block;
position: relative;
cursor: pointer;
outline: none;
user-select: none;
padding: 2px;
width: 60px;
height: 24px;
background-color: #dddddd;
border-radius: 60px;
transition: background 0.4s;
float:left;
}
.field.checkbox input + label:before,
.field.checkbox input + label:after {
display: block;
position: absolute;
content: "";
}
.field.checkbox input + label:before {
top: 2px;
left: 2px;
bottom: 2px;
right: 2px;
background-color: #fff;
border-radius: 30px;
transition: background 0.4s;
}
.field.checkbox input + label:after {
top: 4px;
left: 4px;
bottom: 4px;
width: 30px;
background-color: #dddddd;
border-radius: 30px;
transition: margin 0.4s, background 0.4s;
}
.field.checkbox input:checked + label {
background-color: #8ce196;
}
.field.checkbox input:checked + label:after {
margin-left: 22px;
background-color: #8ce196;
}

View File

@ -24,6 +24,11 @@
eventClick: function(calEvent, jsEvent, view) {
showEvent(calEvent.id);
},
loading: function(isLoading, view) {
if(!isLoading) {
$('td.fc-day').dblclick(function() { window.location.href='https://caterva.eu/events/new?start='+$(this).data('date'); });
}
},
eventRender: function(event, element, view) {
//console.log(view.name);

View File

@ -1,6 +1,6 @@
<tr>
<td>
<label for='id_{{$field.0}}'>{{$field.1}}</label>
<label class="mainlabel" for='id_{{$field.0}}'>{{$field.1}}</label>
</td>
<td class="abook-them">
<input type="checkbox" name='them_{{$field.0}}' id='them_id_{{$field.0}}' value="1" disabled="disabled" {{if $field.2}}checked="checked"{{/if}} />

View File

@ -1,5 +1,4 @@
<div class='field checkbox'>
<label for='id_{{$field.0}}'>{{$field.1}}</label>
<input type="checkbox" name='{{$field.0}}' id='id_{{$field.0}}' value="1" {{if $field.2}}checked="checked"{{/if}}>
<span class='field_help'>{{$field.3}}</span>
<label class="mainlabel" for='id_{{$field.0}}'>{{$field.1}}</label>
<input type="checkbox" name='{{$field.0}}' id='id_{{$field.0}}' value="1" {{if $field.2}}checked="checked"{{/if}}><label class="switchlabel" for='id_{{$field.0}}'></label><span class='field_help'>{{$field.3}}</span>
</div>

View File

@ -1,5 +1,5 @@
<div class='field input color'>
<label for='id_{{$field.0}}' id='label_{{$field.0}}'>{{$field.1}}</label>
<label class="mainlabel" for='id_{{$field.0}}' id='label_{{$field.0}}'>{{$field.1}}</label>
<input class='color' name='{{$field.0}}' id='id_{{$field.0}}' type="text" value="{{$field.2}}">{{if $field.4}} <span class="required">{{$field.4}}</span> {{/if}}
<span id='help_{{$field.0}}' class='field_help'>{{$field.3}}</span>
<div id='end_{{$field.0}}' class='field_end'></div>

View File

@ -1,5 +1,5 @@
<div class='field combobox'>
<label for='id_{{$field.0}}' id='id_{{$field.0}}_label'>{{$field.1}}</label>
<label class="mainlabel" for='id_{{$field.0}}' id='id_{{$field.0}}_label'>{{$field.1}}</label>
{{* html5 don't work on Chrome, Safari and IE9 see https://github.com/thgreasi/datalist-polyfill
<input id="id_{{$field.0}}" type="text" list="data_{{$field.0}}" >
<datalist id="data_{{$field.0}}" >

View File

@ -1,5 +1,5 @@
<div class='field custom'>
<label for='{{$field.0}}'>{{$field.1}}</label>
<label class="mainlabel" for='{{$field.0}}'>{{$field.1}}</label>
{{$field.2}}
<span class='field_help'>{{$field.3}}</span>
</div>

View File

@ -1,5 +1,5 @@
<div class='field input'>
<label for='id_{{$field.0}}' id='label_{{$field.0}}'>{{$field.1}}</label>
<label class="mainlabel" for='id_{{$field.0}}' id='label_{{$field.0}}'>{{$field.1}}</label>
<input name='{{$field.0}}' id='id_{{$field.0}}' type="text" value="{{$field.2}}">{{if $field.4}} <span class="required">{{$field.4}}</span> {{/if}}
<span id='help_{{$field.0}}' class='field_help'>{{$field.3}}</span>
<div id='end_{{$field.0}}' class='field_end'></div>

View File

@ -1,5 +1,4 @@
<div class='field checkbox'>
<label for='id_{{$field.0}}'>{{$field.1}}</label>
<input type="checkbox" name='{{$field.0}}' id='id_{{$field.0}}' value="{{$field.3}}" {{if $field.2}}checked="true"{{/if}}>
<span class='field_help'>{{$field.4}}</span>
<label class="mainlabel" for='id_{{$field.0}}'>{{$field.1}}</label>
<input type="checkbox" name='{{$field.0}}' id='id_{{$field.0}}' value="{{$field.3}}" {{if $field.2}}checked="true"{{/if}}><label class="switchlabel" for='id_{{$field.0}}'></label><span class='field_help'>{{$field.4}}</span>
</div>

View File

@ -1,5 +1,5 @@
<div class='field password'>
<label for='id_{{$field.0}}'>{{$field.1}}</label>
<label class="mainlabel" for='id_{{$field.0}}'>{{$field.1}}</label>
<input type='password' name='{{$field.0}}' id='id_{{$field.0}}' value="{{$field.2}}">
<span class='field_help'>{{$field.3}}</span>
</div>

View File

@ -1,5 +1,5 @@
<div class='field radio'>
<label for='id_{{$field.0}}_{{$field.2}}'>{{$field.1}}</label>
<label class="mainlabel" for='id_{{$field.0}}_{{$field.2}}'>{{$field.1}}</label>
<input type="radio" name='{{$field.0}}' id='id_{{$field.0}}_{{$field.2}}' value="{{$field.2}}" {{if $field.4}}checked="true"{{/if}}>
<span class='field_help'>{{$field.3}}</span>
</div>

View File

@ -1,5 +1,5 @@
<div class='field richtext'>
<label for='id_{{$field.0}}'>{{$field.1}}</label>
<label class="mainlabel" for='id_{{$field.0}}'>{{$field.1}}</label>
<textarea name='{{$field.0}}' id='id_{{$field.0}}' class="fieldRichtext">{{$field.2}}</textarea>
<span class='field_help'>{{$field.3}}</span>
</div>

View File

@ -1,5 +1,5 @@
<div class='field select'>
<label for='id_{{$field.0}}'>{{$field.1}}</label>
<label class="mainlabel" for='id_{{$field.0}}'>{{$field.1}}</label>
<select name='{{$field.0}}' id='id_{{$field.0}}'>
{{foreach $field.4 as $opt=>$val}}<option value="{{$opt}}" {{if $opt==$field.2}}selected="selected"{{/if}}>{{$val}}</option>{{/foreach}}
</select>

View File

@ -1,5 +1,5 @@
<div class='field select'>
<label style="font-weight: normal;" for='id_{{$field.0}}'>{{$field.1}}</label>
<label class="mainlabel" style="font-weight: normal;" for='id_{{$field.0}}'>{{$field.1}}</label>
<select disabled="true" name='{{$field.0}}' id='id_{{$field.0}}'>
{{foreach $field.4 as $opt=>$val}}<option value="{{$opt}}" {{if $opt==$field.2}}selected="selected"{{/if}}>{{$val}}</option>{{/foreach}}
</select>

View File

@ -0,0 +1,12 @@
<div class='field select'>
<label for='id_{{$field.0}}'>{{$field.1}}</label>
<select name='{{$field.0}}' id='id_{{$field.0}}'>
{{foreach $field.4 as $group=>$opts}}
<optgroup label='{{$group}}'>
{{foreach $opts as $opt=>$val}}
<option value="{{$opt}}" {{if $opt==$field.2}}selected="selected"{{/if}}>{{$val}}</option>{{/foreach}}
{{/foreach}}
</optgroup>
</select>
<span class='field_help'>{{$field.3}}</span>
</div>

View File

@ -1,5 +1,5 @@
<div class='field select'>
<label for='id_{{$field.0}}'>{{$field.1}}</label>
<label class="mainlabel" for='id_{{$field.0}}'>{{$field.1}}</label>
<select name='{{$field.0}}' id='id_{{$field.0}}'>
{{$field.4}}
</select>

View File

@ -1,5 +1,5 @@
<div class='field textarea'>
<label for='id_{{$field.0}}'>{{$field.1}}</label>
<label class="mainlabel" for='id_{{$field.0}}'>{{$field.1}}</label>
<textarea name='{{$field.0}}' id='id_{{$field.0}}' {{if $field.4}}{{$field.4}}{{/if}} >{{$field.2}}</textarea>
<span class='field_help'>{{$field.3}}</span>
</div>

View File

@ -1,6 +1,6 @@
<script>$(document).ready(function(){ previewTheme($("#id_{{$field.0}}")[0]); });</script>
<div class='field select'>
<label for='id_{{$field.0}}'>{{$field.1}}</label>
<label class="mainlabel" for='id_{{$field.0}}'>{{$field.1}}</label>
<select name='{{$field.0}}' id='id_{{$field.0}}' {{if $field.5=='preview'}}onchange="previewTheme(this);"{{/if}} >
{{foreach $field.4 as $opt=>$val}}<option value="{{$opt}}" {{if $opt==$field.2}}selected="selected"{{/if}}>{{$val}}</option>{{/foreach}}
</select>

View File

@ -1,5 +1,5 @@
<div class='field yesno'>
<label for='id_{{$field.0}}'>{{$field.1}}</label>
<label class="mainlabel" for='id_{{$field.0}}'>{{$field.1}}</label>
<div class='onoff' id="id_{{$field.0}}_onoff">
<input type="hidden" name='{{$field.0}}' id='id_{{$field.0}}' value="{{$field.2}}">
<a href="#" class='off'>

View File

@ -20,7 +20,7 @@
{{include file="field_input.tpl" field=$adminmail}}
{{include file="field_input.tpl" field=$siteurl}}
{{$timezone}}
{{include file="field_select_grouped.tpl" field=$timezone}}
<input id="install-submit" type="submit" name="submit" value="{{$submit}}" />

View File

@ -5,10 +5,7 @@
<div id="newchannel-desc" class="descriptive-paragraph">{{$desc}}</div>
<div id="newchannel-role-help" class="descriptive-paragraph">{{$help_role}}</div>
<label for="newchannel-role" id="label-newchannel-role" class="newchannel-label" >{{$label_role}}</label>
{{$role_select}}
<div class="newchannel-role-morehelp"><a href="help/roles" title="{{$what_is_role}}" target="_blank">{{$questionmark}}</a></div>
{{include file="field_select_grouped.tpl" field=$role}}
<div id="newchannel-role-end" class="newchannel-field-end"></div>

View File

@ -1,3 +1,6 @@
{{include file="field_checkbox.tpl"}}
{{*
<p id="hide-friends-text">
{{$desc}}
</p>
@ -14,4 +17,4 @@
<div id="hide-friends-end"></div>
</div>
*}}

View File

@ -0,0 +1,11 @@
{{* TODO: Make id configurabel *}}
<select id='timezone_select' name='timezone'>
{{foreach $continents as $continent => $cities}}
<optgroup label="{{$continent}}">
{{foreach $cities as $city => $value}}
<option value='{{$value}}' {{if $value == $selected}}selected='selected'{{/if}}>{{$city}}</option>
{{/foreach}}
</optgroup>
{{/foreach}}
</select>

View File

@ -9,7 +9,7 @@
<h3 class="settings-heading">{{$h_basic}}</h3>
{{include file="field_input.tpl" field=$username}}
{{include file="field_custom.tpl" field=$timezone}}
{{include file="field_select_grouped.tpl" field=$timezone}}
{{include file="field_input.tpl" field=$defloc}}
{{include file="field_checkbox.tpl" field=$allowloc}}
@ -22,10 +22,7 @@
<h3 class="settings-heading">{{$h_prv}}</h3>
<div class="field custom">
<label for="privacy-role-select">{{$role_lbl}}</label>
{{$role_select}}
</div>
{{include file="field_select_grouped.tpl" field=$role}}
<div id="advanced-perm" style="display:{{if $permissions_set}}none{{else}}block{{/if}};">
{{include file="field_checkbox.tpl" field=$hide_presence}}
@ -62,7 +59,7 @@
{{$suggestme}}
{{include file="field_yesno.tpl" field=$blocktags}}
{{include file="field_checkbox.tpl" field=$blocktags}}
{{include file="field_input.tpl" field=$expire}}

View File

@ -9,7 +9,7 @@
<h3 class="settings-heading">{{$f.0}}</h3>
{{foreach $f.1 as $fcat}}
{{include file="{{$field_yesno}}" field=$fcat}}
{{include file="field_checkbox.tpl" field=$fcat}}
{{/foreach}}
{{/foreach}}