source: trunk/www/common/expression_builder.jsp @ 6162

Last change on this file since 6162 was 6162, checked in by Nicklas Nordborg, 10 years ago

References #1730: Move in-page onEvent attributes to external *.js files

All onsubmit event handlers on <form> elements have been removed and replaced addEventListener() calls.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 16.8 KB
Line 
1<%-- $Id: expression_builder.jsp 6162 2012-10-10 14:07:58Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2006, 2007 Nicklas Nordborg
4
5  This file is part of BASE - BioArray Software Environment.
6  Available at http://base.thep.lu.se/
7
8  BASE is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12
13  BASE is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with BASE. If not, see <http://www.gnu.org/licenses/>.
20  ------------------------------------------------------------------
21
22  @author Nicklas
23  @version 2.0
24--%>
25<%@page import="net.sf.basedb.core.StringUtil"%>
26<%@ page pageEncoding="UTF-8" session="false"
27  import="net.sf.basedb.core.DbControl"
28  import="net.sf.basedb.core.SessionControl"
29  import="net.sf.basedb.core.Item"
30  import="net.sf.basedb.core.BioAssaySet"
31  import="net.sf.basedb.core.VirtualDb"
32  import="net.sf.basedb.core.ReporterCloneTemplate"
33  import="net.sf.basedb.core.RawDataType"
34  import="net.sf.basedb.core.RawDataTypes"
35  import="net.sf.basedb.core.RawDataProperty"
36  import="net.sf.basedb.core.ExtendedProperty"
37  import="net.sf.basedb.core.ExtendedProperties"
38  import="net.sf.basedb.core.Formula"
39  import="net.sf.basedb.core.IntensityTransform"
40  import="net.sf.basedb.core.ReporterList"
41  import="net.sf.basedb.core.ItemQuery"
42  import="net.sf.basedb.core.Include"
43  import="net.sf.basedb.core.query.Orders"
44  import="net.sf.basedb.core.query.Hql"
45  import="net.sf.basedb.util.Enumeration"
46  import="net.sf.basedb.util.jep.Jep"
47  import="net.sf.basedb.clients.web.Base"
48  import="net.sf.basedb.util.Values"
49  import="net.sf.basedb.clients.web.util.HTML"
50  import="net.sf.basedb.clients.web.DynamicUtil"
51  import="net.sf.basedb.clients.web.taglib.table.TableColumn"
52  import="java.util.List"
53  import="java.util.LinkedList"
54%>
55<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
56<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
57<%
58  String title = request.getParameter("title");
59  String form = request.getParameter("form");
60  String textarea = request.getParameter("textarea");
61  String callback = request.getParameter("callback");
62  Formula.Type formulaType = Formula.Type.valueOf(request.getParameter("formulatype"));
63  RawDataType rawDataType = RawDataTypes.getRawDataType(request.getParameter("rawdatatype"));
64  int bioAssaySetId = Values.getInt(request.getParameter("bioassayset_id"), -1);
65  boolean restrictions = Values.getBoolean(request.getParameter("restrictions"));
66  int channels = Values.getInt(request.getParameter("channels"));
67  final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
68 
69  DbControl dc = sc.newDbControl();
70  try
71  {
72    BioAssaySet bas = bioAssaySetId == -1 ? null : BioAssaySet.getById(dc, bioAssaySetId);
73    VirtualDb vdb = bas != null ? bas.getExperiment().getVirtualDb() : null;
74    ReporterCloneTemplate template = vdb != null && vdb.hasClonedReporters() ? vdb.getReporterCloneTemplate() : null;
75       
76    IntensityTransform transform = bas == null ? null : bas.getIntensityTransform();
77    int maxRawMappings = bas == null ? 1 : bas.getMaxRawMappingsForSpot();
78
79    List<TableColumn> spotProperties = new LinkedList<TableColumn>();
80    DynamicUtil.addSpotColumns(spotProperties, dc, channels, transform);
81    List<TableColumn> rawProperties = new LinkedList<TableColumn>();
82    if (rawDataType != null)
83    {
84      DynamicUtil.addFormulaColumns(spotProperties, dc, rawDataType, 
85        Formula.Type.COLUMN_EXPRESSION, transform, "", "", maxRawMappings == 1);
86      if (bas != null) DynamicUtil.addExtraColumns(spotProperties, dc, bas, "", "", "[Xtra] ");
87      if (maxRawMappings == 1) DynamicUtil.addRawDataColumns(rawProperties, dc, rawDataType, "", "", "");
88    }
89    List<TableColumn> reporterProperties = new LinkedList<TableColumn>();
90    DynamicUtil.addReporterColumns(reporterProperties, dc, template, "", "", "");
91   
92    ItemQuery<ReporterList> reporterListQuery = ReporterList.getQuery();
93    reporterListQuery.include(Include.MINE, Include.SHARED, Include.IN_PROJECT, Include.OTHERS);
94    reporterListQuery.order(Orders.asc(Hql.property("name")));
95    List<ReporterList> reporterLists = reporterListQuery.list(dc);
96   
97  %>
98  <base:page type="popup" title="<%=title%>">
99  <base:head scripts="table.js" styles="toolbar.css">
100    <script>
101    function getText()
102    {
103      document.forms['expression'].expression.value = window.opener.document.forms['<%=form%>'].elements['<%=textarea%>'].value;
104    }
105    function setExpressionAndClose()
106    {
107      var value = document.forms['expression'].expression.value;
108      <%
109      if (callback != null)
110      {
111        StringBuilder sb = new StringBuilder();
112        sb.append("window.opener.");
113        sb.append(callback).append("(");
114        if (form != null) sb.append("'").append(form).append("',");
115        if (textarea != null) sb.append("'").append(textarea).append("',");
116        sb.append("value)");
117        %>
118        <%=sb.toString()%>
119        <%
120      }
121      else
122      {
123        %>
124        var textElement = window.opener.document.forms['<%=form%>'].elements['<%=textarea%>'];
125        if (textElement.type == 'text') value = value.replace(/\n/g, '');
126        textElement.value = value;
127        <%
128      }
129      %>
130      window.close();
131    }
132    function insertSelected(list, prefix, suffix)
133    {
134      var value = list[list.selectedIndex].value;
135      if (value != '')
136      {
137        if (prefix) value = prefix + value;
138        if (!suffix) suffix = '';
139        encloseSelection(value, suffix);
140      }
141      list.selectedIndex = 0;
142    }
143    function insertReporterListFunction()
144    {
145      var frm = document.forms['expression'];
146      var listFunction = frm.listFunction[frm.listFunction.selectedIndex].value;
147      var listId = frm.reporterList[frm.reporterList.selectedIndex].value;
148      encloseSelection(listFunction+'(' + listId + ')', '');
149      frm.reporterList.selectedIndex = 0;
150    }
151 
152    /*
153      Enclose the selected text with prefix and suffix. Code taken
154      from Trac: http://projects.edgewall.com/trac/
155    */
156    function encloseSelection(prefix, suffix)
157    {
158      var frm = document.forms['expression'];
159      var textarea = frm.expression;
160      textarea.focus();
161        var start, end, sel, scrollPos, subst;
162        if (typeof(document["selection"]) != "undefined")
163        {
164          sel = document.selection.createRange().text;
165        }
166        else if (typeof(textarea["setSelectionRange"]) != "undefined")
167        {
168          start = textarea.selectionStart;
169          end = textarea.selectionEnd;
170          scrollPos = textarea.scrollTop;
171          sel = textarea.value.substring(start, end);
172        }
173        if (sel.match(/ $/))
174        {
175          // exclude ending space char, if any
176            sel = sel.substring(0, sel.length - 1);
177            suffix = suffix + " ";
178        }
179        subst = prefix + sel + suffix;
180        if (typeof(document["selection"]) != "undefined")
181        {
182          var range = document.selection.createRange().text = subst;
183          textarea.caretPos -= suffix.length;
184        }
185        else if (typeof(textarea["setSelectionRange"]) != "undefined")
186        {
187          textarea.value = textarea.value.substring(0, start) + subst +
188                           textarea.value.substring(end);
189          if (sel)
190          {
191            textarea.setSelectionRange(start + subst.length, start + subst.length);
192          }
193          else
194          {
195            textarea.setSelectionRange(start + prefix.length, start + prefix.length);
196          }
197          textarea.scrollTop = scrollPos;
198        }
199      }
200   
201    var properties = new Array();
202    <%
203    for (TableColumn tc : rawProperties)
204    {
205      %>
206      properties['raw.<%=tc.getProperty()%>'] = 1;
207      <%
208    }
209    for (TableColumn tc : reporterProperties)
210    {
211      %>
212      properties['reporter.<%=tc.getProperty()%>'] = 1;
213      <%
214    }
215    %>
216     
217    function validateOnClick()
218    {
219      var frm = document.forms['expression'];
220      if (frm.expression.value != '')
221      {
222        var expression = frm.expression.value.replace('if(', 'jepIf(');
223        try
224        {
225          var result = eval(expression);
226          alert('The expressions seems to be ok.\nNote! This feature is experimental and may not be 100% correct.');
227        }
228        catch (er)
229        {
230          alert(er + '\nNote! This feature is experimental and may not be 100% correct.');
231        }
232      }
233    }
234   
235    function raw(property)
236    {
237      <%
238      if (maxRawMappings != 1)
239      {
240        %>
241        throw 'Cannot use function raw() for bioassayset that has multiple mappings to raw data';
242        <%
243      }
244      %>
245      var rdt = '<%=rawDataType == null ? "" : rawDataType.getId()%>';
246      if (!property) throw 'Property must be specified for function raw()';
247      if (rdt == '') throw 'Cannot use function raw(). No raw data type selected';
248      if (!properties['raw.'+property]) throw 'Property '+property+' not found for raw data type ' + rdt;
249      return Math.random() * 100;
250    }
251   
252    function mean(property)
253    {
254      var rdt = '<%=rawDataType == null ? "" : rawDataType.getId()%>';
255      if (!property) throw 'Property must be specified for function mean()';
256      if (rdt == '') throw 'Cannot use function mean(). No raw data type selected';
257      if (!properties['property.'+property]) throw 'Property '+property+' not found for raw data type ' + rdt;
258      return Math.random() * 100;
259    }
260 
261    function ch(channel)
262    {
263      checkChannel('ch()', channel);
264      return channel;
265    }
266    function rawCh(channel)
267    {
268      checkChannel('rawCh()', channel);
269      return channel;
270    }
271    function checkChannel(name, channel)
272    {
273      var type = '<%=formulaType.name()%>';
274      if (type == '<%=Formula.Type.INTENSITY_EXPRESSION.name()%>')
275      {
276        // Channel function not available
277        throw 'Function ' + name + ' is not available for ' + type;
278      }
279      var channels = <%=channels%>;
280      if (!channel || channel <= 0 || channel > channels)
281      {
282        throw 'Invalid channel: ' + channel + '; must be between 1 and '+ channels;
283      }
284    }
285
286
287   
288    function pos()
289    {
290      return Math.random() * 100;
291    }
292    function rep(property)
293    {
294      if (!property) throw 'Property must be specified for function rep()';
295      if (!properties['reporter.'+property]) throw 'Property '+property+' not found for reporter';
296      return Math.random() * 100;
297    }
298   
299    function xtra(arg)
300    {
301      if (!arg) throw 'One argument is required for function xtra()';
302      return Math.random() * 100;
303    }
304   
305    function log(value)
306    {
307      return Math.log(value);
308    }
309    function log2(value)
310    {
311      return Math.log(value);
312    }
313    function ln(value)
314    {
315      return Math.log(value);
316    }
317    function sqrt(value)
318    {
319      return Math.sqrt(value);
320    }
321    function abs(value)
322    {
323      return Math.abs(value);
324    }
325    function exp(value)
326    {
327      return Math.exp(value);
328    }
329    function score(reporterListId)
330    {
331      return Math.random() * 100;
332    }
333    function jepIf(condition, ifTrue, ifFalse)
334    {
335      if (condition == undefined || ifTrue == undefined || ifFalse == undefined)
336      {
337        throw 'if() needs 3 arguments';
338      }
339      return condition ? ifTrue : ifFalse;
340    }
341    </script>
342  </base:head>
343  <base:body onload="getText()">
344    <h1>Expression builder <base:help helpid="expressionbuilder" /></h1>
345 
346    <form name="expression">
347    <div class="content">
348      <table class="fullform input100 bottomborder">
349      <tr>
350        <td class="filled">
351        <tbl:toolbar subclass="bottomborder">
352          <tbl:label
353            style="width: 100px;"
354            title="Operators:"
355          />
356          <tbl:button 
357            title="AND"
358            tooltip="BOOLEAN AND: expr1 &amp;&amp; expr2"
359            onclick="encloseSelection(' &amp;&amp; ', '')"
360          />
361          <tbl:button 
362            title="OR"
363            tooltip="BOOLEAN OR: expr1 || expr2"
364            onclick="encloseSelection(' || ', '')"
365          />
366          <tbl:button 
367            title="NOT"
368            tooltip="BOOLEAN NOT: !expr1"
369            onclick="encloseSelection('!', '')"
370          />
371          <tbl:button 
372            title="=="
373            tooltip="EQUAL: expr1 == expr2"
374            onclick="encloseSelection(' == ', '')"
375          />
376          <tbl:button 
377            title="!="
378            tooltip="INEQUAL: expr1 != expr2"
379            onclick="encloseSelection(' != ', '')"
380          />
381          <tbl:button 
382            title="&lt;"
383            tooltip="LESS: expr1 &lt; expr2"
384            onclick="encloseSelection(' &lt; ', '')"
385          />
386          <tbl:button 
387            title="&lt;="
388            tooltip="LESS OR EQUAL: expr1 &lt;= expr2"
389            onclick="encloseSelection(' &lt;= ', '')"
390          />
391          <tbl:button 
392            title="&gt;="
393            tooltip="MORE OR EQUAL: expr1 &gt;= expr2"
394            onclick="encloseSelection(' &gt;= ', '')"
395            visible="<%=restrictions%>"
396          />
397          <tbl:button 
398            title="&gt;"
399            tooltip="MORE: expr1 &gt; expr2"
400            onclick="encloseSelection(' &gt; ', '')"
401          />
402          <tbl:button 
403            title="+"
404            tooltip="ADD: expr1 + expr2"
405            onclick="encloseSelection(' + ', '')"
406          />
407          <tbl:button 
408            title="-"
409            tooltip="SUBTRACT: expr1 - expr2"
410            onclick="encloseSelection(' - ', '')"
411          />
412          <tbl:button 
413            title="*"
414            tooltip="MULTIPLY: expr1 * expr2"
415            onclick="encloseSelection(' * ', '')"
416          />
417          <tbl:button 
418            title="/"
419            tooltip="DIVIDE: expr1 / expr2"
420            onclick="encloseSelection(' / ', '')"
421          />
422          <tbl:button 
423            title="( )"
424            tooltip="PARENTHESIS: (expr1)"
425            onclick="encloseSelection('(', ')')"
426          />
427        </tbl:toolbar>
428        <tbl:toolbar subclass="bottomborder">
429          <tbl:label
430            title="Functions:"
431            style="width: 100px;"
432          />
433          <%
434          Enumeration<String, String> functions = Jep.getFunctions();
435          for (int i = 0; i < functions.size(); ++i)
436          {
437            String function = functions.getKey(i);
438            %>
439            <tbl:button 
440              title="<%=function%>"
441              tooltip="<%=functions.getValue(i)%>"
442              onclick="<%="encloseSelection('" + function +"(', ')')"%>"
443            />
444            <%
445          }
446          %>
447          <tbl:label
448            title="Constants:"
449            style="width: 100px;"
450          />
451          <tbl:button 
452            title="null"
453            tooltip="The null (unknown) value"
454            onclick="<%="encloseSelection('', 'null')"%>"
455          />
456          <tbl:button 
457            title="pi"
458            tooltip="<%="The pi value: " + Math.PI %>"
459            onclick="<%="encloseSelection('', '"+Math.PI+"')"%>"
460          />
461          <tbl:button 
462            title="e"
463            tooltip="<%="The base of the natural logarithm: " + Math.E%>"
464            onclick="<%="encloseSelection('', '"+Math.E+"')"%>"
465          />
466        </tbl:toolbar>
467        <tbl:toolbar subclass="bottomborder">
468          <td class="label">Spot:
469            <select name="spot" onchange="insertSelected(this)" style="width: 12em;">
470            <option value="">- select -
471            <%
472            for (TableColumn tc : spotProperties)
473            {
474              if (tc.getJepExpression() != null)
475              {
476                %>
477                <option value="<%=tc.getJepExpression()%>" 
478                  title="<%=HTML.encodeTags(tc.getDescription())%>"><%=HTML.encodeTags(tc.getTitle())%>
479                <%
480              }
481            }
482            %>
483            </select>   
484          </td>
485          <%
486          if (rawDataType != null && rawDataType.isStoredInDb() && rawProperties.size() > 0)
487          {
488            %>
489            <td class="label">Raw data:
490              <select name="rawdata" onchange="insertSelected(this)" style="width: 12em;">
491              <option value="">- select -
492              <%
493              for (TableColumn tc : rawProperties)
494              {
495                %>
496                <option value="<%=tc.getJepExpression()%>" 
497                  title="<%=HTML.encodeTags(tc.getDescription())%>"><%=HTML.encodeTags(tc.getTitle())%>
498                <%
499              }
500              %>
501              </select>
502            </td>
503            <%
504          }
505          %>
506         
507          <td class="label">Reporter:
508            <select name="reporter" onchange="insertSelected(this)" style="width: 12em;">
509            <option value="">- select -
510              <%
511              for (TableColumn tc : reporterProperties)
512              {
513                %>
514                <option value="<%=tc.getJepExpression()%>" 
515                  title="<%=HTML.encodeTags(tc.getDescription())%>"><%=HTML.encodeTags(tc.getTitle())%>
516                <%
517              }
518              %>
519            </select>
520        </tbl:toolbar>
521        <tbl:toolbar subclass="bottomborder"
522          visible="<%=reporterLists.size() > 0%>">
523          <td class="label">
524            Reporter lists:
525           
526            <select name="listFunction" >
527            <option value="score">score
528            <%
529            if (restrictions)
530            {
531              %>
532              <option value="inList">in
533              <option value="notInList">not in
534              <%
535            }
536            %>
537            </select>
538           
539            <select name="reporterList" onchange="insertReporterListFunction()">
540            <option value="">- select -
541              <%
542              for (ReporterList list : reporterLists)
543              {
544                %>
545                <option value="<%=list.getId()%>" 
546                  title="<%=HTML.encodeTags(list.getDescription())%>"><%=HTML.encodeTags(list.getName())%>
547                <%
548              }
549              %>
550            </select>
551          </td>
552        </tbl:toolbar>
553        </td>
554      </tr>
555      <tr class="dynamic">
556        <td class="filled">
557        <textarea class="autohight" name="expression" rows="16"></textarea>
558        </td>
559      </tr>
560      </table>
561
562      </div>
563    </form>
564
565    <base:buttongroup subclass="dialogbuttons">
566      <base:button 
567        onclick="validateOnClick()" title="Validate&hellip;" 
568        image="validate_formula.png"
569        tooltip="Validate the expression. EXPERIMENTAL!!" />
570      <base:button onclick="setExpressionAndClose()" title="Ok" />
571      <base:button onclick="window.close()" title="Cancel" />
572    </base:buttongroup>
573  </base:body>
574  </base:page>
575  <%
576  }
577finally
578{
579  if (dc != null) dc.close();
580}
581%> 
Note: See TracBrowser for help on using the repository browser.