Last active
April 8, 2020 00:41
-
-
Save rolldone/4ad1b24f7afdc3943d9a610d023421f4 to your computer and use it in GitHub Desktop.
BaseRactive Helper CLass
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Ractive from "ractive"; | |
| import Config from "Config"; | |
| Ractive.debug = true; | |
| Ractive.defaults.delimiters = ["[[", "]]"]; | |
| Ractive.defaults.tripleDelimiters = ["[[[", "]]]"]; | |
| Ractive.defaults.isolated = true; | |
| window.componentsHash = {}; /* GLOBAL */ | |
| Ractive.defaults.oninit = function() { | |
| if (this.get("ref")) window.componentsHash[this.get("ref")] = this; | |
| }; | |
| Ractive.defaults.onteardown = function() { | |
| if (this.get("ref") && window.componentsHash[this.get("ref")]) | |
| delete window.componentsHash[this.get("ref")]; | |
| }; | |
| Ractive.defaults.onupdate = function() { | |
| alert("vmdfkmv"); | |
| }; | |
| function lifeCycle(action){ | |
| switch (action) { | |
| case "onconfig": | |
| if (window.watchOnConfig != null) { | |
| window.watchOnConfig.cancel(); | |
| } | |
| window.watchOnConfig = _.debounce(function() { | |
| window.pubsub.emit("ractive.lifecycle", { | |
| action: "onconfig" | |
| }); | |
| }, 100); | |
| window.watchOnConfig(); | |
| break; | |
| case "oncomplete": | |
| if (window.watchOnComplete != null) { | |
| window.watchOnComplete.cancel(); | |
| } | |
| window.watchOnComplete = _.debounce(function() { | |
| window.pubsub.emit("ractive.lifecycle", { | |
| action: "oncomplete" | |
| }); | |
| }, 100); | |
| window.watchOnComplete(); | |
| break; | |
| } | |
| } | |
| Ractive.prototype.onconfig = function () { | |
| lifeCycle('onconfig'); | |
| } | |
| Ractive.prototype.oncomplete = function () { | |
| lifeCycle('oncomplete'); | |
| } | |
| var BaseRactive = Ractive.extend({ | |
| data: function() { | |
| return { | |
| take: 50, | |
| page: 1, | |
| start: 0, | |
| end: 0, | |
| limit_number: 5, | |
| pagination_numbers: [] | |
| }; | |
| }, | |
| onconstruct: function() { | |
| this._super(); | |
| this.reInitializeObserve(); | |
| }, | |
| onconfig: function() { | |
| let self = this; | |
| self._super(); | |
| self.initObServer(); | |
| self.lifeCycle("onconfig"); | |
| }, | |
| oncomplete: function() { | |
| let self = this; | |
| self._super(); | |
| self.lifeCycle("oncomplete"); | |
| }, | |
| lifeCycle: function(action) { | |
| }, | |
| reInitializeObserve: function() { | |
| let self = this; | |
| for (var key in self.newOn) { | |
| self.off(key); | |
| self.on(key, self.newOn[key]); | |
| } | |
| }, | |
| initObServer: function() { | |
| let self = this; | |
| self.observe("", function(newValue, oldValue, keypath) { | |
| if (oldValue != undefined) { | |
| // console.log('newValue',self.data_]); | |
| // $(`[data-ractive=${self.data_key}]`).text(newValue['form_data','email']); | |
| // $(`[data-ractive=${self.data_key}]`).val(newValue['form_data','email']); | |
| // $(`[data-ractive=${self.data_key}]`).html(newValue['form_data','email']); | |
| } | |
| }); | |
| }, | |
| set: function(key, val) { | |
| let self = this; | |
| self.data_key = key; | |
| return self._super(key, val); | |
| }, | |
| findComponentByRef: function(ref) { | |
| window.staticType(ref, [String]); | |
| return componentsHash[ref]; | |
| }, | |
| validURL: function(str) { | |
| var pattern = new RegExp( | |
| "^(https?:\\/\\/)?" + // protocol | |
| "((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // domain name | |
| "((\\d{1,3}\\.){3}\\d{1,3}))" + // OR ip (v4) address | |
| "(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + // port and path | |
| "(\\?[;&a-z\\d%_.~+=-]*)?" + // query string | |
| "(\\#[-a-z\\d_]*)?$", | |
| "i" | |
| ); // fragment locator | |
| return !!pattern.test(str); | |
| }, | |
| safeJSON: function(props, endpoint, index) { | |
| endpoint = endpoint.split("."); | |
| if (endpoint.length == 0) { | |
| return ""; | |
| } | |
| if (index == null) { | |
| index = 0; | |
| } | |
| if (props == null) { | |
| return ""; | |
| } | |
| if (props[endpoint[index]] == null) { | |
| return ""; | |
| } | |
| props = props[endpoint[index]]; | |
| index += 1; | |
| if (index == endpoint.length) { | |
| return props; | |
| } | |
| return this.safeJSON(props, endpoint.join("."), index); | |
| }, | |
| removePropertyByPrefix: function(key, props) { | |
| let newProps = props; | |
| for (var a in newProps) { | |
| if (a.includes(key) == true) { | |
| delete newProps[a]; | |
| } | |
| } | |
| return newProps; | |
| }, | |
| mergeObjectAndFormData: function(props, domFormElement) { | |
| let formData = new FormData(domFormElement); | |
| let result = {}; | |
| for (var entry of formData.entries()) { | |
| result[entry[0]] = entry[1]; | |
| } | |
| props = Object.assign(result, props); | |
| return props; | |
| }, | |
| objectToFormData: function(props) { | |
| let formData = null; | |
| formData = new FormData(); | |
| for (var a in props) { | |
| if (props[a] != null) { | |
| formData.append(a, props[a]); | |
| } | |
| } | |
| return formData; | |
| }, | |
| removePrefix: function(key, props) { | |
| for (var a in props) { | |
| if (props[a] != "") { | |
| let val = props[a]; | |
| delete props[a]; | |
| a = a.replace(key, ""); | |
| props[a] = val; | |
| } else { | |
| delete props[a]; | |
| } | |
| } | |
| return props; | |
| }, | |
| getValuePrefix: function(key, props) { | |
| let theValue = {}; | |
| for (var a in props) { | |
| if (a.includes(key) == true) { | |
| theValue[a] = props[a]; | |
| } | |
| } | |
| return theValue; | |
| }, | |
| getExistValue: function(whatNumber, arrayStoreNumber) { | |
| let isGot = false; | |
| for (let i = 0; i < arrayStoreNumber.length; i++) { | |
| if (arrayStoreNumber[i] == whatNumber) { | |
| isGot = true; | |
| break; | |
| } | |
| } | |
| if (isGot) { | |
| return true; | |
| } | |
| return false; | |
| }, | |
| toEndSCroll: function(callback) { | |
| let self = this; | |
| $(window).scroll(function() { | |
| if ( | |
| $(window).scrollTop() + $(window).height() > | |
| $(document).height() - 1 | |
| ) { | |
| // $(window).unbind('scroll'); | |
| if (self.pendingDebounce != null) { | |
| self.pendingDebounce.cancel(); | |
| } | |
| self.pendingDebounce = _.debounce(function() { | |
| callback(); | |
| }, 500); | |
| self.pendingDebounce(); | |
| } | |
| }); | |
| }, | |
| setUrl: function(urlString, array) { | |
| for (var a = 0; a < array.length; a++) { | |
| for (var key in array[a]) { | |
| if (urlString.match(re)) { | |
| var re = new RegExp(key, "g"); | |
| urlString = urlString.replace(re, array[a][key]); | |
| } | |
| break; | |
| } | |
| } | |
| return urlString; | |
| }, | |
| getData: function(url, queryString) { | |
| let theArg = new Arg(url); | |
| let query = theArg.query(); | |
| query = Object.assign(query, queryString); | |
| let theUrl = theArg.url(url, query); | |
| return new Promise(function(resolve) { | |
| $.ajax({ | |
| method: "GET", | |
| url: theUrl, | |
| processData: false, | |
| contentType: false // what type of data do we expect back from the server | |
| }) | |
| .then(function(res) { | |
| resolve(res); | |
| }) | |
| .fail(function(data, status) { | |
| resolve({ | |
| status: "error", | |
| data: data | |
| }); | |
| }); | |
| }); | |
| }, | |
| postData: function(url, formData) { | |
| return new Promise(function(resolve) { | |
| $.ajax({ | |
| method: "POST", | |
| url: url, | |
| data: formData, | |
| processData: false, | |
| contentType: false // what type of data do we expect back from the server | |
| }) | |
| .then(function(res) { | |
| resolve(res); | |
| }) | |
| .fail(function(data, status) { | |
| resolve({ | |
| status: "error", | |
| data: data | |
| }); | |
| }); | |
| }); | |
| }, | |
| setUpdate: function(key, props) { | |
| let self = this; | |
| return new Promise(function(resolve) { | |
| let currentData = self.get(key) || {}; | |
| console.log("currentData -> ", currentData); | |
| self.set(key, Object.assign(currentData, props)).then(function() { | |
| resolve(); | |
| }); | |
| }); | |
| }, | |
| /** | |
| ----------------------------------------------- | |
| Ini untuk add dan append tanpa duplicate data | |
| ------------------------- **/ | |
| initSelectedData: function(whatId, theArray) { | |
| let theSelectedData = theArray; | |
| let is_same = false; | |
| theSelectedData.forEach(function(item, i) { | |
| if (item == whatId) { | |
| is_same = true; | |
| theSelectedData.splice(i, 1); | |
| } else { | |
| } | |
| }); | |
| if (!is_same) { | |
| theSelectedData.push(whatId); | |
| } | |
| return theSelectedData; | |
| }, | |
| /** | |
| ---------------------------------------------------------------- | |
| Ini untuk type key object lebih bagus dari initSelectedData | |
| ------------------------------ **/ | |
| initSelectedDataKey: function(whatId, theObject, isChecked = false) { | |
| let theSelectedData = theObject; | |
| if (theSelectedData[whatId] == null) { | |
| if (isChecked == true) { | |
| theSelectedData[whatId] = whatId; | |
| } | |
| return theSelectedData; | |
| } | |
| if (isChecked == false) { | |
| delete theSelectedData[whatId]; | |
| } | |
| return theSelectedData; | |
| }, | |
| initGlobally: function() {}, | |
| submitValidation: function(props, callback) { | |
| let self = this; | |
| self.isPending = _.debounce(function(form_data) { | |
| let validation = new Validator(form_data, props.form_rules); | |
| validation.passes(function() { | |
| callback({ | |
| status: "complete", | |
| form_data: form_data, | |
| error: {} | |
| }); | |
| }); | |
| validation.fails(function() { | |
| let newError = {}; | |
| for (var aa in form_data) { | |
| switch (form_data[aa]) { | |
| case "": | |
| case null: | |
| delete form_data[aa]; | |
| break; | |
| } | |
| } | |
| if (validation.errors.errors != null) { | |
| for (let key in validation.errors.errors) { | |
| newError[key] = validation.errors.errors[key][0]; | |
| delete form_data[key]; | |
| } | |
| callback({ | |
| status: "error", | |
| form_data: form_data, | |
| error: newError | |
| }); | |
| } else { | |
| callback({ | |
| status: "valid", | |
| form_data: form_data, | |
| error: newError | |
| }); | |
| } | |
| }); | |
| }, 500); | |
| self.isPending(props.form_data); | |
| }, | |
| inputTextValidation: function(wrapperTarget, props, callback) { | |
| let self = this; | |
| console.log("props.form_data", props.form_data); | |
| let theDom = $(wrapperTarget); | |
| theDom = theDom.find(props.element_target); | |
| theDom.each(function(index, dom) { | |
| $(dom).on("focus change keyup blur keydown", function(e) { | |
| if (self.isPending != null) { | |
| if (e.type != "blur") { | |
| self.isPending.cancel(); | |
| } | |
| } | |
| self.isPending = _.debounce(function(key, value) { | |
| let newObject = {}; | |
| newObject[key] = value; | |
| props.form_data = _.assign({}, props.form_data, newObject); | |
| for (var aa in props.form_data) { | |
| if ( | |
| props.form_data[aa] == null || | |
| props.form_data[aa] == "" | |
| ) { | |
| delete props.form_data[aa]; | |
| } | |
| if (aa == "") { | |
| delete props.form_data[aa]; | |
| } | |
| } | |
| let validation = new Validator( | |
| props.form_data, | |
| props.form_rules | |
| ); | |
| validation.passes(function() { | |
| callback( | |
| { | |
| status: "complete", | |
| form_data: props.form_data, | |
| error: {}, | |
| message: "" | |
| }, | |
| e | |
| ); | |
| }); | |
| validation.fails(function() { | |
| let newError = {}; | |
| if (validation.errors.errors[key]) { | |
| newError[key] = validation.errors.errors[key][0]; | |
| callback( | |
| { | |
| status: "error", | |
| form_data: props.form_data, | |
| error: newError, | |
| message: validation.errors.errors[key][0] | |
| }, | |
| e | |
| ); | |
| } else { | |
| callback( | |
| { | |
| status: "valid", | |
| form_data: props.form_data, | |
| error: newError, | |
| message: "" | |
| }, | |
| e | |
| ); | |
| } | |
| }); | |
| }, 300); | |
| self.isPending(e.target.name, e.target.value); | |
| }); | |
| }); | |
| }, | |
| setTitle: function(whatTitle) { | |
| this.root.findComponent("head-menu").setHeader("page_name", whatTitle); | |
| }, | |
| show: function() { | |
| alert("need to overriding"); | |
| }, | |
| hide: function() { | |
| alert("need to overriding"); | |
| }, | |
| jsonParseUrl: function(whatUrl) { | |
| let theUrl = new Arg(whatUrl); | |
| let theJSON = {}; | |
| theJSON["query"] = theUrl.query(); | |
| theJSON["hash"] = theUrl.hash(); | |
| return theJSON; | |
| }, | |
| jsonToQueryUrl: function(url, whatObject, action) { | |
| let theArg = new Arg(); | |
| if (action == "hash") { | |
| theArg.urlUseHash = true; | |
| } | |
| let theUrl = theArg.url(url, whatObject); | |
| return theUrl; | |
| }, | |
| updateUrlState: function(curUrl, action) { | |
| // console.log(window.location.href,' - '+curUrl); | |
| switch (action) { | |
| case "PUSH_STATE": | |
| if (window.location.href == curUrl) { | |
| return; | |
| } | |
| return window.history.pushState(null, null, curUrl); | |
| } | |
| return window.history.replaceState(null, null, curUrl); | |
| }, | |
| /* -------------------------------------------------------- | |
| * Ini cocok untuk ketika data di salah satu pagination | |
| * number result empty maka lakukan recheck limit pagination kembali | |
| * dengan yang baru | |
| * ---------------------- */ | |
| recheckPaginationAfterEmpty: async function(lastPage) { | |
| let self = this; | |
| if (lastPage == 0) { | |
| return; | |
| } | |
| await self.set("page", lastPage); | |
| await self.set("limit_number", lastPage); | |
| let newUrlState = self.jsonToQueryUrl( | |
| window.location.href, | |
| { | |
| page: self.get("page") | |
| }, | |
| null | |
| ); | |
| self.updateUrlState(newUrlState); | |
| self.initPagination(); | |
| self.set("update_state", new Date()); | |
| }, | |
| /** | |
| -------------------------------------------------------- | |
| Jangan selalu Dipanggil pada saat http request data, | |
| jelek hasilnya, coba aja sendiri | |
| ------------------ **/ | |
| getPaginationNumbers: function(take, page, is_change, is_update_url) { | |
| let self = this; | |
| return new Promise(function(resolve) { | |
| /** Define pushstate url first time **/ | |
| if (is_update_url == null || is_update_url == true) { | |
| let newQuery = { | |
| page: page, | |
| take: take | |
| }; | |
| let curUrl = Arg(window.location.href); | |
| newQuery = Object.assign(curUrl.query(), newQuery); | |
| curUrl = Arg().url(window.location.href, newQuery); | |
| self.updateUrlState(curUrl); | |
| } | |
| /** Will process pagination **/ | |
| switch (is_change) { | |
| case false: | |
| /** If getting false prevent this action **/ | |
| self.set("page", page); | |
| return resolve(); | |
| case true: | |
| self.set("page", page); | |
| break; | |
| } | |
| let limitNumber = self.get("limit_number") || 5; | |
| let start = page - parseInt(limitNumber / 2); | |
| console.log("start", start); | |
| if (start <= 1) { | |
| start = 1; | |
| } | |
| let end = page + limitNumber; | |
| let thePaginationNumbers = []; | |
| let lengthNumber = 0; | |
| for (var a = start; a < end; a++) { | |
| thePaginationNumbers.push(a); | |
| lengthNumber += 1; | |
| } | |
| self.set("pagination_numbers", thePaginationNumbers).then( | |
| function() { | |
| resolve(); | |
| } | |
| ); | |
| }); | |
| }, | |
| waitingDOMLoaded: function(selector, callback) { | |
| let self = this; | |
| if ($(selector).length) { | |
| setTimeout(function() { | |
| callback(); | |
| }, 1000); | |
| } else { | |
| setTimeout(function() { | |
| self.waitingDOMLoaded(selector, callback); | |
| }, 1000); | |
| } | |
| }, | |
| waitingTimeout: function(whatSecondTime) { | |
| return new Promise(function(resolve) { | |
| setTimeout(function() { | |
| resolve(); | |
| }, whatSecondTime); | |
| }); | |
| }, | |
| handleCaptchaListener: function(dom_id, callback) { | |
| let self = this; | |
| window.staticType(dom_id, [String]); | |
| window.staticType(callback, [Function]); | |
| try { | |
| self.grecaptcha = grecaptcha.render(dom_id, { | |
| sitekey: Config.g_captcha_site_key, | |
| callback: function(response) { | |
| return callback(response); | |
| self.setUpdate("form_data", { | |
| recaptcha_token: response | |
| }); | |
| } | |
| }); | |
| } catch (ex) { | |
| alert(ex.message); | |
| } | |
| }, | |
| newOn : {}, | |
| setTemplateData: function(whatVariable, value) { | |
| if (window.template_data == null) { | |
| window.template_data = {}; | |
| } | |
| let self = window.template_data; | |
| self[whatVariable] = _.cloneDeep(value); | |
| console.log("whatVariable", whatVariable); | |
| console.log("value", value); | |
| }, | |
| getTemplateData: function(whatVariable) { | |
| if (window.template_data == null) { | |
| window.template_data = {}; | |
| } | |
| let self = window.template_data; | |
| return self[whatVariable]; | |
| }, | |
| setBindData: function(scope,value) { | |
| var test = document.querySelectorAll(`[data-binding="${scope}"]`); //.map(i => i.innerHTML = value); | |
| test.forEach(function(dom,i){ | |
| dom.innerHTML = value; | |
| }) | |
| // document.querySelector(`[data-binding="${scope}"]`).innerHTML = value; | |
| // document.querySelector(`[data-model="${scope}"]`).value = value; | |
| // document.querySelector(`[data-model="${scope}"]`).value = value; | |
| } | |
| }); | |
| export default BaseRactive; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment