Object data form

Fundamentals

datastructure

My example for the fundamentals in this project is the invoice. The datastructure of the invoice is well know by everybody.

mysql tables

k8documents

  • docID
  • clientID
  • doctypeID
  • docnumber
  • docdate
  • accountID
  • partnernumber
  • name1
  • name2
  • title
  • firstname
  • lastname
  • street
  • country
  • code
  • city

k8documentitems

  • itemID
  • clientID
  • docID
  • position
  • componentID
  • componentnumber
  • text1
  • quantity
  • salesunit
  • pricesingle
  • pricetotal

All tables in object data form need to have a primary key consisting of 1 field with autoincrement.

php Array

$dat:

html input

The name of the form element is written like this:

javascript object

dat:

json object

The json declaration look like this:

Local formats

The internal format for the decimal point is ".", of a date is: YYYY-mm-dd. The number format and date format should regard the local formats. I use the html 5 data and number field. The format of this fields depends on the web browser. The format in the record list with tabulator is defined with placeholders:

  • GLOBALS_decimal_point
  • GLOBALS_thousands_sep
  • GLOBALS_tabulatordateformat
  • GLOBALS_tabulator_datetime_fp

The basic format is english. In BasicFunctions.php in the function mylocale() is the german format defined. All other formats have to be implemented by yourself.

php methods and data access

object_data_form.php

The object_data_form.php is the template for loading the object data form.

datadefinitions.php

For the basic datadefintion have a look to Master data.

The datadefinition contains the html frontend and refers the php classes of the object. In the website you have to add stylesheet and javascript and load the object.

Example for object datadefintion[x]:

  • rightcheck
  • json/form html container
    ['jsonform']['form'][1]['value']=gsread_file('object_invoice_container.html')
  • masterdata
    • save_mode=1
    • record=!!!
    • rightuser_create=true/false
    • rights
      • create
        • 0:public=1
        • 1:admin=1
        • 2:superuser=2
        • 3:member=3
      • read
        ...
      • update
      • delete
  • childs, array for child tables
    • child table definition 1
      • child table definition 1.1
      • child table definition 1.2
    • child table definition 2
  • js_rec_record
    • objectname 1: html template 1
    • objectname 2: html template 2

the configuration of the data access class with child classes:

Each of my tables has 1 primary key. The table, the key and the data class are the most important terms. The "child" array can contain any number of children and can be nested. Additional you must set the master key, the column which contains the parentkey. Rightmode=3 turns off the right checking in the child table. fieldname is the column name of the array.

ProcessData.php

ProcessData.php contains the following methods:

  • GetObject
  • ReadFilter
  • Save
  • Delete / Del

data access class

The data access class has the following methods:

  • __construct($datadefinition)
  • init()
  • bexist($ID)
  • bload($ID)
  • getEntries($clause)
  • bvalidate($postfields)
  • save()
  • add()
  • update()
  • delete($ID)

The data access class support child classes. For each child in the datadefintion a new child class object is declared.

data access rights

Access rights can only implemented by using login and php sessions. The access check is activated for an object in the datadefinition by setting "rightcheck=1". In the data table the column "creatorID" is addedd. Each user can be member in 1 or more role. By opening the website the user is assigned to the role "0" (public). By login the role public is replaced by the roles in the login table: k8login.roles. For each object or table, for each CRUD operation (create, read, update, delete) and role an access check is implemented.

the data access definition in the datadefinition (masterdata.rights):

  • CRUD Operation
    • Role ID
      • Access check

CRUD Operation, sql methods
OperationSql commandReturn values
CreateINSERT true / false
ReadSELECT join
clause
condition for rightuser_update: true/false
condition for rightuser_delete: true/false
UpdateUPDATEtrue / false
DeleteDELETEtrue / false
Roles
IDRoleComment
0publicuser not logged in
1adminall rights in a client
2superuserall rights in the table / object
3memberlogged in user
5friendsassigned in table: k8loginfriends
xotherscreate by yourself
Access check
NumberCheck method
0no rights
1access permission in this client: table.clientID=$_SESSION[clientID]
2permission granted
3user logged in: $_SESSION[userID]<>0
10table.creatorID=$_SESSION[userID]
11check friend k8loginfriends.friendID=$_SESSION[userID]
1000check parent table access rights
...programm your own check

By each CRUD operation the rights are checked. If the operation is not granted an error is returned.

The results of the access check are returned in advance like this (example):

  • with the datadefinitition:
    • masterdata.rightuser_create: true
  • by reading the recordset:
    • clause: userID=creatorID
  • by the record:
    • rightuser_update: true
    • rightuser_delete: true

This are the default rights in the data access class (masterdata.defaultrights=true (default)).

access matrix, cell number=Access check
Operation0:public1:admin2:superuser3:member
Create0121
Read01210
Update01210
Delete01210

Rights from the datadefinition overwrite it. To allow the roles: public and member to read all records in the object, add in the datadefintion:

