source: trunk/www/admin/itemsubtypes/edit_subtype.jsp @ 5713

Last change on this file since 5713 was 5713, checked in by Nicklas Nordborg, 12 years ago

References #1604: Support for multiple files of the same type in a FileSet?

Added data and core layer classes. Started with the gui and seems to work when adding single files of a type. There are some remaining things to implement when used with multiple files. File validation is not yet fully functional. Some of the batch importers need to be fixed as well to be able to handle multiple files of the same type.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 13.6 KB
Line 
1<%-- $Id: edit_subtype.jsp 5713 2011-09-02 13:01:58Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2011 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
9  modify it under the terms of the GNU General Public License
10  as published by the Free Software Foundation; either version 3
11  of the License, or (at your option) any later version.
12
13  BASE is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU 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  @since 2.0
24--%>
25<%@ page pageEncoding="UTF-8" session="false"
26  import="net.sf.basedb.core.SessionControl"
27  import="net.sf.basedb.core.DbControl"
28  import="net.sf.basedb.core.Item"
29  import="net.sf.basedb.core.ItemContext"
30  import="net.sf.basedb.core.Permission"
31  import="net.sf.basedb.core.ItemSubtype"
32  import="net.sf.basedb.core.ItemSubtypeFileType"
33  import="net.sf.basedb.core.PermissionDeniedException"
34  import="net.sf.basedb.core.Metadata"
35  import="net.sf.basedb.core.FileStoreEnabled"
36  import="net.sf.basedb.core.DataFileType"
37  import="net.sf.basedb.core.ItemQuery"
38  import="net.sf.basedb.core.Include"
39  import="net.sf.basedb.core.query.Hql"
40  import="net.sf.basedb.core.query.Orders"
41  import="net.sf.basedb.clients.web.Base"
42  import="net.sf.basedb.clients.web.util.HTML"
43  import="net.sf.basedb.util.Values"
44  import="net.sf.basedb.core.plugin.GuiContext"
45  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
46  import="net.sf.basedb.clients.web.extensions.JspContext"
47  import="net.sf.basedb.clients.web.extensions.edit.EditUtil"
48  import="net.sf.basedb.util.extensions.ExtensionsInvoker"
49  import="java.util.Set"
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<%
55final Item itemType = Item.ITEMSUBTYPE;
56final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
57final ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, null, null);
58final int itemId = cc.getId();
59final String ID = sc.getId();
60final float scale = Base.getScale(sc);
61final DbControl dc = sc.newDbControl();
62try
63{
64  String title = null;
65  ItemSubtype subtype = null;
66  ItemQuery<ItemSubtypeFileType> fileTypesQuery = null;
67 
68  if (itemId == 0)
69  {
70    title="Create item subtype";
71    cc.removeObject("item");
72  }
73  else
74  {
75    subtype = ItemSubtype.getById(dc, itemId);
76    cc.setObject("item", subtype);
77    title = "Edit item subtype -- " + HTML.encodeTags(subtype.getName());
78    subtype.checkPermission(Permission.WRITE);
79    fileTypesQuery = subtype.getDataFileTypes();
80  }
81 
82  Set<Item> subtypableItems = Metadata.getSubtypableItems();
83  final String clazz = "class=\"text\"";
84  final String requiredClazz = "class=\"text required\"";
85  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, GuiContext.item(itemType), subtype);
86  ExtensionsInvoker invoker = EditUtil.useEditExtensions(jspContext);
87  %>
88  <base:page type="popup" title="<%=title%>">
89  <base:head scripts="tabcontrol.js,linkitems.js" styles="tabcontrol.css">
90    <ext:scripts context="<%=jspContext%>" />
91    <ext:stylesheets context="<%=jspContext%>" />
92    <script language="JavaScript">
93    // Validate the "Item subtype" tab
94    function validateItemSubtype()
95    {
96      var frm = document.forms['subtype'];
97      if (Main.trimString(frm.name.value) == '')
98      {
99        alert("You must enter a name");
100        frm.name.focus();
101        return false;
102      }
103      return true;
104    }
105
106    // Submit the form
107    function saveSettings()
108    {
109      var frm = document.forms['subtype'];
110      if (TabControl.validateActiveTab('settings'))
111      {
112        frm.modifiedFileTypes.value = Link.exportModified(frm, 'F', true).join(',');
113        frm.removedFileTypes.value = Link.getActionIds(-1, 'F').join(',');
114        frm.submit();
115      }
116    }
117   
118    function init()
119    {
120      <%
121      if (subtype == null)
122      {
123        %>
124        var frm = document.forms['subtype'];
125        frm.name.focus();
126        frm.name.select();
127        <%
128      }
129      %>
130      initFileTypes();
131      mainItemOnChange();
132    }
133   
134    function initFileTypes()
135    {
136      var frm = document.forms['subtype'];
137      var fileTypes = frm.fileTypes;
138      <%
139      if (fileTypesQuery != null)
140      {
141        fileTypesQuery.include(Include.ALL);
142        fileTypesQuery.order(Orders.asc(Hql.property("itemSubtype.name")));
143        for (ItemSubtypeFileType ft : fileTypesQuery.list(dc))
144        {
145          DataFileType dft = ft.getDataFileType();
146          boolean required = ft.isRequired();
147          boolean multiple = ft.getAllowMultiple();
148          int value = 0;
149          if (required) value += 1;
150          if (multiple) value += 2;
151          %>
152          Link.addNewItem(fileTypes, new Item('F', <%=dft.getId()%>, '<%=HTML.javaScriptEncode(dft.getName())%> <%=required ? "[×]" : "[-]"%>', <%=value%>));
153          <%
154        }
155      }
156      %>
157    }
158   
159    var itemInfo = new Array();
160    <%
161    for (Item item : subtypableItems)
162    {
163      String tmp = "";
164      for (Item related : ItemSubtype.getRelatedItems(item))
165      {
166        tmp += related.name() + ":";
167      }
168      %>
169      var info = new Object();
170      info.value = <%=item.getValue()%>;
171      info.related = '<%=tmp%>';
172      info.fileStoreEnabled = <%=FileStoreEnabled.class.isAssignableFrom(item.getItemClass()) ? "true" : "false"%>;
173      itemInfo['<%=item.name()%>'] = info;
174      <%
175    }
176    %>
177   
178    function getCurrentMainItemType()
179    {
180      var frm = document.forms['subtype'];
181      <%
182      if (subtype != null)
183      {
184        %>
185        var mainType = '<%=subtype.getMainItemType().name()%>';
186        <%
187      }
188      else
189      {
190        %>
191        var mainType = frm.itemType[frm.itemType.selectedIndex].value;
192        <%
193      }
194      %>
195      return mainType;
196    }
197   
198    function mainItemOnChange()
199    {
200      var mainType = getCurrentMainItemType();
201      <%
202      for (Item item : subtypableItems)
203      {
204        %>
205        Main.showHide('section.<%=item.name()%>', itemInfo[mainType].related.indexOf('<%=item.name()%>') >= 0)
206        <%
207      }
208      %>
209      Main.showHide('section.none', itemInfo[mainType].related == '')
210      if (itemInfo[mainType].fileStoreEnabled)
211      {
212        Main.show('filetypes.enabled');
213        Main.hide('filetypes.disabled');
214      }
215      else
216      {
217        Main.show('filetypes.disabled');
218        Main.hide('filetypes.enabled');
219        document.getElementById('filetypes.disabled').innerHTML = 'The selected main item type (' + mainType + ') has not support for attaching data files.';
220      }
221    }
222   
223    var lastList;
224    function relatedItemOnSelect(itemType)
225    {
226      var frm = document.forms['subtype'];
227      lastList = frm['related.'+itemType];
228      var url = 'index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&title=Select+related+subtype&callback=setRelatedCallback';
229      url += '&resetTemporary=1&tmpfilter:INT:itemType=' + itemInfo[itemType].value;
230      if (lastList.length > 1)
231      {
232        var id = Math.abs(parseInt(lastList[1].value));       
233        url += '&item_id='+id;
234      }
235      Main.openPopup(url, 'SelectReleatedSubtype', 1000, 700);
236    }
237    function setRelatedCallback(id, name)
238    {
239      var frm = document.forms['subtype'];
240      var list = lastList;
241      if (list.length < 2 || list[1].value == '0') // >
242      {
243        Forms.addListOption(list, 1, new Option());
244      }
245      list[1].value = id;
246      list[1].text = name;
247      list.selectedIndex = 1;
248    }
249    function addFileTypesOnClick()
250    {
251      var frm = document.forms['subtype'];
252      var itemType = getCurrentMainItemType();
253      var ids = Link.getListIds(frm.fileTypes, 'F');
254      var excludes = ids.join(',');
255      var url = '../../admin/datafiletypes/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectmultiple&callback=addFileTypeCallback';
256      url += '&resetTemporary=1&tmpfilter:INT:itemType=' + itemInfo[itemType].value;
257      url += "&exclude="+excludes;
258      Main.openPopup(url, 'AddFileTypes', 1000, 700);
259    }
260    function addFileTypeCallback(fileTypeId, name)
261    {
262      var item = Link.getItem('F', fileTypeId);
263      var frm = document.forms['subtype'];
264      var required = frm.required.checked;
265      var multiple = frm.multiple.checked;
266      var newValue = 0;
267      if (required) newValue += 1;
268      if (multiple) newValue += 2;
269      if (!item) item = new Item('F', fileTypeId, name+(required ? '[×]' : '[-]'), newValue, '');
270      Link.addItem(frm.fileTypes, item);
271    }
272
273    function removeFileTypesOnClick()
274    {
275      Link.removeSelected(document.forms['subtype'].fileTypes);
276    }
277    function fileTypesOnChange()
278    {
279      var frm = document.forms['subtype'];
280      var item = frm.fileTypes[frm.fileTypes.selectedIndex].item;
281      if (item && item.id)
282      {
283        frm.required.checked = (item.value & 1) > 0;
284        frm.multiple.checked = (item.value & 2) > 0;
285      }
286      else
287      {
288        frm.required.checked = false;
289        frm.multiple.checked = false;
290      }
291    }
292
293    function requiredOnClick()
294    {
295      var frm = document.forms['subtype'];
296      var required = frm.required.checked;
297      var multiple = frm.multiple.checked;
298      var newValue = 0;
299      if (required) newValue += 1;
300      if (multiple) newValue += 2;
301      for (var i = 0; i < frm.fileTypes.length; i++)  // >
302      {
303        var option = frm.fileTypes[i];
304        if (option.selected && option.item.id)
305        {
306          option.item.value = newValue;
307          var text = option.text.replace(/\[.*\]/, '['+(required ? '×' : '-') +']');
308          option.text = text;
309        }
310      }
311    }
312    function multipleOnClick()
313    {
314      requiredOnClick();
315    }
316
317    </script>
318  </base:head>
319  <base:body onload="init()">
320    <p>
321    <form action="index.jsp?ID=<%=ID%>" method="post" name="subtype" onsubmit="return false;">
322    <input type="hidden" name="cmd" value="UpdateItem">
323
324    <h3 class="docked"><%=title%> <base:help tabcontrol="settings" /></h3>
325    <t:tabcontrol id="settings" contentstyle="<%="height: "+(int)(scale*320)+"px;"%>" 
326      position="bottom" remember="<%=subtype != null%>"
327      extensions="<%=invoker%>">
328    <t:tab id="info" title="Item subtype" validate="validateItemSubtype()" helpid="itemsubtype.edit">
329      <table class="form" cellspacing=0>
330      <tr>
331        <td class="prompt">Name</td>
332        <td><input <%=requiredClazz%> type="text" name="name" 
333          value="<%=HTML.encodeTags(subtype == null ? Values.getString(cc.getPropertyValue("name"), "New item subtype") : subtype.getName())%>" 
334          size="40" maxlength="<%=ItemSubtype.MAX_NAME_LENGTH%>"></td>
335      </tr>
336      <tr>
337        <td class="prompt">Main item type</td>
338        <td>
339          <%
340          if (subtype == null)
341          {
342            %>
343            <select name="itemType" class="required unchangeable selectionlist" onchange="mainItemOnChange()">
344            <%
345            int itemCode = Values.getInt(cc.getPropertyValue("itemType"), -1);
346            for (Item item : subtypableItems)
347            {
348              String selected = itemCode == item.getValue() ? "selected" : "";
349              %>
350              <option value="<%=item.name()%>" <%=selected%>><%=item.toString() %>
351              <%
352            }
353            %>
354            </select>
355            <%
356          }
357          else
358          {
359            %>
360            <%=subtype.getMainItemType() %>
361            <%
362          }
363          %>
364        </td>
365      </tr>
366      <tr valign=top>
367        <td class="prompt">Description</td>
368        <td nowrap>
369          <textarea <%=clazz%> rows="4" cols="40" name="description" wrap="virtual"
370            ><%=HTML.encodeTags(subtype == null ? cc.getPropertyValue("description") : subtype.getDescription())%></textarea>
371          <a href="javascript:Main.zoom('Description', 'subtype', 'description')"
372            title="Edit in larger window"><base:icon image="zoom.gif" /></a>
373        </td>
374      </tr>
375      <tr>
376        <td class="prompt">Related subtypes</td>
377        <td><div id="section.none" style="display: none;"><i>- none -</i></div></td>
378      </tr>
379      <%
380      for (Item item : subtypableItems)
381      {
382        %>
383        <tr id="section.<%=item.name()%>" style="display: none;">
384          <td class="subprompt"><%=item%></td>
385          <td>
386            <base:select 
387              id="<%="related."+item.name()%>" 
388              current="<%=subtype == null ? null : subtype.getRelatedSubtype(item) %>"
389              onselect="<%="relatedItemOnSelect('" + item.name() + "')"%>"
390              newitem="<%=subtype == null%>"
391              clazz="selectionlist"
392            />
393          </td>
394        </tr>
395        <%
396      }
397      %>
398      </table>
399      <div align=right>&nbsp;<i><base:icon image="required.gif" /> = required information</i></div>
400    </t:tab>
401    <t:tab
402      id="filetypes"
403      title="File types"
404      helpid="itemsubtype.filetypes">
405      <div id="filetypes.enabled">
406      <table class="form" cellspacing=0>
407      <tr valign="top">
408        <td class="prompt">File types</td>
409        <td>
410          <table border="0" cellspacing="0" cellpadding="0">
411          <tr valign="top">
412          <td>
413            <select name="fileTypes" size="10" multiple style="width: 20em;" 
414              onchange="fileTypesOnChange()">
415            </select>
416            <input type="hidden" name="modifiedFileTypes" value="">
417            <input type="hidden" name="removedFileTypes" value="">
418          </td>
419          <td>
420            <table border="0">
421            <tr><td width="150"><base:button 
422              onclick="addFileTypesOnClick()" 
423              title="Add file types&hellip;" 
424              tooltip="Add file types"
425              /></td></tr>
426            <tr><td width="150"><base:button 
427              onclick="removeFileTypesOnClick()" 
428              title="Remove" 
429              tooltip="Remove the selected file types"
430            /></td></tr>
431            </table>
432          <input type="checkbox" id="required" name="required" value="1" onchange="requiredOnClick()">
433            <label for="required">Required</label><br>
434          <input type="checkbox" id="multiple" name="multiple" value="1" onchange="multipleOnClick()">
435            <label for="multiple">Allow multiple files</label>
436          </td>
437          </tr>
438          </table>
439        </td>
440      </tr>
441      </table>
442      </div>
443      <div id="filetypes.disabled" style="display: none;">
444     
445      </div>
446    </t:tab>
447    </t:tabcontrol>
448
449    <table align="center">
450    <tr>
451      <td width="50%"><base:button onclick="saveSettings()" title="Save" /></td>
452      <td width="50%"><base:button onclick="window.close()" title="Cancel" /></td>
453    </tr>
454    </table>
455    </form>
456  </base:body>
457  </base:page>
458  <%
459}
460finally
461{
462  if (dc != null) dc.close();
463}
464%>
Note: See TracBrowser for help on using the repository browser.