Skip to content

Instantly share code, notes, and snippets.

@frequent
Created August 21, 2015 09:56
Show Gist options
  • Save frequent/0e9ca7ae840a2a8b3882 to your computer and use it in GitHub Desktop.
Save frequent/0e9ca7ae840a2a8b3882 to your computer and use it in GitHub Desktop.
template for Xiaowu
<!-- field-search with tags and filter button -->
<script id="field-search-template" type="text/x-handlebars-template">
<div class="field_container">
<div class="ui-field-contain">
<div class="css-compatability-helper">
<div class="ui-input-text ui-body-{{theme}} ui-input-has-icon ui-corner-all ui-shadow-inset ui-input-has-clear {{status_class}} {{css_class}}">
<form class="save_form document_form">
<input type="text" data-enhanced="true" value="{{value}}" name="search" {{status_attribute}} />
<div class="ui-btn ui-input-clear ui-input-btn ui-corner-all ui-icon-search ui-btn-icon-notext" data-i18n="[node]{{search_i18n}}">
{{search_i18n}}<input tabindex="-1" data-role="button" data-enhanced="true" type="submit" data-i18n="[value]{{search_i18n}}" value=" " {{status_attribute}} />
</div>
<!--
<div class="ui-tag-list ui-tag-list-inset">
{{> taglist-partial}}
</div>
-->
</form>
</div>
{{#if filter_i18n}}
<div class="ui-shadow-inset ui-btn ui-btn-inline ui-corner-all ui-btn-{{theme}} ui-btn-icon-notext ui-icon-filter ui-override-theme {{filter_class}}" data-i18n="[node]{{filter_i18n}}">
<form class="showDocumentTree">
{{filter_i18n}}<input data-role="button" data-enhanced="true" type="submit" data-i18n="[value]{{filter_i18n}}" value=" " />
</form>
</div>
{{/if}}
</div>
</div>
</div>
</script>
/*global window, rJS, RSVP, loopEventListener */
/*jslint nomen: true, indent: 2 */
(function (window, rJS, RSVP, loopEventListener, Handlebars) {
"use strict";
/////////////////////////////////////////////////////////////////
// TEMPLATE API
/////////////////////////////////////////////////////////////////
// field_search_template
// {
// "filter_class": [SET],
// "theme": [theme],
// "css_class": [custom class for gadget],
// "status_class": [SET],
// "status_attribute": [SET],
// "value": [SET],
// "search_i18n": [i18n lookup],
// "filter_i18n": [i18n lookup],
// "tag_list": [taglist_partial objects]
// }]
// }
// taglist-partial
// {
// "type_i18n": [type of tag "filter|create...],
// "value_i18n": [value to create or filter for, eg. region:foo]
// }
var gadget_klass = rJS(window),
templater = gadget_klass.__template_element,
// pre-compile templates
field_search_template = Handlebars.compile(
templater.getElementById("field-search-template").innerHTML
),
taglist_partial = Handlebars.registerPartial(
"taglist-partial",
templater.getElementById("taglist-partial").innerHTML
),
// XXX: find better approach to add filters to url!
// sample: 'fooANDbarORbazANDfilter=a:"b"ORfilter=c:"d"NOTcreate:"Person"'
FILTER_REGEX = /filter=.*?\"[\w\s]+\"/gi,
// retrieve everything before first AND(filter|CREATE) ~ whatever search
SEARCH_REGEX = /(?=AND(filter|create)=.*?)/;
/////////////////////////////////////////////////////////////////
// some methods
/////////////////////////////////////////////////////////////////
gadget_klass
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
.ready(function (my_gadget) {
my_gadget.property_dict = {};
})
.ready(function (my_gadget) {
return my_gadget.getElement()
.push(function (element) {
my_gadget.property_dict.element = element;
my_gadget.property_dict.defer = new RSVP.defer();
});
})
//////////////////////////////////////////////
// acquired method
//////////////////////////////////////////////
.declareAcquiredMethod("setPanelContent", "setPanelContent")
.declareAcquiredMethod("setPanelHeader", "setPanelHeader")
.declareAcquiredMethod("togglePanel", "togglePanel")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("pleasePublishMyState", "pleasePublishMyState")
.declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod('render', function (my_option_dict) {
var gadget = this,
queue = new RSVP.Queue(),
is_disabled = my_option_dict.disabled,
tag_list = [],
empty_string = "",
search_string = my_option_dict.extended_search || "",
search_text = search_string.split(SEARCH_REGEX)[0] || "",
filter_list = search_string.match(FILTER_REGEX) || [],
field_json = my_option_dict.field_json || {},
has_domain_tree = field_json.domain_tree,
configuration_dict = {},
append_class,
append_attribute,
tag,
value,
i,
i_len;
configuration_dict.filter_class = " ui-disabled";
if (is_disabled) {
append_class = " ui-disabled";
append_attribute = ' disabled="disabled';
}
// XXX domain tree temp set
has_domain_tree = true;
my_option_dict.domain_root = [];
if (has_domain_tree) {
gadget.property_dict.has_domain_tree = has_domain_tree;
configuration_dict.filter_class = "";
configuration_dict.filter_i18n = "gen.filter";
// extract filters from URL
for (i = 0, i_len = filter_list.length; i < i_len; i += 1) {
tag = filter_list[i].split("=")[1];
value = tag.replace(/\"/g, "").split(":");
tag_list.push({"type_i18n": value[0], "value_i18n": value[1]});
}
// create panel, fetch domain tree and render
queue.push(function () {
return gadget.setPanelHeader({
"close_i18n": "gen.close",
"i18n": "Configuration",
"clear_i18n": "gen.delete",
"update_i18n": "gen.update",
"tag_list": tag_list
});
});
}
// fill remaining properties
configuration_dict.theme = my_option_dict.theme || "c";
configuration_dict.css_class = my_option_dict.css_class || empty_string;
configuration_dict.status_class = append_class || empty_string;
configuration_dict.status_attribute = append_attribute || empty_string;
configuration_dict.value = search_text;
configuration_dict.search_i18n = "gen.search";
configuration_dict.tag_list = tag_list;
return queue
.push(function (my_templated_html) {
return gadget.translateHtml(field_search_template(configuration_dict));
})
.push(function (my_translated_html) {
gadget.property_dict.element.innerHTML += my_translated_html;
return gadget.property_dict.defer.resolve();
})
.push(function () {
return gadget;
});
})
.declareMethod('getContent', function () {
var input = this.property_dict.element.querySelector('input'),
result = {};
result[input.getAttribute('name')] = input.value;
return result;
})
/////////////////////////////////////////////////////////////////
// declared services
/////////////////////////////////////////////////////////////////
.declareService(function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.property_dict.defer.promise;
})
.push(function () {
var element = gadget.property_dict.element,
form_list = element.querySelectorAll(".field_container form"),
submit_list = [],
filter_button,
i_len,
i;
function routeSubmit(my_event) {
var element = my_event.target.firstElementChild,
event = new Event('submit');
gadget.property_dict.route_active = true;
element.dispatchEvent(event);
}
function formSubmit(my_event) {
if (gadget.property_dict.route_active) {
delete gadget.property_dict.route_active;
return gadget.togglePanel();
}
return new RSVP.Queue()
.push(function () {
return gadget.getContent();
})
.push(function (data) {
return gadget.pleasePublishMyState({
"extended_search": data.search
});
})
.push(function (url) {
console.log(url)
return gadget.pleaseRedirectMyHash(url);
});
}
for (i = 0, i_len = form_list.length; i < i_len; i += 1) {
submit_list.push(loopEventListener(
form_list[i],
"submit",
false,
formSubmit
));
}
// XXX: find better way, bind click + dispatch submit
// Problem is <form> inside JQM enhanced element. Putting <form>
// outside breaks UI and requires custom css to handle forms inline.
// this can be removed along with routeSubmit
filter_button = element.querySelector(".ui-input-has-clear ~ .ui-btn");
if (gadget.property_dict.has_domain_tree && filter_button) {
submit_list.push(loopEventListener(
filter_button,
"click",
false,
routeSubmit
));
}
return RSVP.all(submit_list);
});
});
}(window, rJS, RSVP, loopEventListener, Handlebars));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment