Forms & Database

Enable Users to Edit Their Form Entries


    Usually a form (its contents) is sent and stored and that's it. If the user opens the form again, it is empty again and he or she can fill it out and send it again. This tutorial shows how to enable users to edit their content later.

    There are 2 scenarios:

    1. E. g. scoring one project: The user shall be able to fill in a form and to send it. If (later) he or she opens the form again, data is still there and can be edited and stored again. The database keeps the last version (and makes a history of former versions)

    2. E. g. collecting jokes: The user shall not only be able to fill in the form and edit its content later, he or she shall also be able to add, edit and delete items on a list

    Since u5CMS version 4.5.1 both scenarios have a conflict management out of the box if you just set the hidden and empty input field <input type="hidden" name="firstsaverwins" />, see example code-tabs below.

    Is your u5CMS installation up-to-date and ready for this functionality?
    ×

    For the functionality described on the page at hand, make sure you are using a current u5CMS version. You'll find the version number by surfing to your website and switching your browser to show the HTML source code. At the very bottom of the source code you'll find a line like this:
    <!-- This site runs with u5CMS version 12.4.3 from https://yuba.ch/u5cms -->
    If there is no such line or no version number or one lower than V8.3.3, see the following instructions:

    u5CMS — How to update an existing installation (version 4 and above)
    ×
    These update instructions are for u5CMS versions 4 and above. For versions below 4 read this!

    1. On your server, go to the files of your old (current) u5CMS installation and copy config.php to config.old.php
    2. Download the ZIP-File , unzip it and delete the file favicon.ico
    3. Further, delete all contents in folder r EXCEPT runonce.php
    4. Transfer the remaining files and folders from the ZIP file over the existing installation (FTP upload)
    5. Now, on your server, copy the database connection parameters $host $username $password $db from config.old.php to config.php
      If there are other dedicated settings in config.old.php, set the same in config.php (compare parameter by parameter)
    6. You must now log in to the backend of your (now updated) u5CMS installation via https://urltoyouru5cmsfrontend/u5admin and open a css-object (e. g. csslayout) in PIDVESA
      ×
      PIDVESA: The very right column of your u5CMS backend is your repository. PIDVESA stands for Pages, Images, Documents, Videos, External Links, Special Functions, and Account. Find these things by clicking the respective radios P I D V E S or A in the top right corner of your backend screen.
      PIDVESA: The very right column of your u5CMS backend is your repository. PIDVESA stands for Pages, Images, Documents, Videos, External Links, Special Functions, and Account. Find these things by clicking the respective radios P I D V E S or A in the top right corner of your backend screen; cf short reference (pdf)
      's S code section, for your site to work correctly again.
    7. You must now log in to the backend of your (now updated) u5CMS installation via https://urltoyouru5cmsfrontend/u5admin for that the database will be updated too

    TROUBLE SHOOTING
    A) If the layout does not look right after having done step 7, go to https://urltoyouru5cmsfrontend/u5admin and open a css-object (e. g. csslayout) in PIDVESA
    ×
    PIDVESA: The very right column of your u5CMS backend is your repository. PIDVESA stands for Pages, Images, Documents, Videos, External Links, Special Functions, and Account. Find these things by clicking the respective radios P I D V E S or A in the top right corner of your backend screen.
    PIDVESA: The very right column of your u5CMS backend is your repository. PIDVESA stands for Pages, Images, Documents, Videos, External Links, Special Functions, and Account. Find these things by clicking the respective radios P I D V E S or A in the top right corner of your backend screen; cf short reference (pdf)
    's S special function's code (htmltemplate & css) section and safe it!
    B) If your navigation does not look well, copy this code to cssnavleft in PIDVESA
    ×
    PIDVESA: The very right column of your u5CMS backend is your repository. PIDVESA stands for Pages, Images, Documents, Videos, External Links, Special Functions, and Account. Find these things by clicking the respective radios P I D V E S or A in the top right corner of your backend screen.
    PIDVESA: The very right column of your u5CMS backend is your repository. PIDVESA stands for Pages, Images, Documents, Videos, External Links, Special Functions, and Account. Find these things by clicking the respective radios P I D V E S or A in the top right corner of your backend screen; cf short reference (pdf)
    's→S→Code and this code to cssnavleftsubtop in PIDVESA
    ×
    PIDVESA: The very right column of your u5CMS backend is your repository. PIDVESA stands for Pages, Images, Documents, Videos, External Links, Special Functions, and Account. Find these things by clicking the respective radios P I D V E S or A in the top right corner of your backend screen.
    PIDVESA: The very right column of your u5CMS backend is your repository. PIDVESA stands for Pages, Images, Documents, Videos, External Links, Special Functions, and Account. Find these things by clicking the respective radios P I D V E S or A in the top right corner of your backend screen; cf short reference (pdf)
    's→S→Code and this code to cssnavtop in PIDVESA
    ×
    PIDVESA: The very right column of your u5CMS backend is your repository. PIDVESA stands for Pages, Images, Documents, Videos, External Links, Special Functions, and Account. Find these things by clicking the respective radios P I D V E S or A in the top right corner of your backend screen.
    PIDVESA: The very right column of your u5CMS backend is your repository. PIDVESA stands for Pages, Images, Documents, Videos, External Links, Special Functions, and Account. Find these things by clicking the respective radios P I D V E S or A in the top right corner of your backend screen; cf short reference (pdf)
    's→S→Code

    C) If after A) and B) the layout still does not look right, change the doctype <!DOCTYPE html> to the old one
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">





