; vim: set et : (use-modules (ice-9 regex)) (use-modules (srfi srfi-27)) (load "lang-tags.scm") (define haddelitembtnjs #f) (define haddelcmitembtnjs #f) (define (current-year) (string->number (strftime "%Y" (localtime (current-time))))) (define (random-string len) (define (iter n s) (if (< n 1) s (iter (- n 1) (string-append s (string (integer->char (+ (random-integer 24) 65))))))) (iter len "")) (define (decide-by-lang de en) `((!? "if (strstr($_SERVER['REQUEST_URI'], '/application/') || strstr($_SERVER['REQUEST_URI'], '/review/') || basename(dirname($_SERVER['REQUEST_URI'])) === 'en') {") ,en (!? "} else {") ,de (!? "}"))) (define* (stepform num h1 h2 lis #:key (last #f) (elements-before-overlay `'()) (php-args "") (appname "ds") ) `((!span "") ; dummy for tidy (!php ,(string-append"/* vim: set ts=4 sw=4 et : */ if (!isset($doPDF)) {" php-args)) (@p (define stepform_lis ',lis)) (@p (main ,h1 ,h2 (append ,elements-before-overlay `((!? "}") (@p (overlay `(@p (fieldset (string-append ,,,appname (number->string ,,,num) "App") (string-append "app" (number->string ,,,num) "Ctrl") stepform_lis)))) (!? "if (!isset($doPDF)) {") (!p "* " (@p (parse-mess "?mandatory"))) (!div #((id uibottom)(style "display: none;")) ,(if (= ,num 2) `((!div #((style "display: inline-block; width: 49%;")) (!button #((style "background: darkgrey; margin-right: .5em;") (onclick "return saves2();")) ,(parse-mess "?save"))) (!div #((style "display: inline-block; width: 49%; text-align: right;")) (!button #(onclick "return continue_step3();") ,(parse-mess "?next"))))) ,(if (and (> ,num 2) (not ,last)) `((!div #((style "display: inline-block; width: 49%;")) (!button #((style "background: darkgrey;") (onclick "return save();")) ,(parse-mess "?save"))) (!div #((style "display: inline-block; width: 49%; text-align: right;")) (!button #((onclick ,(string-append "return return_step" (convert (- ,num 1)) "();")) (style "margin-right: .5em;")) ,(parse-mess "?back")) (!button #(onclick ,(string-append "return continue_step" (convert (+ ,num 1)) "();")) ,(parse-mess "?next"))))) ,(if ,last `((!div #((style "display: inline-block; width: 49%;")) (!button #((style "background: darkgrey;") (onclick "return save();")) ,(parse-mess "?save"))) (!div #((style "display: inline-block; width: 49%; text-align: right;")) (!button #((onclick ,(string-append "return return_step" (convert (- ,num 1)) "();")) (style "margin-right: .5em;")) ,(parse-mess "?back")) (!button #(onclick "return check_and_send();") ,(parse-mess "?send")))))) (!? "}"))))) (@p (minjs `((@p (stepdatajs ,,num ,,appname)) (@p (stepsubmitjs ,,num ,,appname)) (@p (stepbootstrapjs ,,num ,,appname)) (@dump ,(string-append "s" (number->string ,num) ".js")) (@p (stepjs ,,num ,,appname)) ))))) (define (stepdatajs num appname) (let ((n (number->string num))) `(,(string-append "window.s" n " = {};\n" "try { window.s" n " = JSON.parse('');\n" "} catch (e) { ; };\n")))) (define (stepsubmitjs num appname) (let ((n (number->string num))) `(,(string-append "function submitValues() {\n" "return safeSubmit({\n" "'s': " n ",\n" "'uid': '',\n" "'value': acc()\n" "});\n" "}\n")))) (define (stepbootstrapjs num appname) (let ((n (number->string num))) `(,(string-append "function stepBootstrap" (convert num) "() {\n" "window.app" n " = angular.module('" appname n "App', []);\n" "window.app" n ".controller('app" n "Ctrl', ['$scope', function ($scope) {\n" "$scope.d = window.s" n ";\n" "}]);\n" "angular.bootstrap($('#" appname n "App'), ['" appname n "App']);\n" "}\n" "function stepActivate" (convert num) "() {\n" "$('#" appname n "App').show();\n" "$('#" appname n "App input').trigger('change');\n" "$('#" appname n "App select').trigger('change');\n" "$('#uibottom').show();\n" "}\n" )))) (define (stepjs num appname) (define func (random-string 10)) `((!? "if (isset($doPDF)) {") ,(string-append "function " func "() { $('#" appname (convert num) "App input, #" appname (convert num) "App textarea, #" appname (convert num) "App select').prop('disabled', true); $('" appname (convert num) "App button').prop('disabled', true).css('display', 'none'); }") ,(string-append "$(document).ready(function () {" func "(); let observer = new MutationObserver(function () { " func "(); }); observer.observe(document.querySelector('#" appname (convert num) "App'), {subtree: true, childList: true,}); });") (!? "}"))) (define* (main h1 h2 lis #:key (style "padding: 0;")) `(!div #((class main)(style ,style)) (!h1 (@p (parse-mess ,h1))) (!h2 (@p (parse-mess ,h2))) ,lis)) (define (minjs lis) `(!script (!? "minStart();" ) "\n" ,lis "\n" (!? "minEnd();"))) (define (newbuttonjs func variable) `(,(minjs (string-append "function " func "(me) {\n" " var v = JSON.parse(acc());\n" " if (typeof v." variable " === 'object') v." variable ".push([]);\n" " else v." variable " = [];\n" " if (safeSubmit({\n" " 's': $(me).closest('fieldset').attr('id').substr(2, 1),\n" " 'uid': '',\n" " 'value': JSON.stringify(v)\n" " })) location.reload();\n" " return false;\n" "}")))) (define (delitembuttonjs) (unless #f (minjs `(,(set! haddelitembtnjs #t) ,(string-append "function delItem(o) {\n" " o.parent().parent().remove();\n" " if (submitValues()) location.reload();\n" " return false;\n" "}"))))) (define (delcmitembuttonjs) (unless haddelcmitembtnjs (minjs `(,(set! haddelitembtnjs #t) ,(string-append "function delCMItem(o) {\n" " o.parent().remove();\n" " if (submitValues()) location.reload();\n" " return false;\n" "}"))))) ;(define (textarea ...) (define (textarea text) `(!textarea #((readonly "readonly")) ,text)) ;(define (textareaonside ...) (define (textareaonside width label text) `((!div #(data-field-span ,width) (!span ,label) (!textarea #((readonly "readonly")) ,text)))) ;(define (checkboxsimple ...) (define (checkboxsimple width name label) `((!div #(data-field-span ,width) (!input #((type "checkbox") (name ,name) (ng-checked ,(string-append "d." name))) " " ,(parse-mess label))))) ;(define (checkboxconglomerate (mehrere mit
getrennt, siehe ds/s5.php ...) (define (checkboxconglomerate width checkboxes textarea-label textarea-name) (define (iter items) (if (null? items) '() (let ((e (car items))) (append `((!input #((type "checkbox") (name ,(car e)) (ng-checked ,(string-append "d." (car e)))) ,(cadr e)) (!br)) (iter (cdr items)))))) `((!div #(data-row-span ,width) (!div #(data-field-span ,width) ,@(iter checkboxes) (!br) ,textarea-label ":" (!textarea #((name ,textarea-name) (rows "2")) ,(string-append "{{ d." textarea-name " }}")) (!br))))) ;(define (multicontainar form classes variable labeldelbtn labelnewbtn btnprefix lis) ;(@p (multicontainer "3" "study" "studies" "Studium loeschen" "Weiteres Studium anlegen" "study" `((@p (legend "...") ....)))) ;(define (multicontainer width form classes variable labeldelbtn labelnewbtn btnprefix lis) ; (if (null? lis) '() (let ((e (car items))) ; (append (list (( ; #:funcnewbtn - explicitly name btn ; #:divargs - arguments for the outer div ; #:labelduration - label text for the duration (define* (multicontainer width class name variable labeldelbtn labelnewbtn #:key (funcnewbtn (random-string 16)) (divargs #()) (labelduration "") (selectname "") (options '()) .opt) `((!div ,(merge-html-args `#((class ,class) (ng-repeat ,(string-append "b in d." variable))) divargs) ,(row width `( (!div #((data-field-span 1) (class "mand")) ,(parse-mess name) "*") ,(textareasimple 2 "" class #t #:prefix "b") ,(if (string=? labelduration "") '() `("\n
" (!div #((style "clear: both;")) " ") ;(!div #((data-field-span 1) (class "mand")) ,(parse-mess labelduration)) ;(!div #((data-field-span 2)) ,(selectonside 1 2 "" labelduration selectname options #t #:prefix "b" #:noempty #t) (!div #((style "clear: both;")) " ") )) (!button #((onclick "return delItem($(this));")) ,(parse-mess labeldelbtn)) ))) (!button #((id ,(string-append "btn_" class)) (onclick ,(string-append "return " funcnewbtn "(this);"))) ,(parse-mess labelnewbtn)) (@p (newbuttonjs ,funcnewbtn ,variable)) (@p (delitembuttonjs)) )) ; #:funcnewbtn - explicitly name btn (define* (custommulticontainer class legend variable labeldelbtn labelnewbtn options #:key (funcnewbtn (random-string 16))) `((!legend ,(parse-mess legend)) (!div ,(merge-html-args `#((style "margin-bottom: 1.5em;")(class ,class) (ng-repeat ,(string-append "b in d." variable)))) (,options ((!button #((onclick "return delCMItem($(this));")) ,(parse-mess labeldelbtn))))) (!button #((id ,(string-append "btn_" class)) (onclick ,(string-append "return " funcnewbtn "(this);"))) ,(parse-mess labelnewbtn)) (@p (newbuttonjs ,funcnewbtn ,variable)) (@p (delcmitembuttonjs)) ) ) (define* (s5spacer #:key (includenbsp #f) . opt) `(("
") (,(if includenbsp `(!div #((style "clear: both;")) " ") '())))) (define* (social width1 width2 label inputs #:key (prefix "d") (message "") (textprefix "") (textarea #f) (comment_on '()) (aftermessage '()) (afterspan '())) `((!legend ,(parse-mess label)) ,(row width1 `((!div #((data-field-span ,width2)) ,@(let iter ((i inputs)) (if (null? i) '() (append `((!input ,`#((type "checkbox") (name ,(car i)) (ng-checked ,(string-append prefix "." (car i))))) " " ,(parse-mess (string-append textprefix (car i))) (!div #((style "clear:both; margin-bottom: .4em;"))) ,(if (member (car i) comment_on) `((!div #((style "display: none; margin-top: .3em; margin-left: 2em; padding-bottom: .8em;") (id ,(string-append (car i) "_comment"))) ,(parse-mess "?social_comment") "*" (!textarea #((class "mand") (ng-value ,(string-append prefix "." (car i) "_comment")) (name ,(string-append (car i) "_comment"))))) (!script ,(string-append "$('input[name=" (car i) "]').on('change', function () {" " if ($(this).is(':checked')) {" " $('#" (car i) "_comment').show();" " } else {" " $('#" (car i) "_comment').hide();" " }" "});"))))) (iter (cdr i))))) ,(if textarea `((!br) ,(parse-mess-as-text (string-append textprefix "sonstiges")) (!textarea #((name "sonstiges") (rows "2")) ,(string-append "{{ " prefix ".sonstiges }}"))) `((!br) ,(string-append (parse-mess-as-text (string-append textprefix "sonstiges")) " ") (!textarea #((name "sonstiges")) ,(string-append "{{ " prefix ".sonstiges }}")))) (!br) ,(if (string=? message "") '() `(!p (!i #((class "fas fa-exclamation-triangle"))) " " ,(parse-mess message))) ,aftermessage) ,afterspan)))) ; fieldsetargs - arguments for the fieldset element (define* (fieldset app cntrl lis #:key (fieldsetargs #()) .opt) `(!fieldset ,(merge-html-args `#((id ,app) (ng-controller ,cntrl) (style "display: none;")) fieldsetargs) ,@lis)) ; #:formargs - arguments for the grid-form (define* (grid-form lis #:key (formargs #())) `(!form ,(merge-html-args `#((class "grid-form")) formargs) ,@lis) ) ; #:divargs - arguments for the overlay div ; #:formargs - arguments for the grid-form (define* (overlay lis #:key (divargs #()) (formargs #()) . opt) `(!div ,(merge-html-args `#((id "overlay")) divargs) (!form ,(merge-html-args `#((class "grid-form")) formargs) ,@lis))) ;textsimple pruefen, sollte ds/s3.php "Geben Sie Ihre aktuelle ...." ;(define (row width lis . style) ; `(!div #(data-row-span ,width) ; ,lis)) ; #:divargs - arguments of the div (define* (row width lis #:key (divargs #()) . opt) `(!div ,(merge-html-args `#((data-row-span ,width)) divargs) ,lis)) ; (if (= (length class) 2) ;(define (row width lis . style) ; `(!div #(data-row-span ,width) ; ,lis)) (define (tabular width1 width2 col1name col2name sumfield1 sumfield2 l) (define (tabular-inner width1 width2 l) (let iter ((lis l)) (if (null? lis) '() (cons `(@p (row ,(+ width1 width2) `((!div #(data-field-span ,,width1) ,,(caar lis)) (!div #(data-field-span ,,width2) ,,(cadar lis))))) (iter (cdr lis)))))) (append `((@p (row ,(+ width1 width2) `((!div #(data-field-span ,,width1) ,,col1name) (!div #(data-field-span ,,width2) ,,col2name))))) (tabular-inner width1 width2 l) `((@p (row ,(+ width1 width2) `((!div #(data-field-span ,,width1) ,,sumfield1) (!div #(data-field-span ,,width2) ,,sumfield2))))) )) ;(define (tabular2 width1 width2 col1name col2name sumfield1 sumfield2 lis1 lis2) ; (let iter ((lis1 lis1) (lis2 lis2)) ; (if (or (null? lis1) (null? lis2)) ; '() ; (let ((e1 (car lis1)) ; (e2 (car lis2))) ; (cons `(@p (row ,(+ width1 width2) ; `((!div #(data-field-span ,width1) ,e1) ; (!div #(data-field-span ,width2) ,e2)))) ; (iter (cdr lis1) (cdr lis2)))))) ; ; (append `((@p (row ,(+ width1 width2)) ; `((!div #(data-field-span ,width1) ,col1name) ; (!div #(data-field-span ,width2) ,col2name)))) ; (iter lis1 lis2) ; `((@p (row ,(+ width1 width2)) ; `((!div #(data-field-span ,width1) ,sumfield1) ; (!div #(data-field-span ,width2) ,sumfield2)))))) (define (tip1 name . tip) (if (null? tip) '() `(!span #(("style" "font-size: 1.2rem; text-transform: none; cursor: pointer;") ("onmouseover" ,(string-append "$('#" name "_tip').show();")) ("onmouseleave" ,(string-append "$('#" name "_tip').hide();")) ("onclick" ,(string-append "$('#" name "_tip').toggle();"))) "ⓘ"))) (define (tip2 name . tip) (if (null? tip) '() `(!p #(("id" ,(string-append name "_tip")) ("style" "display: none; font-size: 1rem; text-align: justify; hyphens: auto;")) ,tip))) ;upload form used in s6 ; #:dataformat - a list of 2 elements specifying the type and accepted documents in input ; #:info - optional list of elements which will be placed below the upload fields ; #:inputclasses - html classes to be added to the file input field ; #:titlemandargs - a string, mainly used to add a " * " in the title infront of the " : ". The mand class would put it after the " : " (define* (s6-upload-form doctype #:key (dataformat '("pdf" "application/pdf, .pdf")) (info `()) (inputclasses "mand") (titlemandargs "*") .options) `(!div #(class "upload") (!b #() ,(string-append (parse-mess-as-text (string-append "?s6_" doctype)) titlemandargs)) (!php ,(string-append "$e = false; if (file_exists(\"../../uploads/\" . $puid . \"_\" . \"" doctype "." (car dataformat) "\")) { $e = true;")) (!span " " (!a #((class "uploaded") (href ,(string-append "download.php?" doctype)) (target "_blank")) ,(parse-mess "?hochgeladen"))) (!form #((style "display: inline-block;") (action "delupload.php") (method "post") (enctype "multipart/form-data")) (!input #((type "hidden") (name ,doctype) (value "1"))) (!input #((type "submit") (class "delete") (onclick "return submitValues();") (value ,(parse-mess-as-text "?del")))) ) (!input #((type "hidden") (name ,(string-append doctype "_done")) (class "done") (value "1"))) (!input #((type "hidden") (name "done") (class "done") (value "1"))) (!php "}") (!form #((action "upload.php") (method "post") (enctype "multipart/form-data")) (!input #((type "hidden") (name ,doctype) (value "1"))) (!input #((type "file") (class ,inputclasses) (name "file") (accept ,(cadr dataformat)))) (!input #((type "submit") (style "display: none;") (onclick "return submitValues();") (value "") (name "upload"))) ) ,info ) ) ; a small infoparagraph ; #:class - class to be added to the ; #:style - style of the

(define* (info-paragraph text #:key (class "fa fa-info") (style "padding-left: 2em; margin-top: .5em; margin-bottom: .5em; font-size: 80%;") (want-space #t) . opt) `(!p ,(if (string=? style "") `#() `#((style ,style))) ,(if want-space `((!i #((class ,class))) " ") `()) ,(parse-mess text) )) ; a list containing an enumumeration of texts ; #:etradivstyleargs - name says it all (extra style arguments for the outer div) ; #:extralistitemargs - a list of extra style arguments for the enumerated texts ; -> if there are 7 items and only item 5 should have an extra style argument the list needs to be '("" "" "" "" "style") ; #:optionalelements - a list of optional elements to be added after the enumeration ; #:upperulmargintop - the margin for the