XRX/Save File Dialog
From Wikibooks, the open-content textbooks collection
Contents |
[edit] Motivation
You want to allow the user to save form data into a named file in an eXist collection that will not conflict with existing files.
[edit] Method
When the user selects a Save button we will use switch/case to open up a save dialogue. In this dialogue we will list all of the current files in a collection and allow the user to create a new file with a name that does not conflict with any existing file names. If the user selects a file from the lists we will replace the current file name with that file name.
[edit] Using the get-child-resources Function
eXist provides a function that lists the files in a collection. You can get a sorted list of all the files in a collection with the following XQuery
xquery version "1.0";
declare namespace xdb="http://exist-db.org/xquery/xmldb";
declare option exist:serialize "method=xml media-type=text/xml indent=yes";
let $collection := request:get-parameter('collection', '/db/test')
return
<files>{
for $child in xdb:get-child-resources($collection)
order by lower-case($child)
return
<file>{$child}</file>
}</files>
When executed, this XQuery will return the files in a collection. For example here is the URL of an XQuery execution with the collection parameter passed as an argument:
list-files-in-collection.xq?collection=/db/rss
<files> <file>news.rss</file> <file>test.rss</file> </files>
We can then use this XML listing to display a list of existing files and allow the user to select a name that is not on this list.
[edit] Sample Program
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xf="http://www.w3.org/2002/xforms"> <head> <title>Save File Dialog</title> <link type="text/css" rel="stylesheet" href="save-panel.css" /> <xf:model> <!-- This is the data that we want to save to a file on the server. --> <xf:instance id="my-data" xmlns=""> <data> <element1>Element 1</element1> <element2>Element 2</element2> <element3>Element 3</element3> <!-- This is the file name that we are going to save the data into. --> <filename>my-filename.xml</filename> </data> </xf:instance> <!-- Placeholder for the list of files in the target collection. --> <xf:instance xmlns="" id="list-files-results"> <data/> </xf:instance> <!-- This does the save. The server-side script must look for the filename element to do the save to the correct file. --> <xf:submission id="save" method="post" action="save.xq" ref="my-data" replace="all" /> <!-- Gets the list of current files in the server-side collection and puts them in the model. --> <xf:submission id="list-files" method="post" action="list-files.xq" replace="instance" instance="list-files-results" /> </xf:model> </head> <body> <h1>Example of Save File Panel</h1> <xf:input ref="element1"> <xf:label>Element 1:</xf:label> </xf:input> <br/> <xf:input ref="element2"> <xf:label>Element 2:</xf:label> </xf:input> <br/> <xf:input ref="element2"> <xf:label>Element 3:</xf:label> </xf:input> <br/> <xf:switch> <xf:case id="default"> <xf:submit submission="save"> <xf:label>Save As...</xf:label> <xf:toggle case="save-dialog" ev:event="DOMActivate" /> </xf:submit> </xf:case> <xf:case id="save-dialog"> <xf:action ev:event="xforms-select"> <xf:send submission="list-files" /> </xf:action> <!-- This turns all the files into buttons that can be selected to select a specific file. --> <xf:repeat nodeset="instance('list-files-results')/file" class="list-files" id="list-files-repeat"> <xf:trigger appearance="minimal"> <xf:label> <xf:output ref="." /> </xf:label> <xf:action ev:event="DOMActivate"> <!-- Set the filename that we will save to to the value under the selected item. --> <xf:setvalue ref="instance('my-data')/filename" value="instance('list-files-results')/file[index('list-files-repeat')]" /> </xf:action> </xf:trigger> </xf:repeat> <xf:input ref="instance('my-data')/filename"> <xf:label>File Name:</xf:label> </xf:input> <br/> <xf:submit submission="list-files"> <xf:label>Refresh</xf:label> </xf:submit> <xf:submit submission="save"> <xf:label>Save</xf:label> </xf:submit> </xf:case> </xf:switch> </body> </html>
[edit] CSS File
@namespace xf url("http://www.w3.org/2002/xforms"); body {font-family: Helvetica, sans-serif;} .list-files { font-size: .8em; color: blue; background-color: white; border: 1px solid black; padding: 5px; }