feat: VivesPOS landing on Winter CMS 1.2 — theme + plugin + Dockerfile
Some checks are pending
Module sub-split / Sub-split (push) Waiting to run
Some checks are pending
Module sub-split / Sub-split (push) Waiting to run
- Base: wintercms/winter branch 1.2 (full framework) - Theme vivespos: Canvas 7 + Bootstrap 5 CDN, custom CSS - Layout: deferred GTM/GA4 tracking, JSON-LD SoftwareApplication - Partials: hero (offline-first), features, modes (offline/nube toggle), screenshots, pricing (3 planes), comparison, FAQ, CTA - Plugin VivesPOS.Site with ContactForm - Dockerfile: PHP 8.2 Apache, port 80, healthcheck - Added winter/wn-pages, blog, sitemap, seo plugins - Active theme set to vivespos
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Autocomplete cell processor for the table control.
|
||||
*/
|
||||
|
||||
+function ($) { "use strict";
|
||||
|
||||
// NAMESPACE CHECK
|
||||
// ============================
|
||||
|
||||
if ($.wn.table === undefined)
|
||||
throw new Error("The $.wn.table namespace is not defined. Make sure that the table.js script is loaded.");
|
||||
|
||||
if ($.wn.table.processor === undefined)
|
||||
throw new Error("The $.wn.table.processor namespace is not defined. Make sure that the table.processor.base.js script is loaded.");
|
||||
|
||||
// CLASS DEFINITION
|
||||
// ============================
|
||||
|
||||
var Base = $.wn.table.processor.string,
|
||||
BaseProto = Base.prototype
|
||||
|
||||
var AutocompleteProcessor = function(tableObj, columnName, columnConfiguration) {
|
||||
//
|
||||
// State properties
|
||||
//
|
||||
|
||||
this.cachedOptionPromises = {}
|
||||
|
||||
//
|
||||
// Parent constructor
|
||||
//
|
||||
|
||||
Base.call(this, tableObj, columnName, columnConfiguration)
|
||||
}
|
||||
|
||||
AutocompleteProcessor.prototype = Object.create(BaseProto)
|
||||
AutocompleteProcessor.prototype.constructor = AutocompleteProcessor
|
||||
|
||||
AutocompleteProcessor.prototype.dispose = function() {
|
||||
this.cachedOptionPromises = null
|
||||
|
||||
BaseProto.dispose.call(this)
|
||||
}
|
||||
|
||||
/*
|
||||
* Forces the processor to hide the editor when the user navigates
|
||||
* away from the cell. Processors can update the sell value in this method.
|
||||
* Processors must clear the reference to the active cell in this method.
|
||||
*/
|
||||
AutocompleteProcessor.prototype.onUnfocus = function() {
|
||||
if (!this.activeCell)
|
||||
return
|
||||
|
||||
this.removeAutocomplete()
|
||||
|
||||
BaseProto.onUnfocus.call(this)
|
||||
}
|
||||
|
||||
/*
|
||||
* Renders the cell in the normal (no edit) mode
|
||||
*/
|
||||
AutocompleteProcessor.prototype.renderCell = function(value, cellContentContainer) {
|
||||
BaseProto.renderCell.call(this, value, cellContentContainer)
|
||||
}
|
||||
|
||||
AutocompleteProcessor.prototype.buildEditor = function(cellElement, cellContentContainer, isClick) {
|
||||
BaseProto.buildEditor.call(this, cellElement, cellContentContainer, isClick)
|
||||
|
||||
var self = this
|
||||
|
||||
this.fetchOptions(cellElement, function autocompleteFetchOptions(options) {
|
||||
self.buildAutoComplete(options)
|
||||
|
||||
self = null
|
||||
})
|
||||
}
|
||||
|
||||
AutocompleteProcessor.prototype.fetchOptions = function(cellElement, onSuccess) {
|
||||
if (this.columnConfiguration.options) {
|
||||
if (onSuccess !== undefined) {
|
||||
onSuccess(this.columnConfiguration.options)
|
||||
}
|
||||
} else {
|
||||
// If options are not provided and not found in the cache,
|
||||
// request them from the server. For dependent autocomplete editors
|
||||
// the caching key contains the master column values.
|
||||
|
||||
if (this.triggerGetOptions(onSuccess) === false) {
|
||||
return
|
||||
}
|
||||
|
||||
var row = cellElement.parentNode,
|
||||
cachingKey = this.createOptionsCachingKey(row),
|
||||
viewContainer = this.getViewContainer(cellElement)
|
||||
|
||||
// Request options from the server. When the table widget builds,
|
||||
// multiple cells in the column could require loading the options.
|
||||
// The AJAX promises are cached here so that we have a single
|
||||
// request per caching key.
|
||||
|
||||
$.wn.foundation.element.addClass(viewContainer, 'loading')
|
||||
|
||||
if (!this.cachedOptionPromises[cachingKey]) {
|
||||
var requestData = {
|
||||
column: this.columnName,
|
||||
rowData: this.tableObj.getRowData(row)
|
||||
},
|
||||
handlerName = this.tableObj.getAlias()+'::onGetAutocompleteOptions'
|
||||
|
||||
this.cachedOptionPromises[cachingKey] = this.tableObj.$el.request(handlerName, {data: requestData})
|
||||
}
|
||||
|
||||
this.cachedOptionPromises[cachingKey].done(function onAutocompleteLoadOptionsSuccess(data){
|
||||
if (onSuccess !== undefined) {
|
||||
onSuccess(data.options)
|
||||
}
|
||||
}).always(function onAutocompleteLoadOptionsAlways(){
|
||||
$.wn.foundation.element.removeClass(viewContainer, 'loading')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
AutocompleteProcessor.prototype.createOptionsCachingKey = function(row) {
|
||||
var cachingKey = 'non-dependent',
|
||||
dependsOn = this.columnConfiguration.dependsOn
|
||||
|
||||
if (dependsOn) {
|
||||
if (typeof dependsOn == 'object') {
|
||||
for (var i = 0, len = dependsOn.length; i < len; i++ )
|
||||
cachingKey += dependsOn[i] + this.tableObj.getRowCellValueByColumnName(row, dependsOn[i])
|
||||
} else
|
||||
cachingKey = dependsOn + this.tableObj.getRowCellValueByColumnName(row, dependsOn)
|
||||
}
|
||||
|
||||
return cachingKey
|
||||
}
|
||||
|
||||
AutocompleteProcessor.prototype.triggerGetOptions = function(callback) {
|
||||
var tableElement = this.tableObj.getElement()
|
||||
if (!tableElement) {
|
||||
return
|
||||
}
|
||||
|
||||
var optionsEvent = $.Event('autocompleteitems.oc.table'),
|
||||
values = {} // TODO - implement loading values from the current row.
|
||||
|
||||
$(tableElement).trigger(optionsEvent, [{
|
||||
values: values,
|
||||
callback: callback,
|
||||
column: this.columnName,
|
||||
columnConfiguration: this.columnConfiguration
|
||||
}])
|
||||
|
||||
if (optionsEvent.isDefaultPrevented()) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
AutocompleteProcessor.prototype.getInput = function() {
|
||||
if (!this.activeCell) {
|
||||
return null
|
||||
}
|
||||
|
||||
return this.activeCell.querySelector('.string-input')
|
||||
}
|
||||
|
||||
AutocompleteProcessor.prototype.buildAutoComplete = function(items) {
|
||||
if (!this.activeCell) {
|
||||
return
|
||||
}
|
||||
|
||||
var input = this.getInput()
|
||||
if (!input) {
|
||||
return
|
||||
}
|
||||
|
||||
if (items === undefined) {
|
||||
items = []
|
||||
}
|
||||
|
||||
$(input).autocomplete({
|
||||
source: this.prepareItems(items),
|
||||
matchWidth: true,
|
||||
menu: '<ul class="autocomplete dropdown-menu table-widget-autocomplete"></ul>',
|
||||
bodyContainer: true
|
||||
})
|
||||
}
|
||||
|
||||
AutocompleteProcessor.prototype.prepareItems = function(items) {
|
||||
var result = {}
|
||||
|
||||
if ($.isArray(items)) {
|
||||
for (var i = 0, len = items.length; i < len; i++) {
|
||||
result[items[i]] = items[i]
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = items
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
AutocompleteProcessor.prototype.removeAutocomplete = function() {
|
||||
var input = this.getInput()
|
||||
|
||||
$(input).autocomplete('destroy')
|
||||
}
|
||||
|
||||
$.wn.table.processor.autocomplete = AutocompleteProcessor;
|
||||
}(window.jQuery);
|
||||
Reference in New Issue
Block a user