Structured data access JS API (EXPERIMENTAL)
An API for accessing structured data with JavaScript |
Type | JAR |
Category | API |
Developed by | |
Active Installs | 2 |
Rating | |
License | GNU Lesser General Public License 2.1 |
Table of contents
Description
With this extension, you can easily access the data from your application. Among the functionalities, you can easily see, modify, add or delete items of your extension.
How to use the JS API
You can use all the methods described in the Structured data access API documentation.
However, since the data is loaded from the server in a asynchronous way, you should add a last parameter callback if you want to be able to use the data.
callback : function(error, data)
error : Ajax error returned if there is any
data : the JSON representation of the Map returned by the method
Load the webjar
To use the structured data access JS API, first you have to load the webjar containing the JavaScript code:
paths: { "xapp": "$!services.webjars.url('org.xwiki.contrib:api-structured-data-js', 'api-structured-data.js')" }
});
require(['xapp'], function(XApp) {
// Your code here
});
Get an application
XApp.getCurrent
Parameters | / |
---|---|
Returns | An AWM app containing all the methods for accessing the application data. |
XApp.getApp
Parameters |
|
---|---|
Returns | An object (AWM app OR XWiki class app) containing all the methods for accessing the application data. |
API
If you want details about the methods, check the Structured data access API documentation.
- getSchema(callback)
- getItems([Map options,] callback)
- getItem(String itemId, [List properties,] callback)
- storeItem(String itemId, Map itemData, callback)
- deleteItem(String itemId, callback)
- getItemDocument(String itemId, [List properties,] callback)
- storeItemDocument(String itemId, Map documentData, callback)
Example
require.config({
paths: { "xapp": "$!services.webjars.url('org.xwiki.contrib:api-structured-data-js', 'api-structured-data.js')" }
});
require(['xapp'], function(XApp) {
var app = XApp.getApp("Ideas", "xwiki"); /* getCurrent(), getApp(appName) and getApp(AppName, wikiName) are available */
/* Asynchronous api */
app.getItems({limit: 50}, function (err, result) {
if (err) { throw err; } // Or handle somehow else...
//Do something with result["YourItem"].yourProp
});
app.getItem("foo", function (err, foo) {
if (err) { throw err; }
foo.genre = 'drama';
foo.releaseDate = (new Date()).getTime();
app.storeItem("foo", foo, function (err) {
if (err) { console.log('something went wrong ! ' + err.stack); }
});
});
});
Get Started : Inline JS editor
In this guide we'll improve the basic Movie Library Application created during the guide for the REST/Velocity/Groovy Structured Data Access API. If you haven't done that yet, create the application using AppWithinMinutes with the properties mentionned in the other guide.
We are going to update the sheet of the application in order to add a JavaScript inline editor : users will be able to edit the movie's properties quickly, in view mode, by double-clicking on a property.
Edition of the sheet
First, we have to edit the sheet of the "Movies" class to add an identifier for each property. The sheet is located at :
- Movies.Code.MoviesSheet for XWiki >= 7.2
- MoviesCode.MoviesSheet for XWiki < 7.2
We have to add (% data-xwiki-editor-property="{propertyName}" %) before the properties displayed. We also have to add the JavaScriptExtension to the page with $xwiki.jsx.use
To simplify the code, we won't create the inline editors for "genre", "release date" and "synopsis" since they can't be easily represented by a String. You can try to improve this example by adding the code necessary to manage a date, a list and a long text property.
{{html wiki="true"}}
#set ($discard = $doc.use('Movies.Code.MoviesClass'))
#set ($discard = $xwiki.jsx.use('Movies.Code.MoviesSheet'))
(% class="xform" %)
(((
; <label for="Movies.Code.MoviesClass_0_name">$escapetool.xml($doc.displayPrettyName('name', false, false))</label>
: (% data-xwiki-editor-property="name" %)$doc.display('name')
; <label for="Movies.Code.MoviesClass_0_genre">$escapetool.xml($doc.displayPrettyName('genre', false, false))</label>
: $doc.display('genre')
; <label for="Movies.Code.MoviesClass_0_director">$escapetool.xml($doc.displayPrettyName('director', false, false))</label>
: (% data-xwiki-editor-property="director" %)$doc.display('director')
; <label for="Movies.Code.MoviesClass_0_releaseDate">$escapetool.xml($doc.displayPrettyName('releaseDate', false, false))</label>
: $doc.display('releaseDate')
; <label for="Movies.Code.MoviesClass_0_synopsis">$escapetool.xml($doc.displayPrettyName('synopsis', false, false))</label>
: $doc.display('synopsis')
; <label for="Movies.Code.MoviesClass_0_ratings">$escapetool.xml($doc.displayPrettyName('ratings', false, false))</label>
: (% data-xwiki-editor-property="ratings" %)$doc.display('ratings')
)))
{{/html}}
{{/velocity}}
Add JS to the sheet
Now, we can start working on the editor, and to do so, we are going to add a JavaScriptExtension object to the sheet. It should be used On demand only and the content must be parsed.
First, we have to load the API and get the application object :
paths: {
"xapp": "$!services.webjars.url('org.xwiki.contrib:api-structured-data-js', 'api-structured-data.js')",
}
});
require(['xapp', "$xwiki.getDocument('Displayer.DisplayEditorJS').getURL('jsx')", 'jquery', 'xwiki-meta'], function(XApp, DSP, $, xm) {
// Get the "Movies" application from the API
var app = XApp.getCurrent();
// Insert the end of the code here
});
Then, we have three main actions to handle :
- Open the inline editor when a user double-click on a property.
- Save the new value in XWiki when the user presses Enter. We will use the "storeItem" method from the API here!
- Display the new value and hide the editor.
We will also make sure that when a user clicks on the page but not on a property, all opened editors are closed so that the user has a way to cancel the edition easily.
Here is the complete code :
paths: {
"xapp": "$!services.webjars.url('org.xwiki.contrib:api-structured-data-js', 'api-structured-data.js')",
}
});
require(['xapp', "$xwiki.getDocument('Displayer.DisplayEditorJS').getURL('jsx')", 'jquery', 'xwiki-meta'], function(XApp, DSP, $, xm) {
// Get the "Movies" application from the API
var app = XApp.getCurrent();
// Open the editor when the user double clicks on a property
var openEditor = function(e) {
// Get the parent container
var container = $(this).parent();
var property = $(this).attr('data-xwiki-editor-property');
var currentValue = $(this).text();
// Add the editor if it doesn't exists
if(!$(container).find(".data-xwiki-property-edit").length) {
$(container).append('<span class="data-xwiki-property-edit"><input type="text" id="inlineEditor-'+property+'" value="'+currentValue+'" /></span>');
$(container).find('.data-xwiki-property-edit').on('click', stopPropagation);
}
$(this).hide();
$(container).find(".data-xwiki-property-edit").show();
var input = $(container).find(".data-xwiki-property-edit input");
$(input).focus();
// Add the keydown event to save the field when the user presses Enter
$(input).on('keydown', saveEditor(property));
}
$('span[data-xwiki-editor-property]').on('dblclick', openEditor);
// Save the new value of the selected property
var saveEditor = function(prop) {
return function(e) {
// Save if the user presses Enter (keyCode = 13)
if(e.keyCode == 13) {
var newValue = $('#inlineEditor-'+prop).val();
// Create the object which will be sent to the REST resource
var json = {};
json[prop] = newValue;
var itemId = XWiki.currentPage;
app.storeItem(itemId, json, displayNewValue(prop, newValue));
}
}
}
// Display the new value and hide the editor after the save
var displayNewValue = function(prop, newValue) {
return function(error, data) {
if(error) {throw error;}
// Get the view block
var viewElmt = $('span[data-xwiki-editor-property="'+prop+'"]');
var editElmt = $(viewElmt).parent().find('.data-xwiki-property-edit');
$(viewElmt).text(newValue);
$(viewElmt).show();
$(editElmt).hide();
}
}
// Close all editors when the user clicks elsewhere on the page
var closeAllEditors = function() {
$('span[data-xwiki-editor-property]').show();
$('.data-xwiki-property-edit').hide();
}
$('html').click(closeAllEditors);
var stopPropagation = function(e) {e.stopPropagation();};
});
Prerequisites & Installation Instructions
We recommend using the Extension Manager to install this extension (Make sure that the text "Installable with the Extension Manager" is displayed at the top right location on this page to know if this extension can be installed with the Extension Manager).
You can also use the manual method which involves dropping the JAR file and all its dependencies into the WEB-INF/lib folder and restarting XWiki.
Dependencies
Dependencies for this extension (org.xwiki.contrib:api-structured-data-js 0.5):