html

Master data form

the list and main form ist created with the master data form (tabulator and jsonform). In jsonform the arrays are added by an htmlsnippet.

structure for array forms

The Arrays in the form have the following structure:

  • class=js_rec_container
    tags: data-rec_indexmax, data-rec_object
    • class=js_rec_head
      • click class=js_rec_new
    • class=js_rec_records
      • class=js_rec_record,
        tags: data-rec_index
        • click class=js_rec_delete
    • class=js_rec_foot

Each Array consist of 2 html snippets:

  • the array-container
  • the record

In datadefinitions.php the array-container is inserted in the datadefinition as html snippet:

The html snippet of the record is inserted in the datadefintion in the js_rec_record tree. The ARRAY_NAME correspond to the datadefinition: childs[0]fieldname=ARRAY_NAME.

json form configuration

  • form element 1
  • form element 2
  • subdata element, fieldtype: 44, class=js_rec_container
    data-rec_indexmax, data-rec_object, data-rec_nest
    • head, fieldtype: 31, class=js_rec_head flex-row
      • recordmarker, fieldtype: 31, class=recordmarker
        • click, fieldtype: 17, class=js_click_new
      • div, fieldtype: 31
        • title line or fields
    • body, "fieldtype": 31, class=js_rec_records
      • items, "fieldtype": 31, class=js_rec_record flex-row
        data-rec_index
        • recordmarker, "fieldtype": 31, class=recordmarker
          • click class=js_click_delete
        • div, "fieldtype": 31,
          • form element items[index][text]
          • form element items[index][quantity]
          • form element items[index][price]
    • foot, "fieldtype": 31, class=js_rec_foot
      • line with sum

right

Example for container (js_rec_container):

Example for a record (js_rec_record)

In the datadefinition of the child the array name is defined with the property "fieldname". This is the name of the array. In the example above the index field is named "index_items". The term is created like this: "index_<fieldname>". This is a placeholder for the record-index.

css

css basics

Let us 1st have a look on our css basics:

  • bootstrap
    • form-control for input
      • height: 34px
      • padding: 6px 12px
    • control-label
      • media>768px {padding-top: 6px;}
  • .masterdata
    • form {padding: 6px}
  • changes
    • .form-control {padding-left: 6px; padding-right: 6px}

css of an array

the array container has the following css classes:

  • rec_container
    • rec_headline
    • rec_records
    • rec_footline

k8-flex-row

I arrange the form elements of an array in a table. I use the flexbox to create this table:

javascript, masterdata.js

windows.onload / init

with the command:

displayMasterData('#masterdata1',url)

the form is loaded and displayed.


Right Handling

this parameters determine the right handling:

  • form
    • masterdata/brights=true/false
    • masterdata/rightuser_create=true/false
  • record:
    • rightuser_update=true/false
    • rightuser_delete=true/false

New, initform()

The New-Button calls the function initform(). Fields and array-container are emptyed.

Display recordset

By clicking on a recordset in the record list the record is displayed in the form. In a master data form the field values are set by the recordset columns. In the object data form the array container with the records have to build up corresponding to the object structure. For a record in the array a html template is defined:

  • js_rec_record[object1]=html_file_object1
  • js_rec_record[object2]=html_file_object2
  • js_rec_record[objectx]=html_file_objectx

The object is looped by main methods to display the function: "gObject2FormBuild(...)" and the records are inserted by "addhtmlrecord(el_rec_container)":

  • gObject2FormBuild(form,el_object,obj,name)
    • Loop object: “prop“
      • If(typeof(obj[prop])=='object'))
        • object=prop / getobjectfromstr(namestr)
        • addhtmlrecord(el_rec_container)
        • gObject2FormBuild(form,el_objectsub, obj[prop],name)
      • else
        • get input element by name
        • set element.value
  • addhtmlrecord(el_rec_container)
    • inserts a new "record" el_rec_records
    • inserts IDs of the object structure
    • HtmlTemplate for object-record

new position

The control element for a new position can be placed everywhere inside the object-container. By looking up the parents elements the first "js_rec_container" is fetched:

add position

the html of the record is appended to the record container. The index of the form elements is replaced with the "data-rec_index". by nested containers all indexes are replaced.

delete position

The control element for a new position can be placed everywhere inside the object-record:

calcualte

the name of the form element is divided into 2 parts:

  • name: "items[5][pricesingle]
  • name_main, "items[5]"
  • name_col:, "items.pricesingle

save

The plugin "jquery.serializejson.js" allows to create an javascript object from all form elements.

var obj = $("form[name='formname']").serializeJSON();

This object is send to the server and the ID of the primary key is sended back. Return '0' was not successful and the error message is displayed.

callback functions

this are the implemented callback functions:

  • dataLoad(el_form,data)
  • dataNew(el_form,data)
  • dataChange(el_form,inputfield)
  • dataSave(el_form,data)

el_form is the javascript form element, data contains the field value pairs of all form elements.