Skip to content
Snippets Groups Projects
Tutorial.rst 51.7 KiB
Newer Older
Carsten  Rose's avatar
Carsten Rose committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
.. ==================================================
.. Header hierachy
.. ==
..  --
..   ^^
..    ''
..     ;;
..      ,,
..
.. --------------------------------------------------
.. Best Practice T3 reST  https://docs.typo3.org/typo3cms/drafts/github/xperseguers/RstPrimer/
.. External Links: `Bootstrap <http://getbootstrap.com/>`_:
.. Add Images: https://wiki.typo3.org/ReST_Syntax#Images
..
.. -*- coding: utf-8 -*- with BOM.


Installation of QFQ
===================
First you have to log in into your Typo3. It is going to look like this:

.. figure:: Images/Typo3FirstLogin.png

Then you have to install the QFQ Extension. Go to https://qfq.io/ to download the extension.
In Typo3: Go to the Extensions Menu and click on the upload button. There you choose the the file,
you just downloaded. Now the QFQ extension is installed. If you get an error message that the file is
too big, you have to edit your php.ini file and increase the memory limit.

Copy/rename the file *<Documentroot>/typo3conf/ext/<ext_dir>/config.example.qfq.ini* to
*<Documentroot>/typo3conf/config.qfq.ini* and configure the necessary values: *config.qfq.ini*
The configuration file is outside the extension directory to not loose it during updates.

First we want to include Bootstrap and Javascript. For that we create a template.
Go to list and create a new page.

.. figure:: Images/Typo3FirstPage1.png

Click on Page (inside)

You can choose some Page Title. I am calling it Home. Next you go to Behaviour:

.. figure:: Images/Typo3FirstPage2.png

Here you choose a URL Alias. I am going to call it home. So in my case, to access this page, if would have
to go to the following website: *www.<nameOfYourWebsite>.<domain>/home*

Then you save it. Now you see a new page which is disabled for now. You have to enable it (so the site
will be visible on the website). Right click the Page Home and click 'Enable'.

.. figure:: Images/Typo3Enable.png

Now on that page you want to include Bootstrap and CSS. For that purpose you click on Home and you add
a new content element. Click on template:

.. figure:: Images/Typo3CreateTemplate2.png

Now we name the Template: ext:site (actually you can call it whatever you want)

Under setup you paste the following:

::

    page = PAGE

    page.meta {
      X-UA-Compatible = IE=edge
      X-UA-Compatible.attribute = http-equiv
      viewport=width=device-width, initial-scale=1
    }

    page.includeCSS {
      file1 = typo3conf/ext/qfq/Resources/Public/Css/bootstrap.min.css
      file2 = typo3conf/ext/qfq/Resources/Public/Css/bootstrap-theme.min.css
      file3 = typo3conf/ext/qfq/Resources/Public/Css/jqx.base.css
      file4 = typo3conf/ext/qfq/Resources/Public/Css/jqx.bootstrap.css
      file5 = typo3conf/ext/qfq/Resources/Public/Css/qfq-bs.css
    }

    page.includeJS {
      file01 = typo3conf/ext/qfq/Resources/Public/JavaScript/jquery.min.js
      file02 = typo3conf/ext/qfq/Resources/Public/JavaScript/bootstrap.min.js
      file03 = typo3conf/ext/qfq/Resources/Public/JavaScript/validator.min.js
      file04 = typo3conf/ext/qfq/Resources/Public/JavaScript/jqx-all.js
      file05 = typo3conf/ext/qfq/Resources/Public/JavaScript/globalize.js
      file06 = typo3conf/ext/qfq/Resources/Public/JavaScript/tinymce.min.js
      file07 = typo3conf/ext/qfq/Resources/Public/JavaScript/EventEmitter.min.js
      file08 = typo3conf/ext/qfq/Resources/Public/JavaScript/typeahead.bundle.min.js
      file09 = typo3conf/ext/qfq/Resources/Public/JavaScript/qfq.min.js

      # Only needed in case FormElement 'annotate' is used.
      file10 = typo3conf/ext/qfq/Resources/Public/JavaScript/fabric.min.js
      file11 = typo3conf/ext/qfq/Resources/Public/JavaScript/qfq.fabric.min.js
    }

    page.10 = TEXT
    page.10.value = Hello World

    page.20 < styles.content.get

The last 3 lines can be removed later. They are just there to see if it works. If it worked on the webpage
we should see the text: "Hello world".

Next you go to Options and mark Constants, Setup und Rootlevel.

.. figure:: Images/Typo3CreateTemplateOptions.png

Next you go to Includes,  Include static and you select: Conten Elements (fluid_styled_content)

.. figure:: Images/Typo3CreateTemplateIncludes.png

Now you are ready to see for a first time your Website (which has for now only one line of text (Hello World)).
To take a look at the website make a right click on Home and press on show.

.. figure:: Images/Typo3Show.png

So now QFQ is installed and Javascript and Bootstrap can be used. Now we want to add the FormEditor to the
website such that from now on we are going to be able to create Forms and FormElements on the website. For that
purpose we Create a new QFQ element and past in a SQL Query:

First you create a new Page called Setup:

.. figure:: Images/Typo3CreateSetup1.png
.. figure:: Images/Typo3CreateSetup2.png

As Page Title you type in Setup (As always you are free to name it however you want).
Next you have to go to Behaviour and under URL Alias you type in setup.
As before you have to enable the page.

