PHP Classes

File: admin/js/cliqf.js

Recommend this page to a friend!
  Classes of Mark Richards   CliqonV4   admin/js/cliqf.js   Download  
File: admin/js/cliqf.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: CliqonV4
Framework with modules to build Web applications
Author: By
Last change: Added support for Blog

Added support for Blog and other changes
Support for User Unit Test module
Merge branch 'master' of https://github.com/webcliq/CliqonV4
Date: 5 years ago
Size: 101,804 bytes
 

Contents

Class file image Download
/* CliqF.Js */ /** Cliqon Form Related Functions - cliqf() * cliqf.x() - app and utility functions, including: ******************************************************************************************************************/ var Cliqf = (function($) { // initialise // var shared values var fcfg = { dz: new Object, resetForm: {}, cancelPageForm: {}, formset: {}, panels: {}, opts: {}, jeditid: '', ceditor: {}, jeditor: {}, teditor: {}, popup_window: '' }, cfg = {}; var _set = function(key,value) { fcfg[key] = value; return fcfg[key]; } var _get = function(key) { return fcfg[key]; } /** Generic CRUD Form Routines and Subroutines * crudButton() * vueForm() * - formMounted() * - frmBtn() * addOption() * deleteButton() * - deleteRecords() * *************************************************************************************/ /** Create or Edit a Record * * @param - number - 0 or valid record number * @param - string - insert or update * @return - HTML display a form **/ var crudButton = function(recid, action) { cfg = Cliq.config(); cfg.recid = recid; cfg.action = action; // Formid acts as HTML ID and switcher // Maybe we could switch this on the fly according to width of screen etc. // Think about User Agent Here if(cfg.formtype == "pageform") { var urlstr = '/admindesktop/'+jlcd+'/page/'+cfg.table+'/'+cfg.tabletype+'/?action=pageform&recid='+recid; uload(urlstr); } else { var urlstr = '/ajax/'+jlcd+'/getform/'+cfg.table+'/'+cfg.tabletype+'/'; aja().method('GET').url(urlstr).cache(false).timeout(2500).type('json') .data({ displaytype: cfg.displaytype, formtype: cfg.formtype, action: action, recid: recid }) .on('40x', function(response) {Cliq.error('Page not Found - '+urlstr+':'+response);}) .on('500', function(response) {Cliq.error('Server Error - '+urlstr+':'+response);}) .on('timeout', function(response) {Cliq.error('Timeout - '+urlstr+':'+response);}) .on('success', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { // Post process returned data cfg.data = JSON.parse(response.script); cfg.action = response.action; // c or u if(cfg.formtype == "columnform") { $('#columnform').empty().html(response.html); } else { // Popupform // Create better formatted title var title =""; recid == 0 ? title = lstr[16] : title = lstr[20]+' - '+recid ; var opts = { content: '<div class="col mr10 pad">'+response.html+'</div>', contentSize: { width: response.model.width, height: response.model.height }, paneltype: 'modal', headerTitle: '<span class="">'+title+': '+cfg.tabletype+'</span>' }; var formPopup = Cliq.win(opts); } vueForm(); } else { Cliq.error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response)); }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+response.msg); } }).go(); } // If Formid != Pageform ends } /** vueForm * Attaches Vue to the Form * @param - * @internal - sets cfg.df **/ var vueForm = function() { cfg.df = new Vue({ el:cfg.data.el, data:cfg.data.data, methods: { // Used with Cliqon 3 field dropdown dat3 plunk: function(id) { var d = $('#day_'+id).val(); var m = $('#month_'+id).val(); var y = $('#year_'+id).val(); Vue.set(cfg.df, 'd_'+id, d+'-'+m+'-'+y); }, // Other button functions // All forms previewbutton: function(evt) { frmBtn(evt, 'previewbutton'); }, // All forms resetbutton: function(evt) { frmBtn(evt, 'resetbutton'); }, // Appears on pageform only cancelbutton: function(evt) { frmBtn(evt, 'cancelbutton'); }, // Submit Button is not a submit submitbutton: function(evt) { frmBtn(evt, 'submitbutton'); }, // Click Icon Handlers clickicon: function(event) { var action = $(event.target).data('action'); frmBtn(event.target, action); }, // Image handlers onFileChange(e) { e.stopImmediatePropagation(); var fldid = $(e.target).data('fldid'); var files = e.target.files || e.dataTransfer.files; if(!files.length) { return; }; this.createImage(files[0], fldid); }, createImage(file, fldid) { var d_image = new Image(); var reader = new FileReader(); var vm = this; reader.onload = (e) => { vm.d_image = e.target.result; }; reader.readAsDataURL(file); }, removeImage: function (e) { e.stopImmediatePropagation(); this.d_image = ''; }, // More here modelChange: function(e) { var table = e.target.value; var tabletypes = []; $("select[data-name='tabletype'] option").each(function() { if(stristr($(this).data('table'), table) === false) { $(this).remove(); }; }); } }, mounted: function() { formMounted(cfg); } }); } /** formMounted() * Instantiates a variety of functions and responses to events that are associated with a Form * that has been published as a Vue template * @param - * @return - **/ var formMounted = function(cliqcfg) { cfg = cliqcfg; var id = 'dataform'; // Execute any code that had to be sent with the page $.globalEval(cfg.data.mounted); // HTML5 Text Types $('input[type="text"], input[type="email"], input[type="url"]').each(function() { var fldid = $(this).attr('id'); var thisfld = $('#'+fldid); if( thisfld.hasClass('nextref') ) { modInput(fldid, 'getnextref',''); }; if( thisfld.hasClass('nextid') ) { modInput(fldid, 'getnextid', ''); }; if( thisfld.hasClass('nextentry') ) { var prefix = thisfld.data('prefix'); modInput(fldid, 'getnextentry', prefix); }; $('.isunique').on('blur', function() { modInput(fldid, 'isunique', ''); }); $('.slugified').on('blur', function() { var toslug = $(thisfld).val(); $(thisfld).val( $.slugify(toslug) ); modInput(fldid, 'isunique', ''); }); if( thisfld.hasClass('autocomplete') ) { var urlstr = $(thisfld).data('url'); $(thisfld).bootcomplete({ url: urlstr, method: 'GET', minLength: 3 }); }; }); // For Textareas $('textarea.json, textarea.toml').each(function() { var fldid = $(this).attr('id'); var thisfld = $('#'+fldid); if( thisfld.hasClass('json') ) { var jsonte = document.getElementById(fldid); fcfg.jeditor = CodeMirror.fromTextArea(jsonte, { lineNumbers: true, mode: "javascript" }); var jsoncontent = thisfld.val(); fcfg.jeditor.getDoc().setValue(jsoncontent); }; if( thisfld.hasClass('toml') ) { var tomledid = document.getElementById(fldid); fcfg.ceditor = CodeMirror.fromTextArea(tomledid,{ lineNumbers: true, mode: "toml" }); var tomlcontent = thisfld.val(); fcfg.ceditor.getDoc().setValue(tomlcontent); }; }); // File and Image $('div.dropzone').each(function() { var fldid = $(this).attr('id'); var thisfld = $('#'+fldid); fcfg.dz = thisfld.dropzone({ url: cfg.uploadurl, init: function() { cfg.subdir = $(this).data('subdir'); cfg.uploadurl = $(this).data('uploadurl'); cfg.filescollection = $(this).data('filescollection'); }, autoProcessQueue: true, headers: { subdir: cfg.subdir }, createImageThumbnails: true, resizeHeight: 120, paramName: cfg.filescollection, maxFilesize: 1, maxFiles: 1, success: function(data) { if(data.status == 'success') { Vue.set(cfg.df, fldid, data.name); } else { msg({buttons:false, type:'danger', text:data.warnings.toString()}); } $(fcfg.dz).find('.dz-progress').addClass('hide'); } }); }); // Tab Handling // Level Handling $('.accesslevel').each(function(e) { var fldid = $(this).attr('id'); // Get var xval = $("#"+fldid+"_val").val(); var defval = explode(':', xval); $("#"+fldid+"_r").val(defval[0]); $("#"+fldid+"_w").val(defval[1]); $("#"+fldid+"_d").val(defval[2]); // Set $(".spinboxes").on("change", function() { var curval = $("#"+fldid+"_r").val() + ":" + $("#"+fldid+"_w").val() + ":" + $("#"+fldid+"_d").val(); $("#"+fldid+"_val").val(curval); Vue.set(cfg.df, fldid, curval); }); }); // Tags $('.tagit').tagit({ availableTags: false, singleField: true, tagLimit: 10 }); // Repeater $('#dataform').repeater({ // start with an empty list of repeaters. Set your first (and only) "data-repeater-item" with style="display:none;" and pass the following configuration flag initEmpty: false, // "show" is called just after an item is added. The item is hidden at this point. If a show callback is not given the item will have $(this).show() called on it. show: function () { $(this).slideDown(); }, // "hide" is called when a user clicks on a data-repeater-delete element. The item is still visible. "hide" is passed a function as its first argument which will properly remove the item. "hide" allows for a confirmation step, to send a delete request to the server, etc. If a hide callback is not given the item will be deleted. hide: function (deleteElement) { if(confirm('Are you sure you want to delete this element?')) { $(this).slideUp(deleteElement); } }, // You can use this if you need to manually re-index the list for example if you are using a drag and drop library to reorder list items. ready: function (setIndexes) { return false; }, // Removes the delete button from the first list item, defaults to false. isFirstItemUndeletable: true }) // JSONeditors if exist $('#dataform div[data-type=jsoneditor]').each(function(e) { fcfg.jeditid = $(this).attr('id'); var options = { search: false, mode: "code", modes: ["code", "form", "tree"] }; if(cfg.action == 'u') { // Update var jeditordata = cfg.data.data[fcfg.jeditid]; } else { // Create var jsondata = $('input[name="'+fcfg.jeditid+'"]').val(); var jeditordata = JSON.parse(jsondata); } fcfg.jeditor = createJSONEditor('#'+fcfg.jeditid, options); fcfg.jeditor.set(jeditordata); }); // Date handling including Datepicker $('select.dateselect').on('change select mouseover', function(e) { var id = explode('_', $(this).attr('id'))[1]; var d = $('#day_'+id).val(); var m = $('#month_'+id).val(); var y = $('#year_'+id).val(); Vue.set(cfg.df, 'd_'+id, d+'-'+m+'-'+y); }); $('.datepicker').each(function(e) { var fldid = $(this).attr('id'); var dp = $(this).datepicker({ format: 'dd-mm-yyyy', uiLibrary: 'bootstrap4', iconsLibrary: 'fontawesome', locale: jlcd+'-'+jlcd }); }) // Autocomplete - In PHP // Password $.hook('confirmpassword').on('blur', function(e) { var id = $(this).attr('id'); var p1 = $('#'+id).val(); var p2 = $('#'+id+'_confirm').val(); if(p1 != p2) { $('#'+id).empty().focus(); Cliq.msg({buttons:false, type:'error', text:lstr[137]}); } }); // Slider $('.slider').slider({ tooltip: 'show', ticks: [0,1,2,3,4,5], ticks_tooltip: true }); $('.slider').on('slide', function(evt) { Vue.set(cfg.df, evt.target.id, evt.value); }); // Reduced width Trumbo editor $.trumbowyg.svgPath = sitepath+'admin/css/icons.svg'; $('#'+id+' textarea.texteditor').each(function() { $(this).trumbowyg({ btns: [ ['formatting'], ['foreColor', 'backColor'], ['strong', 'em', 'horizontalRule'], ['link'], ['insertImage'], ['justifyLeft', 'justifyCenter', 'justifyRight'], ['unorderedList', 'orderedList'], ['viewHTML','fullscreen'] ], autogrow: true, autogrowOnEnter: true }); }); // TinyMCE Editor var tinypath = jspath+'tinymce'; tinymce.baseURL = tinypath; fcfg.teditor = $('.tiny').tinymce({ document_base_url: tinypath, script_url: tinypath, height: 435, theme: 'modern', skin: 'cliqon', plugins: [ 'advlist code codemirror anchor autosave charmap colorpicker contextmenu hr image imagetools insertdatetime lists link nonbreaking paste print preview searchreplace table template textcolor textpattern visualblocks visualchars wordcount fullscreen' ], toolbar1: 'translate | undo redo | insert | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | forecolor backcolor | print preview | code fullscreen', image_advtab: true, codemirror: { indentOnInit: true, // Whether or not to indent code on init. fullscreen: true, // Default setting is false path: jspath+'codemirror', // Path to CodeMirror distribution config: { // CodeMirror config object mode: 'application/x-httpd-php', lineNumbers: false }, width: 800, // Default value is 800 height: 600, // Default value is 550 saveCursorPosition: true, // Insert caret marker jsFiles: [ // Additional JS files to load 'mode/clike/clike.js', 'mode/php/php.js' ] }, setup: function(editor) { // Translate - to be done editor.addButton('translate', { icon: 'moon', // image: '', tooltip: 'Translate Record', onclick: function () { var fldid = $(this).attr('id'); // $did = v-model var textfrom; $.each(cfg.idioms, function(lcdcode, lcdname) { if(lcdcode != jlcd) { textfrom = cfg.df.$data[fldid+'_'+jlcd]; $.ajax({ url: "https://api.microsofttranslator.com/V2/Ajax.svc/Translate", dataType: "jsonp", jsonp: "oncomplete", crossDomain: true, data: {appId: cfg.bingkey, from: jlcd, to: lcdcode, contentType: "text/plain", text: textfrom}, success: function(data, status){ // console.log(data); cfg.df.$data[fldid+'_'+lcdcode] = data; } }); } }); } }) } // End Editor Setup }); // Checkbox handling $('.checkbox0').each(function() { var fid = $(this).attr('name'); var vals = explode(',', $('input[id="'+fid+'"]').getValue()); $('input[name="'+fid+'"]').fieldArray(vals); }); $('.cliqcheckbox').on('change', function(e) { var fid = $(this).attr('name'); var newvals = $('input[name="'+fid+'"]').getValue(); Vue.set(cfg.df, fid, newvals); }); // Click Icon Handlers $('.translatebutton').on('click', function(e) { var fldid = $(this).attr('id'); // $did = v-model var textfrom; $.each(cfg.idioms, function(lcdcode, lcdname) { if(lcdcode != jlcd) { textfrom = cfg.df.$data[fldid+'_'+jlcd]; $.ajax({ url: "https://api.microsofttranslator.com/V2/Ajax.svc/Translate", dataType: "jsonp", jsonp: "oncomplete", crossDomain: true, data: {appId: cfg.bingkey, from: jlcd, to: lcdcode, contentType: "text/plain", text: textfrom}, success: function(data, status) { cfg.df.$data[fldid+'_'+lcdcode] = data; }, error: function(xhr, status, text) { var response = $.parseJSON(xhr.responseText); Cliq.error(JSON.stringify(response)); } }); } }) }) // Miscellaneous // $('.currency').maskMoney(); $('.form-inline').each(function(e) { var fldid = $(this).attr('id'); var thisfld = $('#'+fldid); if( $(thisfld).hasClass('watch') ) { switch(fldid) { case "model": $('select[data-id="c_parent"], select[data-id="c_category"]').on('change', function() { var c_category = $('select[data-id="c_category"]').getValue(); var c_parent = $('select[data-id="c_parent"]').getValue(); $('select[data-id="c_reference"]').setValue(c_parent+'_'+c_category); return cfg.df.$data.c_reference = c_parent+'_'+c_category; }); break; // Other cases of watch here if required } // End switch }; // End 'watch' // Other cases here if required }); } /** formButtons * Handles all Form Buttons - submit, reset, cancel, preview etc. * @param - object - the Event object * @param - string - button action * @return - action **/ var frmBtn = function(evt, action) { switch(action) { case "submitbutton": // Make sure button is type = button, not type = submit !! evt.preventDefault(); var urlstr = $(cfg.data.el).attr('action'); var frmData = getFormData(false); $.ajax({ url: urlstr, data: frmData, cache: false, contentType: false, processData: false, type: 'POST', async: false, timeout: 25000, success: handleResponse, error: handleError }); break; case "previewbutton": var frmData = getFormData(false); cfg.spinner.stop(); var tbl = `<div class="container maxh30 scrollable"> <table class=\"table table-sm table-bordered table-striped\"> `; // Display the key/value pairs for(var pair of frmData.entries()) { switch(pair[0]) { case "d_image": tbl += `<tr style=\"font-weight:normal; font-size: 12px;\"> <td class=\"text-right orangec e30\">`+pair[0]+`</td> <td class=\"text-left bluec e70\"><img src=\"`+rawurldecode(pair[1])+`\" class=\"h120\" /></td> </tr>`; break; // Exclude fields case "token": case "c_level": $tbl += ""; break; default: tbl += `<tr style=\"font-weight:normal; font-size: 12px;\"> <td class=\"text-right orangec e30\">`+pair[0]+`</td> <td class=\"text-left bluec e70\"><pre>`+rawurldecode(pair[1])+`</pre></td> </tr>`; break; } } tbl += `</table></div>`; Cliq.win({ content: tbl, headerTitle: lstr[7] }); break; case "resetbutton": if(cfg.formid == 'pageform') { var q = cfg.resetPageForm; pageForm(q.table, q.tabletype, q.action, q.recid); } else { // columnform $('#dataform').clearform(); } break; case "cancelbutton": collectionAction(store.session('contenttype'), table, tabletype); break; // Good test case "lookupcompany": var options = { // url: '/ajax/'+jlcd+'/getcompanies/dbdirectory/', headerTitle: 'Lookup Company', target: evt, data: {}, parent: '#columnform' } Clq.popup(options); break; // Directory case "geolocate": Cliq.success('Geo Locate'); break; case "getcoords": Cliq.success('Get Coordinates'); break; case "gotowebsite": Cliq.success('Go to Website'); break; case "makeemail": Cliq.success('Send an email to this Company'); break; case "getlink": var urlstr = 'http://google.com/'; fcfg.popup_window = $.popupWindow(urlstr, { height:500,width:800,toolbar:false,scrollbars:false,status:false,resizable:true, left:50,top:80,center:false,createNew:true,name:'weblink',location:false,menubar:false }); break; // More here // Transfer a value from a Select to an associated Input field case "transferval": var fldid = $(evt).data('id'); var newval = $('select[data-id="'+fldid+'"]').getValue(); Vue.set(cfg.df, fldid, newval); break; case "maintainval": return addOption(evt); break; default: Cliq.success(action); break; } } /** Add a new value to an Options or Categories list * * **/ var addOption = function(evt) { var fldid = $(evt).data('id'); var listname = $(evt).data('listname'); cfg = Cliq.config(); var tpl = ` <form name="subpopupform" id="subpopupform" action="#" method="POST" class="pad"> <h5>`+lstr[15]+`</h5> <input type="hidden" name="fldid" value="`+fldid+`" /> <input type="hidden" name="listname" value="`+listname+`" /> <div class="form-group row"> <label for="x_value" class="col-sm-3 col-form-label text-right">`+lstr[100]+`</label> <div class="col-sm-9"> <input type="text" class="form-control " name="x_value" id="x_value" placeholder="value"> </div> </div>`; $.each(cfg.idioms, function(lcdcode, lcdname){ tpl += ` <div class="form-group row"> <label for="x_label_`+lcdcode+`" class="col-sm-3 col-form-label text-right">`+lcdname+`</label> <div class="col-sm-9"> <input type="text" class="form-control" id="x_label_`+lcdcode+`" name="x_label_`+lcdcode+`" placeholder=""> </div> </div> `; }); tpl += `</form>`; return Cliq.msg({ buttons: [ {addClass: 'm10 mt10 btn btn-danger btn-sm', text: lstr[30], onClick: function($noty) { $noty.close(); }}, {addClass: 'm10 mt10 btn btn-primary btn-sm', text: lstr[16], onClick: function($noty) { var frmData = $('#subpopupform').formHash(); var urlstr = '/ajax/'+jlcd+'/addnewoption/dbcollection/list/'; aja().method('POST').url(urlstr).cache(false).timeout(2500).type('json').data(frmData) .on('40x', function(response) {Cliq.error('Page not Found - '+urlstr+':'+response);}) .on('500', function(response) {Cliq.error('Server Error - '+urlstr+':'+response);}) .on('timeout', function(response) {Cliq.error('Timeout - '+urlstr+':'+response);}) .on('success', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { Vue.set(cfg.df, fldid, response.newval); $noty.close(); } else { Cliq.error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response)); }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+response.msg); }; }).go(); }} ], timeout: false, type: 'success', closeWith: ['button'], text: '', template: tpl }); } /** Delete button - invoked from Grid or List row * * @param - string - record ID to be deleted * @return - JSON with response **/ var deleteButton = function(recid) { cfg = Cliq.config(); var params = { table: cfg.table, tabletype: cfg.tabletype, type: 'delete', // deletebefore recid: recid, action: 'deleterecord', before: '', displaytype: cfg.displaytype, msg: lstr[27]+': '+recid }; return deleteRecords(params); } /** Delete records - invoked from Grid or List row * * support different types of delete, apart from by Id * @param - array - Parameters: see deleteButton for template * @return - JSON with response **/ var deleteRecords = function(params) { cfg = Cliq.config(); return Cliq.msg({ buttons: [ {addClass: 'm10 mt10 btn btn-success btn-sm', text: lstr[30], onClick: function($noty) { $noty.close(); }}, {addClass: 'm10 mt10 btn btn-danger btn-sm', text: lstr[114], onClick: function($noty) { var urlstr = '/ajax/'+jlcd+'/'+params.action+'/'+params.table+'/'+params.tabletype+'/'; aja().method('POST').url(urlstr).cache(false).timeout(2500).type('json') .data({ displaytype: params.displaytype, action: params.type, recid: params.recid, before: params.before }) .on('40x', function(response) {Cliq.error('Page not Found - '+urlstr+':'+response);}) .on('500', function(response) {Cliq.error('Server Error - '+urlstr+':'+response);}) .on('timeout', function(response) {Cliq.error('Timeout - '+urlstr+':'+response);}) .on('success', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { var originalnoty = $noty; Cliq.success(lstr[146]+': ' + JSON.stringify(response.msg)); originalnoty.close(); switch(params.displaytype) { case "datagrid": cfg.dg.reload(); break; case "datatable": Cliq.loadTableData(); break; default: reLoad(); break; }; } else { Cliq.error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response)); }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+response.msg); }; }).go(); }} ], timeout: false, closeWith: ['button'], type: 'warning', text: params.msg }); } /** Specialised Form routines and Buttons * * restoreButton(recid) * creatorButton(recid, action) * contentButton() * codeButton() * - makePanel() * - addPanel() * selectButton() * yesnoButton() * checkboxButton() * ************************************************************************************************/ /** Reverts a dbitem record from dbarchive * * @param - string - * @return **/ var restoreButton = function(recid) { cfg = Cliq.config(); return Cliq.msg({ buttons: [ {addClass: 'm10 mt10 btn btn-success btn-sm', text: lstr[30], onClick: function($noty) { $noty.close(); }}, {addClass: 'm10 mt10 btn btn-danger btn-sm', text: lstr[148], onClick: function($noty) { var urlstr = '/ajax/'+cfg.langcd+'/restorerecord/'+cfg.table+'/'+cfg.tabletype+'/'; aja().method('POST').url(urlstr).cache(false).timeout(2500).type('json') .data({ displaytype: cfg.displaytype, action: 'restore', recid: recid }) .on('40x', function(response) {Cliq.error('Page not Found - '+urlstr+':'+response);}) .on('500', function(response) {Cliq.error('Server Error - '+urlstr+':'+response);}) .on('timeout', function(response) {Cliq.error('Timeout - '+urlstr+':'+response);}) .on('success', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { var originalnoty = $noty; Cliq.success(lstr[147]+': ' + JSON.stringify(response.msg)); originalnoty.close(); Cliq.loadTableData(); } else { Cliq.error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response)); }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+response.msg); }; }).go(); }} ], timeout: false, type: 'info', text: lstr[148]+': '+recid }); } /** Create or Edit a Record using Record Creator * * @param - number - 0 or valid record number * @param - string - insert or update * @return - HTML display a form **/ var creatorButton = function(recid, action) { cfg = Cliq.config(); cfg.recid = recid; cfg.action = action; var urlstr = '/ajax/'+jlcd+'/getcreatorform/'+cfg.table+'/'; aja().method('GET').url(urlstr).cache(false).timeout(2500).type('json') .data({action: action, recid: recid, table: cfg.table}) .on('40x', function(response) {Cliq.error('Page not Found - '+urlstr+':'+response);}) .on('500', function(response) {Cliq.error('Server Error - '+urlstr+':'+response);}) .on('timeout', function(response) {Cliq.error('Timeout - '+urlstr+':'+response);}) .on('success', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { // Post process returned data cfg.opts = JSON.parse(response.opts); cfg.action = response.action; // c or u $('#columnform').empty().html(response.html); cfg.df = new Vue({ el:cfg.opts.el, data:cfg.opts.data, methods: { submitbutton: function(evt) { // Make sure button is type = button, not type = submit !! evt.preventDefault(); var urlstr = '/ajax/'+cfg.langcd+'/postcreatorform/'+cfg.table+'/'; var frmData = getFormData(false); $.ajax({ url: urlstr, data: frmData, cache: false, contentType: false, processData: false, type: 'POST', async: false, timeout: 25000, success: handleResponse, error: handleError }); } }, mounted: function() { var thisfld = $('#text'); var tomledid = document.getElementById('text'); fcfg.ceditor = CodeMirror.fromTextArea(tomledid,{ lineNumbers: true, mode: "toml" }); fcfg.ceditor.setSize({width: '100%', height: '600px'}); var tomlcontent = thisfld.val(); fcfg.ceditor.getDoc().setValue(tomlcontent); } }); } else { Cliq.error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response)); }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+response.msg); } }).go(); } /** Content button, invoked from Grid or List row * * This function provides popup windows with TinyMCE as an editor * @param - integer - Record ID * @param - string - default multi-lingual text field * @return - **/ var contentButton = function(recid) { cfg = Cliq.config(); var urlstr = "/ajax/"+jlcd+"/editcontent/"+cfg.table+"/"+cfg.tabletype+"/"; aja().method('GET').url(urlstr).cache(false).timeout(2500).type('json') .data({ displaytype: cfg.displaytype, // datalist viewtype: 'popupview', recid: recid, fldname: 'd_text' }) .on('40x', function(response) {Cliq.error('Page not Found - '+urlstr+':'+response);}) .on('500', function(response) {Cliq.error('Server Error - '+urlstr+':'+response);}) .on('timeout', function(response) {Cliq.error('Timeout - '+urlstr+':'+response);}) .on('success', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { var data = response.data; var opts = { content: response.html, contentSize: { width: 860, height: 642 }, headerTitle: '<span class="">'+lstr[31]+'</span>', callback: function() { // Manage Tabs $('#contenttabs a:first').tab('show'); $('#contenttabs a').click(function (e) { e.preventDefault() $(this).tab('show') }); $('textarea.rte').on('focusin', function(e) { if ($(e.target).closest(".mce-window").length) { e.stopImmediatePropagation(); } }); tinyEditor(cfg, '.rte'); } }; var contentEditor = Cliq.win(opts); } else { Cliq.error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response)); }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+response.msg); } }).go(); } /** TinyMCE Content Editor for a JSPanel Popup * @param - object pass the local cfg * @param - string element **/ var tinyEditor = function(cfg, ele) { var tinypath = jspath+'tinymce'; tinymce.baseURL = tinypath; return $(ele).tinymce({ document_base_url: tinypath, script_url: tinypath, theme: 'modern', skin: 'cliqon', content_style: 'html {padding: 10px 20px; min-height: 400px;}', plugins: [ 'advlist code codemirror anchor autosave charmap colorpicker contextmenu hr image imagetools insertdatetime lists link nonbreaking paste print preview searchreplace table template textcolor textpattern visualblocks visualchars' ], // wordcount toolbar1: 'savebutton translate | undo redo | insert | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | forecolor backcolor | print preview | code', // templates: '/dir/templates.php' - URL return JSON output image_advtab: true, external_filemanager_path: jspath + 'tinymce/plugins/filemanager/', filemanager_title:'Filemanager', external_plugins: { 'filemanager' : jspath + 'tinymce/plugins/filemanager/plugin.min.js'}, codemirror: { indentOnInit: true, // Whether or not to indent code on init. fullscreen: true, // Default setting is false path: jspath+'codemirror', // Path to CodeMirror distribution config: { // CodeMirror config object mode: 'application/x-httpd-php', lineNumbers: false }, width: 800, // Default value is 800 height: 600, // Default value is 550 saveCursorPosition: true, // Insert caret marker jsFiles: [ // Additional JS files to load 'mode/clike/clike.js', 'mode/php/php.js' ] }, setup: function(editor) { // Save to Database editor.addButton('savebutton', { icon: 'save', classes: 'bypassChanges', tooltip: 'Save Record', onclick: function (e) { e.stopImmediatePropagation(); // Get any tinymce Editors if exist and update the Vue instance with Tiny editor content var tinyeditors = tinymce.EditorManager.editors; var frmData = new FormData(); frmData.set('recid', recid); frmData.set('fldname', 'd_text'); $.each(tinyeditors, function(i, teditor) { var fld = trim(teditor.id, '_te'); // works fine var val = tinymce.get(teditor.id).getContent(); frmData.set(fld, rawurlencode(val)); }); var urlstr = '/ajax/'+cfg.langcd+'/savecontent/'+cfg.table+'/'+cfg.tabletype+'/'; $.ajax({ url: urlstr, data: frmData, cache: false, contentType: false, processData: false, type: 'POST', async: false, timeout: 25000, success: function(response, statusText, xhr) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { // Stops erroneous leave page error $('#dataform').submit(function(e) {return false;}); for (var i = tinymce.editors.length - 1 ; i > -1 ; i--) { var ed_id = tinymce.editors[i].id; tinyMCE.execCommand("mceRemoveEditor", true, ed_id); }; Cliq.success(lstr[10]); window.jsPanel.closeChildpanels("body"); return; } else { // Error Cliq.error('Ajax function returned error NotOk - '+response.msg); }; } else { Cliq.error('Response was not JSON object - '+JSON.stringify(response)); } }, error: function(xhr, status, text) { Cliq.error('Error saving Text to Database - '+urlstr+':'+text); } }); return true; } }), // End save to Database // Translate editor.addButton('translate', { icon: 'globe', // image: '', tooltip: 'Translate Record', onclick: function (e) { var tinyeditors = tinymce.EditorManager.editors; var vals = []; $.each(tinyeditors, function(i, teditor) { var fld = trim(teditor.id, '_te'); // works fine var val = tinymce.get(teditor.id).getContent(); vals[fld] = val; }); var textfrom = vals[data.fldname+'_'+jlcd]; $.each(data.idioms, function(lcdcode, lcdname) { if(lcdcode != jlcd) { $.ajax({ url: "https://api.microsofttranslator.com/V2/Ajax.svc/Translate", dataType: "jsonp", jsonp: "oncomplete", crossDomain: true, data: {appId: data.bingkey, from: jlcd, to: lcdcode, contentType: "text/plain", text: textfrom}, success: function(ttxt, status){ $.each(tinyeditors, function(i, teditor) { var fld = trim(teditor.id, '_te'); // works fine if(fld == data.fldname+'_'+lcdcode) { tinymce.get(teditor.id).setContent(ttxt); } }); } }); } }); // End for each languuage plus text } }) // End Translator } // End Editor Setup }); } /** Code button, invoked from Grid or List row * * This function provides popup windows with Codemirror as an editor * @param - integer - Record ID * @return - **/ var codeButton = function(recid) { cfg = Cliq.config(); cfg.fldname = 'd_text'; var urlstr = "/ajax/"+jlcd+"/editcode/"+cfg.table+"/"+cfg.tabletype+"/"; aja().method('GET').url(urlstr).cache(false).timeout(2500).type('json') .data({ displaytype: cfg.displaytype, // datalist viewtype: 'popupview', recid: recid, fldname: cfg.fldname }) .on('40x', function(response) {Cliq.error('Page not Found - '+urlstr+':'+response);}) .on('500', function(response) {Cliq.error('Server Error - '+urlstr+':'+response);}) .on('timeout', function(response) {Cliq.error('Timeout - '+urlstr+':'+response);}) .on('success', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { var opts = { content: response.html, contentSize: { width: 860, height: 642 }, headerTitle: '<span class="">'+lstr[105]+'</span>', callback: function() { var jsonte = document.getElementById(cfg.fldname); fcfg.ceditor = CodeMirror.fromTextArea(jsonte, { lineNumbers: true, theme: 'cobalt', mode: "toml" }); addPanel("top", recid); var jsoncontent = $('#'+cfg.fldname).val(); fcfg.ceditor.getDoc().setValue(jsoncontent); } }; var contentEditor = Cliq.win(opts); } else { Cliq.error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response)); }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+response.msg); } }).go(); } // Code Mirror Panel support routines var makePanel = function(where, recid) { var node = document.createElement("div"); var widget, save; node.id = "panel-menu"; node.className = "h30 lightgray panel" + where; // Menu save = node.appendChild(document.createElement("i")); save.setAttribute("title", lstr[138]); save.setAttribute("class", "fa fa-fw fa-save fa-2x tp3 ml30"); CodeMirror.on(save, "click", function() { var frmData = new FormData(); frmData.set('recid', recid); frmData.set('fldname', cfg.fldname); frmData.set(cfg.fldname, fcfg.ceditor.getDoc().getValue()); var urlstr = '/ajax/'+cfg.langcd+'/savecode/'+cfg.table+'/'+cfg.tabletype+'/'; $.ajax({ url: urlstr, data: frmData, cache: false, contentType: false, processData: false, type: 'POST', async: false, timeout: 25000, success: function(response, statusText, xhr) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { Cliq.msg({type: 'success', buttons: false, text: response.msg}) } else { // Error Cliq.msg({type: 'warning', buttons: false, text: 'Ajax function returned error NotOk - '+response.msg}) }; } else { Cliq.msg({type: 'warning', buttons: false, text: 'Response was not JSON object - '+JSON.stringify(response)}) } }, error: function(xhr, status, text) { Cliq.msg({type: 'warning', buttons: false, text: 'Error saving Text to Database - '+urlstr+':'+text}) } }); return true; }); // label = node.appendChild(document.createElement("span")); // label.textContent = "Menu"; return node; } var addPanel = function(where, recid) { var node = makePanel(where, recid); fcfg.panels[node.id] = fcfg.ceditor.addPanel(node, {position: where, stable: true}); } /** Select Button * displays a generic list in a Noty and operator selects new value from select list * record is update and row / display updated * * @param - Cfg Config * @param - Data from the button or icon * @return - displays a Noty and activates its processes **/ var selectButton = function(cfg, dta) { var usrparams = { 'type': 'select', 'postdata': {'formlettype': 'select'} }; return notyFormPopup(cfg, dta, usrparams); } /** Yes No Button * displays a Radio group in a Noty with various label/value pairs. * Operator selects new values, record is updated and row / display updated * * @param - Cfg Config * @param - Data from the button or icon * @return - displays a Noty and activates its processes **/ var yesnoButton = function(cfg, dta) { var params = { 'type': 'radiogroup', 'postdata': {'formlettype': 'radiogroup'} }; return notyFormPopup(cfg, dta, usrparams); } /** Checkbox Group Button * displays a Check box group in a Noty with various label/value pairs. * Operator selects new values, record is updated and row / display updated * * @param - Cfg Config * @param - Data from the button or icon * @return - displays a Noty and activates its processes **/ var checkboxButton = function(cfg, dta) { var params = { 'type': 'checkboxgroup', 'postdata': {'formlettype': 'checkboxgroup'} }; return notyFormPopup(cfg, dta, usrparams); } /** Generic Noty Popup try await ......... * * @param - Cfg Config * @param - Data from the button or icon * @return - displays a Noty and activates its processes **/ var notyFormPopup = function(cfg, dta, usrparams) { var commonparams = { 'table': cfg.table, 'tabletype': cfg.tabletype, 'type': '', 'fldname': dta.id, 'displaytype': cfg.displaytype, // datatable 'postdata': { 'displaytype': cfg.displaytype, 'action': dta.action, // example - changestatus 'ajabuster': 'anything', 'formlettype': '', 'fldname': dta.id, 'params': dta.params, 'recid': cfg.recid } }; var params = array_replace_recursive(commonparams, usrparams); var tpl = `<form id="notyform" class="form"></form>`; var urlstr = '/ajax/'+jlcd+'/getformletdata/'+params.table+'/'+params.tabletype+'/'; // Get the values for the template - aja().method('GET').url(urlstr).cache(false).timeout(2500).type('json').data(params.postdata) .on('40x', function(response) { error('Page not Found - '+urlstr+':'+response)}) .on('500', function(response) { error('Server Error - '+urlstr+':'+response)}) .on('timeout', function(response){ error('Timeout - '+urlstr+':'+response)}) .on('200', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { // Display the Noty Cliq.msg({ buttons: [ {addClass: 'm10 mt10 btn btn-primary btn-sm', text: lstr[8], onClick: function($noty) { // Update the value in the database var urlstr = '/ajax/'+jlcd+'/postvalue/'+params.table+'/'+params.tabletype+'/'; aja().method('POST').url(urlstr).cache(false).timeout(2500).type('json') .data({ 'recid': params.postdata.recid, 'fldname': dta.id, 'newvalue': $('#'+dta.id).getValue() }) .on('40x', function(response) {Cliq.error('Page not Found - '+urlstr+':'+response);}) .on('500', function(response) {Cliq.error('Server Error - '+urlstr+':'+response);}) .on('timeout', function(response) {Cliq.error('Timeout - '+urlstr+':'+response);}) .on('success', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { var originalnoty = $noty; Cliq.success(lstr[146]+': ' + JSON.stringify(response.msg)); originalnoty.close(); switch(params.displaytype) { case "datagrid": cfg.dg.reload(); break; case "blogarticle": case "datatable": Cliq.loadTableData(); break; default: reLoad(); break; }; } else { Cliq.error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response)); }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+response.msg); }; }).go(); }}, {addClass: 'm10 mt10 btn btn-default btn-sm', text: lstr[30], onClick: function($noty) { $noty.close(); }} ], timeout: false, closeWith: ['button'], type: 'info', text: tpl }); $("#notyform").clqform({"action" : "#", "method" : "POST", "html" : response.data}); } else { // Error error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response)) }; } else { error('Response was not JSON object - '+urlstr+':'+response.msg); } }).go(); } /** Form and Button stuff related to Users * * changePasswordButton(uname, email, recid) * resetPassword(msg) * passwordStrength(pwd) * changeUserStatusButton(recid) * ************************************************************************************************/ /** Change user password * **/ var changePasswordButton = function(uname, email, recid) { cfg = Cliq.config(); cfg.action = 'changepassword'; cfg.displaytype = 'lostpassword'; var urlstr = '/ajax/'+jlcd+'/'+cfg.action+'/'+cfg.table+'/'+cfg.tabletype+'/'; var frmData = new FormData(); frmData.append('id', recid); $.ajax({ url: urlstr, data: frmData, cache: false, contentType: false, processData: false, type: 'POST', async: false, timeout: 25000, success: handleResponse, error: handleError }); } /** Display a formlet to permit the reset of a password * * @param - array JSON - usroptions to configure a Noty * @return - string HTML - creates a Noty popup with content **/ var resetPassword = function(msg) { var options = $.parseJSON(msg); var $noty = Cliq.msg(options); // returns $noty $('.closenoty').on('click', function(e) { $noty.close(); }); $('.submitnoty').on('click', function(e) { e.preventDefault(); var newp = $('input[name="c_password"]').val(); var confp = $('input[name="c_password_confirm"]').val(); // Check if Passwords are equal if(newp === confp) { // Check if password is strong enough newp = passwordStrength(newp); if(newp != "") { var uid = $('input[name="id"]').val(); cfg.action = "resetpassword"; var frmData = new FormData(); frmData.append('c_password', newp); frmData.append('id', uid); frmData.append('token', jwt); var urlstr = '/api/'+jlcd+'/'+cfg.action+'/'+cfg.table+'/'+cfg.tabletype+'/'; $.ajax({ url: urlstr, data: frmData, cache: false, contentType: false, processData: false, type: 'POST', async: false, timeout: 25000, success: handleResponse, error: handleError, complete: function() { $noty.close(); } }); } else { Cliq.error(lstr[149]); }; } else { Cliq.error(lstr[137]); } }); } /** Password strength * **/ var passwordStrength = function(pwd) { var strongRegex = new RegExp("^(?=.{8,})(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*\\W).*$", "g"); var mediumRegex = new RegExp("^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$", "g"); var enoughRegex = new RegExp("(?=.{6,}).*", "g"); // Change if necessary if(strongRegex.test(pwd)) { return pwd; } else { return ''; } } /** Change user status * **/ var changeUserStatusButton = function(recid) { cfg = Cliq.config(); cfg.action = 'changeuserstatus'; cfg.displaytype = 'changestatus'; var urlstr = '/ajax/'+jlcd+'/'+cfg.action+'/'+cfg.table+'/'+cfg.tabletype+'/'; var frmData = new FormData(); frmData.append('id', recid); $.ajax({ url: urlstr, data: frmData, cache: false, contentType: false, processData: false, type: 'POST', async: false, timeout: 25000, success: handleResponse, error: handleError }); } /** Form Support Functions * modInput() * getFormData() * handleResponse() * handleError() * changeStatus(msg) * *************************************************************************************/ /** Next Reference, Next ID, Is Unique * * @param - * @param - * @return - **/ var modInput = function(fldid, action, prefix) // eg 'reference' { cfg = Cliq.config(); // console.log(fldid, action, table, tabletype); var urlstr = '/ajax/'+cfg.langcd+'/'+action+'/'+cfg.table+'/'+cfg.tabletype+'/'; aja().method('GET').url(urlstr) .data({fld: fldid, prefix:prefix, currval: $('#'+fldid).val() }).cache(false) .on('40x', function(response) {Cliq.error('Page not Found - '+urlstr+':'+response);}) .on('500', function(response) {Cliq.error('Server Error - '+urlstr+':'+response);}) .on('timeout', function(response) {Cliq.error('Timeout - '+urlstr+':'+response);}) .on('success', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { switch(action) { case "getnextref": case "getnextentry": case "getnextid": Vue.set(cfg.df, fldid, response.data); $('#'+fldid).val(response.data); break; case "isunique": if(response.data) { $('#'+fldid).val(''); $('#'+fldid).focus(); Cliq.msg({type: 'warning', buttons: false, text: 'Value already exists'}); }; break; }; } else { Cliq.error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response)); }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+response.msg); } }).go(); } /** Get all form data for a form * A function to collect any and all data, including files from a form * @param - boolean - add filename * @param - string - * @return - object - the FormData **/ var getFormData = function(addfilename) { // Test config files // console.log(cfg, fcfg); // cfg contains: displaytype, table and tabletype, langcd // Define the Form ID var id = 'dataform'; var thisform = $('#'+id); // Start a Spinner var target = document.getElementById(cfg.formid); cfg.spinner.spin(target); // Get any tinymce Editors if exist and update the Vue instance with Tiny editor content var tinyeditors = tinymce.EditorManager.editors; if(count(tinyeditors) > 0) { $.each(tinyeditors, function(i, teditor) { var name = trim(teditor.id, '_te'); // works fine var val = tinymce.get(teditor.id).getContent(); // rawurlencode() ?? Vue.set(cfg.df, teditor.id, val); }); }; // If Trumbowyg editor is being used $('#'+id+' textarea.texteditor').each(function() { var fldid = $(this).attr('id'); // var te = $('.trumbowyg-editor').trumbowyg('html'); var te = $(this).trumbowyg('html'); // rawurlencode() ?? Vue.set(cfg.df, fldid, te); }); // If Tagit $('.tagit').each(function() { var fldid = $(this).attr('id'); var tags = $("#"+fldid).tagit("assignedTags"); Vue.set(cfg.df, fldid, tags); }); // JSONeditors if exist - only one JSON Editor if exist and update the Vue instance with Jsoneditor content $('#'+id+' div[data-type=jsoneditor]').each(function() { fcfg.jeditor = findJSONEditor('#'+fcfg.jeditid); var jeditdata = fcfg.jeditor.get(); jeditdata = JSON.stringify(jeditdata); // rawurlencode() ?? Vue.set(cfg.df, fcfg.jeditid, jeditdata); }); // If Codeeditor is being used $('.toml').each(function() { var fldid = $(this).attr('id'); var tomlcontent = fcfg.ceditor.getValue(); Vue.set(cfg.df, fldid, rawurlencode(tomlcontent)); }); // If currency and maskMoney is being used $('.currency').each(function() { var fldid = $(this).attr('id'); var cur = $(this).getValue(); Vue.set(cfg.df, fldid, cur); }) // validation here if required // Now get Data from the Vue Instance var postData = cfg.df.$data; // Test Form Content // console.log(postData); // Now convert Postdata to FormData var frmData = new FormData(); $.each(postData, function(fld, val) { frmData.set(fld, val); }); frmData.append('token', jwt); // Add any AJAX Form upload for a single file if( $('#'+id+' :input').hasClass('form-control-file') ) { var file = $('input[type=file]', thisform)[0].files[0]; if(addfilename) { frmData.append(addfilename, file.name); } else { frmData.append('filename', file.name); } frmData.append(file.name, file, file.filename); } // New image handling will get image contents anyway return frmData; } /** Handle a successful response after form is submitted * After form submits **/ var handleResponse = function(response, statusText, xhr) { // Stop and close the Spinner cfg.spinner.stop(); var table = cfg.table; var tabletype = cfg.tabletype; // first argument to the success callback is the json data object returned by the server if(typeof response == 'object') { var match = /NotOk/.test(response.flag); if(!match == true) { // If popup form, close the window if(cfg.formtype == 'popupform') { jsPanel.closeChildpanels('body'); } else if(cfg.formtype == 'columnform') { $('#columnform').empty().html(response.data); } else if(cfg.formtype == 'pageform') { // Introduce history exit; }; var txt; cfg.action == 'insert' ? txt = lstr[9] : txt = lstr[10]; switch(cfg.displaytype) { case "recordcreator": case "datagrid": var tbl = prettyPrint(response.data.row); $('#columnform').empty().html(tbl); Cliq.success(txt); cfg.dg.reload(); break; case "datacard": var urlstr = '/ajax/'+jlcd+'/getcarddata/'+cfg.table+'/'+cfg.tabletype+'/'; aja().method('GET').url(urlstr).cache(false).timeout(2500).type('json') .on('40x', function(response) { Cliq.error('Page not Found - '+urlstr+':'+response)}) .on('500', function(response) { Cliq.error('Server Error - '+urlstr+':'+response)}) .on('timeout', function(response){ Cliq.error('Timeout - '+urlstr+':'+response)}) .on('200', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { Cliq.success(txt); cfg.dc.$data.admdatacards = response.data; } else { // Error Cliq.error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response)) }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+response.msg); } }).go(); break; case "datalist": case "datatable": // Cliq.loadTableData(); // Cliq.success(txt); var urlstr = "/admindesktop/"+jlcd+"/"+cfg.displaytype+"/"+table+"/"+tabletype+"/"; uLoad(urlstr); break; case "lostpassword": resetPassword(response.msg); break; case "changestatus": changeStatus(response.msg); break; case "datatablesnet": Cliq.success(response.data.msg); // var urlstr = "/plugin/"+jlcd+"/"+cfg.displaytype+"/"+table+"/"+tabletype+"/"; // uLoad(urlstr); cfg.dt = $('#datatable').DataTable(); cfg.dt.ajax.reload(); break; default: var urlstr = "/admindesktop/"+jlcd+"/"+cfg.displaytype+"/"+table+"/"+tabletype+"/"; // uLoad(urlstr); break; } } else { Cliq.error('Ajax function returned error NotOk - '+JSON.stringify(response.msg)) }; } else { Cliq.error('Response was not JSON object - '+JSON.stringify(response)) }; } /** Handle an error after form submitted * Handles any 500 Errors from the AJAX routine */ var handleError = function(xhr, status, text) { cfg.spinner.stop(); var response = $.parseJSON(xhr.responseText); Cliq.error(JSON.stringify(response.msg)); return false; } /** Change general status * **/ var changeStatus = function(msg) { var options = $.parseJSON(msg); var $noty = Cliq.msg(options); // returns $noty $('.closenoty').on('click', function(e) { $noty.close(); }); $('.submitnoty').on('click', function(e) { e.preventDefault(); var sts = $('input[name="c_status"]').val(); var uid = $('input[name="id"]').val(); cfg.action = "dochangestatus"; var frmData = new FormData(); frmData.append('c_status', sts); frmData.append('id', uid); var urlstr = '/ajax/'+jlcd+'/'+cfg.action+'/'+cfg.table+'/'+cfg.tabletype+'/'; $.ajax({ url: urlstr, data: frmData, cache: false, contentType: false, processData: false, type: 'POST', async: false, timeout: 25000, success: handleResponse, error: handleError, complete: function() { $noty.close(); } }); }); } /** Import - Export Routines * * convertArray() * importData() * exportData() * siteUpdate() * - doSiteUpdate() * siteMap() * - setSiteMap() * *************************************************************************************/ /** * Javascript routines to convert an import file in Configuration array format * @param - array - options * @return - test or written content **/ var convertArray = function(opts) { var idms = new Vue({ el: '#admconvertarray', data: { formdata: { idioms: opts.idioms, tables: opts.tables, tabletypes: opts.tabletypes }, inputform: { idiom: 'en', table: 'dbitem', tabletype: 'text', inputfile: '', dbwrite: '' }, testform: { testfile: '' } }, mounted: function() { $('#testform').submit(function(evt) { evt.preventDefault(); var target = document.getElementById('testform'); var opts = {}; var spinner = new Spinner(opts).spin(target); $('#convertresults').empty(); var form = $('#testform'); var frmdata = new FormData(); $.each($('input[type=file]',form)[0].files, function (i, file) { frmdata.append(file.filename, file); frmdata.append(file.name, file); }); var urlstr = '/ajax/'+jlcd+'/dotestarray/'; $.ajax({ url: urlstr, data: frmdata, cache: false, contentType: false, processData: false, type: 'POST', async: false, timeout: 5000, success: function(response) { spinner.stop(); if(typeof response == 'object') { var match = /NotOk/.test(response.flag); if(!match == true) { var content = prettyPrint(response.result, { expanded: true, maxDepth: 5 }); $('#convertresults').empty().html(content); } else { Cliq.error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response.msg)); }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+JSON.stringify(response)) }; }, error: function(xhr, status, text) { spinner.stop(); var response = $.parseJSON(xhr.responseText); Cliq.error(JSON.stringify(response.msg)); } }); return false; }); $('#inputform').submit(function(evt) { evt.preventDefault(); var target = document.getElementById('inputform'); var opts = {}; var spinner = new Spinner(opts).spin(target); $('#convertresults').empty(); var form = $('#inputform'); var frmdata = new FormData(); $.each($(':input', form ), function(i, fld){ frmdata.append( $(fld).data('name'), $(fld).getValue() ); }); $.each($('input[type=file]',form)[0].files, function (i, file) { frmdata.append(file.filename, file); frmdata.append(file.name, file); }); var data = $.parseJSON( $('#formresult').html() ); var urlstr = '/ajax/'+jlcd+'/doconvertarray/'+data.table+'/'+data.tabletype+'/'; $.ajax({ url: urlstr, data: frmdata, cache: false, contentType: false, processData: false, type: 'POST', async: false, timeout: 25000, success: function(response) { spinner.stop(); if(typeof response == 'object') { var match = /NotOk/.test(response.flag); if(!match == true) { var content = prettyPrint(response.result, { expanded: true, maxDepth: 5 }); $('#convertresults').empty().html(content); } else { Cliq.msg({type: 'warning', buttons: false, text: 'Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response.msg)}) }; } else { Cliq.msg({type: 'warning', buttons: false, text: 'Response was not JSON object - '+urlstr+':'+JSON.stringify(response)}) }; }, error: function(xhr, status, text) { spinner.stop(); var response = $.parseJSON(xhr.responseText); Cliq.msg({buttons: false, type: 'error', text: JSON.stringify(response.msg)}); } }); return false; }); } }); } /** * Javascript routines to import a CSV formatted data file into the database * @param - array - options * @return - test or written content **/ var importData = function(opts) { cfg = Cliq.config; cfg.df = new Vue({ el: '#admimportdata', data: { formdata: { idioms: opts.idioms, tables: opts.tables, tabletypes: opts.tabletypes }, inputform: { idiom: 'en', table: 'dbitem', tabletype: 'text', inputfile: '', dbwrite: '', header: '', delimiter: ',', encloser: '"', escape: '\\', longestline: 0 } }, mounted: function() { $('#inputform').submit(function(evt) { evt.preventDefault(); var target = document.getElementById('inputform'); var opts = {}; var spinner = new Spinner(opts).spin(target); $('#convertresults').empty(); var form = $('#inputform'); var frmdata = new FormData(); $.each($(':input', form ), function(i, fld){ frmdata.append( $(fld).data('name'), $(fld).getValue() ); }); $.each($('input[type=file]',form)[0].files, function (i, file) { frmdata.append(file.filename, file); frmdata.append(file.name, file); }); var data = $.parseJSON( $('#formresult').html() ); var urlstr = '/ajax/'+jlcd+'/doimportdata/'+data.table+'/'+data.tabletype+'/'; $.ajax({ url: urlstr, data: frmdata, cache: false, contentType: false, processData: false, type: 'POST', async: false, timeout: 25000, success: function(response) { spinner.stop(); if(typeof response == 'object') { var match = /NotOk/.test(response.flag); if(!match == true) { var content = prettyPrint(response.result, { expanded: true, maxDepth: 5 }); $('#convertresults').empty().html(content); } else { Cliq.msg({type: 'warning', buttons: false, text: 'Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response.msg)}) }; } else { Cliq.msg({type: 'warning', buttons: false, text: 'Response was not JSON object - '+urlstr+':'+JSON.stringify(response)}) }; }, error: function(xhr, status, text) { spinner.stop(); var response = $.parseJSON(xhr.responseText); Cliq.msg({buttons: false, type: 'error', text: JSON.stringify(response.msg)}); } }); return false; }); } }); } /** * Javascript routines to export data to a CSV or Array config file * @param - array - options * @return - test or written content **/ var exportData = function(opts) { var idms = new Vue({ el: '#admexportdata', data: { formdata: { idioms: opts.idioms, tables: opts.tables, tabletypes: opts.tabletypes }, exportform: { idiom: 'en', table: 'dbitem', tabletype: 'text', csvorarray: '', doexport: '' } }, mounted: function() { $('#exportform').submit(function(evt) { evt.preventDefault(); var target = document.getElementById('exportform'); var opts = {}; var spinner = new Spinner(opts).spin(target); $('#convertresults').empty(); var form = $('#exportform'); var frmdata = new FormData(); $.each($(':input', form ), function(i, fld){ frmdata.append( $(fld).data('name'), $(fld).getValue() ); }); var data = $.parseJSON( $('#formresult').html() ); var urlstr = '/ajax/'+jlcd+'/doexportdata/'+data.table+'/'+data.tabletype+'/'; $.ajax({ url: urlstr, data: frmdata, cache: false, contentType: false, processData: false, type: 'POST', async: false, timeout: 25000, success: function(response) { spinner.stop(); if(typeof response == 'object') { var match = /NotOk/.test(response.flag); if(!match == true) { var content = prettyPrint(response.result, { expanded: true, maxDepth: 5 }); $('#convertresults').empty().html(content); } else { Cliq.msg({type: 'warning', buttons: false, text: 'Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response.msg)}) }; } else { Cliq.msg({type: 'warning', buttons: false, text: 'Response was not JSON object - '+urlstr+':'+JSON.stringify(response)}) }; }, error: function(xhr, status, text) { spinner.stop(); var response = $.parseJSON(xhr.responseText); Cliq.msg({buttons: false, type: 'error', text: JSON.stringify(response.msg)}); } }); return false; }); } }); } /** * Javascript routines to manage the site update functions * @param - array - options * @return - test or written content **/ var siteUpdate = function(opts) { $('.topbutton').on('click', function(e) { e.preventDefault(); e.stopImmediatePropagation(); Cliq.topButton(this); }); var tree = $('#tree').gjtree({ iconsLibrary: 'fontawesome', primaryKey: 'id', width: 460, uiLibrary: 'bootstrap4', dataSource: opts.data, selectionType: 'multiple' // imageUrlField: 'flagUrl' }); $('#btnSave').on('click', function () { var selections = tree.getSelections(); doSiteUpdate(selections, 'dofilesdownload'); }); $('#btnCopy').on('click', function () { var selections = tree.getSelections(); doSiteUpdate(selections, 'dofilescopy'); }); var readTokenFromResponse = function(response, attr) { return $(response).find('tr th:contains(' + attr + ')').parent().find('td').text() }; var tpl = ` <div class="list-group-item list-group-item-action flex-column align-items-start"> <div class="d-flex w-100 justify-content-between"> <h6 class="mb-1 redc bold">{title}</h6> <small class="text-muted">{date}</small> </div> <p class="mb-1">{shortBodyPlain}</p> <a href="{url}" target="_blank"><small class="text-muted bluec"><i class="fa fa-external-link-square fa-fw"></i>{url}</small></a> </div> `; jQuery(function($) { $("#rssfeed").rss(opts.rssfeedaddress, { limit: 10, // dateFormat: 'dddd MMM Do', layoutTemplate: '<div class="list-group">{entries}</div>', entryTemplate: tpl, }) }) } // Private function var doSiteUpdate = function(selections, action) { cfg = Cliq.config(); var urlstr = '/ajax/'+jlcd+'/'+action+'/'; aja().method('GET').url(urlstr).cache(false).timeout(2500).type('json') .data({selectedfiles: selections}) .on('40x', function(response) {Cliq.error('Page not Found - '+urlstr+':'+response);}) .on('500', function(response) {Cliq.error('Server Error - '+urlstr+':'+response);}) .on('timeout', function(response) {Cliq.error('Timeout - '+urlstr+':'+response);}) .on('success', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { Cliq.success(response.msg); } else { Cliq.error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response)); }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+response.msg); } }).go(); } var siteMap = function(opts) { console.log('Sitemap Loaded'); cfg = Cliq.config(); // Initial setSiteMap(opts); $('.topbutton').on('click', function(e) { e.preventDefault(); e.stopImmediatePropagation(); Cliq.topButton(this); }); var fldid = opts.fieldid; var thisfld = $('#'+fldid); $('#resetbutton').on('click', function(evt) { $('#'+opts.formid).clearform(); }); $('#generatebutton').on('click', function(evt) { evt.preventDefault(); var urlstr = '/ajax/'+cfg.langcd+'/postsitemap/'+cfg.table+'/'+cfg.tabletype+'/'; var frmData = new FormData; frmData.set(fldid, fcfg.ceditor.getDoc().getValue()); $.ajax({ url: urlstr, data: frmData, cache: false, contentType: false, processData: false, type: 'POST', async: false, timeout: 25000, success: function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { Cliq.success(response.msg); setSiteMap(opts); } else { // Error Cliq.error('Ajax function returned error NotOk - '+response.msg) }; } else { Cliq.error( 'Response was not JSON object - '+urlstr+':'+JSON.stringify(response) ) } }, error: function(xhr, status, text) { Cliq.error(text); } }); }); } // Private function var setSiteMap = function(opts) { var urlstr = '/ajax/'+cfg.langcd+'/getsitemap/'+cfg.table+'/'+cfg.tabletype+'/'; aja().method('GET').url(urlstr).cache(false).timeout(2500).type('json') .on('40x', function(response) {Cliq.error('Page not Found - '+urlstr+':'+response);}) .on('500', function(response) {Cliq.error('Server Error - '+urlstr+':'+response);}) .on('timeout', function(response) {Cliq.error('Timeout - '+urlstr+':'+response);}) .on('success', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { $('textarea[id="d_text"]').setValue(response.data); $('#sitemap').empty().html(response.html); var fldid = opts.fieldid; var thisfld = $('#'+fldid); var tomledid = document.getElementById(fldid); var editor = CodeMirror.fromTextArea(tomledid,{ // lineNumbers: true, autofocus: true, // theme: 'cobalt', mode: "toml" }); var tomlcontent = thisfld.getValue(); fcfg.ceditor.getDoc().setValue(tomlcontent); } else { // Error Cliq.error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response)) }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+response.msg) } }).go(); } /** File System and Model Routines * * fileAdd() * fileEdit(reference) * fileDelete(reference) * *******************************************************************************************************************/ var fileAdd = function() { return fileEdit(''); } var fileEdit = function(ref) { cfg = Cliq.config(); var urlstr = "/ajax/"+jlcd+"/fileeditor/"+cfg.table+"/"+cfg.tabletype+"/"; aja().method('GET').url(urlstr).cache(false).timeout(2500).type('json') .data({ ref: ref }) .on('40x', function(response) {Cliq.error('Page not Found - '+urlstr+':'+response);}) .on('500', function(response) {Cliq.error('Server Error - '+urlstr+':'+response);}) .on('timeout', function(response) {Cliq.error('Timeout - '+urlstr+':'+response);}) .on('success', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { var opts = { content: response.html, contentSize: { width: 580, height: 680 }, paneltype: 'modal', headerTitle: '<span class="">'+lstr[20]+'</span>' }; var filePopup = Cliq.win(opts); var thisfld = $('#filecontent'); var tomledid = document.getElementById('filecontent'); var editor = CodeMirror.fromTextArea(tomledid,{ lineNumbers: true, mode: "toml" }); var tomlcontent = thisfld.val(); fcfg.ceditor.getDoc().setValue(tomlcontent); $('#popupform').submit(function(evt) { evt.preventDefault(); var urlstr = '/ajax/'+cfg.langcd+'/writefile/'+cfg.table+'/'+cfg.tabletype+'/'; var frmData = new FormData(); frmData.set('filepath', $('input[name="filename"]').val()); frmData.set('content', editor.getDoc().getValue()); $.ajax({ url: urlstr, data: frmData, cache: false, contentType: false, processData: false, type: 'POST', async: false, timeout: 25000, success: function(response, statusText, xhr) { // first argument to the success callback is the json data object returned by the server if(typeof response == 'object') { var match = /NotOk/.test(response.flag); if(!match == true) { jsPanel.closeChildpanels('body'); reload(); } else { Cliq.error('Ajax function returned error NotOk - '+JSON.stringify(response.msg)); }; } else { Cliq.error('Response was not JSON object - '+JSON.stringify(response)); }; }, error: function(xhr, status, text) { var response = $.parseJSON(xhr.responseText); Cliq.error(JSON.stringify(response.msg)); return false; } }); }) } else { Cliq.error('Ajax function returned error NotOk - '+urlstr+':'+JSON.stringify(response)); }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+response.msg); } }).go(); } var fileDelete = function(ref) { cfg = Cliq.config(); return Cliq.msg({ buttons: [ {addClass: 'm10 mt10 btn btn-success btn-sm', text: 'Close', onClick: function($noty) { $noty.close(); }}, {addClass: 'm10 mt10 btn btn-danger btn-sm', text: 'Delete', onClick: function($noty) { var urlstr = '/ajax/'+cfg.langcd+'/deletefile/'+cfg.table+'/'+cfg.tabletype+'/'; aja().method('POST').url(urlstr).cache(false).timeout(2500).type('json') .data({ filepath: '/models/'+cfg.table+'.'+ref+'.cfg' }) .on('40x', function(response) {Cliq.error('Page not Found - '+urlstr+':'+response);}) .on('500', function(response) {Cliq.error('Server Error - '+urlstr+':'+response);}) .on('timeout', function(response) {Cliq.error('Timeout - '+urlstr+':'+response);}) .on('success', function(response) { if(typeof response == 'object') { // Test NotOK - value already exists var match = /NotOk/.test(response.flag); if(!match == true) { Cliq.success('File successfully deleted: ' + JSON.stringify(response.data)); reLoad(); } else { // Error Cliq.error('Ajax var returned error NotOk - '+urlstr+':'+JSON.stringify(response)) }; } else { Cliq.error('Response was not JSON object - '+urlstr+':'+data) } }).go(); }} ], timeout: false, type: 'warning', text: 'Delete: '+ref }); } // explicitly return public methods when this object is instantiated return { // outside: inside formMounted: formMounted, crudButton: crudButton, creatorButton: creatorButton, contentButton: contentButton, codeButton: codeButton, deleteButton: deleteButton, deleteRecords: deleteRecords, restoreButton: restoreButton, changePasswordButton: changePasswordButton, changeStatusButton: changeUserStatusButton, siteUpdate: siteUpdate, siteMap: siteMap, fileAdd: fileAdd, fileEdit: fileEdit, fileDelete: fileDelete, selectButton: selectButton, yesnoButton: yesnoButton, checkboxButton: checkboxButton, set: _set, get: _get }; })(jQuery);