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

Last change on this file since 5897 was 5897, checked in by emanuel.dima@uni-tuebingen.de, 9 years ago

fixed language codes translations (now using ISO693-3) + misc

File size: 6.3 KB
Line 
1/** @jsx React.DOM */
2(function() {
3"use strict";
4
5var React = window.React;
6var PT = React.PropTypes;
7var ReactCSSTransitionGroup = window.React.addons.CSSTransitionGroup;
8// own components
9var InfoPopover = window.MyReact.InfoPopover;
10var Panel = window.MyReact.Panel;
11
12
13/////////////////////////////////
14
15var SearchBox = React.createClass({
16        propTypes: {
17                search: PT.func.isRequired,
18                placeholder: PT.string.isRequired,
19        },
20
21        getInitialState: function () {
22                return {
23                        query: "",
24                };
25        },
26
27        handleChange: function(event) {
28        this.setState({query: event.target.value});
29        },
30
31        handleKey: function(event) {
32        if (event.keyCode==13) {
33                this.search();
34        }
35        },
36
37        search: function() {
38                this.props.search(this.state.query);
39        },
40
41        render: function() {
42                return  <input className="form-control input-lg search"
43                                        name="query"
44                                        type="text"
45                                        value={this.state.query}
46                                        placeholder={this.props.placeholder}
47                                        tabIndex="1"
48                                        onChange={this.handleChange}
49                                        onKeyDown={this.handleKey} />  ;
50        }
51});
52
53/////////////////////////////////
54
55var Results = React.createClass({
56        propTypes: {
57                requests: PT.array.isRequired,
58                results: PT.array.isRequired,
59        },
60
61        getInitialState: function () {
62                return { displayKwic: false };
63        },
64
65        toggleKwic: function() {
66                this.setState({displayKwic:!this.state.displayKwic});
67        },
68
69        renderRowsAsHits: function(hit,i) {
70                function renderTextFragments(tf, idx) {
71                        return <span key={idx} className={tf.hit?"keyword":""}>{tf.text}</span>;
72                }
73                return  <p key={i} className="hitrow">
74                                        {hit.fragments.map(renderTextFragments)}
75                                </p>;
76        },
77
78        renderRowsAsKwic: function(hit,i) {
79                var sleft={textAlign:"left", verticalAlign:"middle", width:"50%"};
80                var scenter={textAlign:"center", verticalAlign:"middle", maxWidth:"50%"};
81                var sright={textAlign:"right", verticalAlign:"middle", maxWidth:"50%"};
82                return  <tr key={i} className="hitrow">
83                                        <td style={sright}>{hit.left}</td>
84                                        <td style={scenter} className="keyword">{hit.keyword}</td>
85                                        <td style={sleft}>{hit.right}</td>
86                                </tr>;
87        },
88
89        renderPanelTitle: function(corpus) {
90                var inline = {display:"inline-block"};
91                return  <div style={inline}>
92                                        <span className="corpusName"> {corpus.displayName}</span>
93                                        <span className="institutionName"> — {corpus.institution.name}</span>
94                                </div>;
95        },
96
97        renderPanelInfo: function(corpus) {
98                var inline = {display:"inline-block"};
99                return  <div>
100                                        <InfoPopover placement="left" title={corpus.displayName}>
101                                                <dl className="dl-horizontal">
102                                                        <dt>Institution</dt>
103                                                        <dd>{corpus.institution.name}</dd>
104
105                                                        {corpus.description ? <dt>Description</dt>:false}
106                                                        {corpus.description ? <dd>{corpus.description}</dd>: false}
107
108                                                        {corpus.landingPage ? <dt>Landing Page</dt> : false }
109                                                        {corpus.landingPage ?
110                                                                <dd><a href={corpus.landingPage}>{corpus.landingPage}</a></dd>:
111                                                                false}
112
113                                                        <dt>Languages</dt>
114                                                        <dd>{corpus.languages.join(", ")}</dd>
115                                                </dl>
116                                        </InfoPopover>
117                                        {" "}
118                                        <div style={inline}>
119                                                <button className="btn btn-default btn-xs" onClick={this.zoom}>
120                                                        <span className="glyphicon glyphicon-fullscreen"/>
121                                                </button>
122                                        </div>
123                                </div>;
124        },
125
126        renderPanelBody: function(corpusHit) {
127                var fulllength = {width:"100%"};               
128                if (this.state.displayKwic) {
129                        return  <table className="table table-condensed table-hover" style={fulllength}>
130                                                <tbody>{corpusHit.kwics.map(this.renderRowsAsKwic)}</tbody>
131                                        </table>;
132                } else {
133                        return  <div>{corpusHit.kwics.map(this.renderRowsAsHits)}</div>;
134                }
135        },
136
137        renderResultPanels: function(corpusHit) {
138                if (corpusHit.kwics.length === 0) {
139                        return false;
140                }
141                return  <Panel key={corpusHit.corpus.displayName}
142                                                title={this.renderPanelTitle(corpusHit.corpus)}
143                                                info={this.renderPanelInfo(corpusHit.corpus)}>
144                                        {this.renderPanelBody(corpusHit)}
145                                </Panel>;
146        },
147
148        renderProgressBar: function() {
149                var percents = 100 * this.props.results.length / (this.props.requests.length + this.props.results.length);
150                var sperc = Math.round(percents);
151                var styleperc = {width: sperc+"%"};
152                return this.props.requests.length > 0 ?
153                        <div className="progress" style={{marginBottom:10}}>
154                                <div className="progress-bar progress-bar-striped active" role="progressbar"
155                                        aria-valuenow={sperc} aria-valuemin="0" aria-valuemax="100" style={styleperc} />
156                        </div> :
157                        <span />;
158        },
159
160        renderSearchingMessage: function() {
161                return false;
162                // if (this.props.requests.length === 0)
163                //      return false;
164                // return "Searching in " + this.props.requests.length + " collections...";
165        },
166
167        renderFoundMessage: function() {
168                if (this.props.results.length === 0)
169                        return false;
170                var hits = this.props.results.filter(function(corpusHit) { return corpusHit.kwics.length > 0; }).length;
171                var total = this.props.results.length;
172                return hits + " collections with results found in " + total + " searched collections";
173        },
174
175        renderKwicCheckbox: function() {
176                return  <div key="-option-KWIC-" className="row">
177                                        <div className="float-right" style={{marginRight:17}}>
178                                                <div className="btn-group" style={{display:"inline-block"}}>
179                                                        <label forHtml="inputKwic" className="btn-default">
180                                                                { this.state.displayKwic ?
181                                                                        <input id="inputKwic" type="checkbox" value="kwic" checked onChange={this.toggleKwic} /> :
182                                                                        <input id="inputKwic" type="checkbox" value="kwic" onChange={this.toggleKwic} />
183                                                                }
184                                                                &nbsp;
185                                                                Display as Key Word In Context
186                                                        </label>
187                                                </div>
188                                        </div>
189                                </div>;
190        },
191
192        render: function() {
193                var margintop = {marginTop:"10px"};
194                var margin = {marginTop:"0", padding:"20px"};
195                var inlinew = {display:"inline-block", margin:"0 5px 0 0", width:"240px;"};
196                var right= {float:"right"};
197                return  <div>
198                                        <ReactCSSTransitionGroup transitionName="fade">
199                                                <div key="-searching-message-" style={margintop}>{this.renderSearchingMessage()} </div>
200                                                <div key="-found-message-" style={margintop}>{this.renderFoundMessage()} </div>
201                                                <div key="-progress-" style={margintop}>{this.renderProgressBar()}</div>
202                                                {this.props.results.length > 0 ? this.renderKwicCheckbox() : false}
203                                                {this.props.results.map(this.renderResultPanels)}
204                                        </ReactCSSTransitionGroup>
205                                </div>;
206        }
207});
208
209if (!window.MyAggregator) {
210        window.MyAggregator = {};
211}
212window.MyAggregator.SearchBox = SearchBox;
213window.MyAggregator.Results = Results;
214})();
Note: See TracBrowser for help on using the repository browser.