From now on I am going to use another template. I do this because with my template the webpage is going to look better.
So from now on my webpage will look not the same as your website. Don't worry about it.

Now Create a subpage of Setup. There we will put the FormEditor in.
In order to do that right click Setup, go to Page Actions and click on New:

.. figure:: Images/Typo3FormElement1.png
.. figure:: Images/Typo3FormElement2.png

Here You Type in Form as Page Title and form as an alias.

Next you have to create a template for this page. You can copy the template from the home page.
In order to do that go to Home and copy the Template:

.. figure:: Images/Typo3CopyTemplate.png

Now you go to Setup and click on the past Button:

.. figure:: Images/Typo3CopyTemplate2.png

Now you click on the Form Page and create a new QFQ element.

.. figure:: Images/Typo3FormQFQ.png

There you click on Page Content.
After that Chose the type QFQ Element.

.. figure:: Images/Typo3FormQFQ2.png

Now past in the following code into the Text field:

::

    form={{form:SE}}
    10 {
        sql = SELECT CONCAT('{{pageId:T}}&form=Form&') as _Pagen, '#', 'Name', 'Title', 'Table', '' FROM (SELECT 1) AS fake WHERE  '{{form:SE}}'=''
        head = <table class="table table-hover qfq-table-50">
        tail = </table>
        rbeg = <thead><tr>
        rend = </tr></thead>
        fbeg = <th>
        fend = </th>
        10 {
            # All forms
            sql = SELECT CONCAT('{{pageId:T}}&form=Form&r=', f.id) as _Pagee, f.id, f.name, f.title, f.tableName, CONCAT('form=form&r=', f.id) as _Paged FROM Form AS f  ORDER BY f.name
            rbeg = <tr>
            rend = </tr>
            fbeg = <td>
            fend = </td>
        }
    }


Now your page should look like this:

.. figure:: Images/FormEditor.png

It is important to say that your screen can look different. Probably your list is going to be empty. If so, don't worry.
It doesnt matter as these are all forms which we are not going to use. We are going to create new Forms.

Creating Forms
==============

Now we are going make a little project. We want to create a website where you can apply for different jobs.
Step by step we will create a little recruiting tool out of it. Our first step will be that we create a form where the
applicant can fill out some information about himself like his name, first name, date of birth etc.
To store the data the applicant fills into the form we will create a database, and a little
visualisation of the database.

First of all let's create our database. In order to do that log in into your phpMyAdmin.

There you have to create A database. When you have your Database go to SQL and past in the following code: ::

    CREATE TABLE  `Application`
    (
       `id` INTEGER NOT NULL AUTO_INCREMENT ,
       `name` VARCHAR( 255 ) ,
       `firstName` VARCHAR( 255 ) ,
       `gender` ENUM( 'male','female' ) ,
       `dateOfBirth` DATE ,
       `adrStreet` VARCHAR( 255 ) ,
       `adrZipCity` VARCHAR( 255 ) ,
       `uploadPath` VARCHAR( 255 ) ,
       PRIMARY KEY `id`(`id`)
    ) ENGINE = INNODB DEFAULT CHARSET = utf8

The Query above creates a table with some rows in it. The purpose of that database is that whenever somebody fills
out a form, we will be able to save the data into this database.
The next step is, that we should create our fist Visualisation of our database. At the beginning of a project it seems
silly to do that, but the further we go and the more tables we use in that project, the
more complicated our datastructure is going to become. At that point we are not only happy about the dia, but we are
even dependent of that visualisation of our Database as elsewise we would lose track of our datastructure.
So it is very important to keep in mind, that whenever you have some new tables or new ways the different tables are
connected to each other, to add this into the visualisation.

As soon as our database structure is a little bit more complicated the dia is going to look something like this:

.. figure:: Images/DiaFull.png

The programm we are going to use is called Dia. You can use whatever programm you want. If you want to use the same
program as me you can download it here: http://dia-installer.de/

When you first start the program it will look something like this:

.. figure:: Images/DiaEmpty.png

First you have to create a Diagramm in mode Database.

.. figure:: Images/DiaSettings.png

Next you have to create a rectangle:

.. figure:: Images/DiaRectangle.png

You double-click the box, go to Attributes, and add all the table rows.
At the end it should look like this:

.. figure:: Images/DiaApplicationTable.png

Now we are going to create our first form. Whenever a person wants to apply for a job, he or she has to fill out this form.
For that purpose we go to our website, go to Form and create a new form by clicking on the + sign:

.. figure:: Images/FormEditorFirstForm.png

Then you will see the following screen:

.. figure:: Images/FormEditorBasic.png

For the name you can type in whatever you want to. I am going to call it Application.
The most imporant thing here is that you chose the right table. The data, entered by the user will be saved in that Database Table.
We select of course the Application Table.

.. figure:: Images/FormEditorBasic2.png

Now we are ready to create our first Form Elements. For this purpose go to the Pill Form Element.
Then we click on the + sign.

.. figure:: Images/FormEditorFormElement1.png

First we want to create a textbox, where the user can input his name. So what we want to do is create
a Form Element of the type text, which stores the users input into the row name of the table Application. So what we do is the follwing:
- Name: We type in name (name of the database row)
- Label: Name (is what will be desplayed in front of the textbox)
- Type: Text
Then you can save the Form Element and click at the eye to take a look at the form (how the form looks like).

