source: trunk/www/views/formulas/edit_formula.jsp @ 6217

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

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

Got rid of 'clazz' and 'requiredClazz' string constatns used in several JSP scripts. Better to specify class="" directly on each element since there are cases were we want to add more variants.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 20.1 KB
Line 
1<%-- $Id: edit_formula.jsp 6217 2012-12-14 13:05:00Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg, Martin Svensson
4  Copyright (C) 2007 Nicklas Nordborg
5
6  This file is part of BASE - BioArray Software Environment.
7  Available at http://base.thep.lu.se/
8
9  BASE is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License
11  as published by the Free Software Foundation; either version 3
12  of the License, or (at your option) any later version.
13
14  BASE is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  GNU General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with BASE. If not, see <http://www.gnu.org/licenses/>.
21  ------------------------------------------------------------------
22
23
24  @author Nicklas
25  @version 2.0
26--%>
27<%@ page pageEncoding="UTF-8" session="false"
28  import="net.sf.basedb.core.SessionControl"
29  import="net.sf.basedb.core.DbControl"
30  import="net.sf.basedb.core.Item"
31  import="net.sf.basedb.core.Type"
32  import="net.sf.basedb.core.ItemContext"
33  import="net.sf.basedb.core.Permission"
34  import="net.sf.basedb.core.Formula"
35  import="net.sf.basedb.core.IntensityTransform"
36  import="net.sf.basedb.core.Coloring"
37  import="net.sf.basedb.core.RawDataType"
38  import="net.sf.basedb.core.RawDataTypes"
39  import="net.sf.basedb.core.RawDataProperty"
40  import="net.sf.basedb.core.Project"
41  import="net.sf.basedb.core.PermissionDeniedException"
42  import="net.sf.basedb.util.Values"
43  import="net.sf.basedb.clients.web.Base"
44  import="net.sf.basedb.clients.web.util.HTML"
45  import="net.sf.basedb.core.plugin.GuiContext"
46  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
47  import="net.sf.basedb.clients.web.extensions.JspContext"
48  import="net.sf.basedb.clients.web.extensions.edit.EditUtil"
49  import="net.sf.basedb.util.extensions.ExtensionsInvoker"
50  import="java.util.List"
51%>
52<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
53<%@ taglib prefix="t" uri="/WEB-INF/tab.tld" %>
54<%@ taglib prefix="ext" uri="/WEB-INF/extensions.tld" %>
55<%
56final Item itemType = Item.FORMULA;
57final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
58final ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, null, null);
59final int itemId = cc.getId();
60final String ID = sc.getId();
61final float scale = Base.getScale(sc);
62final DbControl dc = sc.newDbControl();
63try
64{
65  String title = null;
66  Formula formula = null;
67  Formula.Type currentType = null;
68  Type currentValueType = Type.FLOAT;
69  Formula.Parser currentParser = null;
70  Formula.AverageMethod currentAverageMethod = null;
71  RawDataType currentRawDataType = null;
72  RawDataType defaultRawDataType = null;
73  IntensityTransform currentSourceIntensityTransform = null;
74  IntensityTransform currentResultIntensityTransform = null;
75  List<String> expressions = null;
76  Coloring coloring = null;
77
78  int activeProjectId = sc.getActiveProjectId();
79  if (activeProjectId > 0)
80  {
81    Project activeProject = Project.getById(dc, activeProjectId);
82    defaultRawDataType = activeProject.getDefaultRawDataType();
83  } 
84  if (itemId == 0)
85  {
86    title = "Create formula";
87    cc.removeObject("item");
88    String recentType = cc.getRecent("FormulaType", 0);
89    String filterType = cc.getPropertyValue("type");
90    if (filterType != null) currentType =  Formula.Type.fromValue(Values.getInt(filterType));
91    if (currentType == null && recentType != null) currentType = Formula.Type.valueOf(recentType);
92    if (currentType == null) currentType = Formula.Type.COLUMN_EXPRESSION;
93    currentParser = Formula.Parser.fromValue(Values.getInt(cc.getPropertyValue("parser"), 
94      Formula.Parser.JEP.getValue()));
95    currentAverageMethod = Formula.AverageMethod.fromValue(Values.getInt(cc.getPropertyValue("averageMethod"),
96      Formula.AverageMethod.ARITHMETIC_MEAN.getValue()));
97    currentRawDataType = RawDataTypes.getRawDataType(cc.getPropertyValue("rawDataType"));
98    if (currentRawDataType == null)
99    {
100      currentRawDataType = RawDataTypes.getRawDataType(cc.getRecent("RawDataType", 0));
101    }
102    if (cc.getPropertyValue("sourceIntensityTransform") != null)
103    {
104      currentSourceIntensityTransform = IntensityTransform.fromValue(Values.getInt(cc.getPropertyValue("sourceIntensityTransform")));
105    }
106    if (cc.getPropertyValue("resultIntensityTransform") != null)
107    {
108      currentResultIntensityTransform = IntensityTransform.fromValue(Values.getInt(cc.getPropertyValue("resultIntensityTransform")));
109    }
110    coloring = new Coloring();
111    coloring.setUsingColors(Values.getBoolean(cc.getPropertyValue("coloring.usingColors")));
112    coloring.setLogarithmic(Values.getBoolean(cc.getPropertyValue("coloring.logarithmic")));
113    coloring.setMinValue(Values.getFloat(cc.getPropertyValue("coloring.minValue"), null));
114    coloring.setMidValue(Values.getFloat(cc.getPropertyValue("coloring.midValue"), null));
115    coloring.setMaxValue(Values.getFloat(cc.getPropertyValue("coloring.maxValue"), null));
116   
117    currentRawDataType = currentRawDataType != null ? currentRawDataType : defaultRawDataType;
118  }
119  else
120  {
121    formula = Formula.getById(dc, itemId);
122    currentParser = formula.getParser();
123    currentAverageMethod = formula.getAverageMethod();
124    currentType = formula.getFormulaType();
125    currentValueType = formula.getValueType();
126    currentRawDataType = formula.getRawDataType();
127    currentSourceIntensityTransform = formula.getSourceIntensityTransform();
128    currentResultIntensityTransform = formula.getResultIntensityTransform();
129    expressions = formula.getFormulas();
130    coloring = formula.getColoring();
131    cc.setObject("item", formula);
132    title = "Edit formula -- " + HTML.encodeTags(formula.getName());
133  }
134  if (formula != null) formula.checkPermission(Permission.WRITE);
135 
136 
137 
138  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, GuiContext.item(itemType), formula);
139  ExtensionsInvoker invoker = EditUtil.useEditExtensions(jspContext);
140  %>
141  <base:page type="popup" title="<%=title%>">
142  <base:head scripts="tabcontrol.js" styles="tabcontrol.css">
143    <ext:scripts context="<%=jspContext%>" />
144    <ext:stylesheets context="<%=jspContext%>" />
145    <script>
146    // Validate the "Formula" tab
147    function validateFormula()
148    {
149      var frm = document.forms['formula'];
150      if (Main.trimString(frm.name.value) == '')
151      {
152        Forms.showNotification(frm.name, 'You must enter a name');
153        return false;
154      }
155      var type = frm.type[frm.type.selectedIndex].value;
156      var numFormulas = frm.expressions.length;
157      var numChannels = frm.channels.value;
158      if (type == '<%=Formula.Type.INTENSITY_EXPRESSION.name()%>' || type == '<%=Formula.Type.INTENSITY_TRANSFORMATION.name()%>')
159      {
160        // One formula per channel required
161        if (numFormulas != numChannels)
162        {
163          Forms.showNotification(frm.expressions, 'You must enter one formula per channel for type = ' + frm.type[frm.type.selectedIndex].text, null, 'pointer-left');
164          return false;
165        }
166      }
167      else
168      {
169        // Only one formula can be specified
170        if (numFormulas != 1)
171        {
172          Forms.showNotification(frm.expressions, 'You must enter exactly one formula for type = ' + frm.type[frm.type.selectedIndex].text, null, 'pointer-left');
173          return false;
174        }
175      }
176     
177      if (frm.use_colors.checked && !frm.use_colors.disabled)
178      {
179        var minValue = parseFloat(frm.min_value.value);
180        var midValue = parseFloat(frm.mid_value.value);
181        var maxValue = parseFloat(frm.max_value.value);
182        if (isNaN(minValue))
183        {
184          Forms.showNotification(frm.min_value, 'No min value has been specified');
185          return false;
186        }
187        if (isNaN(midValue))
188        {
189          Forms.showNotification(frm.mid_value, 'No mid value has been specified');
190          return false;
191        }
192        if (isNaN(maxValue))
193        {
194          Forms.showNotification(frm.max_value, 'No max value has been specified');
195          return false;
196        }
197        if (minValue > midValue)
198        {
199          Forms.showNotification(frm.mid_value, 'The mid value must be greater than the min value');
200          return false;
201        }
202        if (midValue > maxValue)
203        {
204          Forms.showNotification(frm.max_value, 'The max value must be greater than the mid value');
205          return false;
206        }
207      }
208      return true;
209    }
210
211    // Submit the form
212    function saveSettings()
213    {
214      var frm = document.forms['formula'];
215      if (TabControl.validateActiveTab('settings'))
216      {
217        for (var i = 0; i < frm.expressions.length; i++)
218        {
219          Forms.createHidden(frm, 'formulas', frm.expressions[i].text);
220        }
221        frm.channels.disabled = false; // Otherwise the channels info, isn't sent
222        frm.submit();
223      }
224    }
225   
226    function init()
227    {
228      <%
229      if (formula == null)
230      {
231        %>
232        var frm = document.forms['formula'];
233        frm.name.focus();
234        frm.name.select();
235        <%
236      }
237      %>
238      formulaTypeOnChange();
239    }
240    var rawDataTypes = new Array();
241    <%
242    for (RawDataType rdt : RawDataTypes.getRawDataTypes())
243    {
244      %>
245      rawDataTypes['<%=rdt.getId()%>'] = <%=rdt.getChannels()%>;
246      var a = new Array();
247      <%
248      for (RawDataProperty rp : rdt.getProperties())
249      {
250        %>
251        a['<%=rp.getName()%>'] = 1;
252        <%
253      }
254      %>
255      rawDataTypes['<%=rdt.getId()%>.properties'] = a;
256      <%
257    }
258    %>
259   
260    function rawDataTypeOnChange()
261    {
262      var frm = document.forms['formula'];
263      var rdt = frm.rawdatatype[frm.rawdatatype.selectedIndex].value;
264      if (rdt != '')
265      {
266        frm.channels.value = rawDataTypes[rdt];
267        frm.channels.disabled = true;
268        Main.addClass(frm.channels, 'disabled');
269        Main.removeClass(frm.channels, 'required');
270      }
271      else
272      {
273        frm.channels.disabled = false;
274        Main.removeClass(frm.channels, 'disabled');
275        Main.addClass(frm.channels, 'required');
276      }
277    }
278
279    var selectedExpressionIndex = -1;
280    function expressionsOnClick()
281    {
282      var frm = document.forms['formula'];
283      selectedExpressionIndex = frm.expressions.selectedIndex;
284      frm.expression.value = frm.expressions[selectedExpressionIndex].text;
285    }
286
287    function expressionOnBlur()
288    {
289      var frm = document.forms['formula'];
290      if (selectedExpressionIndex >= 0)
291      {
292        frm.expressions[selectedExpressionIndex].text = frm.expression.value;
293      }
294    }
295   
296    function removeOnClick()
297    {
298      var frm = document.forms['formula'];
299      if (selectedExpressionIndex >= 0)
300      {
301        frm.expressions[selectedExpressionIndex] = null;
302        selectedExpressionIndex = -1;
303      }
304    }
305   
306    function addOnClick()
307    {
308      var frm = document.forms['formula'];
309      if (frm.expression.value != '')
310      {
311        frm.expressions[frm.expressions.length] = new Option(frm.expression.value);
312        selectedExpressionIndex = frm.expressions.length - 1;
313        frm.expressions.selectedIndex = selectedExpressionIndex;
314      }
315    }
316   
317    function openExpressionBuilder()
318    {
319      var frm = document.forms['formula'];
320      var rdt = frm.rawdatatype[frm.rawdatatype.selectedIndex].value;
321      var formulaType = frm.type[frm.type.selectedIndex].value;
322      var channels = frm.channels.value;
323      var restrictions = formulaType == '<%=Formula.Type.COLUMN_RESTRICTION.name()%>';
324      Main.expressionBuilder('<%=ID%>', 'Expression', 'formula', 'expression', formulaType, rdt, channels, restrictions, null, 'setExpressionFromBuilder');
325    }
326 
327    function setExpressionFromBuilder(form, textarea, value)
328    {
329      var frm = document.forms['formula'];
330      frm[textarea].value = value;
331      if (frm.expressions.length == 0)
332      {
333        addOnClick();
334      }
335      else
336      {
337        expressionOnBlur();
338      }
339    }
340 
341    var useColors = new Array();
342    var supportsAverage = new Array();
343    var lockedValueType = new Array();
344    <%
345    for (Formula.Type ft : Formula.Type.values())
346    {
347      Type vt = ft.getValueType();
348      %>
349      useColors['<%=ft.name()%>'] = <%=ft.canUseColoring()%>;
350      supportsAverage['<%=ft.name()%>'] = <%=ft.supportsAverage()%>;
351      lockedValueType['<%=ft.name()%>'] = '<%=vt == null ? "" : vt.name()%>';
352      <%
353    }
354    %>
355 
356    function useColorsOnClick()
357    {
358      var frm = document.forms['formula'];
359      var useColors = frm.use_colors.checked && !frm.use_colors.disabled;
360      frm.min_value.disabled = !useColors;
361      frm.mid_value.disabled = !useColors;
362      frm.max_value.disabled = !useColors;
363      frm.logarithmic.disabled = !useColors;
364      if (useColors)
365      {
366        Main.addClass(frm.min_value, 'required');
367        Main.addClass(frm.mid_value, 'required');
368        Main.addClass(frm.max_value, 'required');
369      }
370      else
371      {
372        Main.removeClass(frm.min_value, 'required');
373        Main.removeClass(frm.mid_value, 'required');
374        Main.removeClass(frm.max_value, 'required');
375      }
376    }
377   
378    function formulaTypeOnChange()
379    {
380      var frm = document.forms['formula'];
381      var formulaType = frm.type[frm.type.selectedIndex].value;
382      var use = useColors[formulaType];
383      frm.use_colors.disabled = !use;
384      useColorsOnClick();
385      var supportsAvg = supportsAverage[formulaType];
386      frm.averageMethod.disabled = !supportsAvg;
387      if (!supportsAvg) frm.averageMethod.selectedIndex = 0;
388      var valueType = lockedValueType[formulaType];
389      if (valueType)
390      {
391        Forms.selectListOption(frm.valueType, valueType);
392        frm.valueType.disabled = true;
393      }
394      else
395      {
396        frm.valueType.disabled = false;
397      }
398    }
399    </script>
400  </base:head>
401  <base:body onload="init()">
402    <h1><%=title%> <base:help tabcontrol="settings" /></h1>
403    <form action="index.jsp?ID=<%=ID%>" method="post" name="formula">
404    <input type="hidden" name="cmd" value="UpdateItem">
405
406    <t:tabcontrol id="settings" 
407      subclass="content dialogtabcontrol"
408      position="bottom"  remember="<%=formula != null%>"
409      extensions="<%=invoker%>">
410    <t:tab id="info" title="Formula" validate="validateFormula()" helpid="formula.edit">
411      <table class="fullform input100">
412      <tr>
413        <th>Name</th>
414        <td><input class="text required" type="text" name="name" 
415          value="<%=HTML.encodeTags(formula == null ? Values.getString(cc.getPropertyValue("name"), "New formula") : formula.getName())%>" 
416          maxlength="<%=Formula.MAX_NAME_LENGTH%>"></td>
417        <td></td>
418      </tr>
419      <tr>
420        <th>Type</th>
421        <td>
422          <select name="type" class="required" onchange="formulaTypeOnChange()" style="width: 15em;">
423          <%
424          for (Formula.Type type : Formula.Type.values())
425          {
426            String selected = type == currentType ? "selected" : "";
427            %>
428            <option value="<%=type.name()%>" <%=selected%>><%=HTML.encodeTags(type.toString())%>
429            <%
430          }
431          %>
432          </select>
433        </td>
434        <td></td>
435      </tr>
436      <tr>
437        <th>Parser</th>
438        <td>
439          <select name="parser" class="required" style="width: 15em;">
440          <%
441          for (Formula.Parser parser : Formula.Parser.values())
442          {
443            String selected = parser == currentParser ? "selected" : "";
444            %>
445            <option value="<%=parser.name()%>" <%=selected%>><%=HTML.encodeTags(parser.toString())%>
446            <%
447          }
448          %>
449          </select>
450        </td>
451        <td></td>
452      </tr>
453      <tr>
454        <th>Raw data type</th>
455        <td>
456          <select name="rawdatatype" onchange="rawDataTypeOnChange()" style="width: 15em;">
457          <option value="">- none -
458          <%
459          for (RawDataType rdt :  RawDataTypes.getSortedRawDataTypes(new RawDataTypes.NameComparator()))
460          {
461            String selected = rdt == currentRawDataType ? "selected" : "";
462            %>
463            <option value="<%=rdt.getId()%>" <%=selected%>><%=HTML.encodeTags(rdt.getName())%>
464            <%
465          }
466          %>
467          </select>
468        </td>
469        <td></td>
470      </tr>
471      <tr>
472        <th>Channels</th>
473        <td><input <%=currentRawDataType != null ? "class=\"text disabled\" disabled" : "class=\"text required\""%> type="text" name="channels" 
474          style="width:15em;"
475          value="<%=formula == null ? (currentRawDataType == null ? Values.getInt(cc.getPropertyValue("channels")) : currentRawDataType.getChannels()) : formula.getChannels()%>" 
476           maxlength="10" onkeypress="return Numbers.integerOnly(event)"
477          ></td>
478        <td></td>
479      </tr>
480      <tr class="big">
481        <th>Expressions</th>
482        <td>
483          <table>
484          <tr>
485            <td>
486            <select name="expressions" size="3" style="width: 26em;"
487              onchange="expressionsOnClick()" multiple class="required">
488              <%
489              if (expressions != null)
490              {
491                for (String expression : expressions)
492                {
493                  %>
494                  <option><%=HTML.encodeTags(expression)%>
495                  <%
496                }
497              }
498              %>
499            </select>
500            </td>
501            <td><base:button onclick="removeOnClick()" title="Remove" /></td>
502            <td></td>
503          </tr>
504          <tr>
505          <td>
506            <input type="text" name="expression" class="text" style="width: 26em;"
507              maxlength="<%=Formula.MAX_FORMULA_LENGTH%>"
508              onblur="expressionOnBlur()">
509          </td>
510          <td>
511            <base:button onclick="addOnClick()" title="Add" />
512          </td>
513          <td>
514            <base:button onclick="openExpressionBuilder()" 
515              image="expression_builder.png"
516              title="Expression builder&hellip;" />
517          </td>
518          </table>
519        </td>
520        <td></td>
521      </tr>
522      <tr>
523        <th>Value type</th>
524        <td>
525          <select name="valueType" style="width: 15em;">
526          <option value="">- unknown -
527          <%
528          for (Type type : Type.values())
529          {
530            String selected = type == currentValueType ? "selected" : "";
531            %>
532            <option value="<%=type.name()%>" <%=selected%>><%=HTML.encodeTags(type.toString())%>
533            <%
534          }
535          %>
536          </select>
537        </td>
538        <td></td>
539      </tr>
540      <tr>
541        <th>Avg. method</th>
542        <td>
543          <select name="averageMethod" class="required" style="width: 15em;">
544          <%
545          for (Formula.AverageMethod method : Formula.AverageMethod.values())
546          {
547            String selected = method == currentAverageMethod ? "selected" : "";
548            %>
549            <option value="<%=method.name()%>" <%=selected%>><%=HTML.encodeTags(method.toString())%>
550            <%
551          }
552          %>
553          </select>
554        </td>
555        <td></td>
556      </tr>
557      <tr>
558        <th>Intensity<br>transformation</th>
559        <td>
560          <b>Source</b>
561          <select name="sourceIntensityTransform" style="width: 15em;">
562          <option value="">- any -
563          <%
564          for (IntensityTransform t : IntensityTransform.values())
565          {
566            String selected = t == currentSourceIntensityTransform ? "selected" : "";
567            %>
568            <option value="<%=t.name()%>" <%=selected%>><%=HTML.encodeTags(t.toString())%>
569            <%
570          }
571          %>
572          </select>
573          <b>Result</b>
574          <select name="resultIntensityTransform" style="width: 15em;">
575          <option value="">- any -
576          <%
577          for (IntensityTransform t : IntensityTransform.values())
578          {
579            String selected = t == currentResultIntensityTransform ? "selected" : "";
580            %>
581            <option value="<%=t.name()%>" <%=selected%>><%=HTML.encodeTags(t.toString())%>
582            <%
583          }
584          %>
585          </select>
586        </td>
587        <td></td>
588      </tr>
589      <tr>
590        <th></th>
591        <td>
592          <input type="checkbox" name="use_colors" id="useColors" value="1" 
593            <%=coloring.isUsingColors() ? "checked" : "" %>
594            onclick="useColorsOnClick()">
595          <label for="useColors"><b>Use colors</b></label>
596         
597          <input type="checkbox" name="logarithmic" id="logarithmic" value="1" 
598            <%=coloring.isLogarithmic() ? "checked" : "" %>>
599          <label for="logarithmic"><b>Logarithmic</b></label> 
600        </td>
601        <td></td>
602      </tr>
603      <tr>
604        <th class="subprompt"></th>
605        <td>
606          <b>Min value</b>
607          <input type="text" class="text" name="min_value" style="width: 6em;"
608             value="<%=Values.formatNumber(coloring.getMinValue(), -1)%>"
609             maxlength="6" onkeypress="return Numbers.numberOnly(event)">
610          <b>Mid value</b>
611          <input type="text" class="text" name="mid_value" style="width: 6em;"
612             value="<%=Values.formatNumber(coloring.getMidValue(), -1)%>"
613             maxlength="6" onkeypress="return Numbers.numberOnly(event)">
614          <b>Max value</b>
615          <input type="text" class="text" name="max_value" style="width: 6em;"
616             value="<%=Values.formatNumber(coloring.getMaxValue(), -1)%>"
617             maxlength="6" onkeypress="return Numbers.numberOnly(event)">
618        </td>
619        <td></td>
620      </tr>
621      <tr class="dynamic">
622        <th>Description</th>
623        <td>
624          <textarea class="text" rows="4" name="description" id="description"
625            ><%=HTML.encodeTags(formula == null ? cc.getPropertyValue("description") : formula.getDescription())%></textarea>
626        </td>
627        <td style="width: 20px;">
628          <base:zoom textarea="description" title="Description" />
629        </td>
630      </tr>
631      </table>
632    </t:tab>
633    </t:tabcontrol>
634    </form>
635
636    <div class="legend">
637      <base:icon image="required.png" />= required information
638    </div>
639
640    <base:buttongroup subclass="dialogbuttons">
641      <base:button onclick="saveSettings()" title="Save" />
642      <base:button onclick="window.close()" title="Cancel" />
643    </base:buttongroup>
644  </base:body>
645  </base:page>
646  <%
647}
648finally
649{
650  if (dc != null) dc.close();
651}
652%>
Note: See TracBrowser for help on using the repository browser.