diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..75a223a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +.git +.gitignore +node_modules +README.md +CHANGELOG.md +CONTRIBUTING.md +LICENSE diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..f6adc4a --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,16 @@ +# Description + +## How to reproduce + +It helps a lot if you can create a working example from this template: +https://codepen.io/pen?template=pBxBXm + +## Expected result + +## Actual result + +# Environment + +jQuery version: +Browser: +OS: diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..66c8160 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1 @@ +Please make sure to target the "experimental" branch! diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..71a0efe --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +api diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..6bd009c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,181 @@ +# Changelog + +## 2.0.21 + +* Fix tooltip getting overwritten (#241) +* Update dev dependencies + +## 2.0.20 + +* Update dev dependencies + +## 2.0.19 + +* Fix warnings from jquery-migrate (#230) by Shaun Case +* Upgrade dependencies + +## 2.0.18 + +* Upgrade dependencies +* Formatting fix (remove tabs) +* Add FUNDING.yml +* Fix changelog (#218) + +## 2.0.17 + +* Upgrade jquery to 3.5.0 because of vulnerability in previous versions + +## 2.0.16 + +* Get text instead of html in callback result (#214) +* Enable shift+enter to submit form (#216) + +## 2.0.15 + +* Remove deprecated .blur() calls and replace them with .on() (#211) + +## 2.0.14 + +* Remove deprecated jQuery functions and replace them by modern counterparts (#211) + +## 2.0.13 + +* Accept list of tuples as items for select element (#208 by @emjayko) + +## 2.0.12 + +* Wrap the plugins in functions for non-conflict mode (#205) + +## 2.0.11 + +* Use text() instead of html() for revert (#203) + +## 2.0.10 + +* Regenerate the minified files + +## 2.0.9 + +* Allow resubmiting if onsubmit or submit returns false (#201 by @RobdeT) + +## 2.0.8 + +* Update dependencies to fix security vulnerabilities (CVE-2019-11358, and in js-yaml) + +## 2.0.7 + +* Change isSubmitting back to false onComplete (#192) +* Width/height now correctly taken into account for masked inputs (#189) +* Pass event object to the before callback (#188) + +## 2.0.6 + +* Fix cancel when ESC is pressed (#177) by @thezoggy +* Fix "main" entry of package.json (#181) + +## 2.0.5 + +* Sorting of select items is now an option (default is not sorted). by @nathanvda (#178) + +## 2.0.3 + +* Add ability to apply css to input element (#173) + +## 2.0.2 + +* Fix a bug where selected value will get added to the select options. by @eman1986 (#166) + +## 2.0.1 + +* Fix width setting to number, url and email (#163) + +## 2.0.0 + +* BREAKING: remove ajaxupload and old datepicker plugins (new datepicker added) +* BREAKING: change the autogrow plugin for another one +* Add datepicker plugin for jQuery-UI's datepicker +* Add form param to onblur apply (#37) +* Allow onblur function to cancel form if it returns false (#14) +* Properly cleanup after destroy. by @Scottmitch (#125) +* Return submitdata if it's a function. by @mkdgs (#109) +* Add onedit example + doc. by @chriskeeble (#122) +* Stop event propagation for charcounter. by @twashing (#86) +* Add multiselect support. by @nicholasryan (#75) +* Add html5 text attributes, email, number and url types. by @nfreear (#87) +* Add maxlength to textarea too. by @estebistec (#68) +* Add option to style buttons and add id to form. by @quocvu (#71) +* Add intercept option useful for preprocessing data. by @randell (#66) +* Pass the source event to the onedit hook. by @gfouquet (#104) +* Return element to target function (#67) +* Add 'before' option. by @bp323 (#113) +* Fix issue with html encodable characters (#110) +* Add checkbox type. by @oneslash and @pushpinderbagga (#52) +* Correctly check if checkbox is checked +* Select options are now sorted by value. by @jjwdesign (#97) +* Add submitdata to callback. by @mikemeier (#64) +* Adjust the width of the element to account for border/margin/padding +* Fix loadtext not showing (#15) +* Pass a response callback function to custom target function. by bshelton229. (#65) +* Add showfn for jquery animations before displaying form (#46) +* Remove extra loop. by @dgm (#45) +* Better demo page showing more example +* Add proper API documentation +* Add usage documentation in README.md +* Add Dockerfile to serve the demos +* Add LICENSE file + +## 1.8.0 + +* A lot of cleanup in the repo after years of abandon +* The demos folder now contains a page (index.html) with all the demo code +* Removed Textile stuff +* Removed SQLite from the demo +* Add support for configuring size and maxlength. by @bonkowski (#32) +* Set "cache" to false on loadurl. Fix issue with IE8. by @spikex (#33) +* Add package.json for npm hosting +* Remove eval to allow compilation with Closure & Fix for newer jQuery. by @flavour (#158) +* Fix issue with width/height (#137) +* Fix issue with selected in select element (#106) +* Add label settings. by @tomasm- (#40) + +## 1.7.3 + +* Add support for "jQuery plugin repository": http://plugins.jquery.com/ + +## 1.7.2 + +* Submit on change if input type select and no submit button defined ("gregpyp":http://github.com/gregpyp) + +## 1.7.1 + +* Namespace default event as click.editable ("Zangetsu":http://github.com/Zangetsu) +* Trim whitespace when determining the selected value of pulldown ("binarylogic":http://github.com/binarylogic) +* Make default settings publicly available ("lawrencepit":http://github.com/lawrencepit) +* Allow ajax calls other than 'html', e.g. json and script calls. ("lawrencepit":http://github.com/lawrencepit) +* Do not follow links if they are editable ("Darwin":http://github.com/darwin) +* make JSLInt happy ("olleolleolle":http://github.com/olleolleolle) + +## 1.7.0 + +* Full control over jQuery AJAX options for those who want to tinker. +* Fix problem with IE and placeholder with HTML tags. +* Add $.editable('disable'), $.editable('enable') and $.editable('destroy') +* Add onedit, onsubmit, onreset and onerror hooks. +* Allow passing select options as JavaScript object. +* Fix IE throwing error with textareas when width or height was set to 'none'. + +## 1.6.2 + +* Fix problems when xhtml is served application/xhtml+xml. + +## 1.6.1 + +* Submit method can now be POST (default) or PUT. +* Fix form being submitted twice in some cases. + +## 1.6.0 + +* Onblur parameter can now be a function. +* Support for any arbitrary event for triggering Jeditable +* Submitting of form will be canceled if submit() method of custom input returns false. +* Custom inputs now have access to reset() method. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..b392950 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,15 @@ +# Notes to contributors + +* Target the 'experimental' branch +* Use 4 spaces for indent +* Use UNIX-style line ending +* Use UTF-8 without BOM +* Use a javascript linter +* Use single quotes for strings + +# Generate the API doc + +~~~bash +npm -g install documentation +documentation build src -f html -o api +~~~ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7d5a0ee --- /dev/null +++ b/Dockerfile @@ -0,0 +1,35 @@ +# serve the demo page of jquery-jeditable +# https://github.com/NicolasCARPi/jquery_jeditable + +# use apache + php +FROM php:8.0-apache + +# select version or branch here +ENV JEDITABLE_VERSION master + +LABEL org.label-schema.name="jquery-jeditable demo" \ + org.label-schema.description="Run Apache and php to serve jquery-jeditable demo page" \ + org.label-schema.url="https://jeditable.elabftw.net" \ + org.label-schema.vcs-url="https://github.com/NicolasCARPi/jquery_jeditable" \ + org.label-schema.version=$JEDITABLE_VERSION\ + org.label-schema.maintainer="nicolas.carpi@curie.fr" \ + org.label-schema.schema-version="1.0" + +# install npm +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get -y --no-install-recommends install gnupg \ + && curl -sL https://deb.nodesource.com/setup_14.x | bash - \ + && apt-get install -y nodejs \ + && npm install -g documentation \ + && rm -rf /var/lib/apt/lists/* \ + && a2enmod headers + +COPY . /var/www/html +RUN ln -s /var/www/html/src /var/www/html/demos/src +COPY ./apache/000-default.conf /etc/apache2/sites-enabled/000-default.conf +COPY ./apache/php.ini /usr/local/etc/php/php.ini + +# generate api doc +WORKDIR /var/www/html +RUN documentation build src -f html -o demos/api +EXPOSE 80 diff --git a/FUNDING.yml b/FUNDING.yml new file mode 100644 index 0000000..7c1a358 --- /dev/null +++ b/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms +liberapay: NicolasCARPi +github: NicolasCARPi diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..e739f7b --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,32 @@ +/** + * Gruntfile.js + * + * Run 'grunt' in shell to minify javascript + * + */ +module.exports = function(grunt) { + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + uglify: { + options: { + banner: '/*! <%= pkg.name %> <%= pkg.homepage %> */\n', + mangle: false + }, + dist: { + files: { + 'dist/jquery.jeditable.min.js': 'src/jquery.jeditable.js', + 'dist/jquery.jeditable.autogrow.min.js': 'src/jquery.jeditable.autogrow.js', + 'dist/jquery.jeditable.charcounter.min.js': 'src/jquery.jeditable.charcounter.js', + 'dist/jquery.jeditable.datepicker.min.js': 'src/jquery.jeditable.datepicker.js', + 'dist/jquery.jeditable.masked.min.js': 'src/jquery.jeditable.masked.js', + 'dist/jquery.jeditable.time.min.js': 'src/jquery.jeditable.time.js', + } + } + } + }); + + grunt.loadNpmTasks('grunt-contrib-uglify-es'); + grunt.registerTask('default', 'uglify'); + +}; diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..86111c6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +Copyright 2006 Mika Tuupola, Dylan Verheul, Nicolas CARPi + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile deleted file mode 100644 index eca7f22..0000000 --- a/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -VERSION = 1.7.1 -SHELL = /bin/sh -DOWNLOAD = /var/www/www.appelsiini.net/htdocs/download -JSPACKER = /home/tuupola/bin/jspacker -JSMIN = /home/tuupola/bin/jsmin - -#all: jeditable packed minified latest wysiwyg -all: jeditable minified latest wysiwyg - -jeditable: jquery.jeditable.js - cp jquery.jeditable.js $(DOWNLOAD)/jquery.jeditable-$(VERSION).js - -packed: jquery.jeditable.js - $(JSPACKER) < jquery.jeditable.js > jquery.jeditable.pack.js - cp jquery.jeditable.pack.js $(DOWNLOAD)/jquery.jeditable-$(VERSION).pack.js - -minified: jquery.jeditable.js - $(JSMIN) < jquery.jeditable.js > jquery.jeditable.mini.js - cp jquery.jeditable.mini.js $(DOWNLOAD)/jquery.jeditable-$(VERSION).mini.js - -latest: jquery.jeditable.js jquery.jeditable.pack.js - cp jquery.jeditable.js $(DOWNLOAD)/jquery.jeditable.js - cp jquery.jeditable.ajaxupload.js $(DOWNLOAD)/jquery.jeditable.ajaxupload.js - cp jquery.jeditable.autogrow.js $(DOWNLOAD)/jquery.jeditable.autogrow.js -# cp jquery.jeditable.datepicker.js $(DOWNLOAD)/jquery.jeditable.datepicker.js - cp jquery.jeditable.masked.js $(DOWNLOAD)/jquery.jeditable.masked.js -# cp jquery.jeditable.tageditor.js $(DOWNLOAD)/jquery.jeditable.tageditor.js - cp jquery.jeditable.time.js $(DOWNLOAD)/jquery.jeditable.time.js - cp jquery.jeditable.timepicker.js $(DOWNLOAD)/jquery.jeditable.timepicker.js - cp jquery.jeditable.charcounter.js $(DOWNLOAD)/jquery.jeditable.charcounter.js -# cp jquery.jeditable.pack.js $(DOWNLOAD)/jquery.jeditable.pack.js - cp jquery.jeditable.mini.js $(DOWNLOAD)/jquery.jeditable.mini.js - - -.PHONY: wysiwyg -wysiwyg: - cp wysiwyg/jquery.jeditable.wysiwyg.js $(DOWNLOAD)/jquery.jeditable.wysiwyg.js - -tests: jquery.jeditable.js - rm examples/lib/jquery.jeditable.js - cp jquery.jeditable.js examples/lib/ - -tarball: examples/index.html - rm examples/lib/jquery.jeditable.js - cp jquery.jeditable.js examples/lib/ - /usr/local/bin/tar -X ignore.txt -czvf jEditable_examples-$(VERSION).tar.gz examples/* - cp jEditable_examples-$(VERSION).tar.gz $(DOWNLOAD) diff --git a/README.md b/README.md new file mode 100644 index 0000000..fb7279d --- /dev/null +++ b/README.md @@ -0,0 +1,251 @@ +# jquery-jeditable + +[![npm](https://img.shields.io/npm/v/jquery-jeditable.svg)](https://www.npmjs.com/package/jquery-jeditable) +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/0cb32ce695b743d68257021455330c66)](https://www.codacy.com/app/elabftw/jquery_jeditable) +[![GitHub license](https://img.shields.io/github/license/NicolasCARPi/jquery_jeditable.svg)](https://github.com/NicolasCARPi/jquery_jeditable/blob/master/LICENSE) + +# DEPRECATION NOTICE + +**This project is deprecated** and should not be used in a fresh project. Have a look at [Malle](https://github.com/deltablot/malle/) library instead. It is more or less the same, but in typescript and without a jQuery dependency. + +## Alternative library + +Use [Malle](https://github.com/deltablot/malle/). + + +## Description + +Edit in place plugin for [jQuery](https://jquery.com/) (compatible with jQuery v3.4.0+). + +Bind it to an element on the page, and when clicked the element will become a form that will be sent by asynchronous (ajax) POST request to an URL. + +[![demo](https://i.imgur.com/lEmY8l0.gif)](https://jeditable.elabftw.net) + +Works with text inputs, textarea, select, datepicker, and more… Comes with a ton of different options you can use to do exactly what you want! + +## Live demo + +See it in action: [LIVE DEMO](https://jeditable.elabftw.net/) + +## Installation + +~~~bash +npm install jquery-jeditable +~~~ + +## Usage + +### Loading the library + +Use a ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -

You might also want to check default inputs demo. - -

- - -

Autogrow textarea

-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.

-

Depends on - Autogrow - by Chrys Bader.

- -
- -
-

Ajax File Upload

-

-

- Fileupload which uses Ajax File Upload plugin. - For security reasons after uploading this demo only display file size and name. -
-
-
-

-
- - -
- -

Masked Input

-

-

Depends on - Masked Input by Josh Bush. -

- -
-
- -

Time Picker

-

-

- Depends on Timepicker - by Jason Huck. -

- -
-
- -

Time Picker 2

-

-

- Similar as previous but without dependenices. See how to create inputs tutorial. -

- -
- -
- -

Character counter

-

-

- Using character counter. -

- -
- - - - - - - - - - - - - diff --git a/custom_autocomplete.html b/custom_autocomplete.html deleted file mode 100644 index f31bec1..0000000 --- a/custom_autocomplete.html +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - -Jeditable Custom Input Types Demo - - - - - - - - - - - - - - - - - - - -
- -
- -
- -

Autocomplete

-

-

- Using autocomplete plugin. -

- -
- - - - - - - - - - - - - diff --git a/default.html b/default.html deleted file mode 100644 index 4df2b91..0000000 --- a/default.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - -Jeditable Edit In Place Demo - - - - - - - - - - - - -
- -
- -
- -

You might also want to check custom inputs demo. - -

Normal textarea

- -

- -

Inlined select

-

dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutp

- -

Textile renderer

-
- -

Different events

-

- Click me if you dare! or maybe you should - doubleclick instead? Really lazy people can just - mouseover me... -

- -
- - - - - - - - - diff --git a/demos/css/main.css b/demos/css/main.css new file mode 100644 index 0000000..260cb5a --- /dev/null +++ b/demos/css/main.css @@ -0,0 +1,62 @@ +body { + text-align: center; + font-size: 120%; + background-color: #eee; +} + +.jumbotron { + background-color: #fff; +} + +.card-title { + font-weight: bold; +} + +.card { + border: 1px solid #ccc; + border-radius: 5px; + margin: 5px; +} + +.example { + border: 1px solid #ccc; + border-radius: 5px; + padding: 10px; + background-color: #fff; +} + +.custom-class input, button { + margin-right: 10px; +} + +.custom-class input { + padding: 8px; + border: 1px solid #ccc; + border-radius: 5px; +} + +.trigger:hover { + cursor: pointer; +} + +.editable input[type=submit] { + color: #F00; + font-weight: bold; +} +.editable input[type=button] { + color: #0F0; + font-weight: bold; +} + +.inline { + display: inline; +} + +h4 { + text-align: left; +} + +/* for the full example */ +label { + margin-right: 5px; +} diff --git a/demos/css/prism.css b/demos/css/prism.css new file mode 100644 index 0000000..a5d440d --- /dev/null +++ b/demos/css/prism.css @@ -0,0 +1,140 @@ +/* PrismJS 1.11.0 +http://prismjs.com/download.html?themes=prism&languages=clike+javascript */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + background: none; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol, +.token.deleted { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #a67f59; + background: hsla(0, 0%, 100%, .5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function { + color: #DD4A68; +} + +.token.regex, +.token.important, +.token.variable { + color: #e90; +} + +.token.important, +.token.bold { + font-weight: bold; +} +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} + diff --git a/demos/img/spinner.svg b/demos/img/spinner.svg new file mode 100644 index 0000000..614a1a6 --- /dev/null +++ b/demos/img/spinner.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/demos/index.html b/demos/index.html new file mode 100644 index 0000000..1f8cc92 --- /dev/null +++ b/demos/index.html @@ -0,0 +1,476 @@ + + + + + + + + + + + jQuery-jeditable Demos + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+

jQuery-jeditable

+

Edit in place plugin for jQuery

+

This is a demo page, have a look at the source to see how each example is implemented!

+

GitHub repository

+

Documentation

+

API Documentation

+
+ +

Core features

+
<!-- include this in your HTML -->
+<script src=/path/to/jquery.jeditable.min.js></script>
+
+ +
+ + +
+
+

Basic minimal example

+
The most basic example (press enter to validate). No options.
+

Click this text to edit it.

+

Show source code

+
+
$(".editable-text").editable("save.php");
+
+
+
+ + +
+
+

Complete example

+
A more complete example with a bunch of options.
+

Click this text to edit it.

+

Show source code

+
+
/* data that will be sent along */
+var submitdata = {}
+/* this will make the save.php script take a long time so you can see the spinner ;) */
+submitdata['slow'] = true;
+submitdata['pwet'] = 'youpla';
+
+$(".editable-text-full").editable("save.php", {
+    indicator : "<img src='img/spinner.svg' />",
+    type : "text",
+    // only limit to three letters example
+    //pattern: "[A-Za-z]{3}",
+    onedit : function() { console.log('If I return false edition will be canceled'); return true;},
+    before : function() { console.log('Triggered before form appears')},
+    callback : function(result, settings, submitdata) {
+        console.log('Triggered after submit');
+        console.log('Result: ' + result);
+        console.log('Settings.width: ' + settings.width);
+        console.log('Submitdata: ' + submitdata.pwet);
+    },
+    cancel : 'Cancel',
+    cssclass : 'custom-class',
+    cancelcssclass : 'btn btn-danger',
+    submitcssclass : 'btn btn-success',
+    maxlength : 200,
+    // select all text
+    select : true,
+    label : 'This is a label',
+    onreset : function() { console.log('Triggered before reset') },
+    onsubmit : function() { console.log('Triggered before submit') },
+    showfn : function(elem) { elem.fadeIn('slow') },
+    submit : 'Save',
+    submitdata : submitdata,
+    /* submitdata as a function example
+    submitdata : function(revert, settings, submitdata) {
+        console.log("Revert text: " + revert);
+        console.log(settings);
+        console.log("User submitted text: " + submitdata.value);
+    },
+    */
+    tooltip : "Click to edit...",
+    width : 160
+});
+
+/* target as a function example
+$(".editable-text-full").editable(function(input, settings, elem) {
+    console.log(input);
+    console.log(settings);
+    console.log($(elem).data('test'));
+}, {});
+*/
+
+
+
+
+ + +
+
+

Normal textarea

+
Example of the 'textarea' type.
+

If you click anywhere on this text, it will become a textarea that you can edit. And then you can click OK to save it.

+
+

Show source code

+
+
$(".editable_textarea").editable("save.php", {
+    type   : 'textarea',
+    submit : 'OK',
+    cancel : 'Nope'
+});
+
+
+
+ + +
+
+

Select

+
Example of the 'select' type.
+
+

THIS IS A SELECT, click it to get a select menu. Options are from the "data" setting.

+

THIS IS A SELECT WITH JSON FEED, click it to get a select menu. Options are loaded from an ajax request getting JSON.

+

THIS IS A MULTIPLE SELECT.You can select several values (try holding Shift or Ctrl).

+
+
+

Show source code

+
+
// inline select
+$(".editable-select").editable("save.php", {
+    type   : "select",
+    // this data will be sorted by value
+    data   : '{"Wiki":"Wiki","Banana":"Banana","Apple":"Apple", "Pear":"Pear", "selected":"Pear"}',
+    submitdata : function() { return {id : 42, something: 'else'};},
+    style  : "inherit",
+});
+// with JSON feed
+$(".editable-select-json").editable("save.php", {
+    type   : "select",
+    loadurl : "json.php",
+    submit : "OK",
+    style  : "inherit"
+});
+// MULTIPLE SELECT
+$(".multiple-select").editable("save.php", {
+    type : "select",
+    data   : '{"Wiki":"Wiki","Banana":"Banana","Apple":"Apple", "Pear":"Pear"}',
+    submit: 'OK',
+    multiple : true,
+    onblur: function() { return true; },
+    // use intercept to display the results as we want it
+    intercept: function(result, status) {
+        return "You selected: " + result + ". ";
+    },
+    onerror: function(settings, self, xhr) {
+        console.log("Error with status code: " + xhr.status);
+    },
+    submitdata : function(revert, settings, result) {
+        console.log("User selected values: " + result.value);
+    },
+});
+
+
+
+ +
+ +
+ + +
+
+

Different events

+
By default a click will trigger an edit. But you can bind other events as shown below.
+

+ Click me if you dare! or maybe you should + doubleclick instead? Really lazy people can just + mouseover me... +

+

Show source code

+
+
// click
+$(".click").editable("save.php", {
+    tooltip   : "Click to edit...",
+    style  : "inherit"
+});
+
+// double click
+$(".dblclick").editable("save.php", {
+    tooltip   : "Doubleclick to edit...",
+    event     : "dblclick",
+    style  : "inherit"
+});
+
+// mouseover
+$(".mouseover").editable("save.php", {
+    tooltip   : "Move mouseover to edit...",
+    event     : "mouseover",
+    style  : "inherit"
+});
+
+
+
+
+ + +
+
+

Intercepting the data sent back

+

Useful if you want to process the returned data before it hits the page.

+

Click here to test the intercept option.

+

Show source code

+
+
$(".intercept").editable("json2.php", {
+    submit : 'OK',
+    intercept : function(jsondata) {
+        json = JSON.parse(jsondata);
+        console.log(json.status);
+        console.log(json.other);
+        return json.result;
+    },
+});
+
+
+
+
+ + + +
+
+

E-mail, numbers, URL

+

You can restrict input to emails, numbers or urls

+ +

-2.06

+

https://www.example.com

+

Show source code

+
+
// EMAIL
+$(".email").editable("save.php", {
+    type: "email",
+    tooltip: "Enter a valid email address",
+    placeholder: "nico.tesla@example.com",
+});
+// NUMBER
+$(".number").editable("save.php", {
+    type: "number",
+    tooltip: "Click to edit: number",
+    placeholder: "0",
+    min: 0,
+    max: 10,
+    step: 1
+});
+// URL
+$(".url").editable("save.php", {
+    type: "url",
+    tooltip: "Enter a valid URL",
+    placeholder: "https://www.example.com"
+});
+
+
+
+
+ + + +
+
+

Styling the buttons

+

If you want to use different css class for the submit and cancel button. Also show how to add an ID to the form.

+

Click here to show the buttons

+

Show source code

+
+
$(".css-buttons").editable("save.php", {
+    submit : 'OK',
+    cancel : 'Cancel',
+    cssclass : 'custom-class',
+    cancelcssclass : 'btn btn-danger',
+    submitcssclass : 'btn btn-success',
+    formid : 'abc-123'
+});
+
+
+
+
+ + +
+
+

Checkbox

+

Click here to test checkbox input

+

Show source code

+
+
$(".checkbox").editable("save.php", {
+    type      : "checkbox",
+    submit : 'ok'
+});
+
+
+
+
+ +

Features requiring plugins

+ + +
+
+

Date Picker (requires jQuery-ui datepicker)

+
<!-- also include this in your HTML -->
+<script src=/path/to/jquery.jeditable.datepicker.min.js></script>
+<!-- also include jQuery-UI JS and CSS files -->
+
+

16-09-2018

+

Show source code

+
+
$(".datepicker").editable("save.php", {
+    type      : 'datepicker',
+    submit : 'OK',
+    datepicker : {
+        format: "dd-mm-yy"
+    },
+    tooltip   : "Click to edit..."
+});
+
+
+
+
+ + +
+
+

Autogrow textarea

+
<!-- also include this in your HTML -->
+<script src=/path/to/jquery.jeditable.autogrow.min.js></script>
+<script src=/path/to/jquery.autogrowtextarea.js></script>
+
+

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.

+

Depends on Autogrow-Textarea by Jevin O. Sewaruth.

+

Show source code

+
+
$(".autogrow").editable("save.php", {
+    type      : "autogrow",
+    submit    : 'OK',
+    cancel    : 'cancel',
+    tooltip   : "Click to edit...",
+    onblur    : "ignore"
+});
+
+
+
+
+ +
+ +
+ + +
+
+

Masked Input

+
<!-- also include this in your HTML -->
+<script src=/path/to/jquery.jeditable.masked.min.js></script>
+<script src=/path/to/jquery.maskedinput.js></script>
+
+

19/12/2017

+

Depends on + Masked Input by Josh Bush. +

+

Show source code

+
+
$(".masked").editable("save.php", {
+    type      : "masked",
+    mask      : "99/99/9999",
+    submit    : 'OK',
+    tooltip   : "Click to edit..."
+});
+
+
+
+
+ + + +
+
+

Time Picker

+
<!-- also include this in your HTML -->
+<script src=/path/to/jquery.jeditable.time.min.js></script>
+
+

16:30

+

Show source code

+
+
$(".timepicker").editable("save.php", {
+    type      : 'time',
+    submit    : 'OK',
+    tooltip   : "Click to edit..."
+});
+
+
+
+
+ + +
+
+

Character counter

+
<!-- also include this in your HTML -->
+<script src=/path/to/jquery.jeditable.charcounter.min.js></script>
+<script src=/path/to/jquery.charcounter.js></script>
+
+

The number of characters in the textarea will be counted.

+

Show source code

+
+
$(".charcounter").editable("save.php", {
+    type      : "charcounter",
+    submit    : 'OK',
+    tooltip   : "Click to edit...",
+    onblur    : "ignore",
+    charcounter : {
+        characters : 60
+    }
+});
+
+
+
+
+ +
+
+ + + diff --git a/demos/index.js b/demos/index.js new file mode 100644 index 0000000..5fa6e6d --- /dev/null +++ b/demos/index.js @@ -0,0 +1,244 @@ +$(document).ready(function() { + // make all examples reachable with Tab key for accessibility + $(".example").editableAriaShim(); + + // hide all source code + $('.source').hide(); + // to toggle the source + $('.trigger').click(function() { + var sourceDiv = $(this).next('.source'); + + if (sourceDiv.is(':visible')) { + $(this).html(" Show source code"); + } else { + $(this).html(" Hide source code"); + } + + sourceDiv.toggle(); + }); + + // BASIC MINIMAL EXAMPLE + $(".editable-text").editable("save.php"); + + // FULL EXAMPLE WITH PLENTY OF OPTIONS + // custom submitted data fields + var submitdata = {}; + submitdata['slow'] = true; + submitdata['pwet'] = 'youpla'; + + $(".editable-text-full").editable("save.php", { + indicator : "", + type : "text", + // only limit to three letters example + //pattern: "[A-Za-z]{3}", + onedit : function() { console.log('If I return false edition will be canceled'); return true;}, + before : function() { console.log('Triggered before form appears');}, + callback : function(result, settings, submitdata) { + console.log('Callback function: triggered after submit'); + console.log('Result: ' + result); + console.log('Settings.width: ' + settings.width); + console.log('Submitdata: ' + submitdata.pwet); + }, + cancel : 'Cancel', + cssclass : 'custom-class', + cancelcssclass : 'btn btn-danger', + // select all text + select : true, + submitcssclass : 'btn btn-success', + maxlength : 200, + onerror: function(settings, self, xhr) { + console.log("Error with status code: " + xhr.status); + // reset the form + self.reset(); + }, + label : 'This is a label', + onreset : function() { console.log('Triggered before reset') }, + onblur : function() { console.log('Triggered on blur event');return true; }, + onsubmit : function() { console.log('Triggered before submit') }, + showfn : function(elem) { elem.fadeIn('slow') }, + submit : 'Save', + submitdata : submitdata, + /* submitdata as a function example + submitdata : function(revert, settings, submitdata) { + console.log("Revert text: " + revert); + console.log(settings); + console.log("User submitted text: " + submitdata.value); + }, + */ + tooltip : "Click to edit...", + width : 160 + }); + + + // NORMAL TEXTAREA + $(".editable_textarea").editable("save.php", { + type : 'textarea', + submit : 'OK', + cancelcssclass : 'btn btn-danger', + submitcssclass : 'btn btn-success', + cancel : 'Nope', + width: 300 + }); + + // INLINE SELECT + $(".editable-select").editable("save.php", { + type : "select", + sortselectoptions: true, + // custom class for the select element + inputcssclass: 'some-class', + // do nothing onBlur + onblur: 'ignore', + data : '{"Wiki":"Wiki","Banana":"Banana","Apple":"Apple", "Pear":"Pear", "selected":"Pear"}', + submitdata : function() { return {id : 42, something: 'else'};}, + style : "inherit" + }); + // INLINE SELECT WITH JSON + $(".editable-select-json").editable("save.php", { + type : "select", + loadurl : "json.php", + loadtext : "Fetching JSON…", + submit : "OK", + style : "inherit" + }); + // MULTIPLE SELECT + $(".multiple-select").editable("save.php", { + type : "select", + data : '{"Wiki":"Wiki","Banana":"Banana","Apple":"Apple", "Pear":"Pear"}', + submit: 'OK', + multiple : true, + onblur: function() { return true; }, + // use intercept to display the results as we want it + intercept: function(result, status) { + return "You selected: " + result + ". "; + }, + onerror: function(settings, self, xhr) { + console.log("Error with status code: " + xhr.status); + }, + submitdata : function(revert, settings, result) { + console.log("User selected values: " + result.value); + }, + }); + + // DIFFERENT EVENTS + // click + $(".click").editable("save.php", { + tooltip : "Click to edit...", + style : "inherit" + }); + + // double click + $(".dblclick").editable("save.php", { + tooltip : "Doubleclick to edit...", + event : "dblclick", + style : "inherit" + }); + + // mouseover + $(".mouseover").editable("save.php", { + tooltip : "Move mouseover to edit...", + event : "mouseover", + style : "inherit" + }); + + // INTERCEPT + // GET BACK JSON AND PROCESS IT BEFORE DISPLAY + $(".intercept").editable("json2.php", { + submit : 'OK', + intercept : function(jsondata) { + json = JSON.parse(jsondata); + console.log(json.status); + console.log(json.other); + return json.result; + }, + }); + + // EMAIL + $(".email").editable("save.php", { + type: "email", + tooltip: "Enter a valid email address", + placeholder: "nico.tesla@example.com", + }); + // NUMBER + $(".number").editable("save.php", { + type: "number", + tooltip: "Click to edit: number", + placeholder: "0", + min: 0, + max: 10, + step: 1 + }); + // URL + $(".url").editable("save.php", { + type: "url", + tooltip: "Enter a valid URL", + placeholder: "https://www.example.com" + }); + + + // CSS BUTTONS + $(".css-buttons").editable("save.php", { + submit : 'OK', + cancel : 'Cancel', + cssclass : 'custom-class', + cancelcssclass : 'btn btn-danger', + submitcssclass : 'btn btn-success', + formid : 'abc-123' + }); + + // CHECKBOX + $(".checkbox").editable("save.php", { + type : "checkbox", + submit : 'ok' + }); + + // CHAR COUNTER + $(".charcounter").editable("save.php", { + type : "charcounter", + submit : 'OK', + tooltip : "Click to edit...", + onblur : "ignore", + charcounter : { + characters : 60 + } + }); + + // MASKED INPUT + $(".masked").editable("save.php", { + type : "masked", + mask : "99/99/9999", + submit : 'OK', + tooltip : "Click to edit..." + }); + + // AUTOGROW + $(".autogrow").editable("save.php", { + type : "autogrow", + submit : 'OK', + cancel : 'cancel', + tooltip : "Click to edit...", + onblur : "ignore" + }); + // DATEPICKER + $(".datepicker").editable("save.php", { + type : 'datepicker', + datepicker : { + format: "dd-mm-yy" + }, + submit : 'OK', + tooltip : "Click to edit..." + }); + // TIME + $(".timepicker").editable("save.php", { + type : 'time', + submit : 'OK', + tooltip : "Click to edit..." + }); + + // Non existing element should not cause error + $("#nosuch").editable("save.php", { + type : 'textarea', + submit : 'OK' + }); + +}); + diff --git a/demos/js/jquery.autogrowtextarea.js b/demos/js/jquery.autogrowtextarea.js new file mode 100644 index 0000000..58d2d52 --- /dev/null +++ b/demos/js/jquery.autogrowtextarea.js @@ -0,0 +1,89 @@ +/*! + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Jevin O. Sewaruth + * ---------------------------------------------------------------------------- + * + * Autogrow Textarea Plugin Version v3.0 + * http://www.technoreply.com/autogrow-textarea-plugin-3-0 + * + * THIS PLUGIN IS DELIVERD ON A PAY WHAT YOU WANT BASIS. IF THE PLUGIN WAS USEFUL TO YOU, PLEASE CONSIDER BUYING THE PLUGIN HERE : + * https://sites.fastspring.com/technoreply/instant/autogrowtextareaplugin + * + * Date: October 15, 2012 + */ + +jQuery.fn.autoGrow = function(options) { + return this.each(function() { + var settings = jQuery.extend({ + extraLine: true, + }, options); + + var mirror; + + var createMirror = function(textarea) { + jQuery(textarea).after('
'); + return jQuery(textarea).next('.autogrow-textarea-mirror')[0]; + }; + + var sendContentToMirror = function (textarea) { + mirror.innerHTML = String(textarea.value) + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(/'/g, ''') + .replace(//g, '>') + .replace(/\n/g, '
') + + (settings.extraLine? '.
.' : '') + ; + + if (jQuery(textarea).height() !== jQuery(mirror).height()) + jQuery(textarea).height(jQuery(mirror).height()); + }; + + var growTextarea = function() { + sendContentToMirror(this); + }; + + // Create a mirror + mirror = createMirror(this); + + // Style the mirror + mirror.style.display = 'none'; + mirror.style.wordWrap = 'break-word'; + mirror.style.whiteSpace = 'pre-wrap'; + mirror.style.padding = jQuery(this).css('paddingTop') + ' ' + + jQuery(this).css('paddingRight') + ' ' + + jQuery(this).css('paddingBottom') + ' ' + + jQuery(this).css('paddingLeft'); + + mirror.style.borderStyle = jQuery(this).css('borderTopStyle') + ' ' + + jQuery(this).css('borderRightStyle') + ' ' + + jQuery(this).css('borderBottomStyle') + ' ' + + jQuery(this).css('borderLeftStyle'); + + mirror.style.borderWidth = jQuery(this).css('borderTopWidth') + ' ' + + jQuery(this).css('borderRightWidth') + ' ' + + jQuery(this).css('borderBottomWidth') + ' ' + + jQuery(this).css('borderLeftWidth'); + mirror.style.width = jQuery(this).css('width'); + mirror.style.fontFamily = jQuery(this).css('font-family'); + mirror.style.fontSize = jQuery(this).css('font-size'); + mirror.style.lineHeight = jQuery(this).css('line-height'); + mirror.style.letterSpacing = jQuery(this).css('letter-spacing'); + + // Style the textarea + this.style.overflow = 'hidden'; + this.style.minHeight = this.rows+'em'; + + // Bind the textarea's event + this.onkeyup = growTextarea; + this.onfocus = growTextarea; + + // Fire the event for text already present + sendContentToMirror(this); + + }); +}; diff --git a/demos/js/jquery.charcounter.js b/demos/js/jquery.charcounter.js new file mode 100644 index 0000000..d558fdf --- /dev/null +++ b/demos/js/jquery.charcounter.js @@ -0,0 +1,79 @@ +/** + * + * @file Charcounter project: attaches a character counter to each textarea element in the jQuery object + * @copyright © 2007 Tom Deater (http://www.tomdeater.com) + * @licence MIT + * @example Charcounter example: + * $("#myTextArea").charCounter(max, settings); + * + */ +(function($) { + $.fn.charCounter = function (max, settings) { + max = max || 100; + settings = $.extend({ + container: '', + classname: 'charcounter', + format: '(%1 characters remaining)', + pulse: true, + delay: 0 + }, settings); + + var p, timeout; + + function pulse(el, again) { + if (p) { + window.clearTimeout(p); + p = null; + } + el.animate({ opacity: 0.1 }, 100, function () { + $(this).animate({ opacity: 1.0 }, 100); + }); + if (again) { + p = window.setTimeout(function () { pulse(el); }, 200); + } + } + + function count(el, container) { + el = $(el); + if (el.val().length > max) { + el.val(el.val().substring(0, max)); + if (settings.pulse && !p) { + pulse(container, true); + } + } + if (settings.delay > 0) { + if (timeout) { + window.clearTimeout(timeout); + } + timeout = window.setTimeout(function () { + container.html(settings.format.replace(/%1/, (max - el.val().length))); + }, settings.delay); + } else { + container.html(settings.format.replace(/%1/, (max - el.val().length))); + } + } + + return this.each(function () { + var container = (!settings.container.match(/^<.+>$/)) ? $(settings.container) : $(settings.container) + .insertAfter(this) + .addClass(settings.classname); + + $(this) + .bind('keydown', function () { count(this, container); }) + .bind('keypress', function () { count(this, container); }) + .bind('keyup', function () { count(this, container); }) + .bind('focus', function () { count(this, container); }) + .bind('mouseover', function () { count(this, container); }) + .bind('mouseout', function () { count(this, container); }) + .bind('paste', function () { + var me = this; + setTimeout(function () { count(me, container); }, 10); + }); + if (this.addEventListener) { + this.addEventListener('input', function () { count(this, container); }, false); + } + count(this, container); + }); + }; + +})(jQuery); diff --git a/demos/js/jquery.maskedinput.js b/demos/js/jquery.maskedinput.js new file mode 100644 index 0000000..992ee2e --- /dev/null +++ b/demos/js/jquery.maskedinput.js @@ -0,0 +1,198 @@ +/* + jQuery Masked Input Plugin + Copyright (c) 2007 - 2015 Josh Bush (digitalbush.com) + Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license) + Version: 1.4.1 +*/ +!function(factory) { + "function" == typeof define && define.amd ? define([ "jquery" ], factory) : factory("object" == typeof exports ? require("jquery") : jQuery); +}(function($) { + var caretTimeoutId, ua = navigator.userAgent, iPhone = /iphone/i.test(ua), chrome = /chrome/i.test(ua), android = /android/i.test(ua); + $.mask = { + definitions: { + "9": "[0-9]", + a: "[A-Za-z]", + "*": "[A-Za-z0-9]" + }, + autoclear: !0, + dataName: "rawMaskFn", + placeholder: "_" + }, $.fn.extend({ + caret: function(begin, end) { + var range; + if (0 !== this.length && !this.is(":hidden")) return "number" == typeof begin ? (end = "number" == typeof end ? end : begin, + this.each(function() { + this.setSelectionRange ? this.setSelectionRange(begin, end) : this.createTextRange && (range = this.createTextRange(), + range.collapse(!0), range.moveEnd("character", end), range.moveStart("character", begin), + range.select()); + })) : (this[0].setSelectionRange ? (begin = this[0].selectionStart, end = this[0].selectionEnd) : document.selection && document.selection.createRange && (range = document.selection.createRange(), + begin = 0 - range.duplicate().moveStart("character", -1e5), end = begin + range.text.length), + { + begin: begin, + end: end + }); + }, + unmask: function() { + return this.trigger("unmask"); + }, + mask: function(mask, settings) { + var input, defs, tests, partialPosition, firstNonMaskPos, lastRequiredNonMaskPos, len, oldVal; + if (!mask && this.length > 0) { + input = $(this[0]); + var fn = input.data($.mask.dataName); + return fn ? fn() : void 0; + } + return settings = $.extend({ + autoclear: $.mask.autoclear, + placeholder: $.mask.placeholder, + completed: null + }, settings), defs = $.mask.definitions, tests = [], partialPosition = len = mask.length, + firstNonMaskPos = null, $.each(mask.split(""), function(i, c) { + "?" == c ? (len--, partialPosition = i) : defs[c] ? (tests.push(new RegExp(defs[c])), + null === firstNonMaskPos && (firstNonMaskPos = tests.length - 1), partialPosition > i && (lastRequiredNonMaskPos = tests.length - 1)) : tests.push(null); + }), this.trigger("unmask").each(function() { + function tryFireCompleted() { + if (settings.completed) { + for (var i = firstNonMaskPos; lastRequiredNonMaskPos >= i; i++) if (tests[i] && buffer[i] === getPlaceholder(i)) return; + settings.completed.call(input); + } + } + function checkVal(allow) { + var i, c, pos, test = input.val(), lastMatch = -1; + for (i = 0, pos = 0; len > i; i++) if (tests[i]) { + for (buffer[i] = getPlaceholder(i); pos++ < test.length; ) if (c = test.charAt(pos - 1), + tests[i].test(c)) { + buffer[i] = c, lastMatch = i; + break; + } + if (pos > test.length) { + clearBuffer(i + 1, len); + break; + } + } else buffer[i] === test.charAt(pos) && pos++, partialPosition > i && (lastMatch = i); + return allow ? writeBuffer() : partialPosition > lastMatch + 1 ? settings.autoclear || buffer.join("") === defaultBuffer ? (input.val() && input.val(""), + clearBuffer(0, len)) : writeBuffer() : (writeBuffer(), input.val(input.val().substring(0, lastMatch + 1))), + partialPosition ? i : firstNonMaskPos; + } + function getPlaceholder(i) { + return settings.placeholder.charAt(i < settings.placeholder.length ? i : 0); + } + function seekNext(pos) { + for (;++pos < len && !tests[pos]; ) ; + return pos; + } + function seekPrev(pos) { + for (;--pos >= 0 && !tests[pos]; ) ; + return pos; + } + function shiftL(begin, end) { + var i, j; + if (!(0 > begin)) { + for (i = begin, j = seekNext(end); len > i; i++) if (tests[i]) { + if (!(len > j && tests[i].test(buffer[j]))) break; + buffer[i] = buffer[j], buffer[j] = getPlaceholder(j), j = seekNext(j); + } + writeBuffer(), input.caret(Math.max(firstNonMaskPos, begin)); + } + } + function shiftR(pos) { + var i, c, j, t; + for (i = pos, c = getPlaceholder(pos); len > i; i++) { + if (tests[i]) { + if (j = seekNext(i), t = buffer[i], buffer[i] = c, !(len > j && tests[j].test(t))) { + break; + } + c = t; + } + } + } + function androidInputEvent() { + var curVal = input.val(), pos = input.caret(); + if (oldVal && oldVal.length && oldVal.length > curVal.length) { + for (checkVal(!0); pos.begin > 0 && !tests[pos.begin - 1];) { + pos.begin--; + } + if (0 === pos.begin) { + for (;pos.begin < firstNonMaskPos && !tests[pos.begin];) { + pos.begin++; + } + } + input.caret(pos.begin, pos.begin); + } else { + for (checkVal(!0); pos.begin < len && !tests[pos.begin];) { + pos.begin++; + } + input.caret(pos.begin, pos.begin); + } + tryFireCompleted(); + } + function blurEvent() { + checkVal(), input.val() != focusText && input.change(); + } + function clearBuffer(start, end) { + var i; + for (i = start; end > i && len > i; i++) { + tests[i] && (buffer[i] = getPlaceholder(i)); + } + } + function keydownEvent(e) { + if (!input.prop("readonly")) { + var pos, begin, end, k = e.which || e.keyCode; + oldVal = input.val(), 8 === k || 46 === k || iPhone && 127 === k ? (pos = input.caret(), + begin = pos.begin, end = pos.end, end - begin === 0 && (begin = 46 !== k ? seekPrev(begin) : end = seekNext(begin - 1), + end = 46 === k ? seekNext(end) : end), clearBuffer(begin, end), shiftL(begin, end - 1), + e.preventDefault()) : 13 === k ? blurEvent.call(this, e) : 27 === k && (input.val(focusText), + input.caret(0, checkVal()), e.preventDefault()); + } + } + function keypressEvent(e) { + if (!input.prop("readonly")) { + var p, c, next, k = e.which || e.keyCode, pos = input.caret(); + if (!(e.ctrlKey || e.altKey || e.metaKey || 32 > k) && k && 13 !== k) { + if (pos.end - pos.begin !== 0 && (clearBuffer(pos.begin, pos.end), shiftL(pos.begin, pos.end - 1)), + p = seekNext(pos.begin - 1), len > p && (c = String.fromCharCode(k), tests[p].test(c))) { + if (shiftR(p), buffer[p] = c, writeBuffer(), next = seekNext(p), android) { + var proxy = function() { + $.proxy($.fn.caret, input, next)(); + }; + setTimeout(proxy, 0); + } else input.caret(next); + pos.begin <= lastRequiredNonMaskPos && tryFireCompleted(); + } + e.preventDefault(); + } + } + } + function writeBuffer() { + input.val(buffer.join("")); + } + + + var input = $(this), buffer = $.map(mask.split(""), function(c, i) { + return "?" != c ? defs[c] ? getPlaceholder(i) : c : void 0; + }), defaultBuffer = buffer.join(""), focusText = input.val(); + input.data($.mask.dataName, function() { + return $.map(buffer, function(c, i) { + return tests[i] && c != getPlaceholder(i) ? c : null; + }).join(""); + }), input.one("unmask", function() { + input.off(".mask").removeData($.mask.dataName); + }).on("focus.mask", function() { + if (!input.prop("readonly")) { + clearTimeout(caretTimeoutId); + var pos; + focusText = input.val(), pos = checkVal(), caretTimeoutId = setTimeout(function() { + input.get(0) === document.activeElement && (writeBuffer(), pos == mask.replace("?", "").length ? input.caret(0, pos) : input.caret(pos)); + }, 10); + } + }).on("blur.mask", blurEvent).on("keydown.mask", keydownEvent).on("keypress.mask", keypressEvent).on("input.mask paste.mask", function() { + input.prop("readonly") || setTimeout(function() { + var pos = checkVal(!0); + input.caret(pos), tryFireCompleted(); + }, 0); + }), chrome && android && input.off("input.mask").on("input.mask", androidInputEvent), + checkVal(); + }); + } + }); +}); diff --git a/demos/js/prism.js b/demos/js/prism.js new file mode 100644 index 0000000..d92e921 --- /dev/null +++ b/demos/js/prism.js @@ -0,0 +1,6 @@ +/* PrismJS 1.11.0 +http://prismjs.com/download.html?themes=prism&languages=markup+clike+javascript */ +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(\w+)\b/i,t=0,n=_self.Prism={manual:_self.Prism&&_self.Prism.manual,disableWorkerMessageHandler:_self.Prism&&_self.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof r?new r(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&").replace(/e.length)return;if(!(w instanceof s)){h.lastIndex=0;var _=h.exec(w),P=1;if(!_&&m&&b!=t.length-1){if(h.lastIndex=k,_=h.exec(e),!_)break;for(var A=_.index+(d?_[1].length:0),j=_.index+_[0].length,x=b,O=k,N=t.length;N>x&&(j>O||!t[x].type&&!t[x-1].greedy);++x)O+=t[x].length,A>=O&&(++b,k=O);if(t[b]instanceof s||t[x-1].greedy)continue;P=x-b,w=e.slice(k,O),_.index-=k}if(_){d&&(p=_[1].length);var A=_.index+p,_=_[0].slice(p),j=A+_.length,S=w.slice(0,A),C=w.slice(j),M=[b,P];S&&(++b,k+=S.length,M.push(S));var E=new s(g,f?n.tokenize(_,f):_,y,_,m);if(M.push(E),C&&M.push(C),Array.prototype.splice.apply(t,M),1!=P&&n.matchGrammar(e,t,r,b,k,!0,g),i)break}else if(i)break}}}}},tokenize:function(e,t){var r=[e],a=t.rest;if(a){for(var l in a)t[l]=a[l];delete t.rest}return n.matchGrammar(e,r,t,0,0,!1),r},hooks:{all:{},add:function(e,t){var r=n.hooks.all;r[e]=r[e]||[],r[e].push(t)},run:function(e,t){var r=n.hooks.all[e];if(r&&r.length)for(var a,l=0;a=r[l++];)a(t)}}},r=n.Token=function(e,t,n,r,a){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length,this.greedy=!!a};if(r.stringify=function(e,t,a){if("string"==typeof e)return e;if("Array"===n.util.type(e))return e.map(function(n){return r.stringify(n,t,e)}).join("");var l={type:e.type,content:r.stringify(e.content,t,a),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:a};if(e.alias){var i="Array"===n.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(l.classes,i)}n.hooks.run("wrap",l);var o=Object.keys(l.attributes).map(function(e){return e+'="'+(l.attributes[e]||"").replace(/"/g,""")+'"'}).join(" ");return"<"+l.tag+' class="'+l.classes.join(" ")+'"'+(o?" "+o:"")+">"+l.content+""},!_self.document)return _self.addEventListener?(n.disableWorkerMessageHandler||_self.addEventListener("message",function(e){var t=JSON.parse(e.data),r=t.language,a=t.code,l=t.immediateClose;_self.postMessage(n.highlight(a,n.languages[r],r)),l&&_self.close()},!1),_self.Prism):_self.Prism;var a=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return a&&(n.filename=a.src,n.manual||a.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(n.highlightAll):window.setTimeout(n.highlightAll,16):document.addEventListener("DOMContentLoaded",n.highlightAll))),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); +Prism.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype://i,cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i,inside:{punctuation:[/^=/,{pattern:/(^|[^\\])["']/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup; +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(?:true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/}; +Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|\d*\.?\d+(?:[Ee][+-]?\d+)?|NaN|Infinity)\b/,"function":/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*\()/i,operator:/-[-=]?|\+[+=]?|!=?=?|<>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^\/])\/(?!\/)(\[[^\]\r\n]+]|\\.|[^\/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0},"function-variable":{pattern:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)|[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/i,alias:"function"}}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,greedy:!0,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/()[\s\S]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.javascript,alias:"language-javascript",greedy:!0}}),Prism.languages.js=Prism.languages.javascript; diff --git a/php/json.php b/demos/json.php similarity index 58% rename from php/json.php rename to demos/json.php index e5cca77..95381c0 100644 --- a/php/json.php +++ b/demos/json.php @@ -1,9 +1,9 @@ ");return settings.rows?textarea.attr("rows",settings.rows):textarea.height(settings.height),settings.cols?textarea.attr("cols",settings.cols):textarea.width(settings.width),$(this).append(textarea),textarea},plugin:function(settings,original){$("textarea",this).autoGrow()}})}(jQuery); \ No newline at end of file diff --git a/dist/jquery.jeditable.charcounter.min.js b/dist/jquery.jeditable.charcounter.min.js new file mode 100644 index 0000000..e74d8f5 --- /dev/null +++ b/dist/jquery.jeditable.charcounter.min.js @@ -0,0 +1,3 @@ +/*! jquery-jeditable https://github.com/NicolasCARPi/jquery_jeditable#readme */ + +"use strict";!function($){$.editable.addInputType("charcounter",{element:function(settings,original){var textarea=$("");return settings.rows?textarea.attr("rows",settings.rows):"none"!==settings.height&&textarea.height(settings.height),settings.cols?textarea.attr("cols",settings.cols):"none"!==settings.width&&textarea.width(settings.width),settings.maxlength&&textarea.attr("maxlength",settings.maxlength),$(this).append(textarea),textarea}},select:{element:function(settings,original){var select=$("").attr({maxlength:settings.maxlength,placeholder:settings.placeholder,min:settings.min,max:settings.max,step:settings.step,tooltip:settings.tooltip,type:_supportInType("number")});return"none"!==settings.width&&input.css("width",settings.width),$(this).append(input),input}},email:{element:function(settings,original){var input=$("").attr({maxlength:settings.maxlength,placeholder:settings.placeholder,tooltip:settings.tooltip,type:_supportInType("email")});return"none"!==settings.width&&input.css("width",settings.width),$(this).append(input),input}},url:{element:function(settings,original){var input=$("").attr({maxlength:settings.maxlength,pattern:settings.pattern,placeholder:settings.placeholder,tooltip:settings.tooltip,type:_supportInType("url")});return"none"!==settings.width&&input.css("width",settings.width),$(this).append(input),input}}},addInputType:function(name,input){$.editable.types[name]=input}},$.fn.editable.defaults={name:"value",id:"id",type:"text",width:"auto",height:"auto",event:"click.editable keydown.editable",onblur:"cancel",tooltip:"Click to edit",loadtype:"GET",loadtext:"Loading...",placeholder:"Click to edit",sortselectoptions:!1,loaddata:{},submitdata:{},ajaxoptions:{}}}(jQuery); \ No newline at end of file diff --git a/dist/jquery.jeditable.time.min.js b/dist/jquery.jeditable.time.min.js new file mode 100644 index 0000000..e9bc406 --- /dev/null +++ b/dist/jquery.jeditable.time.min.js @@ -0,0 +1,3 @@ +/*! jquery-jeditable https://github.com/NicolasCARPi/jquery_jeditable#readme */ + +"use strict";!function($){$.editable.addInputType("time",{element:function(settings,original){for(var option,hourselect=$(''),hour=0;hour<=23;hour++)hour<10&&(hour="0"+hour),option=$("