.. figure:: Images/FormEditorName.png

It should look something like this:

.. figure:: Images/FormEditorName2.png

Now do the same thing for the First Name. It works exactely the same way. I won't explain it again. Now your form should look like this.

.. figure:: Images/FormEditorName3.png

Next we want to create a checkbox, where the user can enter his gender. As there are only 2 genders.
For that purpose we create a new form Element of the type checkbox.

- Name: We type in gender (name of the database row)
- Label: Gender (is what will be displayed in front of the Checkboxes)
- Type: Radio

Detailed information: https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info-053/Manual.html#type-radio

.. figure:: Images/FormEditorBasicGender2.png

But here it is not enough to only create a checkbox. In addition we have to define which possibilities the user has for an input.
We do that as follows: We go to the pill value and write the following into the textbox parameter: ::

    itemList=male,female

Now it is going to look like this:

.. figure:: Images/FormEditorGender3.png

But we want that the 2 radios are at the same line. For that purpose we edit the Form Element. We go to the Pill Layout and
change MaxLength to 2.

.. figure:: Images/FormEditorGender4.png

In general if you want to put n elements on the same line, Put n as the MaxLength.

Next we want to create a textbox, where the user can enter his date of birth. We do the exactely same thing as what we did
when we wanted to create a textbox for the name or the first name. But this time the type of the Form Element is going to be
Date.
Details: https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info-053/Manual.html#type-date


.. figure:: Images/FormEditorDateOfBirth.png

As an exercise for you, you can add 2 more Form Elements (Textboxes) where the user can enter his Street (incl. number) and
zip. It should look like this:

.. figure:: Images/FormEditorAdresses.png

Now we have a few Form Elements but it doesn't look very nice. Moreover everything is on the same pill. So we want to create 2 pills.
One pill for your personal data like name, first Name, date of birth and gender and another pill for your adress.
For that purpose we are going create a new Form element. This time it will be a Form element of class container und of type pill.
Details: https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info-053/Manual.html#type-pill-tab

.. figure:: Images/FormEditorPill1.png

Next we want to assign all Form elements which contain personal data to that pill. To do that, edit one of the form Elements which
should be in this pill and assign it to the corresponding pill:

.. figure:: Images/FormEditorPill2.png

We do the exact same thing for all the elements which contain personal data. I am not going to show it for each element,
as it's the same for all.

Next we have to create a second pill which contains all form Elements for the adress. As before create a new pill:

.. figure:: Images/FormEditorPill3.png

And assign the 2 left form Elements to that pill (excately as before).

Now your Form should look something like this:

.. figure:: Images/FormEditorPill4.png


Report
======


Next we want to create a page where we can see a list of all applications so far. Because the problem is that people have the
possibility to open the Form and write their names into the Form but that information is displayed nowhere.
So now, in order to see later anything in that list of all applications, it would be useful if you open the Form and type something in.
Because if we don't, the list of applications will be empty of corse.
Next go to Typo3 and create a new page.

.. figure:: Images/Typo3ReportCreateNewPage.png

.. figure:: Images/Typo3ReportCreateNewPage2.png

Next you have to give the page a title. I am going to call it Applications:

.. figure:: Images/Typo3ReportCreateNewPage3.png

And you have to give the page a page Alias.

.. figure:: Images/Typo3ReportCreateNewPage4.png

As always you have to enable the page.

.. figure:: Images/Typo3ReportCreateNewPage5.png

Next you have to put some content on the Applications page. For that purpose create a new QFQ Element:

.. figure:: Images/Typo3ReportCreateNewPage6.png

Click on Page Content:

.. figure:: Images/Typo3ReportCreateNewPage7.png

Chose the type QFQ Element.

.. figure:: Images/Typo3ReportCreateNewPage8.png

Now you can put SQL Queries into the Text box.

You can paste the following SQL Query into the Text box: ::

    10 {
      sql = SELECT a.id, a.name, a.firstname, a.gender, a.dateOfBirth, a.adrStreet, a.adrZipCity FROM Application AS a
        head = <table class='table table-hover qfq-table-50'><thead><tr><th>#</th><th>name</th><th>First Name</th> <th>Gender</th><th>Date of birth</th><th>Street</th><th>Zip</th></tr><thead><tbody>
        tail = </tbody></table>
        rbeg = <tr>
        rend = </tr>
        fbeg = <td>
        fend = </td>

    }

This code displays all Applications so far. The first part (The select statement) is just usual SQL Code. You should know that
already. The interesting part is the part below the SQL statement. Here a little explaination of that part of the code:

*  head = ... : This line is being executed before the SQL statement gets executed. So it is generating a table header.
*  tail = ... : This line is being executed as soon as the SQL stement is fininshed and all the data has been displayed on the screen.
*  rbeg = ... : Rbeg means row beginn. At every row beginn a <tr> is being placed.
*  rend is row end, fbeg is field beginn and fend is field end. So whenever a field or a row starts or ends, one of the HTML statements
are going to be executed.

Details: https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info-053/Manual.html#qfq-keywords-bodytext

So now your page is going to look like this:

.. figure:: Images/Typo3RecordDone.png

Our next goal is to add a little putton at the left of every row of the table. It is going to look like this:

.. figure:: Images/Typo3RecordButtonEditShow.png