Scenario 1
Enable users to send form data and call the form later for editing (so called [mf]-forms)

If a form is in the intranet ?
×

There are two methods, how users become intranet members:

i. You enter the respective e-mail adresses in the intranet members list (PIDVESA's A (where is this?)) and offer a page where the users can order the password, see page 34 in .

OR

ii. Offer a page on which the users may register themselves with your intranet, see Automatic Intranet Inscriptions.

If you do not want to have the form in the intranet, remove the exclamation marks (best is to rename these to pages) and manually set logins according to page 31 in


(its u5CMS object name must begin with the character ! for that) you can add this behaviour: If the user opens the form again his or her data is still filled in, the form can be edited. If the user sends it again, this new version will be present in the database. All that only works with form data still on status "1) new". If you want to work this with other status, change the where-clause $mfwhereclause in config.php.

To enable this behavior, add [mf] if per-user or [mfs] if user-unspecific to the end of your form as follows:
[mf] works user-specifically. Since u5CMS 6.5.1 you may use [mfs] for user-unspecific approaches.

[:h]
[mf][:fi]
[:fo]

Example code
×


[fo:]
[fi:]
[le:]Your score[:le]
[au:]You are logged in as[:au]
[h:]

<input type="hidden" name="thanks" value="thanks" />

<label>Conclusion*</label>
<select name="conclusion_mandatory">
<option value="">please select</option>
<option value="1">poor</option>
<option value="2">medium</option>
<option value="3">good</option>
</select>

<label>Comments</label><textarea rows="3" style="width:98%" type="text" name="comments"></textarea>

<label></label><input type="submit" value="save" /> (later editing is possible)

<input type="hidden" name="in2my" value="off" /><!-- e-mail notifications to admin off-->
<input type="hidden" name="em2cu" value="off" /><!-- e-mail notifications to customer off-->
<input type="hidden" name="em2me" value="off" /><!-- e-mail notifications to me off-->
<input type="hidden" name="firstsaverwins" /><!--no value, just remove input tag if last saver shall win-->
[:h]
[mf][:fi]
[:fo]



Language versions: DO NOT translate the names!
×

Important: If you create two or three language versions of the form, it is crucial that you DO NOT translate the names of the form-fields, every language version MUST have THE IDENTICAL form-field-names!

GOOD ✔:
Englisch Version:  <label>Place:</label><input type="text" name="place" />
French Version:     <label>Lieu: </label><input type="text" name="place" />

WRONG ✘:
Englisch Version:  <label>Place:</label><input type="text" name="place" />
French Version:     <label>Lieu: </label><input type="text" name="lieu" />



Advanced JavaScript on [mf]-forms
×

If you are a very advanced user you want perhaps to introduce a JavaScript function that does something with the form AFTER it is COMPLETELY loaded INCLUDING all fields pre-filled with the data coming from the database. I. e. the point in time when your function begins to fire is very crucial. It is important to know, that the classic onLoad DOES FIRE TO EARLY because data is written to the form fields after onLoad.
The solution is, that your function has to be launched by the function starterscript. The function starterscript itself will be automatically launched by the CMS at the earliest point in time possible, i. e. when the form is ready. The function starterscript is only available and only necessary on pages with forms when they are in the edit mode, i. e. when it is a [mf]-tagged form (these are always in edit mode as described on top of the page at hand) or for non-[mf]-forms ONLY when formedit.php is in the browser’s address field). In other words, if it is not an [mf]-tagged form and you want to launch your function in context of the end users visit and form-filling (and not your later editing), start yourscript classicaly at the end of the page and do not use starterscript.

