|
Cookbook /
WikiForms RecipesSummary: Various recipes for the WikiForms recipe
Version:
Prerequisites:
Status:
Maintainer:
Categories: Forms
Leaving without savingI lost quit a few edits due to sheer stupidity. Leaving the page before saving. I found a bit of java code to prevent this. Simply add the code below to your (farm)config.php or create a new file and include_once that one. I added a language string for English and Dutch, ensure they are on one line in your editor. ( no hidden linefeeds )
if ($action == 'edit') {
XLSDV('en', array(
'e_sure' => 'You have attempted to leave this page. If you have made any chan
ges to the fields without clicking the Save button, your changes will be lost.
Are you sure you want to exit this page?'
));
XLSDV('nl', array(
'e_sure' => 'Je doet een poging deze pagina te verlaten, weet je dat zeker? De
wijzigingen zijn nog niet opgeslagen!!'
));
SDV($InputTags['e_saveeditbutton'][':html'],"<input type='submit' \$InputFormArg
s onclick='needToConfirm = false;'>");
SDV($InputTags['e_previewbutton'][':html'],"<input type='submit' \$InputFormArgs
onclick='needToConfirm = false;'>");
SDV($InputTags['e_cancelbutton'][':html'],"<input type='submit' \$InputFormArgs
onclick='needToConfirm = false;'>");
SDV($InputTags['e_resetbutton'][':html'],"<input type='submit' \$InputFormArgs o
nclick='needToConfirm = false;'>");
SDV($InputTags['e_savebutton'][':html'],"<input type='submit' \$InputFormArgs on
click='needToConfirm = false;'>
<script language='JavaScript'>
var needToConfirm = true;
window.onbeforeunload = confirmExit;
function confirmExit()
{
if (needToConfirm) return \"" . XL('e_sure') . "\";
}
</script>
"
);
}
Another alternative is to use Mozilla Firefox with the "Save Text Area" extension. This allows you to save the data in the textarea to a local text file and once linked you can enable autosave--which works even when you inadvertantly close the browser. Then, all your work is saved locally. BenWilson October 28, 2005, at 09:16 PM Assign and reference titles for numeric page namesThis is a 2 part feature: assign titles to pages with numeric names; and reference a numeric page by its title. To assign a title, declare one of the fields to be type
Now we need a way to reference a page by its title. formtitle.phpΔ answers this requirement. This adds [[?page title]] markup to resolve references to pages that include the page's title in the RecentChanges change summary. You need to tell it the location of a page in your forms group where the new entry form is:
$NewGlossaryPage = 'Glossary.NewEntry'; //for example
include_once("$FarmD/cookbook/formtitle.php");
If you now write
Note that this markup assumes you only want to do this for one forms group per wiki. It needed a special and unambiguous markup and I chose Pagelist/searchbox template to search through Wikiform groupsDescriptionI'm using this template to search through multiple Wikiform groups from a searchbox directive. The results are displayed as a table with the following structure (links in example are fakes):
The title information is taken from paragraph 9 on my Wikiform pages. It would be cool if I could suppress the :title: markup that precedes the actual document title (documents are stored as attachments of the wikiform pages), but I don't know how to do that. A slight problem is that pages in the searched groups that are not Wikiform pages are included in the list as well, leading to random lines to be included in the title field. Another slight problem is that the number of titles displayed is limited by $maxincludes, which might not always be enough. (I have set the value to 250, but there are ca. 3200 documents in my application.) I could exclude the non-document pages as they do not start with a numeric character, but that would load up the searchbox with a rather lengthy string (searching pages 0*, 1*, 2*, 3*, ..., 9*), but I haven't implemented it that way yet because it seems crude. I'll look for a smarter way (if there is any). --Henning October 19, 2006, at 10:27 AM Template
[[#headerinclude]]
(:if equal {<$Group}:)
(:table cellspacing:5px:)
(:cell:)'''Group'''
(:cell:)'''Page'''
(:cell:)'''Title'''
(:cell:)
(:if:)
(:cellnr:)[[{=$Group}]]
(:cell:)[[{=$FullName}|{=$Title}]]
(:cell:)(:include {=$FullName} lines=9..9:)
(:if equal {>$Group}:)
(:tableend:)
----
(:if:)
[[#headerincludeend]]
authorplain field typeThis field type allows you to populate it with the author's name automatically, but without the profile markup. In EntryForm(), insert the following clause (may need to appear before the one matching "author"):
} elseif (preg_match('/^authorplain(?:=(\\d+))?$/',$f[$i]['etype'],$m)) {
$col = ($m[2]) ? $m[2] : 32;
if ($editing) $author = DeLink($fv[$f[$i]['element']]);
else $author = FmtPageName('$Author',$pagename);
$out[] = "<input type='text' size='$col' name='".$f[$i]['element'].
"' value='$author' />";
Also, in FormData(), insert the following clause:
if (preg_match('/^authorplain/',$f[$i]['etype'])) {
$v = $_REQUEST[$f[$i]['element']];
}
shi December 20, 2006, at 02:44 PM Added in version 1.0.52 jr March 22, 2007, at 06:38 PM
buttondate field typeI added this field type to allow the convenience of a button for setting today's date while editing an existing form, e.g. "date closed" of an issue tracking system. Note that the "Today" button is only shown while the date is undefined, to ensure that if the user changes an existing date, s/he really intended to do so. Insert the following code near the top of wikiform.php:
## Add set date script to Header
$HTMLHeaderFmt['todays_date']= <<<SET_DATE
<script language="JavaScript">
<!-- Begin
function SetDate(elementName, y, m, d)
{
// NOTE: we require that the Y/M/D elements appear
// in that order in the form
var date = new Array(y, m, d);
var index = 0;
elements = document.getElementsByName(elementName);
len = elements.length;
for(i = 0; i < len; i++)
{
elements[i].value = String(date[index]);
index += 1;
}
return;
}
// End -->
</script>
SET_DATE;
In EntryForm(), insert the following clause:
} elseif (preg_match('/^buttondate$/',$f[$i]['etype'],$m)) {
if ($editing)
$date = ($fv[$f[$i]['element']]) ? $fv[$f[$i]['element']] : 'yyyy-mm-dd';
else
$date = 'yyyy-mm-dd';
$y = substr($date,0,4);
$m = substr($date,5,2);
$d = substr($date,8,2);
$out[] = "<input type='text' size='5' maxlength='4' name='".
$f[$i]['element']."[]' value='$y' /> - ".
"<input type='text' size='3' maxlength='2' name='".
$f[$i]['element']."[]' value='$m' /> - ".
"<input type='text' size='3' maxlength='2' name='".
$f[$i]['element']."[]' value='$d' />";
// only show "today" button if date does not yet have a value
if ('yyyy' == $y)
{
$date = strftime('%Y-%m-%d',time());
$y = substr($date,0,4);
$m = substr($date,5,2);
$d = substr($date,8,2);
$element_name = $f[$i]['element'] . "[]";
$out[] .= "<input type=button value='Today' onClick=\"SetDate('$element_name', $y, $m, $d)\">";
}
Also, in FormData(), insert the following clause:
elseif (preg_match('/^buttondate$/',$f[$i]['etype']))
$v = str_replace('yyyy-mm-dd','',
implode('-',$_REQUEST[$f[$i]['element']]));
shi December 20, 2006, at 02:44 PM Added as a "today's date" checkbox in version 1.0.52 (no Javascript required). jr March 22, 2007, at 06:38 PM
attach field typeThis creates a new field type 'attach' which silently adds "Attach:" markup to the input data. This makes attaching files to the page easier, since you don't have to put in the "Attach:" by hand, which is helpful for naieve users. In EntryForm(), insert the following clause:
} elseif (preg_match('/^attach(?:=(\\d+))?$/', $f[$i]['etype'], $m)) {
$col = ($m[1]) ? $m[1] : 54;
$out[] = "<input type='text' size='$col' name='".
$f[$i]['element']."' value='".
(($editing) ? DeFile($fv[$f[$i]['element']]) : $default).
"' />";
}
Also, in FormData(), insert the following clause:
elseif (preg_match('/^attach(?:=(\\d+))?$/',$f[$i]['etype'],$m)) {
$v = $_REQUEST[$f[$i]['element']];
if ($v) {
$v = str_replace('Attach:', '', $v);
$v = "Attach:$v";
}
}
Kathryn Andersen February 06, 2007, at 05:39 PM
query against field valuesHere is one way to implement a query to search given field values and return them in the
(Note that this example query form, above, is non-functional without the data and php code to go along with it -- this is just to give you an idea of what it looks like) As you look at the following example here are some points to give you context:
In the page containing the
(:messages:)\\
[+[[Add | Add a new book]]+]
(:input form "http://www.ccl-al.org/pmwiki/pmwiki.php?n=Alb.BookCatalog" method="GET":)
(:input hidden name=n "Alb.BookCatalog":)
|| border=0
|| Original Author Query:||(:input text name=origauthorquery:)|| Albanian Author Query:||(:input text name=albauthorquery:)||
|| Original Title Query:||(:input text name=origtitlequery:)|| Albanian Title Query:||(:input text name=albtitlequery:)||
|| Original Publisher Query:||(:input text name=origpubquery:)|| Albanian Publisher Query:||(:input text name=albpubquery:)||
|| Type Query:||(:input checkbox name=typebookquery value=1:) Book\\
(:input checkbox name=typebookletquery value=1:) Booklet\\
(:input checkbox name=typetractquery value=1:) Tract|| Availability:||(:input select name=availability value=1 label="BOTH in print and out of print":)
(:input select name=availability value=2 label="ONLY books still in print":)
(:input select name=availability value=3 label="ONLY books out of print":) ||
(:input submit Search:)
(:input end:)
All Items matching original author={$origauthorquery} original title={$origtitlequery} type=={$typequery} inprint=={$availablequery}
(:wikilist engauthor="{$origauthorquery}" engtitle="{$origtitlequery}" albauthor="{$albauthorquery}" albtitle="{$albtitlequery}" origpublisher="{$origpubquery}" albpublisher="{$albpubquery}" type="={$typequery}" inprint="={$availablequery}" :)
In the local/ directory create a custom configuration file (named Alb.BookCatalog.php in my case) with this php code:
<?php
foreach ($_GET as $k=>$v) {
$foo = htmlspecialchars($v);
# This keeps the field values current with the form from submission to
# submission, but has nothing to do with PTV
$InputValues[$k] = $foo;
# This creates a PTV
$FmtPV['$'.$k] = "'$foo'";
}
# If all (tract/book/booklet) are blank that's equivalent to all being
# selected -- none doesn't make any sense.
if ($FmtPV['$typebookquery'] != "'1'" && $FmtPV['$typebookletquery'] != "'1'" && $FmtPV['$typetractquery'] != "'1'") {
$FmtPV['$typebookquery'] = "'1'";
$FmtPV['$typebookletquery'] = "'1'";
$FmtPV['$typetractquery'] = "'1'";
$InputValues['typebookquery'] = 1;
$InputValues['typebookletquery'] = 1;
$InputValues['typetractquery'] = 1;
}
# Now from 3 variables ($type . <book|booklet|tract> . query) we need
# to form one variable ($typequery) to be used in the actual query with
# a value such as "book" or "book|tract" or etc
$typequery = '';
if ($FmtPV['$typebookquery'] == "'1'") {
$typequery = 'Book';
}
if ($FmtPV['$typebookletquery'] == "'1'") {
if ($typequery != '') {
$typequery .= '|';
}
$typequery .= "Booklet";
}
if ($FmtPV['$typetractquery'] == "'1'") {
if ($typequery != '') {
$typequery .= '|';
}
$typequery .= "Tract";
}
$FmtPV['$typequery'] = "'$typequery'";
# Now from the $availability variable we need to make a query-able variable
# called $availablequery containing either blank (out of print) or "Yes" (in print
# or "|Yes" (either in print or out of print)
if ($FmtPV['$availability'] == "'3'") {
$FmtPV['$availablequery'] = "''";
} else {
if ($FmtPV['$availability'] == "'2'") {
$FmtPV['$availablequery'] = "'Yes'";
} else {
# this is the default - whether the value is "1" (after form submission)
# or whether it is blank (upon initial form access)
$FmtPV['$availablequery'] = "'|Yes'";
}
}
Peter Bowers December 12, 2007 Note the presence of Cookbook:ProcessForm which takes care of the basic creation of PVs as well as maintaining form values between submissions. Once you have that recipe installed you can put forms like this on any page without messing with group-specific or page-specific code. The only time you would need the page-specific code would be to do various validations. Peter Bowers March 06, 2008, at 11:40 AM
|