When we click on the button we will open the Form Application of the respective person. So the idea is the following.
When you open up a form with a few parameters like for example the id of the person logged in, you can edit the data of
that certain person. So if for example Kevin Miller who lives at Examplestreet 123 changes his adress to Examplestreet
128 you can open the Form Application with his id as a parameter and edit his data. If you would open up the Form without
any id the Form would't know from which person you want to change the data. The result: You are going to create a new Application
instead of changing an existing user.
So what you want to do: Whenever you open the Form Application, you want to pass a parameter namely your id.
So first we create the button you can see in the image above. To do that go back to your QFQ Record on the Application page and
edit the QFQ Element.

Delete the whole Query and paste in the following SQL Statement: ::

    form={{form}}

    10 {
      sql = SELECT CONCAT('{{pageId:T}}&form=Application&') as _Pagee, a.id, a.name, a.firstname, a.gender, a.dateOfBirth, a.adrStreet, a.adrZipCity FROM Application AS a, (SELECT 1) AS fake WHERE  '{{form:SE}}'=''
        head = <table class='table table-hover qfq-table-50'><thead><tr><th>Form</th><th>#</th><th>name</th><th>First Name</th> <th>Gender</th><th>Date of birth</th><th>Street</th><th>Zip</th></tr><thead><tbody>
        tail = </tbody></table>
        rbeg = <tr>
        rend = </tr>
        fbeg = <td>f
        fend = </td>

    }

This SQL statement is a little more complicated, but most of the content didn't change at all. Now I am going to give an explanation
of the new lines of code:

- *form = {{form}}*: this line tells the website, that on that specific page we want to create a button, which opens up a Form.
If this line would miss, we could't open the form. If you don't know what I mean, just delete the first line of code, save
the QFQ element, go to the webpage and try to open the Form with the little button at the left. You will see, the button is
not working.

Details: https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info-053/Manual.html#qfq-keywords-bodytext

- *SELECT CONCAT('{{pageId:T}}&form=Application&') as _Pagee*: This line create the button which opens up the Form.
  Details: https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info-053/Manual.html#store-typo3-bodytext-t

  - *{{pageId:T}}* is just a number. When you go to the Typo3 Page, and you hover over the page of Application, you will see
    the Page Alias and the Page id. Here the Statement *{{pageId:T}}* goes to Typo3 and checks what the PageId of the current page is.
    The reason why *{{pageId:T}}* is a part of the URL is simple. We don't want to create a new page just to open up a Form. The Form
    is going to be opened on the Application page.

  - *&form=Application&*: This line opens up the Form Application. Whenever you want to create a link, where a specific Form is
    going to be opened, you have to specify which Form you want to open up, with this notation.

  - *AS _Pagee: This part tells QFQ that we want to create a button with an edit symbol on it.

- *(SELECT 1) AS fake WHERE  '{{form:SE}}'=''*: This statement is at the end of the SQL Statement and looks complicated. What it does:
If this line of code wouldn't be there you would have the following problem. When you open up the link, you want to see only the Form,
and not the list of all other Applicants under the form. This line of code does exactely that. It does hide the list of
people as soon as you open up the form.
If it is not clear what is meant by that I'll show you a few screenshots to illustrate the problem:

If you would delete the following statement: *(SELECT 1) AS fake WHERE  '{{form:SE}}'=''*, this would happen:

When I open up the Application page it will look something like this:

.. figure:: Images/Typo3FakeExample1.png

So far it is fine. But if we click on the edit button, we see that the Form displayed as wished, but the list of applicants is still
bellow the Form:

.. figure:: Images/Typo3FakeExample2.png

But we don't want that. We want that if we open up the Form, the rest of the list won't be displayed anymore. So if we paste back
the following line of code: ::

    (SELECT 1) AS fake WHERE  '{{form:SE}}'=''

into the SQL statement, when we open the Form, the list is going to be hidden.

Now we have a page, where all Applications are listed. But there is still a problem: When we open the form of a person, the form is
empty. But what we want is that whatever data the Applicant entered and saved, when he opened the Form, should be displayed when we open
the form.
To fix that problem we have to do the following:

When we click on the Editbutton on the Applications page, we have to "tell the button" which person's record we want to change.
So we go back to the Typo3 page and edit the QFQ element again.
Delete your query and paste the following: ::

    form={{form}}

    10 {
      sql = SELECT CONCAT('{{pageId:T}}&form=Application&r=',a.id) as _Pagee, a.id, a.name, a.firstname, a.gender, a.dateOfBirth, a.adrStreet, a.adrZipCity FROM Application AS a, (SELECT 1) AS fake WHERE  '{{form:SE}}'=''
        head = <table class='table table-hover qfq-table-50'><thead><tr><th>Form</th><th>#</th><th>name</th><th>First Name</th> <th>Gender</th><th>Date of birth</th><th>Street</th><th>Zip</th></tr><thead><tbody>
        tail = </tbody></table>
        rbeg = <tr>
        rend = </tr>
        fbeg = <td>
        fend = </td>

    }

Now when you open the form, you can see all available information about the person.

Login
=====

Now we want a LogIn page.
For that we have to create a folder in Typo3 where we define all FE Users. We have to define all usergroups and users.
Later you might want to integrate an LDAP database for that purpose. But more on that later. Moreover you have to
create a first user with username and password in order to be able to login.
In this tutorial I am not going to explain that in detail.

Next go to your Typo3 page and add a login Element on the page "Home".

.. figure:: Images/Typo3Login1.png

