picky-client 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- metadata +2 -33
- data/sinatra_prototype/Gemfile +0 -13
- data/sinatra_prototype/app.rb +0 -65
- data/sinatra_prototype/book.rb +0 -42
- data/sinatra_prototype/config.ru +0 -2
- data/sinatra_prototype/images/picky.png +0 -0
- data/sinatra_prototype/javascripts/compiler.jar +0 -0
- data/sinatra_prototype/javascripts/generate_bundles +0 -25
- data/sinatra_prototype/javascripts/jquery-1.3.2.js +0 -4376
- data/sinatra_prototype/javascripts/jquery-1.4.3.min.js +0 -166
- data/sinatra_prototype/javascripts/jquery.scrollTo-1.4.2.js +0 -215
- data/sinatra_prototype/javascripts/jquery.timer.js +0 -75
- data/sinatra_prototype/javascripts/picky.addination.js +0 -36
- data/sinatra_prototype/javascripts/picky.allocation_renderer.js +0 -291
- data/sinatra_prototype/javascripts/picky.allocations_cloud.js +0 -91
- data/sinatra_prototype/javascripts/picky.backend.js +0 -86
- data/sinatra_prototype/javascripts/picky.client.js +0 -62
- data/sinatra_prototype/javascripts/picky.controller.js +0 -107
- data/sinatra_prototype/javascripts/picky.data.js +0 -78
- data/sinatra_prototype/javascripts/picky.extensions.js +0 -15
- data/sinatra_prototype/javascripts/picky.min.js +0 -17
- data/sinatra_prototype/javascripts/picky.results_renderer.js +0 -103
- data/sinatra_prototype/javascripts/picky.source.js.tar +0 -0
- data/sinatra_prototype/javascripts/picky.translations.js +0 -50
- data/sinatra_prototype/javascripts/picky.view.js +0 -214
- data/sinatra_prototype/library.csv +0 -540
- data/sinatra_prototype/stylesheets/stylesheet.css +0 -184
- data/sinatra_prototype/stylesheets/stylesheet.sass +0 -225
- data/sinatra_prototype/views/configure.haml +0 -170
- data/sinatra_prototype/views/search.haml +0 -108
- data/spec/picky-client/generator_spec.rb +0 -141
@@ -1,62 +0,0 @@
|
|
1
|
-
var Localization = {
|
2
|
-
// TODO Remove.
|
3
|
-
location_delimiters: { de:'in', fr:'à', it:'a', en:'in', ch:'in' },
|
4
|
-
|
5
|
-
explanation_delimiters: { de:'und', fr:'et', it:'e', en:'and', ch:'und' }
|
6
|
-
};
|
7
|
-
|
8
|
-
// The client handles parameters and
|
9
|
-
// offers an insert method.
|
10
|
-
//
|
11
|
-
var PickyClient = function(config) {
|
12
|
-
|
13
|
-
// Params handling.
|
14
|
-
//
|
15
|
-
|
16
|
-
// This is used to generate the correct query strings, localized.
|
17
|
-
//
|
18
|
-
// e.g with locale it:
|
19
|
-
// ['title', 'ulysses', 'Ulysses'] => 'titolo:ulysses'
|
20
|
-
//
|
21
|
-
// This needs to correspond to the parsing in the search engine.
|
22
|
-
//
|
23
|
-
Localization.qualifiers = config.qualifiers || {};
|
24
|
-
|
25
|
-
// This is used to explain the preceding word in the suggestion text.
|
26
|
-
//
|
27
|
-
// e.g. with locale it:
|
28
|
-
// ['title', 'ulysses', 'Ulysses'] => 'Ulysses (titolo)'
|
29
|
-
//
|
30
|
-
Localization.explanations = config.explanations || {};
|
31
|
-
|
32
|
-
// TODO Explain.
|
33
|
-
//
|
34
|
-
Localization.explanation_delimiters = { de:'und', fr:'et', it:'e', en:'and', ch:'und' };
|
35
|
-
|
36
|
-
// Either you pass it a backends hash with full and live,
|
37
|
-
// or you pass it full and live (urls), which will then
|
38
|
-
// be wrapped in appropriate backends.
|
39
|
-
//
|
40
|
-
var backends = config.backends;
|
41
|
-
if (backends) {
|
42
|
-
backends.live || alert('Both a full and live backend must be provided.');
|
43
|
-
backends.full || alert('Both a full and live backend must be provided.');
|
44
|
-
} else {
|
45
|
-
config.backends = {
|
46
|
-
live: config.live && new LiveBackend(config.live) || alert('A live backend path must be provided.'),
|
47
|
-
full: config.full && new FullBackend(config.full) || alert('A live backend path must be provided.')
|
48
|
-
};
|
49
|
-
}
|
50
|
-
|
51
|
-
// The central Picky controller.
|
52
|
-
//
|
53
|
-
var controller = config.controller && new config.controller(config) || new PickyController(config);
|
54
|
-
|
55
|
-
// Insert a query into the client and run it.
|
56
|
-
// Default is a full query.
|
57
|
-
//
|
58
|
-
this.insert = function(query, full) {
|
59
|
-
controller.insert(query, full || true);
|
60
|
-
};
|
61
|
-
|
62
|
-
};
|
@@ -1,107 +0,0 @@
|
|
1
|
-
var PickyController = function(config) {
|
2
|
-
|
3
|
-
var view = new PickyView(this, config);
|
4
|
-
|
5
|
-
var backends = config.backends;
|
6
|
-
var beforeCallback = config.before || function(params, query, offset) { };
|
7
|
-
var successCallback = config.success || function(data, query) { };
|
8
|
-
var afterCallback = config.after || function(data, query) { };
|
9
|
-
|
10
|
-
// If the given backend cannot be found, ignore the search request.
|
11
|
-
//
|
12
|
-
var search = function(type, query, callback, offset, specificParams) {
|
13
|
-
var currentBackend = backends[type];
|
14
|
-
if (currentBackend) { currentBackend.search(query, callback, offset, specificParams); };
|
15
|
-
};
|
16
|
-
|
17
|
-
var fullSearchCallback = function(data, query) {
|
18
|
-
data = successCallback(data, query) || data;
|
19
|
-
|
20
|
-
view.fullResultsCallback(data);
|
21
|
-
|
22
|
-
afterCallback(data, query);
|
23
|
-
};
|
24
|
-
var fullSearch = function(query, possibleOffset, possibleParams) {
|
25
|
-
var params = possibleParams || {};
|
26
|
-
var offset = possibleOffset || 0;
|
27
|
-
liveSearchTimer.stop();
|
28
|
-
|
29
|
-
params = beforeCallback(params, query, offset) || params;
|
30
|
-
|
31
|
-
search('full', query, fullSearchCallback, offset, params);
|
32
|
-
};
|
33
|
-
var liveSearchCallback = function(data, query) {
|
34
|
-
data = successCallback(data, query) || data;
|
35
|
-
|
36
|
-
view.liveResultsCallback(data);
|
37
|
-
|
38
|
-
afterCallback(data, query);
|
39
|
-
};
|
40
|
-
var liveSearch = function(query, possibleParams) {
|
41
|
-
var params = possibleParams || {};
|
42
|
-
|
43
|
-
params = beforeCallback(params) || params;
|
44
|
-
|
45
|
-
search('live', query, liveSearchCallback, 0);
|
46
|
-
};
|
47
|
-
|
48
|
-
// The timer is initially instantly stopped.
|
49
|
-
//
|
50
|
-
var liveSearchTimer = $.timer(180, function(timer) {
|
51
|
-
liveSearch(view.text());
|
52
|
-
timer.stop();
|
53
|
-
});
|
54
|
-
liveSearchTimer.stop();
|
55
|
-
|
56
|
-
this.insert = function(query, full) {
|
57
|
-
view.insert(query);
|
58
|
-
|
59
|
-
if (full) { fullSearch(query); } // TODO
|
60
|
-
};
|
61
|
-
|
62
|
-
var clearButtonClicked = function() {
|
63
|
-
liveSearchTimer.stop();
|
64
|
-
};
|
65
|
-
this.clearButtonClicked = clearButtonClicked;
|
66
|
-
|
67
|
-
var searchTextCleared = function() {
|
68
|
-
liveSearchTimer.stop();
|
69
|
-
};
|
70
|
-
this.searchTextCleared = searchTextCleared;
|
71
|
-
|
72
|
-
var shouldTriggerSearch = function(event) {
|
73
|
-
var validTriggerKeys = [
|
74
|
-
0, // special char (ä ö ü etc...)
|
75
|
-
8, // backspace
|
76
|
-
13, // enter
|
77
|
-
32, // space
|
78
|
-
46, // delete
|
79
|
-
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, // numbers
|
80
|
-
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90 // a-z
|
81
|
-
];
|
82
|
-
|
83
|
-
return $.inArray(event.keyCode, validTriggerKeys) > -1;
|
84
|
-
};
|
85
|
-
var searchTextEntered = function(text, event) {
|
86
|
-
if (shouldTriggerSearch(event)) {
|
87
|
-
if (event.keyCode == 13) { fullSearch(text); } else { liveSearchTimer.reset(); }
|
88
|
-
}
|
89
|
-
};
|
90
|
-
this.searchTextEntered = searchTextEntered;
|
91
|
-
|
92
|
-
var searchButtonClicked = function(text) {
|
93
|
-
fullSearch(text);
|
94
|
-
};
|
95
|
-
this.searchButtonClicked = searchButtonClicked;
|
96
|
-
|
97
|
-
var allocationChosen = function(text) {
|
98
|
-
fullSearch(text);
|
99
|
-
};
|
100
|
-
this.allocationChosen = allocationChosen;
|
101
|
-
|
102
|
-
// Move to a view object.
|
103
|
-
var addinationClicked = function(text, event) {
|
104
|
-
fullSearch(text, event.data.offset);
|
105
|
-
};
|
106
|
-
this.addinationClicked = addinationClicked;
|
107
|
-
};
|
@@ -1,78 +0,0 @@
|
|
1
|
-
// The data is basically the model behind the search.
|
2
|
-
//
|
3
|
-
|
4
|
-
// Container for an allocation.
|
5
|
-
//
|
6
|
-
function Allocation(type, weight, count, combination, ids, rendered) {
|
7
|
-
var self = this;
|
8
|
-
|
9
|
-
this.type = type; // 'books'
|
10
|
-
this.weight = weight; // 5.14
|
11
|
-
this.count = count; // 14
|
12
|
-
this.combination = combination; // [['title', 'Old', 'old'], ['title', 'Man', 'man']]
|
13
|
-
this.ids = ids || [];
|
14
|
-
this.rendered = rendered || [];
|
15
|
-
this.entries = this.rendered;
|
16
|
-
|
17
|
-
this.isType = function(name) {
|
18
|
-
return name == self.type;
|
19
|
-
};
|
20
|
-
};
|
21
|
-
|
22
|
-
// Container for the allocations.
|
23
|
-
//
|
24
|
-
// allocs (should) come preordered by weight.
|
25
|
-
//
|
26
|
-
function Allocations(allocations) {
|
27
|
-
var self = this;
|
28
|
-
|
29
|
-
this.allocations = [];
|
30
|
-
|
31
|
-
// Wrap and save the allocations.
|
32
|
-
//
|
33
|
-
for (var i = 0, l = allocations.length; i < l; i++) {
|
34
|
-
var alloc = allocations[i];
|
35
|
-
var new_allocation = new Allocation(alloc[0], alloc[1], alloc[2], alloc[3], alloc[4], alloc[5]);
|
36
|
-
this.allocations.push(new_allocation);
|
37
|
-
}
|
38
|
-
this.length = this.allocations.length;
|
39
|
-
|
40
|
-
this.each = function(callback) {
|
41
|
-
return $.each(this.allocations, callback);
|
42
|
-
};
|
43
|
-
};
|
44
|
-
|
45
|
-
// Container for the types.
|
46
|
-
//
|
47
|
-
// data:
|
48
|
-
// offset: X
|
49
|
-
// duration: X
|
50
|
-
// total: X
|
51
|
-
// allocations:
|
52
|
-
// Allocation[] of [weight, count, combination, Entry[] of [id, content]]
|
53
|
-
//
|
54
|
-
function PickyData(data) {
|
55
|
-
var self = this;
|
56
|
-
|
57
|
-
// Attributes.
|
58
|
-
//
|
59
|
-
var total = data.total;
|
60
|
-
var duration = data.duration;
|
61
|
-
var offset = data.offset;
|
62
|
-
var allocations = new Allocations(data.allocations || []);
|
63
|
-
|
64
|
-
// Expose some attributes.
|
65
|
-
//
|
66
|
-
this.total = total;
|
67
|
-
this.duration = duration;
|
68
|
-
this.offset = offset;
|
69
|
-
this.allocations = allocations;
|
70
|
-
|
71
|
-
// Are there any results?
|
72
|
-
//
|
73
|
-
var isEmpty = function() {
|
74
|
-
return total == 0;
|
75
|
-
};
|
76
|
-
this.isEmpty = isEmpty;
|
77
|
-
|
78
|
-
};
|
@@ -1,15 +0,0 @@
|
|
1
|
-
Array.prototype.index = function(val) {
|
2
|
-
for(var i = 0, l = this.length; i < l; i++) {
|
3
|
-
if(this[i] == val) return i;
|
4
|
-
}
|
5
|
-
return null;
|
6
|
-
};
|
7
|
-
|
8
|
-
Array.prototype.include = function(val) {
|
9
|
-
return this.index(val) !== null;
|
10
|
-
};
|
11
|
-
|
12
|
-
Array.prototype.remove = function(index) {
|
13
|
-
this.splice(index, 1);
|
14
|
-
return this;
|
15
|
-
};
|
@@ -1,17 +0,0 @@
|
|
1
|
-
Array.prototype.index=function(b){for(var d=0,f=this.length;d<f;d++)if(this[d]==b)return d;return null};Array.prototype.include=function(b){return this.index(b)!==null};Array.prototype.remove=function(b){this.splice(b,1);return this};var PickyI18n={};$(function(){PickyI18n.locale=$("html").attr("lang").split("-")[0]||"en"});
|
2
|
-
var dictionary={common:{join:{de:"und",fr:"et",it:"e",en:"and",ch:"und"},"with":{de:"mit",fr:"avec",it:"con",en:"with",ch:"mit"},of:{de:"von",fr:"de",it:"di",en:"of",ch:"vo"},to:{de:"bis",fr:"\u00e0",it:"alla",en:"to",ch:"bis"}},results:{addination:{more:{de:"Weitere Resultate",fr:"Autres r\u00e9sultats",it:"Altri risultati",en:"More results",ch:"Mee Resultaat"}},header:{de:"Ergebnisse",fr:"R\u00e9sultats",it:"Risultati",en:"Results",ch:"Erg\u00e4bnis"}}},t=function(b){for(var d=PickyI18n.locale||
|
3
|
-
"en",f=b.split(".").concat(d),c=dictionary,j=0,r=f.length;j<r;j++){c=c[f[j]];if(c==undefined){c="Translation missing: "+b+"."+d;break}}return c};function Allocation(b,d,f,c,j,r){var e=this;this.type=b;this.weight=d;this.count=f;this.combination=c;this.ids=j||[];this.entries=this.rendered=r||[];this.isType=function(k){return k==e.type}}function Allocations(b){this.allocations=[];for(var d=0,f=b.length;d<f;d++){var c=b[d];this.allocations.push(new Allocation(c[0],c[1],c[2],c[3],c[4],c[5]))}this.length=this.allocations.length;this.each=function(j){return $.each(this.allocations,j)}}
|
4
|
-
function PickyData(b){var d=b.total,f=b.duration,c=b.offset;b=new Allocations(b.allocations||[]);this.total=d;this.duration=f;this.offset=c;this.allocations=b;this.isEmpty=function(){return d==0}};var PickyView=function(b,d){var f=d.showResultsLimit||10,c=$("#picky input.query"),j=$("#picky div.reset"),r=$("#picky input.search_button"),e=$("#picky div.status"),k=$("#picky .dashboard"),s=$("#picky .results"),o=$("#picky .no_results"),g=new PickyAddination(this,s),n=new PickyAllocationsCloud(this),u=new PickyResultsRenderer(g),w=function(){j.fadeTo(166,1)},z=function(){n.hide();s.empty();o.hide()},D=function(m){c.val(m);j.fadeTo(166,0);B("empty");e.empty();z()},x=function(){return c.val()};this.text=
|
5
|
-
x;var A=function(m){e.text(m);m>0&&m<=5&&e.fadeTo("fast",0.5).fadeTo("fast",1)},E=function(m){if(m.isEmpty())return"none";if(m.total>f&&m.allocations.length>1)return"support";return"ok"},B=function(m){k.attr("class","dashboard "+m)};this.insert=function(m){c.val(m);c.select()};this.fullResultsCallback=function(m){B(E(m));if(m.isEmpty()){z();A(0);o.show();w()}else if(m.total>f&&m.allocations.length>1){z();w();n.show(m);A(m.total)}else if(m.offset==0){z();A(m.total);u.render(m);s.show();w()}else{g.remove();
|
6
|
-
u.render(m);$.scrollTo("#picky .results div.info:last",{duration:500,offset:-12})}c.focus()};this.liveResultsCallback=function(m){B(E(m));A(m.total)};this.allocationChosen=function(m){m=m.data.query;c.val(m);b.allocationChosen(m)};this.addinationClicked=function(m){b.addinationClicked(x(),m)};(function(){c.keyup(function(m){if(x()==""){D();b.searchTextCleared()}else{b.searchTextEntered(x(),m);w()}});r.click(function(){x()==""||b.searchButtonClicked(x())});j.click(function(){D("");b.clearButtonClicked();
|
7
|
-
c.focus()})})();c.focus()};var PickyBackend=function(b){var d=function(f,c,j,r){var e=r||{};e=$.extend({query:f,offset:j},r);$.ajax({type:"GET",url:b,data:e,success:function(k){c&&c(new PickyData(k))},dataType:"json"})};this.search=function(f,c,j,r,e){d(f,function(k){c&&c(e,k)},j,r)}},LiveBackend=function(b){var d=new PickyBackend(b);this.search=function(f,c,j,r,e){e=e||{};latestRequestTimestamp=new Date;e.live=latestRequestTimestamp;d.search(f,function(k,s){if(!k.live||k.live==latestRequestTimestamp)c&&c(s)},j,r,e)}},FullBackend=
|
8
|
-
function(b){var d=new PickyBackend(b);this.search=function(f,c,j,r,e){e=e||{};latestRequestTimestamp=new Date;e.full=latestRequestTimestamp;d.search(f,function(k,s){if(!k.full||k.full==latestRequestTimestamp)c&&c(s)},j,r,e)}};var PickyController=function(b){var d=new PickyView(this,b),f=b.backends,c=b.before||function(){},j=b.success||function(){},r=b.after||function(){},e=function(g,n){g=j(g,n)||g;d.fullResultsCallback(g);r(g,n)},k=function(g,n,u){u=u||{};n=n||0;o.stop();u=c(u,g,n)||u;var w=f.full;w&&w.search(g,e,n,u)},s=function(g,n){g=j(g,n)||g;d.liveResultsCallback(g);r(g,n)},o=$.timer(180,function(g){var n=d.text();c({});var u=f.live;u&&u.search(n,s,0,void 0);g.stop()});o.stop();this.insert=function(g,n){d.insert(g);
|
9
|
-
n&&k(g)};this.clearButtonClicked=function(){o.stop()};this.searchTextCleared=function(){o.stop()};this.searchTextEntered=function(g,n){if($.inArray(n.keyCode,[0,8,13,32,46,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90])>-1)n.keyCode==13?k(g):o.reset()};this.searchButtonClicked=function(g){k(g)};this.allocationChosen=function(g){k(g)};this.addinationClicked=function(g,n){k(g,n.data.offset)}};var Localization={location_delimiters:{de:"in",fr:"\u00e0",it:"a",en:"in",ch:"in"},explanation_delimiters:{de:"und",fr:"et",it:"e",en:"and",ch:"und"}},PickyClient=function(b){Localization.qualifiers=b.qualifiers||{};Localization.explanations=b.explanations||{};Localization.explanation_delimiters={de:"und",fr:"et",it:"e",en:"and",ch:"und"};var d=b.backends;if(d){d.live||alert("Both a full and live backend must be provided.");d.full||alert("Both a full and live backend must be provided.")}else b.backends=
|
10
|
-
{live:b.live&&new LiveBackend(b.live)||alert("A live backend path must be provided."),full:b.full&&new FullBackend(b.full)||alert("A live backend path must be provided.")};var f=b.controller&&new b.controller(b)||new PickyController(b);this.insert=function(c,j){f.insert(c,j||true)}};var PickyAddination=function(b,d){this.remove=function(){d.find(".addination").remove()};this.render=function(f){var c=f.total,j=void 0;j=j||0;j=f.offset+20+j;var r=j+20;f=f.total;if(f<r)r=f;f={offset:j,start:j+1,end:r};if(f.offset<c){c=$("<div class='addination current'>"+t("results.addination.more")+"<div class='tothetop'><a href='javascript:$.scrollTo(0,{ duration: 500});'>↑</a></div></div>");c.bind("click",{offset:f.offset},b.addinationClicked);return c}else return""}};var PickyResultsRenderer=function(b){var d=["street_number","zipcode"],f=function(e){var k=e[e.length-1];e=e.slice(0,e.length-1);if(e==[])e=[e];if(!d.include(k[0]))if(k[1].match(/[^\*~]$/))k[1]+="*";e.push(k);return e},c=function(e){for(var k=Localization.explanations&&Localization.explanations[PickyI18n.locale]||{},s=[],o,g=0,n=e.length;g<n;g++){o=e[g];var u=o[0];u=k[u]||u;s.push([u,o[1]])}return s},j=function(e,k){var s=Localization.explanation_delimiters[PickyI18n.locale],o=c(f(k));o=$.map(o,function(g){return[g[0].replace(/([\w\s\u00c4\u00e4\u00d6\u00f6\u00dc\u00fc\u00e9\u00e8\u00e0]+)/,
|
11
|
-
"<strong>$1</strong>"),g[1]].join(" ")});o=o.join(" "+s+" ");return'<div class="explanation">'+e+" "+o+"</div>"},r=function(e,k){var s='<div class="info">';s+=j(k.type,k.combination);if(e.offset>0)s+='<div class="tothetop"><a href="javascript:$.scrollTo(0,{ duration: 500 });">↑</a></div>';s+='<div class="clear"></div></div>';return s};this.render=function(e){var k=$("#picky .results");e.allocations.each(function(s,o){k.append(r(e,o)).append(o.entries.join("")).append(b.render(e))})}};function AllocationRenderer(b){function d(a){var h={},p={},i=[],q;q=0;for(l=a.length;q<l;q++){var v=a[q][0];if(v in h){h[v]=h[v]+" "+a[q][1];i.push(q)}else{h[v]=a[q][1];p[q]=v}}for(q in p)a[q][1]=h[p[q]];for(q=i.length-1;q>=0;q--)a.remove(i[q]);return a}function f(a,h){var p=h||false,i=a[0],q=a[1],v=D[i];if(v){if(v.method)q=q[v.method]();if(v.format)q=v.format.replace(/%1\$s/,q)}i=w[i]||i;if(p&&!(v&&v.ignoreSingle))return q+" ("+i+")";return q}function c(a){if(a.length==0)return"";else if(a.length==
|
12
|
-
1)return f(a[0],true);else{var h=[],p=[];a=d(a);for(var i=0,q=a.length;i<q;i++)if(a[i][0]=="first_name")h.unshift(f(a[i]));else a[i][0]=="maiden_name"?p.push(f(a[i])):h.push(f(a[i]));p.length>0&&h.push(p);return h.join(" ")}}function j(a){return function(h,p){for(var i=0,q=a.length;i<q;i++)if(a[i][0]==p)return a[i][1];return""}}function r(a){if(a.length==0)return"";var h=a=d(a);h.sort(function(v,y){return v[0]<y[0]?-1:1});for(var p=[],i=0,q=h.length;i<q;i++)p.push(h[i][0]);return x[p].replace(/:(zipcode|city)/g,
|
13
|
-
j(a))}function e(a){var h=a[0];return a[1]+" ("+(w[h]||h)+")"}function k(a){if(a.length==0)return"";result=[];a=d(a);for(var h=0,p=a.length;h<p;h++)result.push(e(a[h]));return result.join(", ")}function s(a){for(var h=[],p=[],i=[],q=0,v=a.length;q<v;q++){var y=a[q];if(E.include(y[0]))i.push(y);else A.include(y[0])?h.push(y):p.push(y)}var C;if(i.length>0)C=i[i.length-1];else if(p.length>0)C=p[p.length-1];else if(h.length>0)C=h[h.length-1];z.include(C[0])||(C[1]+="...");a=c(h);p=k(p);i=r(i);return[a,
|
14
|
-
p,i]}function o(a){var h=a[0],p=a[1];a=a[2];var i="";i=h!=""?p!=""?[h,p].join(B):h:p;if(a=="")return i;return[i,a].join(m)}function g(a){var h=[],p,i;for(i in a){p=a[i][0];p=u[p]||p;h[i]=p+":"+a[i][1]}return h.join(" ")}var n=PickyI18n.locale,u=Localization.qualifiers&&Localization.qualifiers[n]||{},w=Localization.explanations&&Localization.explanations[n]||{};n=Localization.location_delimiters[n];this.explanation=this.query=this.text="";var z=["street_number","zipcode"];this.contract=d;var D={maiden_name:{format:"(-%1$s)",
|
15
|
-
method:"capitalize",ignoreSingle:true},name:{format:"<strong>%1$s</strong>",method:"toUpperCase",ignoreSingle:true},first_name:{format:"%1$s",method:"capitalize"}};this.who=c;var x={zipcode:":zipcode ["+w.city+"]",city:":city","city,zipcode":":zipcode :city"};this.where=r;this.what=k;var A=["first_name","name","maiden_name"],E=["zipcode","city"];this.trisect=s;var B=", ",m=" "+n+" ";this.fuse=o;this.querify=g;this.render=function(a){var h=a.combination,p=a.count;a=g(h);h=o(s(h));h=$('<li><div class="text">'+
|
16
|
-
h+'</div><div class="count">'+p+"</div></li>");h.bind("click",{query:a},b);return h}};var PickyAllocationsCloud=function(b){var d=$("#picky .allocations"),f=d.find(".shown"),c=d.find(".more"),j=d.find(".hidden"),r=function(){d.hide()},e=new AllocationRenderer(function(o){r();b.allocationChosen(o)}),k=function(o){var g=[];o.each(function(n,u){g.push(e.render(u))});return g},s=function(o){if(o.length==0)return $("#search .allocations").hide();f.empty();c.hide();j.empty().hide();if(o.length>3){$.each(o.slice(0,2),function(g,n){f.append(n)});$.each(o.slice(2),function(g,n){j.append(n)});
|
17
|
-
c.show()}else $.each(o,function(g,n){f.append(n)});return $("#search .allocations").show()};c.click(function(){c.hide();j.show()});this.hide=r;this.show=function(o){s(k(o.allocations));d.show()}};
|
@@ -1,103 +0,0 @@
|
|
1
|
-
var PickyResultsRenderer = function(addination) {
|
2
|
-
|
3
|
-
// Adds asterisks to the last token.
|
4
|
-
//
|
5
|
-
var no_asterisks = ['street_number', 'zipcode']; // TODO Works. Parametrize!
|
6
|
-
var asteriskifyLastToken = function(combination) {
|
7
|
-
var last_part = combination[combination.length-1];
|
8
|
-
var parts = combination.slice(0, combination.length-1);
|
9
|
-
if (parts == []) { parts = [parts]; }
|
10
|
-
if (!no_asterisks.include(last_part[0])) {
|
11
|
-
// Replace with * unless there is already one or a tilde.
|
12
|
-
//
|
13
|
-
if (last_part[1].match(/[^\*~]$/)) { last_part[1] += '*'; }
|
14
|
-
}
|
15
|
-
parts.push(last_part);
|
16
|
-
return parts;
|
17
|
-
};
|
18
|
-
|
19
|
-
// Replaces the category with an explanation of the category.
|
20
|
-
//
|
21
|
-
var explainCategory = function(combination) {
|
22
|
-
var explanations = Localization.explanations && Localization.explanations[PickyI18n.locale] || {}; // TODO
|
23
|
-
var parts = [];
|
24
|
-
var combo;
|
25
|
-
|
26
|
-
for (var i = 0, l = combination.length; i < l; i++) {
|
27
|
-
combo = combination[i];
|
28
|
-
var explanation = combo[0];
|
29
|
-
explanation = explanations[explanation] || explanation;
|
30
|
-
parts.push([explanation, combo[1]]);
|
31
|
-
}
|
32
|
-
return parts;
|
33
|
-
};
|
34
|
-
|
35
|
-
//
|
36
|
-
//
|
37
|
-
var explain = function(type, combination) {
|
38
|
-
var explanation_delimiter = Localization.explanation_delimiters[PickyI18n.locale];
|
39
|
-
|
40
|
-
var parts = explainCategory(asteriskifyLastToken(combination));
|
41
|
-
var replaced = $.map(parts, function(part) {
|
42
|
-
var category = part[0].replace(/([\w\sÄäÖöÜüéèà]+)/, "<strong>$1</strong>");
|
43
|
-
var token = part[1];
|
44
|
-
return [category, token].join(' ');
|
45
|
-
});
|
46
|
-
replaced = replaced.join(' ' + explanation_delimiter + ' ');
|
47
|
-
|
48
|
-
return '<div class="explanation">' + type + ' ' + replaced + '</div>';
|
49
|
-
};
|
50
|
-
|
51
|
-
// TODO Make customizable.
|
52
|
-
//
|
53
|
-
var renderHeader = function(data, allocation) {
|
54
|
-
// TODO Make type definable. (Mapping, i18n)
|
55
|
-
//
|
56
|
-
var header_html = '<div class="info">';
|
57
|
-
header_html += explain(allocation.type, allocation.combination);
|
58
|
-
if (data.offset > 0) {
|
59
|
-
header_html += '<div class="tothetop"><a href="javascript:$.scrollTo(0,{ duration: 500 });">↑</a></div>'; // searchEngine.focus();
|
60
|
-
}
|
61
|
-
|
62
|
-
// TODO Parametrize!
|
63
|
-
// var names = '';
|
64
|
-
// var firstEntryName = $(allocation.entries[0]).find('.name').html();
|
65
|
-
// var lastEntryName = $(allocation.entries[allocation.entries.length-1]).find('.name').html();
|
66
|
-
// if(firstEntryName == lastEntryName) {
|
67
|
-
// var firstEntryFirstName = $(allocation.entries[0]).find('.first_name').html();
|
68
|
-
// var lastEntryFirstName = $(allocation.entries[allocation.entries.length-1]).find('.first_name').html();
|
69
|
-
// names = '<div class="names">' + firstEntryName + ', ' + firstEntryFirstName + ' ' + t('common.to') + ' ' + lastEntryFirstName + '</div>';
|
70
|
-
// }
|
71
|
-
// else {
|
72
|
-
// names = '<div class="names">' + firstEntryName + ' ' + t('common.to') + ' ' + lastEntryName + '</div>';
|
73
|
-
// }
|
74
|
-
|
75
|
-
// var rangeStart = data.offset + 1;
|
76
|
-
// var rangeEnd = data.offset + allocation.entries.length;
|
77
|
-
// var rangeText = (rangeStart == rangeEnd) ? rangeStart : rangeStart + '-' + rangeEnd;
|
78
|
-
// var range = '<div class="range">' + rangeText + ' ' + t('common.of') + ' ' + data.total + '</div>';
|
79
|
-
|
80
|
-
// if (data.total > 20) { // TODO Make settable.
|
81
|
-
// // header_html += '<div class="clear"></div>'; // TODO
|
82
|
-
// // header_html += names; // TODO
|
83
|
-
// // header_html += range; // TODO
|
84
|
-
// }
|
85
|
-
|
86
|
-
// For smooth addination scrolling. Don't ask.
|
87
|
-
//
|
88
|
-
header_html += '<div class="clear"></div></div>';
|
89
|
-
|
90
|
-
return header_html;
|
91
|
-
};
|
92
|
-
|
93
|
-
// Render results with the data.
|
94
|
-
//
|
95
|
-
this.render = function(data) {
|
96
|
-
var results = $('#picky .results'); // TODO Extract, also from view.
|
97
|
-
data.allocations.each(function(i, allocation) {
|
98
|
-
results.append(renderHeader(data, allocation)) // TODO header.render(data);
|
99
|
-
.append(allocation.entries.join(''))
|
100
|
-
.append(addination.render(data));
|
101
|
-
});
|
102
|
-
};
|
103
|
-
};
|
Binary file
|
@@ -1,50 +0,0 @@
|
|
1
|
-
// Translations
|
2
|
-
//
|
3
|
-
var PickyI18n = { };
|
4
|
-
|
5
|
-
// Set the correct locale for all js code.
|
6
|
-
//
|
7
|
-
$(function() {
|
8
|
-
PickyI18n.locale = $('html').attr('lang').split('-')[0] || 'en';
|
9
|
-
});
|
10
|
-
|
11
|
-
var dictionary = {
|
12
|
-
common:{
|
13
|
-
join: { de: 'und', fr: 'et', it: 'e', en: 'and', ch: 'und' },
|
14
|
-
'with': { de: 'mit', fr: 'avec',it: 'con', en: 'with', ch: 'mit' },
|
15
|
-
of: { de: 'von', fr: 'de', it: 'di', en: 'of', ch: 'vo' },
|
16
|
-
to: { de: 'bis', fr: 'à', it: 'alla', en: 'to', ch: 'bis' }
|
17
|
-
},
|
18
|
-
results:{
|
19
|
-
addination:{
|
20
|
-
more:{
|
21
|
-
de: 'Weitere Resultate',
|
22
|
-
fr: 'Autres résultats',
|
23
|
-
it: 'Altri risultati',
|
24
|
-
en: 'More results',
|
25
|
-
ch: 'Mee Resultaat'
|
26
|
-
}
|
27
|
-
},
|
28
|
-
header:{
|
29
|
-
de: 'Ergebnisse',
|
30
|
-
fr: 'Résultats',
|
31
|
-
it: 'Risultati',
|
32
|
-
en: 'Results',
|
33
|
-
ch: 'Ergäbnis'
|
34
|
-
}
|
35
|
-
}
|
36
|
-
};
|
37
|
-
var t = function(key) {
|
38
|
-
var locale = PickyI18n.locale || 'en';
|
39
|
-
var keys = key.split('.').concat(locale);
|
40
|
-
var current = dictionary;
|
41
|
-
|
42
|
-
for (var i = 0, l = keys.length; i < l; i++) {
|
43
|
-
current = current[keys[i]];
|
44
|
-
if (current == undefined) {
|
45
|
-
current = 'Translation missing: ' + key + '.' + locale;
|
46
|
-
break;
|
47
|
-
}
|
48
|
-
};
|
49
|
-
return current;
|
50
|
-
};
|
@@ -1,214 +0,0 @@
|
|
1
|
-
// Add PickyResults?
|
2
|
-
var PickyView = function(picky_controller, config) {
|
3
|
-
|
4
|
-
var controller = picky_controller;
|
5
|
-
|
6
|
-
var showResultsLimit = config.showResultsLimit || 10;
|
7
|
-
|
8
|
-
var searchField = $('#picky input.query');
|
9
|
-
var clearButton = $('#picky div.reset');
|
10
|
-
var searchButton = $('#picky input.search_button');
|
11
|
-
var resultCounter = $('#picky div.status');
|
12
|
-
var dashboard = $('#picky .dashboard');
|
13
|
-
|
14
|
-
var results = $('#picky .results'); // Push into results.
|
15
|
-
var noResults = $('#picky .no_results');
|
16
|
-
|
17
|
-
var addination = new PickyAddination(this, results); // Push into results.
|
18
|
-
|
19
|
-
var allocationsCloud = new PickyAllocationsCloud(this);
|
20
|
-
var resultsRenderer = new PickyResultsRenderer(addination); // TODO Rename results.
|
21
|
-
|
22
|
-
// Toggle the clear button visibility.
|
23
|
-
//
|
24
|
-
var showClearButton = function() {
|
25
|
-
clearButton.fadeTo(166, 1.0);
|
26
|
-
};
|
27
|
-
var hideClearButton = function() {
|
28
|
-
clearButton.fadeTo(166, 0.0);
|
29
|
-
};
|
30
|
-
|
31
|
-
// TODO Move to results
|
32
|
-
var clearResults = function() {
|
33
|
-
results.empty();
|
34
|
-
};
|
35
|
-
var hideEmptyResults = function() {
|
36
|
-
noResults.hide();
|
37
|
-
};
|
38
|
-
|
39
|
-
var focus = function() {
|
40
|
-
searchField.focus();
|
41
|
-
};
|
42
|
-
var select = function() {
|
43
|
-
searchField.select();
|
44
|
-
};
|
45
|
-
|
46
|
-
// Cleans the interface of any results or choices presented.
|
47
|
-
//
|
48
|
-
var clean = function() {
|
49
|
-
allocationsCloud.hide();
|
50
|
-
clearResults();
|
51
|
-
hideEmptyResults();
|
52
|
-
};
|
53
|
-
|
54
|
-
// Resets the whole view to the inital state.
|
55
|
-
//
|
56
|
-
var reset = function(to_text) {
|
57
|
-
searchField.val(to_text);
|
58
|
-
hideClearButton();
|
59
|
-
setSearchStatus('empty');
|
60
|
-
resultCounter.empty();
|
61
|
-
clean();
|
62
|
-
};
|
63
|
-
|
64
|
-
var bindEventHandlers = function() {
|
65
|
-
searchField.keyup(function(event) {
|
66
|
-
if (isTextEmpty()) {
|
67
|
-
reset();
|
68
|
-
controller.searchTextCleared();
|
69
|
-
} else {
|
70
|
-
controller.searchTextEntered(text(), event);
|
71
|
-
showClearButton();
|
72
|
-
}
|
73
|
-
});
|
74
|
-
|
75
|
-
searchButton.click(function(event) {
|
76
|
-
if (!isTextEmpty()) {
|
77
|
-
controller.searchButtonClicked(text());
|
78
|
-
}
|
79
|
-
});
|
80
|
-
|
81
|
-
clearButton.click(function() {
|
82
|
-
reset('');
|
83
|
-
controller.clearButtonClicked();
|
84
|
-
focus();
|
85
|
-
});
|
86
|
-
};
|
87
|
-
|
88
|
-
var text = function() {
|
89
|
-
return searchField.val();
|
90
|
-
};
|
91
|
-
this.text = text; // TODO Remove.
|
92
|
-
var isTextEmpty = function() {
|
93
|
-
return text() == '';
|
94
|
-
};
|
95
|
-
|
96
|
-
var showEmptyResults = function() {
|
97
|
-
clean();
|
98
|
-
updateResultCounter(0);
|
99
|
-
noResults.show();
|
100
|
-
showClearButton();
|
101
|
-
};
|
102
|
-
var showTooManyResults = function(data) {
|
103
|
-
clean();
|
104
|
-
showClearButton();
|
105
|
-
allocationsCloud.show(data);
|
106
|
-
updateResultCounter(data.total);
|
107
|
-
};
|
108
|
-
var showResults = function(data) {
|
109
|
-
clean();
|
110
|
-
updateResultCounter(data.total);
|
111
|
-
resultsRenderer.render(data);
|
112
|
-
results.show();
|
113
|
-
showClearButton();
|
114
|
-
};
|
115
|
-
|
116
|
-
var appendResults = function(data) {
|
117
|
-
addination.remove(); // TODO Where should this be?
|
118
|
-
resultsRenderer.render(data);
|
119
|
-
$.scrollTo('#picky .results div.info:last', { duration: 500, offset: -12 });
|
120
|
-
};
|
121
|
-
|
122
|
-
var updateResultCounter = function(total) {
|
123
|
-
resultCounter.text(total); // ((total > 999) ? '999+' : total); // TODO Decide on this.
|
124
|
-
flashResultCounter(total);
|
125
|
-
};
|
126
|
-
|
127
|
-
var alertThreshold = 5;
|
128
|
-
var flashResultCounter = function(total) {
|
129
|
-
if (total > 0 && total <= alertThreshold) {
|
130
|
-
resultCounter.fadeTo('fast', 0.5).fadeTo('fast', 1);
|
131
|
-
}
|
132
|
-
};
|
133
|
-
|
134
|
-
var tooManyResults = function(data) {
|
135
|
-
return data.total > showResultsLimit && data.allocations.length > 1;
|
136
|
-
};
|
137
|
-
var resultStatusFor = function(data) {
|
138
|
-
if (data.isEmpty()) { return 'none'; };
|
139
|
-
if (tooManyResults(data)) { return 'support'; }
|
140
|
-
return 'ok';
|
141
|
-
};
|
142
|
-
var setSearchStatus = function(statusClass) {
|
143
|
-
dashboard.attr('class', 'dashboard ' + statusClass);
|
144
|
-
};
|
145
|
-
var setSearchStatusFor = function(data) {
|
146
|
-
setSearchStatus(resultStatusFor(data));
|
147
|
-
};
|
148
|
-
|
149
|
-
// Insert a search text into the search field.
|
150
|
-
// Field is always selected when doing that.
|
151
|
-
//
|
152
|
-
var insert = function(text) {
|
153
|
-
searchField.val(text);
|
154
|
-
select();
|
155
|
-
};
|
156
|
-
this.insert = insert;
|
157
|
-
|
158
|
-
// Callbacks.
|
159
|
-
//
|
160
|
-
|
161
|
-
// Full results handling.
|
162
|
-
//
|
163
|
-
var fullResultsCallback = function(data) {
|
164
|
-
setSearchStatusFor(data);
|
165
|
-
|
166
|
-
if (data.isEmpty()) {
|
167
|
-
showEmptyResults();
|
168
|
-
} else if (tooManyResults(data)) {
|
169
|
-
showTooManyResults(data);
|
170
|
-
} else {
|
171
|
-
if (data.offset == 0) {
|
172
|
-
showResults(data);
|
173
|
-
} else {
|
174
|
-
appendResults(data);
|
175
|
-
}
|
176
|
-
};
|
177
|
-
|
178
|
-
focus();
|
179
|
-
};
|
180
|
-
this.fullResultsCallback = fullResultsCallback;
|
181
|
-
|
182
|
-
// Live results handling.
|
183
|
-
//
|
184
|
-
var liveResultsCallback = function(data) {
|
185
|
-
setSearchStatusFor(data);
|
186
|
-
|
187
|
-
updateResultCounter(data.total);
|
188
|
-
};
|
189
|
-
this.liveResultsCallback = liveResultsCallback;
|
190
|
-
|
191
|
-
// Callback for when an allocation has been chosen
|
192
|
-
// in the allocation cloud.
|
193
|
-
//
|
194
|
-
var allocationChosen = function(event) {
|
195
|
-
var text = event.data.query;
|
196
|
-
|
197
|
-
searchField.val(text);
|
198
|
-
|
199
|
-
controller.allocationChosen(text);
|
200
|
-
};
|
201
|
-
this.allocationChosen = allocationChosen;
|
202
|
-
|
203
|
-
// Callback for when the addination has been clicked.
|
204
|
-
//
|
205
|
-
var addinationClicked = function(event) {
|
206
|
-
controller.addinationClicked(text(), event);
|
207
|
-
};
|
208
|
-
this.addinationClicked = addinationClicked;
|
209
|
-
|
210
|
-
//
|
211
|
-
//
|
212
|
-
bindEventHandlers();
|
213
|
-
focus();
|
214
|
-
};
|