<script>
yourfunction() {
//here comes your self-made JavaScript
}
function starterscript() {
yourfunction();
}
</script>

Remember, script-tags must be somewhere between [h:] and [:h] !


Scenario 2
Enable users to use the form for more than one item, let them add, edit, and delete items

  1. Create a form, e. g. named !jokesform
    example code
    ×

    [fo:]
    [fi:]
    [le:]Your joke[:le]
    [au:]Welcome[:au]
    [h:]
    <input type="hidden" name="thanks" value="!jokeslist" />
    <label>Name*</label><input type="text" name="name_mandatory" />
    <label>Joke*</label><textarea rows="3" style="width:98%" type="text" name="joke_mandatory"></textarea>
    <center><label>&nbsp;</label><input type="submit" value="save" /></center>
    <div style="float:right"><a href="index.php?c=!jokeslist">cancel</a></div>
    <input type="hidden" name="in2my" value="off" /><!-- e-mail notifications to admin off-->
    <input type="hidden" name="em2cu" value="off" /><!-- e-mail notifications to customer off-->
    <input type="hidden" name="em2me" value="off" /><!-- e-mail notifications to me off-->
    <input type="hidden" name="firstsaverwins" /><!--don't set value, just remove input tag if last saver shall win-->

    <!-- TOEDITITEMS_LOGINS_SAME_AS_[!jokesform] -->
    <!-- TODELETEITEMS_LOGINS_SAME_AS_[!jokesform] -->


    [:h]
    [:fi]
    [:fo]

    Advanced JavaScript in such forms
    ×

    If you are a very advanced user you want perhaps to introduce a JavaScript function that does something with the form AFTER it is COMPLETELY loaded INCLUDING all fields pre-filled with the data coming from the database. I. e. the point in time when your function begins to fire is very crucial. It is important to know, that the classic onLoad DOES FIRE TO EARLY because data is written to the form fields after onLoad.
    The solution is, that your function has to be launched by the function starterscript. The function starterscript itself will be automatically launched by the CMS at the earliest point in time possible, i. e. when the form is ready. The function starterscript is only available and only necessary on pages with forms when they are in the edit mode, i. e. when it is a [mf]-tagged form (these are always in edit mode as described on top of the page at hand) or for non-[mf]-forms ONLY when formedit.php is in the browser’s address field). In other words, if it is not an [mf]-tagged form and you want to launch your function in context of the end users visit and form-filling (and not your later editing), start yourscript classicaly at the end of the page and do not use starterscript.

    <script>
    yourfunction() {
    //here comes your self-made JavaScript
    }
    function starterscript() {
    yourfunction();
    }
    </script>

    Remember, script-tags must be somewhere between [h:] and [:h] !


    Please note the exclamation mark in both names !jokesform and !jokeslist. The exclamation mark makes them intranet-pages!

    Make sure your thanks-value points exactly to the list with the items, in our example this is !jokeslist

    Make sure you mention the above two green steering-html-comments telling the system which logins shall be required for the transactions edit and delete (these transactions are offered on the page !jokeslist).


    “ONLYMINE”: How to restrict users to edit and delete ONLY their OWN items
    ×

    If you want to restrict the users to edit and delete only their own items (meaning when editing/deleting they have to be logged in with the same username as during having added the item), add the prefix SELF_ to the two steering-html-comments:

    <!-- SELF_TOEDITITEMS_LOGINS_SAME_AS_[!jokesform] -->
    <!-- SELF_TODELETEITEMS_LOGINS_SAME_AS_[!jokesform] -->



    Extension1: User stay on form when save clicked
    ×


    1. Remove the Line
      <label>&nbsp;</label><input type="submit" value="save" />
      in !jokesform.

    2. Again in !jokesform, replace the line
      <input type="hidden" name="thanks" value="!jokeslist" />
      with this:
      [$$$:!jokessave]

    3. Create a page exactly named !jokessave, its content must be this:

      [h:]
      <style>
      @keyframes sbmtbttndv {
      0% {background:yellow;left:-50px;top:-50px;}
      100% {background-color:lightgreen;left:0px;top:0px;}
      }
      </style>
      <script src="u5admin/shortcut.js"></script>
      <script>
      shortcut.add("Ctrl+S",function(){document.getElementById('sbmtbttn').click();})
      foundchanges=0;
      foundupload=0;
      monitorchangesoncedone=0;
      monitorchangesinitialdata='';
      monitorchangescurrentdata='';
      function u5uploaddetected() {
      foundupload=1;
      }
      function save() {
      foundupload=0;
      monitorchangesoncedone=0;
      monitorchangesinitialdata='';
      monitorchangescurrentdata='';
      oldbodybg=document.getElementById('body').style.background;
      document.getElementById('body').style.background='lightgreen';
      setTimeout("document.getElementById('body').style.background=oldbodybg",333);
      document.getElementById('sbmtbttndv').style.background='lightgreen';
      foundchanges=0;
      if(location.href.indexOf('formdataedit.php')<0)location.href='index.php?c=!jokeslist';
      foundchanges=0;
      }
      </script>
      <input type="hidden" name="thanks" value="save()" />
      <div id="sbmtbttndv" style="background:lightgreen;padding:7px;margin-left:20px;opacity:0.9;position:fixed;left:0;top:0;white-space:nowrap;animation-name:sbmtbttndv;animation-duration:1s;">
      <a href="index.php?c=!jokeslist">quit</a>
      &nbsp;&nbsp;&nbsp;
      <input id="sbmtbttn" type="submit" value="save [Ctrl+S]" /><span id="monitorchangesasterisk" style="visibility:hidden;color:red;margin-left:-7px;font-weight:bold;font-size:120%">*</span>
      <script>
      if(location.href.indexOf('formdataedit.php')<0&&location.href.indexOf('formdatadel.php')<0)document.getElementById('sbmtbttn').value='add [Ctrl+S]';
      function monitorchanges() {
      e=document.getElementsByName("u5form")[0].elements;
      monitorchangescurrentdata='';
      for(i=0;i<e.length;i++) {
      if(e[i].type!='hidden') {
      if(monitorchangesoncedone==0)monitorchangesinitialdata+=' '+e[i].value;
      monitorchangescurrentdata+=' '+e[i].value;
      }
      }
      monitorchangesoncedone=1;
      setTimeout("monitorchanges()",777)
      if(monitorchangesinitialdata==monitorchangescurrentdata&&foundupload==0){foundchanges=0;document.getElementById('sbmtbttndv').style.background='lightgreen';document.getElementById('monitorchangesasterisk').style.visibility='hidden';document.title=document.title.replace(/\*/g,'')}
      else {foundchanges=1;document.getElementById('sbmtbttndv').style.background='pink';document.getElementById('monitorchangesasterisk').style.visibility='visible';document.title='*'+document.title.replace(/\*/g,'')}
      }
      window.onload = function() {monitorchanges();}
      window.onbeforeunload = function() {
      if(foundchanges!=0&&location.href.indexOf('formdatadel.php')<0)return('There are unsaved changes which will be lost if you are proceeding!');
      if(top===self)self.focus();
      }
      </script>
      </div>
      [:h]




    Extension 2: Secure delete
    ×

    To prevent users from directly deleting content, add these lines somewhere between [fo:] and [:fo]

    <span id="scrdlt" style="display:none"><hr>
    <label>Confirm deleting by entering <b>99</b> here: </label><input size="77" style="width:100px" type="text" name="cliving" /><hr></span>
    <script>
    if(location.href.indexOf('formdatadel.php')>0)document.getElementById('scrdlt').style.display='inline';
    else document.u5form.cliving.value=99;
    </script>





  2. Create a page rendering a list with all items (jokes) entered in the above form.
    Name this page !jokeslist
    example code
    ×

    [:add:!jokesform]
    [h:]<table>[:h]
    [name*,joke*|!jokesform|||1|<tr>
    <td><a href="e?n=!jokesform&id=$id">edit</a></td>
    <td>|<td><a href="d?n=!jokesform&id=$id">delete</a></td>
    </tr>|</td><td>|id desc:dat]
    [h:]</table>[:h]


    The :dat-command used here is explained at

    Do not forget to offer a link to !jokesform (that enables users to add new items).

    If you implemented “ONLYMINE”...
    ×

    ... you want to hide the edit and delete links which won’t work (because the respective items do not belong to the user logged-in).

    Add dynamic classnames and further the style to hide all edit and delete links. Then, with JavaScript, re-display only the links blonging to the user who is currently logged-in:

    [:add:!jokesform]
    [h:]<table>[:h]
    [name*,joke*|!jokesform|||1|<tr>
    <td><a href="e?n=!jokesform&id=$id" class="$ah" style="display:none">edit</a></td>
    <td>|<td><a href="d?n=!jokesform&id=$id" class="$ah" style="display:none">delete</a></td></tr>|</td><td>|id desc:dat]
    [h:]</table>[:h]

    [h:]
    <script> //this script shows all edit and delete links belonging to the user
    show=document.getElementsByClassName('<?php echo md5(u5flatidnlower($_SERVER['PHP_AUTH_USER'])) ?>');
    //If your u5CMS version is before 6.x.x, write strtolower instead of u5flatidnlower
    for(i=0;i<show.length;i++) {
    show[i].style.display='inline';
    }
    </script>
    [:h]


    Things to know:

    $ah looks like PHP but it is not, it is a recursive variable belonging to the :dat-command delivering the md5-hash of the username to whom the respective record belongs.

    The JavaScript re-displaying the edit and delete links uses PHP to get the username of the user currently logged in, therefore you have to switch on PHP in the config.php of your u5CMS installation!


About the intranet-logins for !jokesform and !jokeslist
×

How users become intranet members
×

There are two methods, how users become an intranet members:

i. You enter the respective e-mail adresses in the intranet members list (PIDVESA's A (where is this?)) and offer a page where the users can order the password, see page 34 in .

OR

ii. Offer a page on which the users may register themselves with your intranet, see Automatic Intranet Inscriptions.

If you do not want to have the form nor the items list in the intranet, remove the exclamation marks (best is to rename these to pages; do not forget to remove the exclamation marks also in the code of the respective pages!) and manually set logins according to page 31 in



How to create a public version of !jokeslist
×

The page !jokeslist is not publicly accessible because its name starts with an exclamation mark denoting that it is an intranet-page. To create a public version of !jokeslist (of course offering a login link to the intranet version) create a page, e. g. jokeslistpub (note: NO exclamation mark in the name) and enter this code there:

To edit or delete items, please [log in:!jokeslist]
[$$$:!jokeslist]




Language versions: DO NOT translate the names!
×

Important: If you create two or three language versions of the form, it is crucial that you DO NOT translate the names of the form-fields, every language version MUST have THE IDENTICAL form-field-names!

GOOD ✔:
Englisch Version:  <label>Place:</label><input type="text" name="place" />
French Version:     <label>Lieu: </label><input type="text" name="place" />

WRONG ✘:
Englisch Version:  <label>Place:</label><input type="text" name="place" />
French Version:     <label>Lieu: </label><input type="text" name="lieu" />


Why and how to keep scroll positions on the list
×

After saving an edit of an item which is located on the lower part of the list (e. g. !jokeslist), you will return to the list but on top. To avoid this, read how to keep scroll positions.


How to enable users to upload files, e. g. images


Easier cross-referencing foo!form foo!list etc.
×

In the above !jokesform !jokeslist example you always have to type !jokes. Since u5CMS 8.1.0, when introducing an exclamation mark as delimiter, say you name your pages !jokes!form and !jokes!list, you may cross-reference them with dynamic radical [_pagename!_] plus endings resulting in [_pagename!_]!form and [_pagename!_]!list (no whitespace!). However, this does not work for the SAME_AS-commands shown in the example code. For the SAME_AS-commands it is recommended to point them to a dummy page, which login situation will be inherited then. The endings are updated when you are renaming pages, however, they are not substring-safe, so make them substring-unique (e. g. the endings form edit list pub are substring-unique, the endings over lover dover over2 are not).



Download

Content Management System u5CMS

Service

English⇄German Translation Service

Flowers

blumen-bern-maarsen.ch