6 CXGN.List - a javascript library to implement the lists on the SGN platform
10 There are two important list functions in this library, listed below. All other functions should be considered private and/or deprecated.
13 * addToListMenu(listMenuDiv, dataDiv)
15 this function will generate a select of all available lists and allow the content to be added to a list (from a search, etc). The first parameter is the id of the div tag where the menu should be drawn. The second parameter is the div that contains the data to be added. This can be a textfield, a div or span tag, or a multiple select tag.
17 * pasteListMenu(divName, menuDiv, buttonName)
19 this will generate an html select box of all the lists, and a "paste" button, to paste into a textarea (typically). The divName is the id of the textarea, the menuDiv is the id where the paste menu should be placed.
22 Public List object functions
24 * listSelect(divName, types)
26 will create an html select with id and name 'divName'. Optionally, a list of types can be specified that will limit the menu to the respective types.
29 You have to instantiate the list object first:
31 var lo = new CXGN.List(); var s = lo.listSelect('myseldiv', [ 'trials' ]);
34 * validate(list_id, type, non_interactive)
36 * transform(list_id, new_type)
41 Lukas Mueller <lam87@cornell.edu>
47 //JSAN.use('jqueryui');
49 if (!CXGN) CXGN = function () { };
51 CXGN.List = function () {
56 CXGN.List.prototype = {
58 // Return the data as a straight list
60 getList: function(list_id) {
64 url: '/list/contents/'+list_id,
66 success: function(response) {
68 //document.write(response.error);
74 error: function(response) {
75 alert("An error occurred.");
83 // this function also returns some metadata about
84 // list, namely its type.
86 getListData: function(list_id) {
92 data: { 'list_id': list_id },
93 success: function(response) {
95 alert(response.error);
106 getListType: function(list_id) {
110 url: '/list/type/'+list_id,
112 success: function(response) {
113 if (response.error) {
114 alert(response.error);
117 type = response.list_type;
121 error: alert('An error occurred. Cannot determine type. ')
126 setListType: function(list_id, type) {
129 url: '/list/type/'+list_id+'/'+type,
131 success: function(response) {
132 if (response.error) {
133 alert(response.error);
136 alert('Type of list '+list_id+' set to '+type);
143 allListTypes: function() {
146 url: '/list/alltypes',
148 success: function(response) {
149 if (response.error) {
150 alert(response.error);
161 typesHtmlSelect: function(list_id, html_select_id, selected) {
162 var types = this.allListTypes();
163 var html = '<select id="'+html_select_id+'" onchange="javascript:changeListType(\''+html_select_id+'\', '+list_id+');" >';
164 html += '<option name="null">(none)</option>';
165 for (var i=0; i<types.length; i++) {
166 var selected_html = '';
167 if (types[i][1] == selected) {
168 selected_html = ' selected="selected" ';
170 html += '<option name="'+types[i][1]+'"'+selected_html+'>'+types[i][1]+'</option>';
176 newList: function(name) {
177 var oldListId = this.existsList(name);
181 alert('Please provide a name for the new list.');
185 if (oldListId === null) {
189 data: { 'name': name },
190 success: function(response) {
191 if (response.error) {
192 alert(response.error);
195 newListId=response.list_id;
202 alert('A list with name "'+ name + '" already exists. Please choose another list name.');
205 alert("An error occurred. Cannot create new list right now.");
209 availableLists: function(list_type) {
212 url: '/list/available',
213 data: { 'type': list_type },
215 success: function(response) {
216 if (response.error) {
217 //alert(response.error);
220 //alert("LISTS OF TYPE "+list_type+": "+lists.join(","));
222 error: function(response) {
223 alert("An error occurred");
229 //return the newly created list_item_id or 0 if nothing was added
230 //(due to duplicates)
231 addItem: function(list_id, item) {
232 var exists_item_id = this.existsItem(list_id,item);
233 if (exists_item_id ===0 ) {
236 url: '/list/item/add',
237 data: { 'list_id': list_id, 'element': item },
238 success: function(response) {
239 if (response.error) {
240 alert(response.error);
245 var new_list_item_id = this.existsItem(list_id,item);
246 return new_list_item_id;
251 addBulk: function(list_id, items) {
253 var elements = items.join("\t");
259 url: '/list/add/bulk',
260 data: { 'list_id': list_id, 'elements': elements },
261 success: function(response) {
262 if (response.error) {
263 alert(response.error);
266 if (response.duplicates) {
267 alert("The following items are already in the list and were not added: "+response.duplicates.join(", "));
269 count = response.success;
276 removeItem: function(list_id, item_id) {
279 url: '/list/item/remove',
280 data: { 'list_id': list_id, 'item_id': item_id }
284 deleteList: function(list_id) {
288 data: { 'list_id': list_id }
292 renderLists: function(div) {
293 var lists = this.availableLists();
295 html = html + '<input id="add_list_input" type="text" /><input id="add_list_button" type="button" value="new list" /><br />';
297 if (lists.length===0) {
298 html = html + "None";
299 jQuery('#'+div).html(html);
302 html += '<table border="0" cellpadding="2" title="Available lists">';
303 html += '<tr><td><i>list name</i></td><td><i>#</i></td><td><i>type</i></td><td colspan="3"><i>actions</i></td></tr>\n';
304 for (var i = 0; i < lists.length; i++) {
305 html = html + '<tr><td><b>'+lists[i][1]+'</b></td><td>'+lists[i][3]+'</td><td>'+lists[i][5]+'</td><td><a href="javascript:showListItems(\'list_item_dialog\','+lists[i][0]+')">view</a></td><td>|</td><td><a href="javascript:deleteList('+lists[i][0]+')">delete</a></td><td>|</td><td><a href="/list/download?list_id='+lists[i][0]+'">download</a></td></tr>\n';
307 html = html + '</table>';
308 jQuery('#'+div).html(html);
310 jQuery('#add_list_button').click(function() {
311 var lo = new CXGN.List();
313 var name = jQuery('#add_list_input').val();
320 listNameById: function(list_id) {
321 lists = this.availableLists();
322 for (var n=0; n<lists.length; n++) {
323 if (lists[n][0] == list_id) { return lists[n][1]; }
327 renderItems: function(div, list_id) {
328 var list_data = this.getListData(list_id);
329 var items = list_data.elements;
330 var list_type = list_data.type_name;
331 var list_name = this.listNameById(list_id);
334 html += '<table><tr width="100"><td>List name ';
336 html += '</td><td><input type="text" id="updateNameField" size="10" value="'+list_name+'" /></td><td><input type="button" id="updateNameButton" value="update" /><td width="100%" align="right"><font size="1">List ID</td><td><div id="list_id_div" style="font-size:tiny" >'+list_id+'</div></font></td></tr>';
338 html += '<tr><td>Type</td><td>'+this.typesHtmlSelect(list_id, 'type_select', list_type)+'</td><td colspan="2"><input type="button" value="validate" onclick="javascript:validateList('+list_id+',\'type_select\')" /></td></tr></table>';
340 html += 'Add new elements: <br /><textarea id="dialog_add_list_item" ></textarea><input id="dialog_add_list_item_button" type="submit" value="Add" /><br />';
342 html += '<b>List items</b> ('+items.length+')<br />';
344 for(var n=0; n<items.length; n++) {
345 html = html + items[n][1] + ' <input id="'+items[n][0]+'" type="button" value="remove" /><br />';
347 jQuery('#'+div).html(html);
349 for (var n=0; n<items.length; n++) {
350 var list_item_id = items[n][0];
352 jQuery('#'+items[n][0]).click(
354 var lo = new CXGN.List();
355 var i = lo.availableLists();
357 lo.removeItem(list_id, this.id );
358 lo.renderItems(div, list_id);
359 lo.renderLists('list_dialog');
364 jQuery('#dialog_add_list_item_button').click(
366 addMultipleItemsToList('dialog_add_list_item', list_id);
367 var lo = new CXGN.List();
368 lo.renderItems(div, list_id);
372 jQuery('#updateNameButton').click(
374 var lo = new CXGN.List();
375 var new_name = jQuery('#updateNameField').val();
376 var list_id = jQuery('#list_id_div').html();
377 lo.updateName(list_id, new_name);
378 alert("Changed name to "+new_name+" for list id "+list_id);
383 existsList: function(name) {
388 data: { 'name': name },
389 success: function(response) {
390 list_id = response.list_id;
396 existsItem: function(list_id, name) {
399 url: '/list/exists_item',
401 data: { 'list_id' : list_id, 'name':name },
402 success: function(response) {
403 list_item_id = response.list_item_id;
410 addToList: function(list_id, text) {
411 var list = text.split("\n");
414 var info = this.addBulk(list_id, list);
420 /* listSelect: Creates an html select with lists of requested types.
423 div_name: The div_name where the select should appear
424 types: a list of list types that should be listed in the menu
427 listSelect: function(div_name, types) {
428 var lists = new Array();
431 for (var n=0; n<types.length; n++) {
432 var more = this.availableLists(types[n]);
434 for (var i=0; i<more.length; i++) {
441 lists = this.availableLists();
444 var html = '<select id="'+div_name+'_list_select" name="'+div_name+'_list_select" >';
445 for (var n=0; n<lists.length; n++) {
446 html = html + '<option value='+lists[n][0]+'>'+lists[n][1]+'</option>';
448 html = html + '</select>';
452 updateName: function(list_id, new_name) {
454 url: '/list/name/update',
456 data: { 'name' : new_name, 'list_id' : list_id },
457 success: function(response) {
458 if (response.error) {
459 alert(response.error);
463 alert("The name of the list was changed to "+new_name);
466 error: function(response) { alert("An error occurred."); }
468 this.renderLists('list_dialog');
471 validate: function(list_id, type, non_interactive) {
472 var missing = new Array();
475 url: '/list/validate/'+list_id+'/'+type,
477 success: function(response) {
478 if (response.error) {
479 alert(response.error);
482 missing = response.missing;
485 error: function(response) { alert("An error occurred while validating the list "+list_id); error=1; }
488 if (error === 1 ) { return; }
490 if (missing.length==0) {
491 if (!non_interactive) { alert("This list passed validation."); }
495 alert("List validation failed. Elements not found: "+ missing.join(","));
500 transform: function(list_id, new_type) {
501 var transformed = new CXGN.List();
503 url: '/list/transform/'+list_id+'/'+new_type,
505 success: function(response) {
506 if (response.error) {
507 alert(response.error);
510 transformed = response.transform;
513 error: function(response) { alert("An error occurred while validating the list "+list_id); }
517 transform2Ids: function(list_id) {
518 var list_type = this.getListType(list_id);
520 if (list_type == 'traits') { new_type = 'trait_ids'; }
521 if (list_type == 'locations') { new_type = 'location_ids'; }
522 if (list_type == 'trials') { new_type = 'project_ids'; }
523 if (list_type == 'projects') { new_type = 'project_ids'; }
524 if (list_type == 'plots') { new_type = 'plot_ids'; }
525 if (list_type == 'accessions') { new_type = 'accession_ids'; }
528 return { 'error' : "cannot convert the list because of unknown type" };
531 var transformed = this.transform(list_id, new_type);
533 return { 'transformed' : transformed };
539 function setUpLists() {
540 jQuery('#list_dialog').dialog( {
544 title: 'Available lists',
545 buttons: { "Done" : function() {
546 jQuery('#list_dialog').dialog("close"); }
551 jQuery('#list_item_dialog').dialog( {
557 jQuery('#list_item_dialog').dialog("close"); }
560 title: 'List contents'
563 jQuery('#lists_link').click(
564 function() { show_lists(); }
569 function show_lists() {
570 jQuery('#list_dialog').dialog("open");
572 var l = new CXGN.List();
573 l.renderLists('list_dialog');
577 function pasteListMenu (div_name, menu_div, button_name) {
578 var lo = new CXGN.List();
582 if (button_name === undefined) {
583 button_name = 'paste';
586 html = lo.listSelect(div_name);
587 html = html + '<input type="button" value="'+button_name+'" onclick="javascript:pasteList(\''+div_name+'\')" /><br />';
589 jQuery('#'+menu_div).html(html);
592 function pasteList(div_name) {
593 var lo = new CXGN.List();
594 var list_name = jQuery('#'+div_name+'_list_select').val();
595 var list_content = lo.getList(list_name);
599 for (var n=0; n<list_content.length; n++) {
600 list_text = list_text + list_content[n][1]+"\r\n";
602 jQuery('#'+div_name).text(list_text);
609 * listMenuDiv - the name of the div where the menu will be displayed
610 * dataDiv - the div from which the data will be copied (can be a div, textarea, or html select
611 * options - optional hash with the following keys:
612 - selectText: if the dataDiv is an html select and selectText is true, the text and not the value will be copied into the list
613 - listType: the type of lists to display in the menu
614 - typesSourceDiv: obtain the type from this source div
619 function addToListMenu(listMenuDiv, dataDiv, options) {
620 var lo = new CXGN.List();
629 if (options.selectText) {
630 selectText = options.selectText;
632 if (options.typeSourceDiv) {
633 type = getData(options.typeSourceDiv, selectText);
634 type = type.replace(/(\n|\r)+$/, '');
637 type = options.listType;
640 html = '<input type="text" id="'+dataDiv+'_new_list_name" size="8" />';
641 html += '<input type="hidden" id="'+dataDiv+'_list_type" value="'+type+'" />';
642 html += '<input id="'+dataDiv+'_add_to_new_list" type="button" value="add to new list" /><br />';
643 html += lo.listSelect(dataDiv, [ type ]);
645 html += '<input id="'+dataDiv+'_button" type="button" value="add to list" />';
647 if (dataDiv == 'stock_data' && document.referrer.match(/solgs/)) {
648 html += '<input style="clear: both" id="goto_gs_button" type="button" value="Go to GS" />';
651 jQuery('#'+listMenuDiv).html(html);
655 jQuery('#'+dataDiv+'_add_to_new_list').click(
657 var lo = new CXGN.List();
658 var new_name = jQuery('#'+dataDiv+'_new_list_name').val();
659 var type = jQuery('#'+dataDiv+'_list_type').val();
661 var data = getData(dataDiv, selectText);
663 list_id = lo.newList(new_name);
665 var elementsAdded = lo.addToList(list_id, data);
666 if (type) { lo.setListType(list_id, type); }
667 alert("Added "+elementsAdded+" list elements to list "+new_name+" and set type to "+type);
672 jQuery('#'+dataDiv+'_button').click(
674 var data = getData(dataDiv, selectText);
675 list_id = jQuery('#'+dataDiv+'_list_select').val();
676 var lo = new CXGN.List();
677 var elementsAdded = lo.addToList(list_id, data);
679 alert("Added "+elementsAdded+" list elements");
684 jQuery(document).on("click", "#goto_gs_button", function() {
686 if (document.referrer.match(/solgs/)){
687 window.location.href= document.referrer;
689 window.location.href = window.location.protocol + "//" +window.location.host + '/solgs/search';
696 function getData(id, selectText) {
697 var divType = jQuery("#"+id).get(0).tagName;
700 if (divType == 'DIV' || divType =='SPAN' || divType === undefined) {
701 data = jQuery('#'+id).html();
703 if (divType == 'SELECT' && selectText) {
704 data = jQuery('#'+id+" option:selected").text();
706 if (divType == 'SELECT' && ! selectText) {
707 var return_data = jQuery('#'+id).val();
709 if (return_data instanceof Array) {
710 data = return_data.join("\n");
716 if (divType == 'TEXTAREA') {
717 data = jQuery('textarea#'+id).val();
724 function addTextToListMenu(div) {
725 var lo = new CXGN.List();
726 var html = lo.listSelect(div);
727 html = html + '<input id="'+div+'_button" type="button" value="add to list" />';
729 document.write(html);
731 jQuery('#'+div+'_button').click(
733 var text = jQuery('textarea#div').val();
734 var list_id = jQuery('#'+div+'_list_select').val();
735 lo.addToList(list_id, text);
736 lo.renderLists('list_dialog');
742 function addSelectToListMenu(div) {
743 var lo = new CXGN.List();
744 var html = lo.listSelect(div);
745 html = html + '<input id="'+div+'_button" type="button" value="add to list" />';
747 document.write(html);
749 jQuery('#'+div+'_button').click(
751 var selected_items = jQuery('#'+div).val();
752 var list_id = jQuery('#'+div+'_list_select').val();
753 addArrayToList(selected_items, list_id);
754 lo.renderLists('list_dialog');
761 // add the text in a div to a list
762 function addDivToList(div_name) {
763 var list_id = jQuery('#'+div_name+'_list_select').val();
764 var lo = new CXGN.List();
765 var list = jQuery('#'+div_name).val();
766 var items = list.split("\n");
768 for(var n=0; n<items.length; n++) {
769 var added = lo.addItem(list_id, items[n]);
775 function addTextToList(div, list_id) {
776 var lo = new CXGN.List();
777 var item = jQuery('#'+div).val();
778 var id = lo.addItem(list_id, item);
780 alert('Item "'+item+'" was not added because it already exists');
782 lo.renderLists('list_dialog');
786 function addMultipleItemsToList(div, list_id) {
787 var lo = new CXGN.List();
788 var content = jQuery('#'+div).val();
790 alert("No items - Please enter items to add to the list.");
793 var items = content.split("\n");
795 var duplicates = new Array();
796 for (var n=0; n<items.length; n++) {
797 var id = lo.addItem(list_id, items[n]);
799 duplicates.push(items[n]);
802 if (duplicates.length >0) {
803 alert("The following items were not added because they are already in the list: "+ duplicates.join(", "));
805 lo.renderLists('list_dialog');
809 function addArrayToList(items, list_id) {
810 var lo = new CXGN.List();
811 var duplicates = new Array();
812 for (var n=0; n<items.length; n++) {
813 var id = lo.addItem(list_id, items[n]);
815 duplicates.push(items[n]);
818 if (duplicates.length >0) {
819 alert("The following items were not added because they are already in the list: "+ duplicates.join(", "));
823 function deleteList(list_id) {
824 var lo = new CXGN.List();
825 var list_name = lo.listNameById(list_id);
826 if (confirm('Delete list "'+list_name+'"? (ID='+list_id+'). This cannot be undone.')) {
827 lo.deleteList(list_id);
828 lo.renderLists('list_dialog');
829 alert('Deleted list '+list_name);
833 function deleteItemLink(list_item_id) {
834 var lo = new CXGN.List();
835 lo.deleteItem(list_item_id);
836 lo.renderLists('list_dialog');
839 function showListItems(div, list_id) {
840 var l = new CXGN.List();
841 jQuery('#'+div).dialog("open");
842 l.renderItems('list_item_dialog', list_id);
845 function addNewList(div_id) {
846 var lo = new CXGN.List();
847 var name = jQuery('#'+div_id).val();
850 alert("Please specify a name for the list.");
854 var list_id = lo.existsList(name);
856 alert('The list '+name+' already exists. Please choose another name.');
860 lo.renderLists('list_item_dialog');
863 function changeListType(html_select_id, list_id) {
864 var type = jQuery('#'+html_select_id).val();
865 var l = new CXGN.List();
866 l.setListType(list_id, type);
867 l.renderLists('list_dialog');
871 validateList - check if all the elements in a list are of the correct type
874 * list_id: the id of the list
875 * html_select_id: the id of the html select containing the type list
879 function validateList(list_id, html_select_id) {
880 var lo = new CXGN.List();
881 var type = jQuery('#'+html_select_id).val();
882 lo.validate(list_id, type);