Test jQuery: jeditable is best
This commit is contained in:
parent
63b3cf65ec
commit
46eacb1b1a
@ -1,479 +0,0 @@
|
||||
2010-05-23 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
split out the callback tests from main test file
|
||||
|
||||
2010-05-23 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
figured out how to have two more tests be in the generic suite
|
||||
|
||||
2010-05-23 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
started splitting the testsuite into multiple files and also started breaking down the tests for the different editor types into their own describe blocks that share behaviour with more generic blocks
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
starte splitting test suite into multiple files for more clarity. First stage involves pushing out setup into 'shared setup' and referencing that with should_behave_like in each testsuite. Works fine so far. :)
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
more todos
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
started experimenting with jquery 1.4 - it all seems to work quite fine, apart from a few testsuite fixes because hasClass has become stricter in jquery 1.4
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
applied patch from superami to allow the callback to handle the dom reset itself. Thanks again!
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
documented that input sizing via css is preferred
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
applied patch from superami to add input size support
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
more thoughts on the future...
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
better documentation
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
no longer accidentally committing in textareas when entering a newline
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
deprecated preinit and postclose callbacks as better alternatives are now implemented
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added missing semicolons
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added some documentation on the callbacks
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
changed openEditor to return the :input field directly to shorten testcode
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added should- will- and did- open / close callbacks to the inplace editor
|
||||
|
||||
2010-05-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
what I'm up to changes...
|
||||
|
||||
2010-05-20 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
renamed back to release notes, thats what they really are
|
||||
|
||||
2010-05-14 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
renamed release notes to backwards compatibility notes as I won't be writing real release notes for now
|
||||
|
||||
2010-05-14 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
switched default behaviour of editor to use .text() to extract values from dom. Use use_html:true to switch this behaviour
|
||||
|
||||
2010-05-14 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
should really use JSpect context to bring in my helpers
|
||||
|
||||
2010-05-14 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
updated version for next release
|
||||
|
||||
2010-05-14 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
changed deprecation marker to denote the version something was deprecated for easier removal and extended it to the documentation too
|
||||
|
||||
2010-05-14 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
worked on todos and on designing the callback interface
|
||||
|
||||
2010-05-14 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
updated changelog before release
|
||||
|
||||
2010-05-14 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
markdowned the documentation and moved more of it out of the source file so the source code is shorter and it is clearer where to find what information
|
||||
|
||||
2010-05-13 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added some documentation and moved a test to a more logical location
|
||||
|
||||
2010-05-13 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
updated changelog before release
|
||||
|
||||
2010-05-13 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
simplified test suite by introducing edit openEditor and enableEditor helpers that set some default default settings
|
||||
|
||||
2010-05-13 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
reworked all callbacks to receive the editor dom node as their this argument
|
||||
|
||||
2010-05-13 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
moved documentation into RELEASE NOTES and TODO files
|
||||
|
||||
2010-05-13 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
updated changelog before release
|
||||
|
||||
2010-05-13 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
the editor will now throw if you provide neither a callback or a url parameter to it. This lead to quite some fallout in the testsuite as it still enabled lots of editors with neither option...
|
||||
|
||||
2010-05-13 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
updated to jspec 4.3.1
|
||||
|
||||
2010-05-13 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
updated documentation to be easier to grasp and more in line to what the documentation of the homepage has been
|
||||
|
||||
2010-05-11 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
updated version to something more sane for the next release
|
||||
|
||||
2010-05-11 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
more documentation fixes and some generall small cleanup
|
||||
|
||||
2010-05-11 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
small enhancements to documentation but mostly removed and reordered TODOs and REFACTs
|
||||
|
||||
2010-05-11 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
improved documentation with an overview of how the inline editor works
|
||||
|
||||
2010-05-11 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
fixed missing var statements
|
||||
|
||||
2010-05-11 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
applied patch from robert that adds a cancel option like in jquery-ui to not open the editor when the click event happened on a cancel event
|
||||
|
||||
2010-05-10 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added missing documentation
|
||||
|
||||
2010-05-10 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
enhanced callback protocol, added postclose and now checking the returnvalue of preinit. If it returns false, the editor is not opened
|
||||
|
||||
2010-05-07 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
fixed postclose callback to always be called after the editor has restored the new value either from the server or from the callback
|
||||
|
||||
2010-05-07 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added postclose callback to do cleanup work after the editor has closed
|
||||
|
||||
2010-05-07 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added preinit callback to the options
|
||||
|
||||
2010-05-06 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added test and fix that return commits in all browsers
|
||||
|
||||
2010-05-04 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
removed stray debugger statement
|
||||
|
||||
2010-04-27 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
fixed test in firefox (background-color was not returned as part of background and transparent was used as the default background color for p elements (instead of inherit as we expected)) and added another fix for firefox to send blur events to other open editors.
|
||||
|
||||
2010-04-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added documentation on how to use the callback interface for the callback submit
|
||||
|
||||
2010-04-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added tests to verify that the animation color can be specified by a parameter
|
||||
|
||||
2010-04-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added jquery ui
|
||||
|
||||
2010-04-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added saving animation support
|
||||
|
||||
2010-04-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
fixed failuresOnly by not overwriting this.options in the tests and some small cleanups
|
||||
|
||||
2010-04-21 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added a callback interface to submit to callback that allows the editor to know when the callback is done saving it's values
|
||||
|
||||
2010-04-21 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added field type to tests that where applied to text, textarea and select fields
|
||||
|
||||
2010-04-21 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added todos
|
||||
|
||||
2010-04-21 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
updated to 4.2.1 of jspec
|
||||
|
||||
2010-03-28 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
updated jspec to 4.1.0
|
||||
|
||||
2010-03-28 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added testcase to ensure all commits include the params optional parameter
|
||||
|
||||
2010-03-25 mhaecker
|
||||
|
||||
setting correct mime types for the demo files
|
||||
|
||||
2010-03-23 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
updated changelog before release
|
||||
|
||||
2010-03-23 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
removed todos from release script
|
||||
|
||||
2010-03-23 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
updated release script to say what it does and tagg and push the release
|
||||
|
||||
2010-03-23 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added changelog updating to the release script
|
||||
|
||||
2010-03-23 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
ignoring script file that stores my username and password, so I don't accidentally commit it. :)
|
||||
|
||||
2010-03-23 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added scripts to automate releasing to google code
|
||||
|
||||
2010-03-23 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
ignoring build directory
|
||||
|
||||
2010-03-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
fixed select support to not submit the default choice accidentally
|
||||
|
||||
2010-03-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
experimental changes to get rhino to work (still a total failure though)
|
||||
|
||||
2010-03-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
reworked demo to go all through the callback function so no server side functionality is required for the demo
|
||||
|
||||
2010-03-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
bugfix for testfailure resulting from jspec 3.3.3's strictire matching comparison
|
||||
|
||||
2010-03-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
updated jspec to 3.3.3
|
||||
|
||||
2010-03-22 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
tried to activate failures only mode
|
||||
|
||||
2010-03-18 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
cleanup and comments
|
||||
|
||||
2010-03-05 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
fixed bug where changing the text of an inline editor that put its own default text in the editor after it was created would lead to it loosing that value on click
|
||||
|
||||
2010-03-05 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
new version of env.js
|
||||
|
||||
2010-03-01 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
setting background color directly and not via the background property
|
||||
|
||||
2010-03-01 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
do not overwrite background-color if it hover_class is specified
|
||||
|
||||
2010-02-19 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
trying failuresOnly option but it doesn't seem to work. :/
|
||||
|
||||
2010-02-19 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
updated jspec version
|
||||
|
||||
2010-02-19 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
removed callbackShowErrors option as there is now an error sink that can be used to disable all errors if required
|
||||
|
||||
2010-02-19 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
changed refact comments
|
||||
|
||||
2010-02-18 Martin Haecker <spamfaenger@gmx.de>
|
||||
|
||||
added error_sink option to get all error messages via a callback out of the editor
|
||||
|
||||
2010-02-14 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
removed leftover bug comment
|
||||
|
||||
2010-02-14 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
allow 0 or empty string as valid return values from submit callback
|
||||
|
||||
2010-02-14 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
do not commit if nothing was changed in the editor
|
||||
|
||||
2010-02-14 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
changes to not commit if nothing was changed in the editor - even if commit was pressed
|
||||
|
||||
2010-02-14 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
escape submitted text so that special charactes like &/=<> do not make problems
|
||||
|
||||
2010-02-14 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
removed stray debugger statements
|
||||
|
||||
2010-02-14 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
added changelog entry and added information about patches
|
||||
|
||||
2010-02-14 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
added changelog entry and added information about patches
|
||||
|
||||
2010-02-14 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
removed unneeded demo files
|
||||
|
||||
2010-02-14 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
new feature: allow css class for hover instead of immediate values
|
||||
|
||||
2010-02-14 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
updated testrunners to allow mocking of ajax requests
|
||||
|
||||
2010-02-13 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
preventing multiple editors on the same element and changed the way the editor is preventing opening it twice to not use an instance variable
|
||||
|
||||
2010-02-13 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
finished objectifying the editor and the first round of method breakdown into relatively manageable bits
|
||||
|
||||
2010-02-13 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
more preparation for breakdown into smaller functions + small reorganizaton of testsuite to make it shorter and sweeter
|
||||
|
||||
2010-02-13 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
expanded checks and documentation for select element to allow extra speces and real arrays for select option definitions
|
||||
|
||||
2010-02-13 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
more cleanup and small bugfixes to how selects are generated
|
||||
|
||||
2010-02-11 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
slowly moving the methods into the InlineEditor object and breaking them down into smaller ones. Plus fix to the escaping of stuff in the inline editor
|
||||
|
||||
2010-02-11 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
even more breaking down into functions for prettier code
|
||||
|
||||
2010-02-11 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
running the demo from the latest source
|
||||
|
||||
2010-02-07 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
wrapped in (function($){})(jQuery) for more compatibility and removed the String prototype changes
|
||||
|
||||
2010-02-07 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
reworked intro comment to contain refact and todo sections
|
||||
|
||||
2010-02-07 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
merged documentation and custom settings declaration to get rid of duplication
|
||||
|
||||
2010-02-07 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
first batch of testcases for the inline editor
|
||||
|
||||
2010-02-07 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
added some todos
|
||||
|
||||
2010-02-07 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
updated testrunners to run jquery.editinplace.js (rhino doesn't work yet as the latest release of env.js fails to load propperly
|
||||
|
||||
2010-02-07 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
added support libraries for rhino and jquery
|
||||
|
||||
2010-02-07 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
removed leftover from template - tests are now written for jquery.editinplace.js
|
||||
|
||||
2010-02-06 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
moved edit in place into lib folder
|
||||
|
||||
2010-02-06 Martin Haecker <mhaecker@cs.tu-berlin.de>
|
||||
|
||||
added local jspec instance
|
||||
|
||||
2009-06-09 DaveHauenstein
|
||||
|
||||
added a new parameter
|
||||
|
||||
2009-04-09 davehauenstein
|
||||
|
||||
- Minor Updates
|
||||
- Script: Changed default save and cancel input fields to button elements
|
||||
- Demo: Minor text changes and added link to demo.js file
|
||||
- Demo: Added local version of jQuery lib instead of linking to google's
|
||||
|
||||
2009-04-06 davehauenstein
|
||||
|
||||
updated link in demo
|
||||
|
||||
2009-04-06 davehauenstein
|
||||
|
||||
initial import
|
||||
|
||||
2009-04-06
|
||||
|
||||
Initial directory structure.
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
Hacking
|
||||
=======
|
||||
|
||||
To run the teststuite just open [the testrunner](spec/dom.html) in your browser of choice. (I found Webkit Nightlies to be most pleasant to debug in). For more comfort install jspec via `gem install jspec` then you can run `jspec bind --browser <yourprobwser>` in the root directory of the project to re-execute the testsuite whenever you save changes to a file.
|
||||
|
||||
If you don't see any tests when executing the testsuite, don't worry, it is set up to only show failing tests.
|
||||
|
||||
If you see an enhancement or happen to need one of the things mentioned in the [TODO](TODO) file, please don't hesitate to implement them with a testsuite to boost and send me a patch.
|
||||
@ -1,31 +0,0 @@
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2009, Dave Hauenstein <davehauenstein@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms, with or
|
||||
without modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of Dave Hauenstein, nor the names of any contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission of the contributor.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
@ -1,58 +0,0 @@
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
editInPlace is a jQuery plugin that turns any element or group of elements
|
||||
into an Ajax in-place editor using only one line of code. It’s written using the jQuery
|
||||
library, which is freely available at http://jquery.com.
|
||||
|
||||
|
||||
SUPPORT AND BUG REPORTS
|
||||
-----------------------
|
||||
|
||||
Bug reports, as well as feature requests, may be submitted [on the google code page](http://code.google.com/p/jquery-in-place-editor/issues/list)
|
||||
|
||||
|
||||
QUICK START
|
||||
-----------
|
||||
|
||||
Include jquery and the editin place scripts in your html page (preferably at the bottom so the page loads faster).
|
||||
|
||||
<script type="text/javascript" src="path/to/js/jquery.js"></script>
|
||||
<script type="text/javascript" src="path/to/js/jquery.editinplace.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(".inplace-editor").editInPlace({
|
||||
url: "path/to/server/script.php"
|
||||
});
|
||||
</script>
|
||||
|
||||
Create a div with the class 'inplace-editor'
|
||||
|
||||
<div class="inplace-editor"></div>
|
||||
|
||||
Create a server side handler script (php, python, etc...), this example will use php
|
||||
|
||||
The following parameters will be sent via a POST requeset to the server script
|
||||
|
||||
* update_value
|
||||
* element_id
|
||||
* original_html
|
||||
|
||||
e.g. in script.php:
|
||||
|
||||
$_POST['update_value']
|
||||
$_POST['element_id']
|
||||
$_POST['original_html']
|
||||
|
||||
Alternatively you can set the option callback, so you can controll the whole saving process yourself (update other parts of the webpage and possibly not even save to the server at all). The editor accepts a wealth of other options to customize how it behaves. They are documented inline [in the sourcecode](lib/jquery.editInPlace.js) and are exposed as $.fn.editInPlace.defaults where you can change them globally for your app. For more examples of how to use the editor, have [a look at the demo html](demo/index.html) and [javascript](demo/js/demo.js).
|
||||
|
||||
|
||||
DOCUMENTATION
|
||||
-------------
|
||||
|
||||
The Editor works in two stages. After initialization it is closed, wich means that it listens to a click on the element it was bound to. When clicked it will open, which means it replaces the content of the bound field with the configured GUI (input, textarea or select), preinitialized to show the value that was shown in that DOM element before. If the user then cancels or doesn't change anything, everything is returned to what it was before. If the user makes a change and commits, that new value is either submitted to the configured URL or to the configured callback and then the editor GUI is again replaced by just the edited value and the editor again listenes to a click.
|
||||
|
||||
To support automated acceptance tests better the editor will set the class .editInPlace-active as soon as it opens, and will only remove it when it has finished any interaction with the server or the callback interface has told it so.
|
||||
|
||||
More documenataion can be found on [the google code page of this product](http://code.google.com/p/jquery-in-place-editor/)
|
||||
|
||||
Thats it! Have fun using it!
|
||||
@ -1,12 +0,0 @@
|
||||
Backwards compatibility breaks in 2.3.0:
|
||||
- Default saving text is changed to the just edited value
|
||||
|
||||
Backwards compatibility breaks in 2.2.0:
|
||||
|
||||
- Now using .text() to get the value of the inline editor by default, you can set extract_with_html:true to override this.
|
||||
- submit to callback with hand over originalValue as third argument instead of originalHTML
|
||||
- submit to server now uses originalValue on the original_html value
|
||||
|
||||
Backwards compatibility breaks in 2.1.0:
|
||||
|
||||
- All callbacks now recieve the DOM-Node of the editor set as their this context
|
||||
@ -1,140 +0,0 @@
|
||||
TODO
|
||||
====
|
||||
- do not change editor content on cancel if callback doesn't return anything
|
||||
- saving animation doesn't work when jquery-ui isn't present. Find workaround or have other default saving animation
|
||||
- Consider to deprecate the ajax callbacks in favor of the delegate interface.
|
||||
- consider to remove / deprecate the textarea sizing support, css is a much better interface to this
|
||||
- Find a workable solution to the textareay enters are not preserved problem. Many people have stumbled about it, either document solutions to it or create a default behaviour that works nicely.
|
||||
- consolidate documentation for options and callbacks
|
||||
- Rename settings so they make more sense (e.g. saving_image -> saving_image_url) but keep backwards compatible to old settings
|
||||
also make all settings consistent in their underscore usage (i.e. don't use any. :)
|
||||
params -> extra_submit_parameters / context_parametes
|
||||
- consider to accept string parameters like jquery UI for 'disable', 'enable', 'remove' etc.
|
||||
- Rework parameters of success and error server callback
|
||||
- Change deprecation notes to state the version the deprecation was put in, not when it will be removed.
|
||||
- rename RELEASE NOTES to BACKWARDS COMPATIBILITY NOTES or BACKWARDS INCOMPATIBLE CHANGES or BACKWARDS COMPATIBILITY CHANGES as I don't see myself as writing release notes anytime soon
|
||||
- Allow the user to chose if html source should be edited or text (default to text). Probably needs a way
|
||||
for the user to decide how the result should be embedded (think about editing wiki-text and inserting rendered html)
|
||||
- Update to jQuery 1.4.x, aparently something breaks
|
||||
- expand the interface to submit to functions to make it easier to integrate into custom applications
|
||||
(fold in show progress, offer callbacks for different lifecycle events, ...)
|
||||
- consider to pass the original dom element instead of it's id in the callback function. (However $('#' + original_id) also accomplishes this)
|
||||
- support live events to trigger inline editing to ease highly dynamic websites better
|
||||
- when using live events, the editor can't guarantee the order of ediors if multiple editors register for the same element.
|
||||
- could add debug mode to raise / show error if this is detected on click (multiple editors where bound, mixture of live / immediate events)
|
||||
- select on choosing if no buttons are shown (should be able to disable this if wanted)
|
||||
- Allow the editor to show up on hoverig above it (make sure to do it in a way that doesn't crash IE 7)
|
||||
- More animations during submit: show spinner
|
||||
- Unify usage of text and html to take and deliver content to the inline editor and enable the user to choose with a setting (document carefully as that will change the default behaviour)
|
||||
Solve by callback interface that can transform the code if needed.
|
||||
- Allow continous validation / transformation while the user types. I.e. wiki-edit with live preview (from server / function)
|
||||
- add validation callback to be asked before any submitting (this could also be called continuous while editing
|
||||
(for each character?) maybe a dedicated callback for each would be valuable)
|
||||
- allow aditional_params to be set as json/object that is then serialized with correct encoding on submit
|
||||
- consider size parameter for the inline edit box (but this can already nicely accomplished through css)
|
||||
- Replace argument list of saving callback with dictionary
|
||||
- Option to always restore the original content, could help for editors that you would always want to render empty, i.e. they display their results somewhere else
|
||||
- Change all callbacks to get the editor dom node as the first argument, so the editor object itself is never exposed
|
||||
- Consider to expose the options argument as a second argument to all callbacks
|
||||
- Consider adding $(..).editInPlace().destroy() or something similar to completely remove the editor
|
||||
- Support overriding individual options with the metadata plugin
|
||||
- Option to load URL for editor content
|
||||
- Group options sensibly and have section headers for them.
|
||||
- Move documentation out of edit in place into the README and update that
|
||||
- deprecate callback arguments that are no longer usefull / needed. For example:
|
||||
- The first argument of the 'callback' option was removed. Use $(this).attr('id') instead if you need it.
|
||||
- success and error callbacks got the editor DOM element as the second argument. Use $(this) instead.
|
||||
- Consider editor types as subclasses so different inline editors can be built more easily.
|
||||
- Could also break out functional classes, callback handling, lifecycle events / delegate behaviour
|
||||
- Consider every optional callback as optional delegete call?
|
||||
- dependencies of editors, i.e. typing in one will update another aka bindings?
|
||||
- Could also be live updating of delegate / calling of callbacks
|
||||
- consider to trigger all the callbacks as events?
|
||||
- could be an alternative, might be more idiomatic event driven dom programming
|
||||
- include spinner image as data url into javascript (add code that writes this as mime thingy for IE)
|
||||
- consider to enable the client to specify a prefix / namespace for all css-classes in the inplace editor to make it easier to avoid clashes with outside css
|
||||
|
||||
Expansions to jspec
|
||||
-------------------
|
||||
- add jspec with focus support
|
||||
- change the way the grammar works to have less magic and more plain javascript (i.e. use 'with' statement less, support real throwaway this objects for the tests)
|
||||
|
||||
REFACT
|
||||
------
|
||||
- Find a way to share enableEditor, openEditor and edit between different testsuites
|
||||
- Extract parts of the testsuite to be run with should_behave_like
|
||||
- Split testsuite into different files, at least one per editor type that should just inlcude generic tests with should_behave_like
|
||||
|
||||
|
||||
Thoughts about a detailed callback
|
||||
----------------------------------
|
||||
|
||||
Could also use callbacks to interact with child-classes, i.e. do the actual work. That could be a really nice interface for child-classes, not sure if it works for everything though, so deeper subclassing may be neccessary
|
||||
|
||||
// these would come just before shouldOpen when using live events
|
||||
shouldInit:
|
||||
willInit:
|
||||
init:
|
||||
didInit:
|
||||
|
||||
shouldHover:
|
||||
willHover:
|
||||
hover:
|
||||
didHover:
|
||||
|
||||
shouldUnhover:
|
||||
willUnhover:
|
||||
unHover:
|
||||
didUnhover:
|
||||
|
||||
// prio 1
|
||||
// maybe combine should and will callbacks?
|
||||
shouldOpen:
|
||||
willOpen: // could be usefull to customize settings? // transform content here
|
||||
open:
|
||||
didOpen:
|
||||
|
||||
// for open editor?
|
||||
// user enters stuff, keypress / changed selection on select
|
||||
// how to deal with validation?
|
||||
shouldChangeContent: // should this be accepted
|
||||
willChangeContent: // transform?
|
||||
changeContent:
|
||||
didChangeContent: // do something with the new information
|
||||
|
||||
shouldSubmitContent: // first callback after submit was called - does it make sense to call something like this if validation didn't work?
|
||||
shouldEnableSubmit: // didChangeContent
|
||||
willSubmitContent: // maybe transform what goes to the server
|
||||
submit:
|
||||
didSubmitContent:
|
||||
// seems not enough, doesn't handle select fields
|
||||
|
||||
// for closed editor? would be really nice to unify with open editor
|
||||
// could be a generic interface to update the displayed values
|
||||
// what about when the editor is open? what interface to use then?
|
||||
shouldUpdateContent: // get notification to update the content, either the view, wrong direction..., something should call this¿
|
||||
willUpdateContent: // could be callback after we get something from the server (also didUpdateContent)
|
||||
updateContent: // could use this to decide between html() and text(), could call changeContent
|
||||
didUpdateContent:
|
||||
|
||||
// maybe
|
||||
shouldSendToServer:
|
||||
willSendToServer:
|
||||
sendToServer
|
||||
didSendToServer:
|
||||
progressFromServer: // probably impossible
|
||||
|
||||
|
||||
// prio 1
|
||||
shouldClose: // willChangeContent / didChangeContent ?
|
||||
willClose: // transform content, could be willSubmitContent
|
||||
close:
|
||||
didClose: // could return false to prevent reinit - not very clear though
|
||||
|
||||
// this should also work when the editor submits the data to the server itself
|
||||
// need callback to compute the data that is sent to the server (e.g. to provide arbitrary json)
|
||||
// need ability to specify http verb to use (PUT, POST, DELETE, etc.)
|
||||
|
||||
shouldReinit: // could be able to customize reinit behaviour?, maybe better shouldOpen? didClose could also remove editor
|
||||
|
||||
Consider to all suffix them with .editInPlace?
|
||||
@ -1,644 +0,0 @@
|
||||
/*
|
||||
|
||||
A jQuery edit in place plugin
|
||||
|
||||
Version 2.2.0
|
||||
|
||||
Authors:
|
||||
Dave Hauenstein
|
||||
Martin Häcker <spamfaenger [at] gmx [dot] de>
|
||||
|
||||
Project home:
|
||||
http://code.google.com/p/jquery-in-place-editor/
|
||||
|
||||
Patches with tests welcomed! For guidance see the tests at </spec/unit/spec.js>. To submit, attach them to the bug tracker.
|
||||
|
||||
License:
|
||||
This source file is subject to the BSD license bundled with this package.
|
||||
Available online: {@link http://www.opensource.org/licenses/bsd-license.php}
|
||||
If you did not receive a copy of the license, and are unable to obtain it,
|
||||
learn to use a search engine.
|
||||
|
||||
*/
|
||||
|
||||
(function($){
|
||||
|
||||
$.fn.editInPlace = function(options) {
|
||||
|
||||
var settings = $.extend({}, $.fn.editInPlace.defaults, options);
|
||||
|
||||
assertMandatorySettingsArePresent(settings);
|
||||
|
||||
preloadImage(settings.saving_image);
|
||||
|
||||
return this.each(function() {
|
||||
var dom = $(this);
|
||||
// This won't work with live queries as there is no specific element to attach this
|
||||
// one way to deal with this could be to store a reference to self and then compare that in click?
|
||||
if (dom.data('editInPlace'))
|
||||
return; // already an editor here
|
||||
dom.data('editInPlace', true);
|
||||
|
||||
new InlineEditor(settings, dom).init();
|
||||
});
|
||||
};
|
||||
|
||||
/// Switch these through the dictionary argument to $(aSelector).editInPlace(overideOptions)
|
||||
/// Required Options: Either url or callback, so the editor knows what to do with the edited values.
|
||||
$.fn.editInPlace.defaults = {
|
||||
url: "", // string: POST URL to send edited content
|
||||
bg_over: "#ffc", // string: background color of hover of unactivated editor
|
||||
bg_out: "transparent", // string: background color on restore from hover
|
||||
hover_class: "", // string: class added to root element during hover. Will override bg_over and bg_out
|
||||
show_buttons: false, // boolean: will show the buttons: cancel or save; will automatically cancel out the onBlur functionality
|
||||
save_button: '<button class="inplace_save">Save</button>', // string: image button tag to use as “Save” button
|
||||
cancel_button: '<button class="inplace_cancel">Cancel</button>', // string: image button tag to use as “Cancel” button
|
||||
params: "", // string: example: first_name=dave&last_name=hauenstein extra paramters sent via the post request to the server
|
||||
field_type: "text", // string: "text", "textarea", or "select"; The type of form field that will appear on instantiation
|
||||
default_text: "(Click here to add text)", // string: text to show up if the element that has this functionality is empty
|
||||
use_html: false, // boolean, set to true if the editor should use jQuery.fn.html() to extract the value to show from the dom node
|
||||
textarea_rows: 10, // integer: set rows attribute of textarea, if field_type is set to textarea. Use CSS if possible though
|
||||
textarea_cols: 25, // integer: set cols attribute of textarea, if field_type is set to textarea. Use CSS if possible though
|
||||
select_text: "Choose new value", // string: default text to show up in select box
|
||||
select_options: "", // string or array: Used if field_type is set to 'select'. Can be comma delimited list of options 'textandValue,text:value', Array of options ['textAndValue', 'text:value'] or array of arrays ['textAndValue', ['text', 'value']]. The last form is especially usefull if your labels or values contain colons)
|
||||
text_size: null, // integer: set cols attribute of text input, if field_type is set to text. Use CSS if possible though
|
||||
|
||||
// Specifying callback_skip_dom_reset will disable all saving_* options
|
||||
saving_text: undefined, // string: text to be used when server is saving information. Example "Saving..."
|
||||
saving_image: "", // string: uses saving text specify an image location instead of text while server is saving
|
||||
saving_animation_color: 'transparent', // hex color string, will be the color the pulsing animation during the save pulses to. Note: Only works if jquery-ui is loaded
|
||||
|
||||
value_required: false, // boolean: if set to true, the element will not be saved unless a value is entered
|
||||
element_id: "element_id", // string: name of parameter holding the id or the editable
|
||||
update_value: "update_value", // string: name of parameter holding the updated/edited value
|
||||
original_value: 'original_value', // string: name of parameter holding the updated/edited value
|
||||
original_html: "original_html", // string: name of parameter holding original_html value of the editable /* DEPRECATED in 2.2.0 */ use original_value instead.
|
||||
save_if_nothing_changed: false, // boolean: submit to function or server even if the user did not change anything
|
||||
on_blur: "save", // string: "save" or null; what to do on blur; will be overridden if show_buttons is true
|
||||
cancel: "", // string: if not empty, a jquery selector for elements that will not cause the editor to open even though they are clicked. E.g. if you have extra buttons inside editable fields
|
||||
|
||||
// All callbacks will have this set to the DOM node of the editor that triggered the callback
|
||||
|
||||
callback: null, // function: function to be called when editing is complete; cancels ajax submission to the url param. Prototype: function(idOfEditor, enteredText, orinalHTMLContent, settingsParams, callbacks). The function needs to return the value that should be shown in the dom. Returning undefined means cancel and will restore the dom and trigger an error. callbacks is a dictionary with two functions didStartSaving and didEndSaving() that you can use to tell the inline editor that it should start and stop any saving animations it has configured. /* DEPRECATED in 2.1.0 */ Parameter idOfEditor, use $(this).attr('id') instead
|
||||
callback_skip_dom_reset: false, // boolean: set this to true if the callback should handle replacing the editor with the new value to show
|
||||
success: null, // function: this function gets called if server responds with a success. Prototype: function(newEditorContentString)
|
||||
error: null, // function: this function gets called if server responds with an error. Prototype: function(request)
|
||||
error_sink: function(idOfEditor, errorString) { alert(errorString); }, // function: gets id of the editor and the error. Make sure the editor has an id, or it will just be undefined. If set to null, no error will be reported. /* DEPRECATED in 2.1.0 */ Parameter idOfEditor, use $(this).attr('id') instead
|
||||
preinit: null, // function: this function gets called after a click on an editable element but before the editor opens. If you return false, the inline editor will not open. Prototype: function(currentDomNode). DEPRECATED in 2.2.0 use delegate shouldOpenEditInPlace call instead
|
||||
postclose: null, // function: this function gets called after the inline editor has closed and all values are updated. Prototype: function(currentDomNode). DEPRECATED in 2.2.0 use delegate didCloseEditInPlace call instead
|
||||
delegate: null // object: if it has methods with the name of the callbacks documented below in delegateExample these will be called. This means that you just need to impelment the callbacks you are interested in.
|
||||
};
|
||||
|
||||
// Lifecycle events that the delegate can implement
|
||||
// this will always be fixed to the delegate
|
||||
var delegateExample = {
|
||||
// called while opening the editor.
|
||||
// return false to prevent editor from opening
|
||||
shouldOpenEditInPlace: function(aDOMNode, aSettingsDict, triggeringEvent) {},
|
||||
// return content to show in inplace editor
|
||||
willOpenEditInPlace: function(aDOMNode, aSettingsDict) {},
|
||||
didOpenEditInPlace: function(aDOMNode, aSettingsDict) {},
|
||||
|
||||
// called while closing the editor
|
||||
// return false to prevent the editor from closing
|
||||
shouldCloseEditInPlace: function(aDOMNode, aSettingsDict, triggeringEvent) {},
|
||||
// return value will be shown during saving
|
||||
willCloseEditInPlace: function(aDOMNode, aSettingsDict) {},
|
||||
didCloseEditInPlace: function(aDOMNode, aSettingsDict) {},
|
||||
|
||||
missingCommaErrorPreventer:''
|
||||
};
|
||||
|
||||
|
||||
function InlineEditor(settings, dom) {
|
||||
this.settings = settings;
|
||||
this.dom = dom;
|
||||
this.originalValue = null;
|
||||
this.didInsertDefaultText = false;
|
||||
this.shouldDelayReinit = false;
|
||||
};
|
||||
|
||||
$.extend(InlineEditor.prototype, {
|
||||
|
||||
init: function() {
|
||||
this.setDefaultTextIfNeccessary();
|
||||
this.connectOpeningEvents();
|
||||
},
|
||||
|
||||
reinit: function() {
|
||||
if (this.shouldDelayReinit)
|
||||
return;
|
||||
|
||||
this.triggerCallback(this.settings.postclose, /* DEPRECATED in 2.1.0 */ this.dom);
|
||||
this.triggerDelegateCall('didCloseEditInPlace');
|
||||
|
||||
this.markEditorAsInactive();
|
||||
this.connectOpeningEvents();
|
||||
},
|
||||
|
||||
setDefaultTextIfNeccessary: function() {
|
||||
if('' !== this.dom.html())
|
||||
return;
|
||||
|
||||
this.dom.html(this.settings.default_text);
|
||||
this.didInsertDefaultText = true;
|
||||
},
|
||||
|
||||
connectOpeningEvents: function() {
|
||||
var that = this;
|
||||
this.dom
|
||||
.bind('mouseenter.editInPlace', function(){ that.addHoverEffect(); })
|
||||
.bind('mouseleave.editInPlace', function(){ that.removeHoverEffect(); })
|
||||
.bind('click.editInPlace', function(anEvent){ that.openEditor(anEvent); });
|
||||
},
|
||||
|
||||
disconnectOpeningEvents: function() {
|
||||
// prevent re-opening the editor when it is already open
|
||||
this.dom.unbind('.editInPlace');
|
||||
},
|
||||
|
||||
addHoverEffect: function() {
|
||||
if (this.settings.hover_class)
|
||||
this.dom.addClass(this.settings.hover_class);
|
||||
else
|
||||
this.dom.css("background-color", this.settings.bg_over);
|
||||
},
|
||||
|
||||
removeHoverEffect: function() {
|
||||
if (this.settings.hover_class)
|
||||
this.dom.removeClass(this.settings.hover_class);
|
||||
else
|
||||
this.dom.css("background-color", this.settings.bg_out);
|
||||
},
|
||||
|
||||
openEditor: function(anEvent) {
|
||||
if ( ! this.shouldOpenEditor(anEvent))
|
||||
return;
|
||||
|
||||
this.workAroundFirefoxBlurBug();
|
||||
this.disconnectOpeningEvents();
|
||||
this.removeHoverEffect();
|
||||
this.removeInsertedDefaultTextIfNeccessary();
|
||||
this.saveOriginalValue();
|
||||
this.markEditorAsActive();
|
||||
this.replaceContentWithEditor();
|
||||
this.connectOpeningEventsToEditor();
|
||||
this.triggerDelegateCall('didOpenEditInPlace');
|
||||
},
|
||||
|
||||
shouldOpenEditor: function(anEvent) {
|
||||
if (this.isClickedObjectCancelled(anEvent.target))
|
||||
return false;
|
||||
|
||||
if (false === this.triggerCallback(this.settings.preinit, /* DEPRECATED in 2.1.0 */ this.dom))
|
||||
return false;
|
||||
|
||||
if (false === this.triggerDelegateCall('shouldOpenEditInPlace', true, anEvent))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
removeInsertedDefaultTextIfNeccessary: function() {
|
||||
if ( ! this.didInsertDefaultText
|
||||
|| this.dom.html() !== this.settings.default_text)
|
||||
return;
|
||||
|
||||
this.dom.html('');
|
||||
this.didInsertDefaultText = false;
|
||||
},
|
||||
|
||||
isClickedObjectCancelled: function(eventTarget) {
|
||||
if ( ! this.settings.cancel)
|
||||
return false;
|
||||
|
||||
var eventTargetAndParents = $(eventTarget).parents().andSelf();
|
||||
var elementsMatchingCancelSelector = eventTargetAndParents.filter(this.settings.cancel);
|
||||
return 0 !== elementsMatchingCancelSelector.length;
|
||||
},
|
||||
|
||||
saveOriginalValue: function() {
|
||||
if (this.settings.use_html)
|
||||
this.originalValue = this.dom.html();
|
||||
else
|
||||
this.originalValue = trim(this.dom.text());
|
||||
},
|
||||
|
||||
restoreOriginalValue: function() {
|
||||
this.setClosedEditorContent(this.originalValue);
|
||||
},
|
||||
|
||||
setClosedEditorContent: function(aValue) {
|
||||
if (this.settings.use_html)
|
||||
this.dom.html(aValue);
|
||||
else
|
||||
this.dom.text(aValue);
|
||||
},
|
||||
|
||||
workAroundFirefoxBlurBug: function() {
|
||||
if ( ! $.browser.mozilla)
|
||||
return;
|
||||
|
||||
// TODO: Opera seems to also have this bug....
|
||||
|
||||
// Firefox will forget to send a blur event to an input element when another one is
|
||||
// created and selected programmatically. This means that if another inline editor is
|
||||
// opened, existing inline editors will _not_ close if they are configured to submit when blurred.
|
||||
// This is actually the first time I've written browser specific code for a browser different than IE! Wohoo!
|
||||
|
||||
// Using parents() instead document as base to workaround the fact that in the unittests
|
||||
// the editor is not a child of window.document but of a document fragment
|
||||
this.dom.parents(':last').find('.editInPlace-active :input').blur();
|
||||
},
|
||||
|
||||
replaceContentWithEditor: function() {
|
||||
var buttons_html = (this.settings.show_buttons) ? this.settings.save_button + ' ' + this.settings.cancel_button : '';
|
||||
var editorElement = this.createEditorElement(); // needs to happen before anything is replaced
|
||||
/* insert the new in place form after the element they click, then empty out the original element */
|
||||
this.dom.html('<form class="inplace_form" style="display: inline; margin: 0; padding: 0;"></form>')
|
||||
.find('form')
|
||||
.append(editorElement)
|
||||
.append(buttons_html);
|
||||
},
|
||||
|
||||
createEditorElement: function() {
|
||||
if (-1 === $.inArray(this.settings.field_type, ['text', 'textarea', 'select']))
|
||||
throw "Unknown field_type <fnord>, supported are 'text', 'textarea' and 'select'";
|
||||
|
||||
var editor = null;
|
||||
if ("select" === this.settings.field_type)
|
||||
editor = this.createSelectEditor();
|
||||
else if ("text" === this.settings.field_type)
|
||||
editor = $('<input type="text" ' + this.inputNameAndClass()
|
||||
+ ' size="' + this.settings.text_size + '" />');
|
||||
else if ("textarea" === this.settings.field_type)
|
||||
editor = $('<textarea ' + this.inputNameAndClass()
|
||||
+ ' rows="' + this.settings.textarea_rows + '" '
|
||||
+ ' cols="' + this.settings.textarea_cols + '" />');
|
||||
|
||||
editor.val(this.triggerDelegateCall('willOpenEditInPlace', this.originalValue));
|
||||
return editor;
|
||||
},
|
||||
|
||||
inputNameAndClass: function() {
|
||||
return ' name="inplace_value" class="inplace_field" ';
|
||||
},
|
||||
|
||||
createSelectEditor: function() {
|
||||
var editor = $('<select' + this.inputNameAndClass() + '>'
|
||||
+ '<option disabled="true" value="">' + this.settings.select_text + '</option>'
|
||||
+ '</select>');
|
||||
|
||||
var optionsArray = this.settings.select_options;
|
||||
if ( ! $.isArray(optionsArray))
|
||||
optionsArray = optionsArray.split(',');
|
||||
|
||||
for (var i=0; i<optionsArray.length; i++) {
|
||||
|
||||
var currentTextAndValue = optionsArray[i];
|
||||
if ( ! $.isArray(currentTextAndValue))
|
||||
currentTextAndValue = currentTextAndValue.split(':');
|
||||
|
||||
var value = trim(currentTextAndValue[1] || currentTextAndValue[0]);
|
||||
var text = trim(currentTextAndValue[0]);
|
||||
|
||||
var selected = (value == this.originalValue) ? 'selected="selected" ' : '';
|
||||
var option = $('<option ' + selected + ' ></option>').val(value).text(text);
|
||||
editor.append(option);
|
||||
}
|
||||
return editor;
|
||||
|
||||
},
|
||||
|
||||
// REFACT: rename opening is not what it's about. Its about closing events really
|
||||
connectOpeningEventsToEditor: function() {
|
||||
var that = this;
|
||||
function cancelEditorAction(anEvent) {
|
||||
that.handleCancelEditor(anEvent);
|
||||
return false; // stop event bubbling
|
||||
}
|
||||
function saveEditorAction(anEvent) {
|
||||
that.handleSaveEditor(anEvent);
|
||||
return false; // stop event bubbling
|
||||
}
|
||||
|
||||
var form = this.dom.find("form");
|
||||
|
||||
form.find(".inplace_field").focus().select();
|
||||
form.find(".inplace_cancel").click(cancelEditorAction);
|
||||
form.find(".inplace_save").click(saveEditorAction);
|
||||
|
||||
if ( ! this.settings.show_buttons) {
|
||||
// TODO: Firefox has a bug where blur is not reliably called when focus is lost
|
||||
// (for example by another editor appearing)
|
||||
if ("save" === this.settings.on_blur)
|
||||
form.find(".inplace_field").blur(saveEditorAction);
|
||||
else
|
||||
form.find(".inplace_field").blur(cancelEditorAction);
|
||||
|
||||
// workaround for firefox bug where it won't submit on enter if no button is shown
|
||||
if ($.browser.mozilla)
|
||||
this.bindSubmitOnEnterInInput();
|
||||
}
|
||||
|
||||
form.keyup(function(anEvent) {
|
||||
// allow canceling with escape
|
||||
var escape = 27;
|
||||
if (escape === anEvent.which)
|
||||
return cancelEditorAction();
|
||||
});
|
||||
|
||||
// workaround for webkit nightlies where they won't submit at all on enter
|
||||
// REFACT: find a way to just target the nightlies
|
||||
if ($.browser.safari)
|
||||
this.bindSubmitOnEnterInInput();
|
||||
|
||||
|
||||
form.submit(saveEditorAction);
|
||||
},
|
||||
|
||||
bindSubmitOnEnterInInput: function() {
|
||||
if ('textarea' === this.settings.field_type)
|
||||
return; // can't enter newlines otherwise
|
||||
|
||||
var that = this;
|
||||
this.dom.find(':input').keyup(function(event) {
|
||||
var enter = 13;
|
||||
if (enter === event.which)
|
||||
return that.dom.find('form').submit();
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
handleCancelEditor: function(anEvent) {
|
||||
// REFACT: remove duplication between save and cancel
|
||||
if (false === this.triggerDelegateCall('shouldCloseEditInPlace', true, anEvent))
|
||||
return;
|
||||
|
||||
var enteredText = this.dom.find(':input').val();
|
||||
enteredText = this.triggerDelegateCall('willCloseEditInPlace', enteredText);
|
||||
|
||||
this.restoreOriginalValue();
|
||||
if (hasContent(enteredText)
|
||||
&& ! this.isDisabledDefaultSelectChoice())
|
||||
this.setClosedEditorContent(enteredText);
|
||||
this.reinit();
|
||||
},
|
||||
|
||||
handleSaveEditor: function(anEvent) {
|
||||
if (false === this.triggerDelegateCall('shouldCloseEditInPlace', true, anEvent))
|
||||
return;
|
||||
|
||||
var enteredText = this.dom.find(':input').val();
|
||||
enteredText = this.triggerDelegateCall('willCloseEditInPlace', enteredText);
|
||||
|
||||
if (this.isDisabledDefaultSelectChoice()
|
||||
|| this.isUnchangedInput(enteredText)) {
|
||||
this.handleCancelEditor(anEvent);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.didForgetRequiredText(enteredText)) {
|
||||
this.handleCancelEditor(anEvent);
|
||||
this.reportError("Error: You must enter a value to save this field");
|
||||
return;
|
||||
}
|
||||
|
||||
this.showSaving(enteredText);
|
||||
|
||||
if (this.settings.callback)
|
||||
this.handleSubmitToCallback(enteredText);
|
||||
else
|
||||
this.handleSubmitToServer(enteredText);
|
||||
},
|
||||
|
||||
didForgetRequiredText: function(enteredText) {
|
||||
return this.settings.value_required
|
||||
&& ("" === enteredText
|
||||
|| undefined === enteredText
|
||||
|| null === enteredText);
|
||||
},
|
||||
|
||||
isDisabledDefaultSelectChoice: function() {
|
||||
return this.dom.find('option').eq(0).is(':selected:disabled');
|
||||
},
|
||||
|
||||
isUnchangedInput: function(enteredText) {
|
||||
return ! this.settings.save_if_nothing_changed
|
||||
&& this.originalValue === enteredText;
|
||||
},
|
||||
|
||||
showSaving: function(enteredText) {
|
||||
if (this.settings.callback && this.settings.callback_skip_dom_reset)
|
||||
return;
|
||||
|
||||
var savingMessage = enteredText;
|
||||
if (hasContent(this.settings.saving_text))
|
||||
savingMessage = this.settings.saving_text;
|
||||
if(hasContent(this.settings.saving_image))
|
||||
// REFACT: alt should be the configured saving message
|
||||
savingMessage = $('<img />').attr('src', this.settings.saving_image).attr('alt', savingMessage);
|
||||
this.dom.html(savingMessage);
|
||||
},
|
||||
|
||||
handleSubmitToCallback: function(enteredText) {
|
||||
// REFACT: consider to encode enteredText and originalHTML before giving it to the callback
|
||||
this.enableOrDisableAnimationCallbacks(true, false);
|
||||
var newHTML = this.triggerCallback(this.settings.callback, /* DEPRECATED in 2.1.0 */ this.id(), enteredText, this.originalValue,
|
||||
this.settings.params, this.savingAnimationCallbacks());
|
||||
|
||||
if (this.settings.callback_skip_dom_reset)
|
||||
; // do nothing
|
||||
else if (undefined === newHTML) {
|
||||
// failure; put original back
|
||||
this.reportError("Error: Failed to save value: " + enteredText);
|
||||
this.restoreOriginalValue();
|
||||
}
|
||||
else
|
||||
// REFACT: use setClosedEditorContent
|
||||
this.dom.html(newHTML);
|
||||
|
||||
if (this.didCallNoCallbacks()) {
|
||||
this.enableOrDisableAnimationCallbacks(false, false);
|
||||
this.reinit();
|
||||
}
|
||||
},
|
||||
|
||||
handleSubmitToServer: function(enteredText) {
|
||||
var data = this.settings.update_value + '=' + encodeURIComponent(enteredText)
|
||||
+ '&' + this.settings.element_id + '=' + this.dom.attr("id")
|
||||
+ ((this.settings.params) ? '&' + this.settings.params : '')
|
||||
+ '&' + this.settings.original_html + '=' + encodeURIComponent(this.originalValue) /* DEPRECATED in 2.2.0 */
|
||||
+ '&' + this.settings.original_value + '=' + encodeURIComponent(this.originalValue);
|
||||
|
||||
this.enableOrDisableAnimationCallbacks(true, false);
|
||||
this.didStartSaving();
|
||||
var that = this;
|
||||
$.ajax({
|
||||
url: that.settings.url,
|
||||
type: "POST",
|
||||
data: data,
|
||||
dataType: "html",
|
||||
complete: function(request){
|
||||
that.didEndSaving();
|
||||
},
|
||||
success: function(html){
|
||||
var new_text = html || that.settings.default_text;
|
||||
|
||||
/* put the newly updated info into the original element */
|
||||
// FIXME: should be affected by the preferences switch
|
||||
that.dom.html(new_text);
|
||||
// REFACT: remove dom parameter, already in this, not documented, should be easy to remove
|
||||
// REFACT: callback should be able to override what gets put into the DOM
|
||||
that.triggerCallback(that.settings.success, html);
|
||||
},
|
||||
error: function(request) {
|
||||
that.dom.html(that.originalHTML); // REFACT: what about a restorePreEditingContent()
|
||||
if (that.settings.error)
|
||||
// REFACT: remove dom parameter, already in this, not documented, can remove without deprecation
|
||||
// REFACT: callback should be able to override what gets entered into the DOM
|
||||
that.triggerCallback(that.settings.error, request);
|
||||
else
|
||||
that.reportError("Failed to save value: " + request.responseText || 'Unspecified Error');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Utilities .........................................................
|
||||
|
||||
triggerCallback: function(aCallback /*, arguments */) {
|
||||
if ( ! aCallback)
|
||||
return; // callback wasn't specified after all
|
||||
|
||||
var callbackArguments = Array.prototype.splice.call(arguments, 1);
|
||||
return aCallback.apply(this.dom[0], callbackArguments);
|
||||
},
|
||||
|
||||
/// defaultReturnValue is only used if the delegate returns undefined
|
||||
triggerDelegateCall: function(aDelegateMethodName, defaultReturnValue, optionalEvent) {
|
||||
// REFACT: consider to trigger equivalent callbacks automatically via a mapping table?
|
||||
if ( ! this.settings.delegate
|
||||
|| ! $.isFunction(this.settings.delegate[aDelegateMethodName]))
|
||||
return defaultReturnValue;
|
||||
|
||||
var delegateReturnValue = this.settings.delegate[aDelegateMethodName](this.dom, this.settings, optionalEvent);
|
||||
return (undefined === delegateReturnValue)
|
||||
? defaultReturnValue
|
||||
: delegateReturnValue;
|
||||
},
|
||||
|
||||
reportError: function(anErrorString) {
|
||||
this.triggerCallback(this.settings.error_sink, /* DEPRECATED in 2.1.0 */ this.id(), anErrorString);
|
||||
},
|
||||
|
||||
// REFACT: this method should go, callbacks should get the dom node itself as an argument
|
||||
id: function() {
|
||||
return this.dom.attr('id');
|
||||
},
|
||||
|
||||
markEditorAsActive: function() {
|
||||
this.dom.addClass('editInPlace-active');
|
||||
},
|
||||
|
||||
markEditorAsInactive: function() {
|
||||
this.dom.removeClass('editInPlace-active');
|
||||
},
|
||||
|
||||
// REFACT: consider rename, doesn't deal with animation directly
|
||||
savingAnimationCallbacks: function() {
|
||||
var that = this;
|
||||
return {
|
||||
didStartSaving: function() { that.didStartSaving(); },
|
||||
didEndSaving: function() { that.didEndSaving(); }
|
||||
};
|
||||
},
|
||||
|
||||
enableOrDisableAnimationCallbacks: function(shouldEnableStart, shouldEnableEnd) {
|
||||
this.didStartSaving.enabled = shouldEnableStart;
|
||||
this.didEndSaving.enabled = shouldEnableEnd;
|
||||
},
|
||||
|
||||
didCallNoCallbacks: function() {
|
||||
return this.didStartSaving.enabled && ! this.didEndSaving.enabled;
|
||||
},
|
||||
|
||||
assertCanCall: function(methodName) {
|
||||
if ( ! this[methodName].enabled)
|
||||
throw new Error('Cannot call ' + methodName + ' now. See documentation for details.');
|
||||
},
|
||||
|
||||
didStartSaving: function() {
|
||||
this.assertCanCall('didStartSaving');
|
||||
this.shouldDelayReinit = true;
|
||||
this.enableOrDisableAnimationCallbacks(false, true);
|
||||
|
||||
this.startSavingAnimation();
|
||||
},
|
||||
|
||||
didEndSaving: function() {
|
||||
this.assertCanCall('didEndSaving');
|
||||
this.shouldDelayReinit = false;
|
||||
this.enableOrDisableAnimationCallbacks(false, false);
|
||||
this.reinit();
|
||||
|
||||
this.stopSavingAnimation();
|
||||
},
|
||||
|
||||
startSavingAnimation: function() {
|
||||
var that = this;
|
||||
this.dom
|
||||
.animate({ backgroundColor: this.settings.saving_animation_color }, 400)
|
||||
.animate({ backgroundColor: 'transparent'}, 400, 'swing', function(){
|
||||
// In the tests animations are turned off - i.e they happen instantaneously.
|
||||
// Hence we need to prevent this from becomming an unbounded recursion.
|
||||
setTimeout(function(){ that.startSavingAnimation(); }, 10);
|
||||
});
|
||||
},
|
||||
|
||||
stopSavingAnimation: function() {
|
||||
this.dom
|
||||
.stop(true)
|
||||
.css({backgroundColor: ''});
|
||||
},
|
||||
|
||||
missingCommaErrorPreventer:''
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Private helpers .......................................................
|
||||
|
||||
function assertMandatorySettingsArePresent(options) {
|
||||
// one of these needs to be non falsy
|
||||
if (options.url || options.callback)
|
||||
return;
|
||||
|
||||
throw new Error("Need to set either url: or callback: option for the inline editor to work.");
|
||||
}
|
||||
|
||||
/* preload the loading icon if it is configured */
|
||||
function preloadImage(anImageURL) {
|
||||
if ('' === anImageURL)
|
||||
return;
|
||||
|
||||
var loading_image = new Image();
|
||||
loading_image.src = anImageURL;
|
||||
}
|
||||
|
||||
function trim(aString) {
|
||||
return aString
|
||||
.replace(/^\s+/, '')
|
||||
.replace(/\s+$/, '');
|
||||
}
|
||||
|
||||
function hasContent(something) {
|
||||
if (undefined === something || null === something)
|
||||
return false;
|
||||
|
||||
if (0 === something.length)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
Loading…
Reference in New Issue
Block a user