source: SRUAggregator/trunk/src/main/resources/assets/js/search.js @ 5957

Last change on this file since 5957 was 5957, checked in by emanuel.dima@uni-tuebingen.de, 9 years ago
  1. alpha15: added support for new spec explains/search; misc UI corrections
File size: 22.5 KB
Line 
1/** @jsx React.DOM */
2(function() {
3"use strict";
4
5window.MyAggregator = window.MyAggregator || {};
6
7var React = window.React;
8var PT = React.PropTypes;
9var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
10
11var CorpusSelection = window.MyAggregator.CorpusSelection;
12var HitNumber = window.MyAggregator.HitNumber;
13var CorpusView = window.MyAggregator.CorpusView;
14var Popover = window.MyReact.Popover;
15var InfoPopover = window.MyReact.InfoPopover;
16var Panel = window.MyReact.Panel;
17var Modal = window.MyReact.Modal;
18
19var multipleLanguageCode = "mul"; // see ISO-693-3
20
21var layers = [
22        {
23                id: "sampa",
24                name: "Phonetic Transcriptions",
25                searchPlaceholder: "stA:z",
26                searchLabel: "SAMPA query",
27                searchLabelBkColor: "#eef",
28        },
29        {
30                id: "text",
31                name: "Text Resources",
32                searchPlaceholder: "Elephant",
33                searchLabel: "Search text",
34                searchLabelBkColor: "#fed",
35        },
36];
37var layerMap = {
38        sampa: layers[0], 
39        text: layers[1],
40};
41
42function Corpora(corpora, updateFn) {
43        var that = this;
44        this.corpora = corpora;
45        this.update = function() { 
46                updateFn(that); 
47        };
48       
49        var sortFn = function(x, y) {
50                var r = x.institution.name.localeCompare(y.institution.name);
51                if (r !== 0) {
52                        return r;
53                }
54                return x.title.toLowerCase().localeCompare(y.title.toLowerCase()); 
55        };
56
57        this.recurse(function(corpus) { corpus.subCorpora.sort(sortFn); });
58        this.corpora.sort(sortFn);
59
60        this.recurse(function(corpus, index) {
61                corpus.visible = true; // visible in the corpus view
62                corpus.selected = true; // selected in the corpus view
63                corpus.expanded = false; // not expanded in the corpus view
64                corpus.priority = 1; // priority in corpus view
65                corpus.index = index; // original order, used for stable sort
66        });
67}
68
69Corpora.prototype.recurseCorpus = function(corpus, fn) {
70        if (false === fn(corpus)) {             
71                // no recursion
72        } else {
73                this.recurseCorpora(corpus.subCorpora, fn);
74        }
75};
76
77Corpora.prototype.recurseCorpora = function(corpora, fn) {
78        var recfn = function(corpus, index){
79                if (false === fn(corpus, index)) {
80                        // no recursion
81                } else {
82                        corpus.subCorpora.forEach(recfn);
83                }
84        };
85        corpora.forEach(recfn);
86};
87
88Corpora.prototype.recurse = function(fn) {
89        this.recurseCorpora(this.corpora, fn);
90};
91
92Corpora.prototype.getLanguageCodes = function() {
93        var languages = {};
94        this.recurse(function(corpus) {
95                corpus.languages.forEach(function(lang) {
96                        languages[lang] = true;
97                });
98                return true;
99        });
100        return languages;
101};
102
103Corpora.prototype.isCorpusVisible = function(corpus, layerId, languageCode) {
104        if (layerId !== "text") {
105                return false;
106        }
107        // yes for any language
108        if (languageCode === multipleLanguageCode) {
109                return true;
110        }
111        // yes if the corpus is in only that language
112        if (corpus.languages && corpus.languages.length === 1 && corpus.languages[0] === languageCode) {
113                return true;
114        }       
115
116        // ? yes if the corpus also contains that language
117        if (corpus.languages && corpus.languages.indexOf(languageCode) >=0) {
118                return true;
119        }
120
121        // ? yes if the corpus has no language
122        // if (!corpus.languages || corpus.languages.length === 0) {
123        //      return true;
124        // }
125        return false;
126};
127
128Corpora.prototype.setVisibility = function(layerId, languageCode) {
129        // top level
130        this.corpora.forEach(function(corpus) {
131                corpus.visible = this.isCorpusVisible(corpus, layerId, languageCode);
132                this.recurseCorpora(corpus.subCorpora, function(c) { c.visible = corpus.visible; });
133        }.bind(this));
134};
135
136Corpora.prototype.getSelectedIds = function() {
137        var ids = [];
138        this.recurse(function(corpus) {
139                if (corpus.visible && corpus.selected) {
140                        ids.push(corpus.id);
141                        return false; // top-most collection in tree, don't delve deeper
142                }
143                return true;
144        });
145
146        // console.log("ids: ", ids.length, {ids:ids});
147        return ids;
148};
149
150Corpora.prototype.getSelectedMessage = function() {
151        var selected = this.getSelectedIds().length;
152        if (this.corpora.length === selected) {
153                return "All available collections";
154        } else if (selected === 1) {
155                return "1 selected collection";
156        }
157        return selected+" selected collections";
158};
159
160
161var AggregatorPage = window.MyAggregator.AggregatorPage = React.createClass({displayName: 'AggregatorPage',
162        propTypes: {
163                ajax: PT.func.isRequired
164        },
165
166        timeout: 0,
167        nohits: { 
168                requests: [],
169                results: [],
170        },
171        anyLanguage: [multipleLanguageCode, "Any Language"],
172
173        getInitialState: function () {
174                return {
175                        corpora: new Corpora([], this.updateCorpora),
176                        languageMap: {},
177                        query: "",
178                        language: this.anyLanguage,
179                        languageFilter: 'byMeta',
180                        searchLayerId: "text",
181                        numberOfResults: 10,
182
183                        searchId: null,
184                        hits: this.nohits,
185                };
186        },
187
188        componentDidMount: function() {
189                this.refreshCorpora();
190                this.refreshLanguages();
191        },
192
193        refreshCorpora: function() {
194                this.props.ajax({
195                        url: 'rest/corpora',
196                        success: function(json, textStatus, jqXHR) {
197                                this.setState({corpora : new Corpora(json, this.updateCorpora)});
198                        }.bind(this),
199                });
200        },
201
202        refreshLanguages: function() {
203                this.props.ajax({
204                        url: 'rest/languages',
205                        success: function(json, textStatus, jqXHR) {
206                                this.setState({languageMap : json});
207                        }.bind(this),
208                });
209        },
210
211        updateCorpora: function(corpora) {
212                this.setState({corpora:corpora});
213        },
214
215        search: function() {
216                var query = this.state.query;
217                if (!query) {
218                        this.setState({ hits: this.nohits, searchId: null });
219                        return;                 
220                }
221                this.props.ajax({
222                        url: 'rest/search',
223                        type: "POST",
224                        data: {
225                                layer: this.state.searchLayerId,
226                                language: this.state.language[0],
227                                query: query,
228                                numberOfResults: this.state.numberOfResults,
229                                corporaIds: this.state.corpora.getSelectedIds(),
230                        },
231                        success: function(searchId, textStatus, jqXHR) {
232                                // console.log("search ["+query+"] ok: ", searchId, jqXHR);
233                                this.setState({searchId : searchId});
234                                this.timeout = 250;
235                                setTimeout(this.refreshSearchResults, this.timeout);
236                        }.bind(this),
237                });
238        },
239
240        refreshSearchResults: function() {
241                if (!this.state.searchId) {
242                        return;
243                }
244                this.props.ajax({
245                        url: 'rest/search/'+this.state.searchId,
246                        success: function(json, textStatus, jqXHR) {
247                                if (json.requests.length > 0) {
248                                        if (this.timeout < 10000) {
249                                                this.timeout = 1.5 * this.timeout;
250                                        }
251                                        setTimeout(this.refreshSearchResults, this.timeout);
252                                        // console.log("new search in: " + this.timeout+ "ms");
253                                } else {
254                                        console.log("search ended; hits:", json);
255                                }
256                                this.setState({hits:json});
257                        }.bind(this),
258                });
259        },
260
261        setLanguageAndFilter: function(languageObj, languageFilter) {
262                this.state.corpora.setVisibility(this.state.searchLayerId, 
263                        languageFilter === 'byGuess' ? multipleLanguageCode : languageObj[0]);
264                this.setState({language: languageObj, languageFilter: languageFilter});
265                this.state.corpora.update();
266        },
267
268        setLayer: function(layerId) {
269                this.state.corpora.setVisibility(layerId, this.state.language[0]);
270                this.state.corpora.update();
271                this.setState({searchLayerId: layerId});
272        },
273
274        setNumberOfResults: function(e) {
275                var n = e.target.value;
276                if (n < 10) n = 10;
277                if (n > 250) n = 250;
278                this.setState({numberOfResults: n});
279                e.preventDefault();
280                e.stopPropagation();
281        },
282
283        stop: function(e) {
284                e.stopPropagation();
285        },
286
287        filterResults: function() {
288                var langCode = this.state.language[0];
289                return this.state.hits.results.map(function(corpusHit) { 
290                        return {
291                                corpus: corpusHit.corpus,
292                                startRecord: corpusHit.startRecord,
293                                endRecord: corpusHit.endRecord,
294                                exception: corpusHit.exception,
295                                diagnostics: corpusHit.diagnostics,
296                                searchString: corpusHit.searchString,
297                                kwics: corpusHit.kwics.filter(function(kwic){
298                                        return kwic.language === langCode || langCode === multipleLanguageCode || langCode === null; 
299                                }),
300                        };
301                });
302        },
303
304        toggleLanguageSelection: function(e) {
305                $(this.refs.languageModal.getDOMNode()).modal();
306                e.preventDefault();
307                e.stopPropagation();
308        },
309
310        toggleCorpusSelection: function(e) {
311                $(this.refs.corporaModal.getDOMNode()).modal();
312                e.preventDefault();
313                e.stopPropagation();
314        },
315
316        handleChange: function(event) {
317        this.setState({query: event.target.value});
318        },
319
320        handleKey: function(event) {
321        if (event.keyCode==13) {
322                this.search();
323        }
324        },
325
326        renderAggregator: function() {
327                var layer = layerMap[this.state.searchLayerId];
328                return  (
329                        React.createElement("div", {className: "top-gap"}, 
330                                React.createElement("div", {className: "row"}, 
331                                        React.createElement("div", {className: "aligncenter", style: {marginLeft:16, marginRight:16}}, 
332                                                React.createElement("div", {className: "input-group"}, 
333                                                        React.createElement("span", {className: "input-group-addon", style: {backgroundColor:layer.searchLabelBkColor}}, 
334                                                                layer.searchLabel
335                                                        ), 
336
337                                                        React.createElement("input", {className: "form-control input-lg search", name: "query", type: "text", 
338                                                                value: this.state.query, placeholder: this.props.placeholder, 
339                                                                tabIndex: "1", onChange: this.handleChange, onKeyDown: this.handleKey}), 
340                                                        React.createElement("div", {className: "input-group-btn"}, 
341                                                                React.createElement("button", {className: "btn btn-default input-lg", type: "button", onClick: this.search}, 
342                                                                        React.createElement("i", {className: "glyphicon glyphicon-search"})
343                                                                )
344                                                        )
345                                                )
346                                        )
347                                ), 
348
349                                React.createElement("div", {className: "wel", style: {marginTop:20}}, 
350                                        React.createElement("div", {className: "aligncenter"}, 
351                                                React.createElement("form", {className: "form-inline", role: "form"}, 
352
353                                                        React.createElement("div", {className: "input-group"}, 
354                                                               
355                                                                React.createElement("span", {className: "input-group-addon nobkg"}, "Search for"), 
356                                                               
357                                                                React.createElement("div", {className: "input-group-btn"}, 
358                                                                        React.createElement("button", {className: "form-control btn btn-default", 
359                                                                                        onClick: this.toggleLanguageSelection}, 
360                                                                                this.state.language[1], " ", React.createElement("span", {className: "caret"})
361                                                                        ), 
362                                                                        React.createElement("span", null)
363                                                                ), 
364
365                                                                React.createElement("div", {className: "input-group-btn"}, 
366                                                                        React.createElement("ul", {ref: "layerDropdownMenu", className: "dropdown-menu"}, 
367                                                                                        layers.map(function(l) { 
368                                                                                                return React.createElement("li", {key: l.id}, " ", React.createElement("a", {tabIndex: "-1", href: "#", 
369                                                                                                        onClick: this.setLayer.bind(this, l.id)}, " ", l.name, " "));
370                                                                                        }.bind(this))
371                                                                               
372                                                                        ),                                                             
373                                                                        React.createElement("button", {className: "form-control btn btn-default", 
374                                                                                        'aria-expanded': "false", 'data-toggle': "dropdown"}, 
375                                                                                layer.name, " ", React.createElement("span", {className: "caret"})
376                                                                        )
377                                                                )
378
379                                                        ), 
380
381                                                        React.createElement("div", {className: "input-group"}, 
382                                                                React.createElement("span", {className: "input-group-addon nobkg"}, "in"), 
383                                                                React.createElement("button", {type: "button", className: "btn btn-default", onClick: this.toggleCorpusSelection}, 
384                                                                        this.state.corpora.getSelectedMessage(), " ", React.createElement("span", {className: "caret"})
385                                                                )
386                                                        ),                                                     
387
388                                                        React.createElement("div", {className: "input-group"}, 
389                                                                React.createElement("span", {className: "input-group-addon nobkg"}, "and show up to"), 
390                                                                React.createElement("div", {className: "input-group-btn"}, 
391                                                                        React.createElement("input", {type: "number", className: "form-control input", min: "10", max: "250", 
392                                                                                style: {width:60}, 
393                                                                                onChange: this.setNumberOfResults, value: this.state.numberOfResults, 
394                                                                                onKeyPress: this.stop})
395                                                                ), 
396                                                                React.createElement("span", {className: "input-group-addon nobkg"}, "hits")
397                                                        )
398                                                )
399                                        )
400                                ), 
401
402                    React.createElement(Modal, {ref: "corporaModal", title: "Collections"}, 
403                                        React.createElement(CorpusView, {corpora: this.state.corpora, languageMap: this.state.languageMap})
404                    ), 
405
406                    React.createElement(Modal, {ref: "languageModal", title: "Select Language"}, 
407                                        React.createElement(LanguageSelector, {anyLanguage: this.anyLanguage, 
408                                                                          languageMap: this.state.languageMap, 
409                                                                          selectedLanguage: this.state.language, 
410                                                                          languageFilter: this.state.languageFilter, 
411                                                                          languageChangeHandler: this.setLanguageAndFilter})
412                    ), 
413
414                                React.createElement("div", {className: "top-gap"}, 
415                                        React.createElement(Results, {requests: this.state.hits.requests, 
416                                                 results: this.filterResults(), 
417                                                 searchedLanguage: this.state.language})
418                                )
419                        )
420                        );
421        },
422        render: function() {
423                return this.renderAggregator();
424        }
425});
426
427
428
429/////////////////////////////////
430
431var LanguageSelector = React.createClass({displayName: 'LanguageSelector',
432        propTypes: {
433                anyLanguage: PT.array.isRequired,
434                languageMap: PT.object.isRequired,
435                selectedLanguage: PT.array.isRequired,
436                languageFilter: PT.string.isRequired,
437                languageChangeHandler: PT.func.isRequired,
438        },
439        mixins: [React.addons.LinkedStateMixin],
440
441        selectLang: function(language) {
442                this.props.languageChangeHandler(language, this.props.languageFilter);
443        },
444
445        setFilter: function(filter) {
446                this.props.languageChangeHandler(this.props.selectedLanguage, filter);
447        },
448
449        renderLanguageObject: function(lang) {
450                var desc = lang[1] + " [" + lang[0] + "]";
451                var style = {
452                        whiteSpace: "nowrap",
453                        fontWeight: lang[0] === this.props.selectedLanguage[0] ? "bold":"normal",
454                };
455                return  React.createElement("div", {key: lang[0]}, 
456                                        React.createElement("a", {tabIndex: "-1", href: "#", style: style, onClick: this.selectLang.bind(this, lang)}, desc)
457                                );
458        },
459
460        renderRadio: function(option) {
461                return  this.props.languageFilter === option ? 
462                                React.createElement("input", {type: "radio", name: "filterOpts", value: option, checked: true, onChange: this.setFilter.bind(this, option)})
463                                : React.createElement("input", {type: "radio", name: "filterOpts", value: option, onChange: this.setFilter.bind(this, option)});
464        },
465
466        render: function() {
467                var languages = _.pairs(this.props.languageMap)
468                                 .sort(function(l1, l2){return l1[1].localeCompare(l2[1]); });
469                languages.unshift(this.props.anyLanguage);
470                languages = languages.map(this.renderLanguageObject);
471                var third = Math.round(languages.length/3);
472                var l1 = languages.slice(0, third);
473                var l2 = languages.slice(third, 2*third);
474                var l3 = languages.slice(2*third, languages.length);
475
476                return  React.createElement("div", null, 
477                                        React.createElement("div", {className: "row"}, 
478                                                React.createElement("div", {className: "col-sm-4"}, l1), 
479                                                React.createElement("div", {className: "col-sm-4"}, l2), 
480                                                React.createElement("div", {className: "col-sm-4"}, l3), 
481                                                React.createElement("div", {className: "col-sm-12", style: {marginTop:10, marginBottom:10, borderBottom:"1px solid #eee"}})
482                                        ), 
483                                        React.createElement("form", {className: "form", role: "form"}, 
484                                                React.createElement("div", {className: "input-group"}, 
485                                                        React.createElement("div", null, 
486                                                        React.createElement("label", {style: {color:'black'}}, 
487                                                                 this.renderRadio('byMeta'), " ", 
488                                                                "Use the collections", "'", " specified language to filter results" 
489                                                        )
490                                                        ), 
491                                                        React.createElement("div", null, 
492                                                        React.createElement("label", {style: {color:'black'}}, 
493                                                                 this.renderRadio('byGuess'), " ", 
494                                                                "Filter results by using a language detector" 
495                                                        )
496                                                        ), 
497                                                        React.createElement("div", null, 
498                                                        React.createElement("label", {style: {color:'black'}}, 
499                                                                 this.renderRadio('byMetaAndGuess'), " ", 
500                                                                "First use the collections", "'", " specified language then also use a language detector"
501                                                        )
502                                                        )
503                                                )
504                                        )
505                                );
506        }
507});
508
509/////////////////////////////////
510
511var Results = React.createClass({displayName: 'Results',
512        propTypes: {
513                requests: PT.array.isRequired,
514                results: PT.array.isRequired,
515                searchedLanguage: PT.array.isRequired,
516        },
517
518        getInitialState: function () {
519                return { 
520                        displayKwic: false,
521                };
522        },
523
524        toggleKwic: function() {
525                this.setState({displayKwic:!this.state.displayKwic});
526        },
527
528        renderRowLanguage: function(hit) {
529                return false; //<span style={{fontFace:"Courier",color:"black"}}>{hit.language} </span> ;
530        },
531
532        renderRowsAsHits: function(hit,i) {
533                function renderTextFragments(tf, idx) {
534                        return React.createElement("span", {key: idx, className: tf.hit?"keyword":""}, tf.text);
535                }
536                return  React.createElement("p", {key: i, className: "hitrow"}, 
537                                        this.renderRowLanguage(hit), 
538                                        hit.fragments.map(renderTextFragments)
539                                );
540        },
541
542        renderRowsAsKwic: function(hit,i) {
543                var sleft={textAlign:"left", verticalAlign:"top", width:"50%"};
544                var scenter={textAlign:"center", verticalAlign:"top", maxWidth:"50%"};
545                var sright={textAlign:"right", verticalAlign:"top", maxWidth:"50%"};
546                return  React.createElement("tr", {key: i, className: "hitrow"}, 
547                                        React.createElement("td", null, this.renderRowLanguage(hit)), 
548                                        React.createElement("td", {style: sright}, hit.left), 
549                                        React.createElement("td", {style: scenter, className: "keyword"}, hit.keyword), 
550                                        React.createElement("td", {style: sleft}, hit.right)
551                                );
552        },
553
554        renderPanelTitle: function(corpus) {
555                var inline = {display:"inline-block"};
556                return  React.createElement("div", {style: inline}, 
557                                        React.createElement("span", {className: "corpusName"}, " ", corpus.title), 
558                                        React.createElement("span", {className: "institutionName"}, " — ", corpus.institution.name)
559                                );
560        },
561
562        renderPanelInfo: function(corpus) {
563                var inline = {display:"inline-block"};
564                return  React.createElement("div", null, 
565                                        React.createElement(InfoPopover, {placement: "left", title: corpus.title}, 
566                                                React.createElement("dl", {className: "dl-horizontal"}, 
567                                                        React.createElement("dt", null, "Institution"), 
568                                                        React.createElement("dd", null, corpus.institution.name), 
569
570                                                        corpus.description ? React.createElement("dt", null, "Description"):false, 
571                                                        corpus.description ? React.createElement("dd", null, corpus.description): false, 
572
573                                                        corpus.landingPage ? React.createElement("dt", null, "Landing Page") : false, 
574                                                        corpus.landingPage ? 
575                                                                React.createElement("dd", null, React.createElement("a", {href: corpus.landingPage}, corpus.landingPage)):
576                                                                false, 
577
578                                                        React.createElement("dt", null, "Languages"), 
579                                                        React.createElement("dd", null, corpus.languages.join(", "))
580                                                )
581                                        ), 
582                                        " ", 
583                                        React.createElement("div", {style: inline}, 
584                                                React.createElement("button", {className: "btn btn-default btn-xs", onClick: this.zoom}, 
585                                                        React.createElement("span", {className: "glyphicon glyphicon-fullscreen"})
586                                                )
587                                        )
588                                );
589        },
590
591        renderDiagnostics: function(corpusHit) {
592                if (!corpusHit.diagnostics || corpusHit.diagnostics.length === 0) {
593                        return false;
594                }
595
596                return corpusHit.diagnostics.map(function(d) {
597                        return  React.createElement("div", {className: "alert alert-danger", role: "alert", key: d.dgnUri}, 
598                                                d.dgnMessage, ": ", d.dgnDiagnostic
599                                        );
600                });
601        },
602
603        renderPanelBody: function(corpusHit) {
604                var fulllength = {width:"100%"};
605                if (this.state.displayKwic) {
606                        return  React.createElement("div", null, 
607                                                this.renderDiagnostics(corpusHit), 
608                                                React.createElement("table", {className: "table table-condensed table-hover", style: fulllength}, 
609                                                        React.createElement("tbody", null, corpusHit.kwics.map(this.renderRowsAsKwic))
610                                                )
611                                        );
612                } else {
613                        return  React.createElement("div", null, 
614                                                this.renderDiagnostics(corpusHit), 
615                                                corpusHit.kwics.map(this.renderRowsAsHits)
616                                        );
617                }
618        },
619
620        renderResultPanels: function(corpusHit) {
621                if (corpusHit.kwics.length === 0 &&
622                        corpusHit.diagnostics.length === 0) {
623                        return false;
624                }
625                return  React.createElement(Panel, {key: corpusHit.corpus.title, 
626                                                title: this.renderPanelTitle(corpusHit.corpus), 
627                                                info: this.renderPanelInfo(corpusHit.corpus)}, 
628                                        this.renderPanelBody(corpusHit)
629                                );
630        },
631
632        renderProgressBar: function() {
633                var percents = 100 * this.props.results.length / (this.props.requests.length + this.props.results.length);
634                var sperc = Math.round(percents);
635                var styleperc = {width: sperc+"%"};
636                return this.props.requests.length > 0 ? 
637                        React.createElement("div", {className: "progress", style: {marginBottom:10}}, 
638                                React.createElement("div", {className: "progress-bar progress-bar-striped active", role: "progressbar", 
639                                        'aria-valuenow': sperc, 'aria-valuemin': "0", 'aria-valuemax': "100", style: styleperc})
640                        ) : 
641                        React.createElement("span", null);
642        },
643
644        renderSearchingMessage: function() {
645                return false;
646                // if (this.props.requests.length === 0)
647                //      return false;
648                // return "Searching in " + this.props.requests.length + " collections...";
649        },
650
651        renderFoundMessage: function(hits) {
652                if (this.props.results.length === 0)
653                        return false;
654                var total = this.props.results.length;
655                return hits + " collections with results found in " + total + " searched collections";
656        },
657
658        renderKwicCheckbox: function() {
659                return  React.createElement("div", {className: "float-right", style: {marginRight:17}}, 
660                                        React.createElement("div", {className: "btn-group", style: {display:"inline-block"}}, 
661                                                React.createElement("label", {forHtml: "inputKwic", className: "btn-default"}, 
662                                                         this.state.displayKwic ? 
663                                                                React.createElement("input", {id: "inputKwic", type: "checkbox", value: "kwic", checked: true, onChange: this.toggleKwic}) :
664                                                                React.createElement("input", {id: "inputKwic", type: "checkbox", value: "kwic", onChange: this.toggleKwic}), 
665                                                       
666                                                        " " + ' ' +
667                                                        "Display as Key Word In Context"
668                                                )
669                                        )
670                                );
671        },
672
673        render: function() {
674                var hits = this.props.results.filter(function(corpusHit) { return corpusHit.kwics.length > 0; }).length;
675                var margintop = {marginTop:"10px"};
676                var margin = {marginTop:"0", padding:"20px"};
677                var inlinew = {display:"inline-block", margin:"0 5px 0 0", width:"240px;"};
678                var right= {float:"right"};
679                return  React.createElement("div", null, 
680                                        React.createElement(ReactCSSTransitionGroup, {transitionName: "fade"}, 
681                                                React.createElement("div", {key: "-searching-message-", style: margintop}, this.renderSearchingMessage(), " "), 
682                                                React.createElement("div", {key: "-found-message-", style: margintop}, this.renderFoundMessage(hits), " "), 
683                                                React.createElement("div", {key: "-progress-", style: margintop}, this.renderProgressBar()), 
684                                                hits > 0 ? 
685                                                        React.createElement("div", {key: "-option-KWIC-", className: "row"}, 
686                                                                this.renderKwicCheckbox()
687                                                        )
688                                                        : false, 
689                                                this.props.results.map(this.renderResultPanels)
690                                        )
691                                );
692        }
693});
694
695var _ = window._ = window._ || {
696        keys: function() {
697                var ret = [];
698                for (var x in o) {
699                        if (o.hasOwnProperty(x)) {
700                                ret.push(x);
701                        }
702                }
703                return ret;
704        },
705
706        pairs: function(o){
707                var ret = [];
708                for (var x in o) {
709                        if (o.hasOwnProperty(x)) {
710                                ret.push([x, o[x]]);
711                        }
712                }
713                return ret;
714        },
715};
716
717})();
Note: See TracBrowser for help on using the repository browser.