When you go to the Pill Pluin you can change the html template of the login page if you don't like the standart
design.
Moreover you have to add you FE User Folder to the "User Storage Page"

.. figure:: Images/Typo3Login2.png

Now when you try to connect to the webpage, you first have to login with your credentials.

Now whenever somebody is logging in, he can see everything. He can edit forms, he can go to the admin panel etc. Of course
we don't want that. We want that every Typo3 page has a FE User Group, assigned to it. So if for example a person is logged in
and this is assigned to the user group Base, he can't access the admin panel.
On order to do that, open Typo3 and click on the Page Setup. Edit the page and go to Access.
There you will se the subsection Usergroup Access Rights. Here you can assign the admin to the Page Setup. ( In the FE User
Folder I called the admin setup). So in my example I am going to assign the Setup Page to the setup Usergroup.

.. figure:: Images/Typo3AccessSetup.png


Now we want to create the Form where we can add new Reviewers to the Table Person. In the FormEditor I enter the following
data:

.. figure:: Images/FormEditorPersonFrom1.png

Now we want to create a form where we the admin of the page can add new Reviewers to the page. That form should contain
5 Textboxes, (name, first name, email adress, adress (street), adress (zip with city) ). Additionally you should add a
radio where you can chose the gender with an itemlist and a datebox, where the user can input his date of birth.
As the primary table you chose the Person table. Since we already did almost the same form I am not going to show you
how it works again. If you are unsure please look how we did the first form.

But the problem is that so far there exists no table named person. So we have to create it first. You can paste
the follwing query into the SQL prompt in order to get that table: ::

    CREATE TABLE  `JobOffer`
    (
        `id` INTEGER NOT NULL AUTO_INCREMENT ,
        `name` VARCHAR( 255 ) ,
        `firstName` VARCHAR( 255 ) ,
        `gender` ENUM('male','female') ,
        `dateOfBirth` DATE ,
        `adrStreet` VARCHAR( 255 ) ,
        `adrZipCity` VARCHAR(255) ,
        `email` VARCHAR( 255 ) ,
        `created` DATETIME ,
        `modified` DATETIME ,
        PRIMARY KEY `id`(`id`)
    ) ENGINE = INNODB DEFAULT CHARSET = utf8

Your Form you just created should look like this:

.. figure:: Images/FormEditorPersonFrom2.png

Important to mention is that you don't add Applicants with that form. You only add Reviewers and Admins to the page.
But for now there is no way how you can distinguish between admin and reviewer since both are saved in the table person.
So what we want to do:
In this form, you should be able to tell the form if the person you want to add to the database should be a reviewer or an
admin.
So first we create a new row in the table Person named flag. The idea is that every reviewer has *flag = 0*, every
admin has *flag = 1*. With the following command you can add the new row to the database: ::

    ALTER TABLE `Person` ADD `flag` INT(11) NOT NULL AFTER `email`;

Next you have to add a radio to the form Person where 1 = admin and 0 = reviewer

.. figure:: Images/FormEditorFlag1.png

and in the pill value paste the following into the textbox parameter.

Now we need a page where we can access that form. So we want a query where we can edit existing reviewers and existing
admins. Moreover we want to see, if the given people are admins or reviewer. So create a new Typo3 page and add a QFQ
element to it. Don't forget to add a page alias. Now try to create the following query:

At the top of the page we want to have a plus sign where you can create a new reviewer/admin. Under that you want 2 tables:
One table for all the admins and the other table for all the reviewers. Moreover you should have an edit button at the left
of every person where you can edit their data.
Here a working query if yours is not working: ::

    form={{form}}
    10 {
      sql = SELECT CONCAT('{{pageId:T}}&form=person&r=0') as _Pagen, '<br><br>' FROM  (SELECT 1) AS
      fake WHERE  '{{form:SE}}'=''
    }
    20 {
      sql = SELECT p.flag AS _flag, IF(p.flag=0,'Reviewer','Admin') AS _type FROM Person AS p GROUP BY p.flag

      10 {
        sql = SELECT CONCAT('{{pageId:T}}&form=person&r=',p.id) as _Pagee, p.id, p.name,
       p.firstname, p.gender,  p.dateOfBirth, p.adrStreet, p.adrZipCity, p.email FROM Person AS p,
        (SELECT 1) AS fake WHERE '{{form:SE}}'='' AND p.flag = '{{flag:R}}'
        head =  <table class='table table-hover' style="width: unset"><b>{{type:R0}}</b>
        tail = </tbody></table>
        rbeg = <tr>
        rend = </tr>
        fbeg = <td>
        fend = </td>

      }
    }


Job Advertisements
=================

Until now it is only possible to apply to a job and to add reviewers, which evaluate all the applications. But we
can't put any job advertisements online. So that's our next task. We want to create three things:

1) A page where the admin can add new Job advertisement. He should be able to write a should description of the job and
   the job requirements. Moreover it should be possible that the admin can set a start and end date. The advertisement
   will only appear on the website in that time intervall. the rest of the time it will be hidden.

2) A page where all the Job Advertisements shown. So that if somebody is looking for a job in that firm, he can look thow
   all the job advertisments on one page and there should be a button apply where we open the Application Form Automatically.

3) Secondly we want to edit the Application Form slightly. It is very important that the person is able not only able to
   apply for a job, but also chose on the form, for which job he is applying. Moreover the applicant should be able to
   upload a few files (like the CV, the letter of motivation or certificate of employment from previous jobs).

So let's start with task 1:
So first thing we have to create a new table in the database and of course as always add it to our database visualisation.
The new table is going to be called job offer and every record contains 1 joboffer with all important information about
the job.
As always I will give you the Query which you can paste into the SQL Prompt to create the table: ::

    CREATE TABLE  `JobOffer`
    (
        `id` INTEGER NOT NULL AUTO_INCREMENT ,
        `type` enum('student','staff') ,
        `title` VARCHAR( 255 ) ,
        `start` DATE ,
        `end` DATE ,
        `status` ENUM( 'open','intranet','closed','finished','trash' ) ,
        `pathFileNameDetail` VARCHAR(255) ,
        `description` TEXT ,
        `emailContact` VARCHAR( 255 ) ,
        `created` DATETIME ,
        `modified` DATETIME ,
    PRIMARY KEY `id`(`id`)
    ) ENGINE = INNODB DEFAULT CHARSET = utf8

Next we add it to the Database visualisation:


.. figure:: Images/DiaJobOffer.png

Next we want to create the form where the admin can add and edit existing job Offers:
For that create a new form, call it job offer and assign the table jobOffer as its primary table:

First we want to create a Textbox Job Title:

.. figure:: Images/FormEditorJobOffer1.png

Next we want to know if the job is primary a student job, or a job for people with a degree. For that purpuse we are going
to create our first select FormElement. Create a new Form Element of the type select, save the data into the column type:
Details: https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info-053/Manual.html#type-select

.. figure:: Images/FormEditorJobOfferType.png

go to values and type in the following into parameter:

.. figure:: Images/FormEditorJobOfferType2.png

Here we work with an itemlist. Usually you don't want to do that. But for now we don't want to put too much complexity
into the database structure, so we leave it like this for now.

Next thing we want to add is a from to date (meaning that the Job advertisement will only be available on the webpage in
this time interval. First we want to create the starting date: So create a new form element with type date:

.. figure:: Images/FormEditorOnline1.png

And we want to create a second form element for the end date:

.. figure:: Images/FormEditorOnline2.png

But the problem now is that the two of them are on 2 different lines. Our goal is, that at the end, it look something
like this:

.. figure:: Images/FormEditorOnline3.png

So now is the first time that we actually do some styling to a form element. We do that as follows:
Edit your textbox where the startpoint of the intervall is chosen.

.. figure:: Images/FormEditorOnline4.png

 Go to the pill layout and do the following changes:

 .. figure:: Images/FormEditorOnline5.png

BS Label Column defines how big the label is renderes.
BS Input Column defines how big the input box is renderes.
BS Note Column defines how big the note is renderes. (until now we never used notes) so don't worry if you don't know
about what note I am talking about.
Important to mention is that the sum of all BS Label Column, BS Input Column and BS Note Column has to sum up to 12 for
each row. Now I might think that in our case it only sums up to 5 and I made an error. But earlier I mentioned that we
want the start and the end date on the same row. So if for example we have 2 form elements in the same row the sum of
all BS Label Columns, BS Input Columns nad BS Note Columns have to add up to 12. That's why I didn't made a mistake so far.

Second thing to mention: We also disabeld */row*. Usually if */row* is enabled, after the form element QFQ will create a new
row. But if we disable it the next form element will be on the same row. That's exactely what we want.

Details: https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info-053/Manual.html#multiple-elements-per-row

Now let's edit the end date form element. First go to the basic pill and change the label:

 .. figure:: Images/FormEditorOnline6.png

Next you go to the pill value and make almost the same changes as before:

 .. figure:: Images/FormEditorOnline7.png

Here instead of disabling */row*, we diable *row*. The reason. We dont want that at the beginning of the form element a new
line is generated.

Next we want to create a first Upload form element. For first you have to know exactely where you want to save your files.
As this is no Typo3 Tutorial I am not going to expain that. So at that time I am assuming that you already know exactely where
the files should be saved.

Create a new from element of type upload:

.. figure:: Images/FormEditorUpload1.png

Next you have to go to the pill value and paste the following Query into the value textbox: ::

    {{SELECT SUBSTRING_INDEX(jo.pathFileNameDetail, '/', -1) FROM JobOffer AS jo WHERE id={{slaveId}} }}

and the follwing Query into the parameter textbox: ::

    slaveId={{id:R0}}
    fileDestination={{SELECT 'fileadmin/jobOffer/', jo.id, '-{{filename}}' FROM JobOffer AS jo WHERE jo.id={{id:R0}} }}
    sqlUpdate={{UPDATE JobOffer SET pathFileNameDetail = '{{fileDestination}}' WHERE id={{slaveId}} LIMIT 1}}

    fileReplace=always

Details: https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info-053/Manual.html#type-upload

Next we want to give the admin the opportunity to write a little description about the job. But the admin should be
able to create a good looking textbox where words can be bold or italic, the admin should be able to chose the font etc.
So we dont want to only give him a regular textbox. We want to create a form element of the type editor:

.. figure:: Images/FormEditorEditor1.png

We want that the textbox is a little bigger than usual. So we go to the pill layout and chose the size 200,600:

.. figure:: Images/FormEditorEditor2.png

Next we go to the pill value and paste the following into the textbox parameter: ::

    editor-plugins=code link lists table textcolor textpattern visualchars

    editor-toolbar=code searchreplace undo redo | styleselect link table | fontselect fontsizeselect | bullist numlist outdent indent | forecolor backcolor bold italic

    editor-menubar=false
    editor-statusbar=false

It is not important to know what every line of code does. The important thing is that this is the code which makes the
editor look good in the form.

The last thing we want to add is a simple textbox where the contact email address for that specific job is stored.

.. figure:: Images/FormEditorEmailContact.png

Now your form should look something like this:

.. figure:: Images/FormEditorJobOffer1.png

Now we need a page from which this form can be accessed. So in the admin area we want to create a page where we can edit
job Offers, create new and delete old. Moreover we should have a list of all current job Offers.

For that purpose we want to create a new Typo3 page in the admin panel. As always we want to give the page a useful title
and don't forget to add a page alias. Moreover we have to enable the page and add a QFQ element. I am not going to
do that step by step as it already has been explained earlier.

You can paste the following Query into the QFQ element: ::

    form={{form}}

    10 {
      sql = SELECT CONCAT('{{pageId:T}}&form=jobOffer&r=0') as _Pagen FROM  (SELECT 1) AS fake WHERE  '{{form:SE}}'=''
    }
    20 {
      sql = SELECT CONCAT('{{pageId:T}}&form=jobOffer&r=',jo.id) as _Pagee, jo.id, jo.type, jo.title, jo.start, jo.end, jo.description, jo.emailContact FROM JobOffer AS jo, (SELECT 1) AS fake WHERE  '{{form:SE}}'='' AND jo.start<=NOW() AND NOW()<= jo.end
        head = <table class='table table-hover qfq-table-50'><thead><tr><th>Form</th><th>#</th><th>Type</th><th>Title</th> <th>Start</th><th>End</th><th>Description</th><th>Email</th></tr><thead><tbody>
        tail = </tbody></table>
        rbeg = <tr>
        rend = </tr>
        fbeg = <td>
        fend = </td>

    }

Since this is all either usual SQL or already explained QFQ notation, i am going to leave it as an exercise for you to
understand this code.
It might be better if instead of copying my code, trying to do it first on your own.

Next we want to create a page where potential applicants can apply. We can use almost the same Query for this new page
than for the existing admin page.

As as always create a new Typo3 page and add a QFQ element. You can paste the following Query into the QFQ Element: ::

    form={{form}}

    10 {
      sql = SELECT CONCAT('u:{{pageId:T}}&form=Application&r=0','|t:Apply|b:1|s:1') as _link, jo.id, jo.type, jo.title, jo.start, jo.end, jo.description, jo.emailContact FROM JobOffer AS jo, (SELECT 1) AS fake WHERE  '{{form:SE}}'='' AND jo.start<=NOW() AND NOW()<= jo.end
        head = <table class='table table-hover qfq-table-50'><thead><tr><th>Form</th><th>#</th><th>Type</th><th>Title</th> <th>Start</th><th>End</th><th>Description</th><th>Email</th></tr><thead><tbody>
        tail = </tbody></table>
        rbeg = <tr>
        rend = </tr>
        fbeg = <td>
        fend = </td>

    }

Here we see the following statement which might be new for you: ::

    CONCAT('u:{{pageId:T}}&form=Application&r=0','|t:Apply|b:1|s:1') as _link

Until now whenever we wanted to create a button to open a form, we always worked with *_Pagen* or *Pagee*. These are most
of the time good enough. But this time we needed something more. We needed a button with the word "Apply" on it.
For that purpuse we used the button *_link* insted of *_Pagee*. One more thing you might find confunsing are the qualifier.
We well go throw all qualifiers used in this example:

u: The u qualifier is used in the first part of the link *(u:{{pageId:T}}&form=Application&r=0')*. The u qualifier just
tells QFQ that whatever comes in between u: and | is going to be the link.

t: Whatever comes in between t: and | is going to be written on the button.

b: For b you have a few choices. b:1 just means that you render a button, b:danger would render a red button. These are
just bootstrap buttons.

s: *s:0* means no sip, *s:1* means a sip.

Details: https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info-053/Manual.html#column-link

Now the problem is that when we click on the link, the application form is called. But we don't know for which Job
the applicant wants to apply. That's why we have to modify the form application a little bit.
We add a new column to the Table Application. In this new Column we are going to store for which job the person just applied.
Here the SQL Query to add the new Column: ::

    ALTER TABLE `Application` ADD `joId` int(11) NOT NULL AFTER `id`

As always we have to make that change also in the visualisation of the database. But this time we also want to make a new
connection between the table JobOffer and the Table Application:

.. figure:: Images/DiaAddJoId.png

So you might ask yourself, why we just did that. We want the following: Whenever we click on the apply button, our
goal is of course to know for which job this person just applied for. So we have to save in the database this information.
The way we do that is the following. Let's suppose you are a user of this website and you want to apply for a job.
Your first step is going to be to click on the apply button on the Page "Jobs" for whatever job you are best suited for.
But if you click on that button "Apply", we automatically open up the form Application. But we want that the form Application
knows exactly for which Job we want to apply for. So how do we do that?
We just check on which "Apply" buttons you click. We take the parameter joId (which is the unique id of the job) as a
parameter for the form. So the form knows which job you are applying for and saves that automatically in the database.

If you don't know what I am talking about, don't worry. We try to go though this together.
If we click on the button apply now, the form is not going to know for which job we are applying for. So we want to change
that. In order to do that go to Typo3 and edit the QFQ element of the page Jobs. Delete the Query and paste in the
following Query: ::

    form={{form}}

    10 {
      sql = SELECT CONCAT('u:{{pageId:T}}&form=Application&r=0&joId=',jo.id,'|t:Apply|b:1|s:1') as _link, jo.id, jo.type, jo.title, jo.start, jo.end, jo.description, jo.emailContact FROM JobOffer AS jo, (SELECT 1) AS fake WHERE  '{{form:SE}}'='' AND jo.start<=NOW() AND NOW()<= jo.end
        head = <table class='table table-hover qfq-table-50'><thead><tr><th>Form</th><th>#</th><th>Type</th><th>Title</th> <th>Start</th><th>End</th><th>Description</th><th>Email</th></tr><thead><tbody>
        tail = </tbody></table>
        rbeg = <tr>
        rend = </tr>
        fbeg = <td>
        fend = </td>

    }

The only difference from before to now is the following: we changed the link from : ::

    CONCAT('u:{{pageId:T}}&form=Application&r=0|t:Apply|b:1|s:1') as _link

to: ::

    CONCAT('u:{{pageId:T}}&form=Application&r=0&joId=',jo.id,'|t:Apply|b:1|s:1') as _link

So now you can see that we added a new parameter to the link. The jo.id so the unique id which tells the form exactly
for which job the applicant just applied for.

So our next step is to edit the form in a way that the job title is displayed at the top of the page and additionally
stores the data into the database. So you have to edit the form Application. Add a new FormElement and and make a
readonly textbox out of it:

.. figure:: Images/FormElementReadonlyTextbox.png

Next go to the pill value and paste into the textbox value the following Query: ::

    {{SELECT jo.title FROM JobOffer AS jo WHERE {{joId:S0}} = jo.id}}

This Query just selects the title of the Job which has the id of the job, the user just applied for.
A confusing part of this Query might be the follwoing: *{{joId:S0}}*.
This expression is a variable in QFQ. joId is just the name of the parameter we opened the form with and the S0 means
that it looks for that information in the sip store.

Now the form is going to look like this:

.. figure:: Images/FormEditorReadonly2.png

So we see that when we open the link now the form knows exactly for which job you applied for. But we want that the
job is at the top of the Form. So we edit the FormElement and go to the pill Check&Order and set the order to 5. Then
this element will be on top.

.. figure:: Images/FormElementOrder.png

But our work is not done. We don't just want that the job type is shown at the webpage. We also want that information
stored in the database (in the Table Application).
So you have to create a new FormElement and of the Type Extra.

Details: https://docs.typo3.org/typo3cms/drafts/github/T3DocumentationStarter/Public-Info-053/Manual.html#type-extra

.. figure:: Images/FormEditorExtraJoId1.png

Go to the pill value and paste in the following Query into the textbox value: ::

    {{joId:S0}}

Now whenever somebody wants to apply for a job, we can see in the database for which job he acutally applied for.

But now we have the following problem: If now we go to tha page applications (that's the page where the admin of the page
can see all the applications) the admin can't see who applied for which job. So we want a better looking page where the admin
has a seperate list for all jobs which are offered. We additionally only want to display the job offers for jobs, which are
still online. So let's change the query in such a way. But first you should add a few jobs and a few applications so that
you see a difference to before.

So now your application page will look like this:

.. figure:: Images/Typo3ApplicationCathegories.png

Delete your query on the page Applications and paste in the follwoing: ::

    form={{form}}
    10 {
      sql = SELECT CONCAT('{{pageId:T}}&form=Application&r=0') as _Pagen, '<br><br>' FROM  (SELECT 1) AS
      fake WHERE  '{{form:SE}}'=''
    }
    20 {
      sql = SELECT jo.id AS _joId, jo.title AS _joTitle FROM JobOffer AS jo WHERE
      jo.start <= NOW() AND NOW() <= jo.end

      10 {
        sql = SELECT CONCAT('{{pageId:T}}&form=Application&r=',a.id) as _Pagee, a.id, a.name,
        a.firstname, a.gender,  a.dateOfBirth, a.adrStreet, a.adrZipCity FROM Application AS a,
        (SELECT 1) AS fake WHERE '{{form:SE}}'='' AND a.joId = '{{joId:R}}'
        head =  <table class='table table-hover' style="width: unset"><b>{{joTitle:R0}}</b>
        tail = </tbody></table>
        rbeg = <tr>
        rend = </tr>
        fbeg = <td>
        fend = </td>

      }
    }

Since everything should be clear in this query I am not going to explain it in detail. But you should still read it and
try to understand it. Even better: try it yourself without copying my code.

Next we want that the applicant can upload his CV and his letter of motivation. Now we run into a problem:
Unfortunately we only have one row named pathFileName in the table Application. So if we want that the user can upload 1
single file, we are fine. The reason: We can save the path in the row pathFileName. Now we want that the user can upload
2 different files. A CV and the letter of motivation. So you could add a new row and call the one pathFileNameCV and the
other one pathFileNameLetterOfMotivation. But what if one day a third upload file should be handed in. For example
certificate of employment or language certificates. In this case it is a bad idea to just create a new row for every
single upload.
We will do it way more dynamic. We will create a new Table named Ggroup. In this Ggroup we are going to save all path.

To create that now Table named Ggroup paste in the following query into the SQL prompt: ::