Skip to content

Instantly share code, notes, and snippets.

@rolldone
Last active April 8, 2020 00:41
Show Gist options
  • Select an option

  • Save rolldone/4ad1b24f7afdc3943d9a610d023421f4 to your computer and use it in GitHub Desktop.

Select an option

Save rolldone/4ad1b24f7afdc3943d9a610d023421f4 to your computer and use it in GitHub Desktop.
BaseRactive Helper CLass
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