Skip to content

Instantly share code, notes, and snippets.

@frequent
Created May 15, 2014 08:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save frequent/cf775c51097579d7e13c to your computer and use it in GitHub Desktop.
Save frequent/cf775c51097579d7e13c to your computer and use it in GitHub Desktop.
settings.js
/*global console */
(function (window, rJS) {
"use strict";
// event listener
function startListenTo(obj, type, fn) {
if (obj.addEventListener) {
obj.addEventListener(type, fn, false);
} else if (obj.attachEvent) {
obj["e" + type + fn] = fn;
obj[type + fn] = function() {
obj["e" + type + fn](window.event);
}
obj.attachEvent("on" + type, obj[type + fn]);
}
}
// event removal
function stopListenTo(obj, type, fn) {
if (obj.removeEventListener) {
obj.removeEventListener(type, fn, false);
} else if (obj.detachEvent) {
obj.detachEvent("on" + type, obj[type + fn]);
obj[type + fn] = null;
obj["e" + type + fn] = null;
}
}
// validation for non-empty string
function validator(str) {
var i, len, el, err, pass, split, key, value, arr;
for (i = 0, arr = str.split("&"), len = arr.length; i < len; i += 1) {
el = arr[i];
split = el.split("=");
key = split[0];
value = split[1];
if (value === "") {
err = err || {};
err[key] = null;
err.failed = true;
} else {
pass = pass || {};
pass[key] = value;
}
}
return err || pass;
}
// merge two flat objects not overwriting existing properties
function mergeObjects(a, b) {
var prop;
for (prop in a) {
if (a.hasOwnProperty(prop) && !b[prop]) {
b[prop] = a[prop];
}
}
return b;
}
// generate a listitem
function makeListItem (record) {
var link, input, id, label, form, item;
item = document.createElement("li");
if (!record) {
item.className = "translate";
item.setAttribute("data-i18n", "state_dict.no_records");
item.textContent = i18n.t("state_dict.no_records");
} else {
id = record._id;
item.className = "ui-li-has-checkbox";
// link to item displayed
link = document.createElement("a");
link.href = "#projects%26allDocs_updates|query:portal_type=portal_category+category_type=project+_id=" + record._id;
link.textContent = record.value;
// checkbox & label
label = document.createElement("label");
input = document.createElement("input");
input.setAttribute("type", "radio");
input.setAttribute("value", id);
input.setAttribute("name", "_id");
item.appendChild(link);
label.appendChild(input);
item.appendChild(label);
}
return item;
};
rJS(window)
.declareMethod('render', function (options) {
var gadget, form_list, i, form_len, param, promise_list, form, not_bound,
formHandler, opts, is_init;
gadget = this;
is_init = options === undefined;
opts = options || {};
promise_list = [];
form_list = opts.form_list || document.getElementsByTagName("form");
// allow bindings on initial call to render()
if (!gadget.state_parameter_dict.bound) {
not_bound = true;
}
// handler for validation and re-rendering on form submits
formHandler = function (e) {
var form, valid, field, field_name, setValid;
form = e.target;
valid = validator($(form).serialize());
setValid = function (e) {
var classes, focus_field;
focus_field = e.target;
classes = focus_field.parentNode.className;
focus_field.parentNode.className = classes.replace(" invalid ", "");
stopListenTo(focus_field, "focus", setValid);
};
// highlight invalid form fields and remove on focus
if (valid.failed) {
for (field_name in valid) {
if (valid.hasOwnProperty(field_name) && field_name !== "failed") {
field = form.querySelector("input[name=" + field_name +"]");
field.parentNode.className += " invalid ";
startListenTo(field, "focus", setValid);
}
}
// render form with submitted data
} else {
gadget.render({"form_list": [form], "data": valid});
}
// block actual form submission
e.preventDefault();
return false;
};
// loop over the list of forms, parse action and bind to submit
// NOTE: if all submits go through jIO, there will always be a "&"!
for (i = 0, form_len = form_list.length; i < form_len; i += 1) {
form = form_list[i];
param = decodeURIComponent(form.getAttribute("action") || "")
.split("&");
if (not_bound) {
startListenTo(form, "submit", formHandler);
}
promise_list[i] = gadget.acquire_parseParam(param.slice(1).join("&"))
.then(function (parsed) {
var method;
// override method declared in action with hidden input value
if (opts.data && opts.data.force_method) {
method = opts.data.force_method;
delete opts.data.force_method;
}
// only query on form submits and form listening for updates
if (parsed.on_render || opts.data) {
return gadget["acquire_" + (method || parsed.method)](
mergeObjects(opts.data, parsed.data)
);
}
});
}
return RSVP.all(promise_list)
.then(function (response_list) {
var i, j, len, response, data, form, list, fragment, submit, input;
for (i = 0, len = response_list.length; i < len; i += 1) {
response = response_list[i];
if (response && response.data) {
data = response.data;
form = document.getElementsByTagName("form")[i];
list = form.getElementsByTagName("ul")[0];
fragment = document.createDocumentFragment();
if (data.total_rows === 0) {
fragment.appendChild(makeListItem());
} else {
for (j = 0; j < data.total_rows; j += 1) {
fragment.appendChild(makeListItem(data.rows[j].doc));
}
submit = $(form).find("input[type=submit]").length;
if (submit === 0) {
// add a hidden input forcing (non generic) remove!
input = document.createElement("input");
input.setAttribute("type", "hidden");
input.setAttribute("name", "force_method");
input.setAttribute("value", "remove");
form.appendChild(input);
// add translate and enhance submit button
submit = document.createElement("input");
submit.className = "translate";
submit.setAttribute("type", "submit");
submit.setAttribute(
"data-i18n",
"[value]global_dict.page_dict.settings.remove"
);
submit.setAttribute(
"value",
i18n.t("global_dict.page_dict.settings.remove")
);
submit.setAttribute("data-inline", true);
submit.setAttribute("data-icon", "delete");
form.appendChild(submit);
$(form).find("input[type=submit]").button();
}
}
while (list.firstChild) {
list.removeChild(list.firstChild);
}
list.appendChild(fragment);
$(list).listview("refresh").find("input").each(function () {
$(this).checkboxradio();
});
}
}
// lock gadget from future bindings
gadget.state_parameter_dict.bound = true;
// re-render all forms to update the ones who should be updated
if (!options.update) {
gadget.render({"update": true});
}
});
})
.declareAcquiredMethod("acquire_changeLanguage", "acquire_changeLanguage")
.declareAcquiredMethod("acquire_remove", "acquire_remove")
.declareAcquiredMethod("acquire_post", "acquire_post")
.declareAcquiredMethod("acquire_allDocs", "acquire_allDocs")
.declareAcquiredMethod("acquire_parseParam", "acquire_parseParam");
}(window, rJS));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment