combine lists
[sgn.git] / js / CXGN / List.js
blob4f056dc43a812a1846cbbac72621a1946f53edb1
2 /* 
4 =head1 NAME
6 CXGN.List - a javascript library to implement the lists on the SGN platform
8 =head1 DESCRIPTION
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. 
28 Usage:
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)
39 =head1 AUTHOR
41 Lukas Mueller <lam87@cornell.edu>
43 =cut
47 //JSAN.use('jqueryui');
49 if (!CXGN) CXGN = function () { };
51 CXGN.List = function () { 
52     this.list = [];
56 CXGN.List.prototype = { 
57     
58     // Return the data as a straight list
59     //
60     getList: function(list_id) {        
61         var list;
62         
63         jQuery.ajax( { 
64             url: '/list/contents/'+list_id,
65             async: false,
66             success: function(response) { 
67                 if (response.error) { 
68                     //document.write(response.error);
69                 }
70                 else { 
71                     list = response;
72                 }
73             },
74             error: function(response) { 
75                 alert("An error occurred.");
76             }
77         });
78         return list;
80     },
83     // this function also returns some metadata about
84     // list, namely its type.
85     //
86     getListData: function(list_id) { 
87         var list;
88         
89         jQuery.ajax( { 
90             url: '/list/data',
91             async: false,
92             data: { 'list_id': list_id },
93             success: function(response) { 
94                 if (response.error) { 
95                     alert(response.error);
96                 }
97                 else { 
98                     list = response;
99                 }
100             }
101         });
102         
103         return list;
104     },
106     getListType: function(list_id) { 
107         var type;
109         jQuery.ajax( { 
110             url: '/list/type/'+list_id,
111             async: false,
112             success: function(response) { 
113                 if (response.error) { 
114                     alert(response.error);
115                 }
116                 else { 
117                     type = response.list_type;
118                     return type;
119                 }
120             },
121             error: function () {
122                 alert('An error occurred. Cannot determine type. ');
123             }
124            
125         });
126         return type;
127     },
128             
129     setListType: function(list_id, type) { 
130         
131         jQuery.ajax( { 
132             url: '/list/type/'+list_id+'/'+type,
133             async: false,
134             success: function(response) { 
135                 if (response.error) { 
136                     alert(response.error);
137                 }
138                 else { 
139                     //alert('Type of list '+list_id+' set to '+type);
140                 }
141             } 
142         });
143     },
146     allListTypes: function() { 
147         var types;
148         jQuery.ajax( { 
149             url: '/list/alltypes',
150             async: false,
151             success: function(response) { 
152                 if (response.error) { 
153                     alert(response.error);
154                 }
155                 else { 
156                     types = response;
157                 }
158             }
159         });
160         return types;
161                      
162     },
163     
164     typesHtmlSelect: function(list_id, html_select_id, selected) { 
165         var types = this.allListTypes();
166         var html = '<select class="form-control" id="'+html_select_id+'" onchange="javascript:changeListType(\''+html_select_id+'\', '+list_id+');" >';
167         html += '<option name="null">(none)</option>';
168         for (var i=0; i<types.length; i++) { 
169             var selected_html = '';
170             if (types[i][1] == selected) { 
171                 selected_html = ' selected="selected" ';
172             }
173             html += '<option name="'+types[i][1]+'"'+selected_html+'>'+types[i][1]+'</option>';
174         }
175         html += '</select>';
176         return html;
177     },
179     newList: function(name) { 
180         var oldListId = this.existsList(name);
181         var newListId = 0;
182         
183         if (name == '') { 
184             alert('Please provide a name for the new list.');
185             return 0;
186         }
188         if (oldListId === null) { 
189             jQuery.ajax( { 
190                 url: '/list/new',
191                 async: false,
192                 data: { 'name': name },
193                 success: function(response) { 
194                     if (response.error) { 
195                         alert(response.error);
196                     }
197                     else { 
198                         newListId=response.list_id;
199                     }
200                 }
201             });
202             return newListId;
203         }
204         else { 
205             alert('A list with name "'+ name + '" already exists. Please choose another list name.');
206             return 0;
207         }
208         alert("An error occurred. Cannot create new list right now.");
209         return 0;
210     },
212     availableLists: function(list_type) { 
213         var lists = [];
214         jQuery.ajax( { 
215             url: '/list/available',
216             data: { 'type': list_type },
217             async: false,
218             success: function(response) { 
219                 if (response.error) { 
220                     //alert(response.error);  //do not alert here
221                 }
222                 lists = response;
223             },
224             error: function(response) { 
225                 alert("An error occurred");
226             }
227         });
228         return lists;
229     },
231     publicLists: function(list_type) { 
232         var lists = [];
233         jQuery.ajax( { 
234             url: '/list/available_public',
235             data: { 'type': list_type },
236             async: false,
237             success: function(response) { 
238                 if (response.error) { 
239                     alert(response.error);
240                 }
241                 lists = response;
242             },
243             error: function(response) { 
244                 alert("An error occurred");
245             }
246         });
247         return lists;
248     },
250     //return the newly created list_item_id or 0 if nothing was added
251     //(due to duplicates)
252     addItem: function(list_id, item) { 
253         var exists_item_id = this.existsItem(list_id,item);
254         if (exists_item_id ===0 ) { 
255             jQuery.ajax( { 
256                 async: false,
257                 url: '/list/item/add',
258                 data:  { 'list_id': list_id, 'element': item },
259                 success: function(response) { 
260                     if (response.error) { 
261                         alert(response.error); 
262                         return 0;
263                     }
264                 }
265             });
266             var new_list_item_id = this.existsItem(list_id,item);
267             return new_list_item_id;
268         }
269         else { return 0; }
270     },
272     addBulk: function(list_id, items) { 
273         
274         var elements = items.join("\t");
276         var count;
277         jQuery.ajax( { 
278             async: false,
279             method: 'POST',
280             url: '/list/add/bulk',
281             data:  { 'list_id': list_id, 'elements': elements },
282             success: function(response) { 
283                 if (response.error) { 
284                     alert(response.error);
285                 }
286                 else { 
287                     if (response.duplicates) { 
288                         alert("The following items are already in the list and were not added: "+response.duplicates.join(", "));
289                     }
290                     count = response.success;
291                 }               
292             }
293         });
294         return count;
295     },
296     
297     removeItem: function(list_id, item_id) {
298         jQuery.ajax( {
299             async: false,
300             url: '/list/item/remove',
301             data: { 'list_id': list_id, 'item_id': item_id }
302         });
303     },
304     
305     deleteList: function(list_id) { 
306         jQuery.ajax( { 
307             url: '/list/delete',
308             async: false,
309             data: { 'list_id': list_id }
310         });
311     },
313     renderLists: function(div) { 
314         var lists = this.availableLists();
315         var html = '';
316         html = html + '<div class="input-group"><input id="add_list_input" type="text" class="form-control" placeholder="Create New List" /><span class="input-group-btn"><button class="btn btn-primary" type="button" id="add_list_button" value="new list">New List</button></span></div><br/>';
317         
318         if (lists.length===0) { 
319             html = html + "None";
320             jQuery('#'+div+'_div').html(html);
321         }
323         html += '<table class="table table-hover table-condensed">';
324         html += '<thead><tr><th>&nbsp;</th><th>List Name</th><th>Count</th><th>Type</th><th colspan="4">Actions</th></tr></thead><tbody>'; 
325         for (var i = 0; i < lists.length; i++) { 
326             html += '<tr><td><input type="checkbox" name="list_select_checkbox" value="'+lists[i][0]+'"/></td>';
327             html += '<td><b>'+lists[i][1]+'</b></td>';
328             html += '<td>'+lists[i][3]+'</td>';
329             html += '<td>'+lists[i][5]+'</td>';
330             html += '<td><a title="View" id="view_list_'+lists[i][1]+'" href="javascript:showListItems(\'list_item_dialog\','+lists[i][0]+')"><span class="glyphicon glyphicon-th-list"></span></a></td>';
331             html += '<td><a title="Delete" id="delete_list_'+lists[i][1]+'" href="javascript:deleteList('+lists[i][0]+')"><span class="glyphicon glyphicon-remove"></span></a></td>';
332             html += '<td><a target="_blank" title="Download" id="download_list_'+lists[i][1]+'" href="/list/download?list_id='+lists[i][0]+'"><span class="glyphicon glyphicon-arrow-down"></span></a></td>';
333             if (lists[i][6] == 0){
334                 html += '<td><a title="Make Public" id="share_list_'+lists[i][1]+'" href="javascript:togglePublicList('+lists[i][0]+')"><span class="glyphicon glyphicon-share-alt"></span></a></td></tr>';
335             } else if (lists[i][6] == 1){
336                 html += '<td><a title="Make Private" id="share_list_'+lists[i][1]+'" href="javascript:togglePublicList('+lists[i][0]+')"><span class="glyphicon glyphicon-ban-circle"></span></a></td></tr>';
337             }
338         }
339         html = html + '</tbody></table>';
340         html += '<div id="list_group_select_action"></div>';
342         jQuery('#'+div+'_div').html(html);
344         jQuery('#add_list_button').click(function() { 
345             var lo = new CXGN.List();
346             
347             var name = jQuery('#add_list_input').val();
348             
349             lo.newList(name);
350             lo.renderLists(div);
351         });
353         jQuery('#view_public_lists_button').click(function() { 
354             jQuery('#public_list_dialog').modal('show');
355             var lo = new CXGN.List();
356             lo.renderPublicLists('public_list_dialog_div');
357         });
359         jQuery("input[name='list_select_checkbox']").click(function() {
360             var total=jQuery("input[name='list_select_checkbox']:checked").length;
361             var list_group_select_action_html='';
362             if (total == 0) {
363                 list_group_select_action_html += '';
364             } else {
365                 var selected = [];
366                 $("input:checkbox:checked").each(function() {
367                     selected.push($(this).attr('value'));
368                 });
370                 list_group_select_action_html = '<hr><div class="row well well-sm"><div class="col-sm-4">For Selected Lists:</div><div class="col-sm-8">';
371                 if (total == 1) {
372                     list_group_select_action_html += '<a class="btn btn-default btn-sm" style="color:white" href="javascript:deleteSelectedListGroup(['+selected+'])">Delete</a><a class="btn btn-default btn-sm" style="color:white" href="javascript:makePublicSelectedListGroup(['+selected+'])">Make Public</a><a class="btn btn-default btn-sm" style="color:white" href="javascript:makePrivateSelectedListGroup(['+selected+'])">Make Private</a>';      
373                 } else if (total > 1) {
374                     list_group_select_action_html += '<a class="btn btn-default btn-sm" style="color:white" href="javascript:deleteSelectedListGroup(['+selected+'])">Delete</a><a class="btn btn-default btn-sm" style="color:white" href="javascript:makePublicSelectedListGroup(['+selected+'])">Make Public</a><a class="btn btn-default btn-sm" style="color:white" href="javascript:makePrivateSelectedListGroup(['+selected+'])">Make Private</a><br/><br/><div class="input-group input-group-sm"><input type="text" class="form-control" id="new_combined_list_name" placeholder="New List Name"><span class="input-group-btn"><a class="btn btn-default btn-sm" style="color:white" href="javascript:combineSelectedListGroup(['+selected+'])">Combine</a></span></div>';
375                 }
376                 list_group_select_action_html += '</div></div>';
377             }
378             jQuery("#list_group_select_action").html(list_group_select_action_html);
379         });
380     },
382     renderPublicLists: function(div) {
383         var lists = this.publicLists();
384         var html = '';
386         html += '<table id="public_list_data_table" class="table table-hover table-condensed">';
387         html += '<thead><tr><th>List Name</th><th>Count</th><th>Type</th><th>Actions</th><th>&nbsp;</th><th>&nbsp;</th></tr></thead><tbody>'; 
388         for (var i = 0; i < lists.length; i++) { 
389             html += '<tr><td><b>'+lists[i][1]+'</b></td>';
390             html += '<td>'+lists[i][3]+'</td>';
391             html += '<td>'+lists[i][5]+'</td>';
392             html += '<td><a title="View" id="view_public_list_'+lists[i][1]+'" href="javascript:showPublicListItems(\'list_item_dialog\','+lists[i][0]+')"><span class="glyphicon glyphicon-th-list"></span></a></td>';
393             html += '<td><a target="_blank" title="Download" id="download_public_list_'+lists[i][1]+'" href="/list/download?list_id='+lists[i][0]+'"><span class="glyphicon glyphicon-arrow-down"></span></a></td>';
394             html += '<td><a title="Copy to Your Lists" id="copy_public_list_'+lists[i][1]+'" href="javascript:copyPublicList('+lists[i][0]+')"><span class="glyphicon glyphicon-plus"></span></a></td>';
395         }
396         html = html + '</tbody></table>';
398         jQuery('#'+div).html(html);
400         jQuery('#public_list_data_table').DataTable({
401             "destroy": true,
402             "columnDefs": [   { "orderable": false, "targets": [3,4,5] }  ]
403         });
404     },
405     
406     listNameById: function(list_id) { 
407         lists = this.availableLists();
408         for (var n=0; n<lists.length; n++) { 
409             if (lists[n][0] == list_id) { return lists[n][1]; }
410         }
411     },
413     publicListNameById: function(list_id) { 
414         lists = this.publicLists();
415         for (var n=0; n<lists.length; n++) { 
416             if (lists[n][0] == list_id) { return lists[n][1]; }
417         }
418     },
420     renderItems: function(div, list_id) { 
421         var list_data = this.getListData(list_id);
422         var items = list_data.elements;
423         var list_type = list_data.type_name;
424         var list_name = this.listNameById(list_id);
425         
426         var html = '';
427         html += '<table class="table"><tr><td>List ID</td><td id="list_id_div">'+list_id+'</td></tr>';
428         html += '<tr><td>List name:<br/><input type="button" class="btn btn-primary btn-xs" id="updateNameButton" value="Update" /></td>';
429         html += '<td><input class="form-control" type="text" id="updateNameField" size="10" value="'+list_name+'" /></td></tr>';
430         html += '<tr><td>Type:<br/><input id="list_item_dialog_validate" type="button" class="btn btn-primary btn-xs" value="Validate" onclick="javascript:validateList('+list_id+',\'type_select\')" /></td><td>'+this.typesHtmlSelect(list_id, 'type_select', list_type)+'</td></tr>';
431         html += '<tr><td>Add New Items:<br/><button class="btn btn-primary btn-xs" type="button" id="dialog_add_list_item_button" value="Add">Add</button></td><td><textarea id="dialog_add_list_item" type="text" class="form-control" placeholder="Add Item To List" /></textarea></td></tr></table>';
433         html += '<table id="list_item_dialog_datatable" class="table table-condensed table-hover table-bordered"><thead style="display: none;"><tr><th><b>List items</b> ('+items.length+')</th><th>&nbsp;</th></tr></thead><tbody>';
435         for(var n=0; n<items.length; n++) { 
436             html = html +'<tr><td>'+ items[n][1] + '</td><td><input id="'+items[n][0]+'" type="button" class="btn btn-default btn-xs" value="Remove" /></td></tr>';
437         }
438         html += '</tbody></table>';
439         
440         jQuery('#'+div+'_div').html(html);
442         jQuery('#list_item_dialog_datatable').DataTable({
443             destroy: true,
444             scrollY:        '30vh',
445             scrollCollapse: true,
446             paging:         false,
447         });
449         for (var n=0; n<items.length; n++) { 
450             var list_item_id = items[n][0];
452             jQuery('#'+items[n][0]).click(
453                 function() { 
454                     var lo = new CXGN.List();
455                     var i = lo.availableLists();
456                     
457                     lo.removeItem(list_id, this.id );
458                     lo.renderItems(div, list_id);
459                     lo.renderLists('list_dialog');
460                 });
461         }
462         
463         jQuery('#dialog_add_list_item_button').click(
464             function() { 
465                 jQuery('#working_modal').modal("show");
466                 addMultipleItemsToList('dialog_add_list_item', list_id);
467                 var lo = new CXGN.List();
468                 lo.renderItems(div, list_id);
469                 jQuery('#working_modal').modal("hide");
470             }
471         );
472         
473         jQuery('#updateNameButton').click(
474             function() { 
475                 var lo = new CXGN.List();
476                 var new_name =  jQuery('#updateNameField').val();
477                 var list_id = jQuery('#list_id_div').html();
478                 lo.updateName(list_id, new_name);
479                 alert("Changed name to "+new_name+" for list id "+list_id);
480             }
481         );
482     },
483     
484     renderPublicItems: function(div, list_id) { 
485         var list_data = this.getListData(list_id);
486         var items = list_data.elements;
487         var list_type = list_data.type_name;
488         var list_name = this.publicListNameById(list_id);
489         
490         var html = '';
491         html += '<table class="table"><tr><td>List ID</td><td id="list_id_div">'+list_id+'</td></tr>';
492         html += '<tr><td>List name:</td>';
493         html += '<td>'+list_name+'</td></tr>';
494         html += '<tr><td>Type:</td><td>'+list_type+'</td></tr>';
495         html += '</table>';
496         html += '<table id="public_list_item_dialog_datatable" class="table table-condensed table-hover table-bordered"><thead style="display: none;"><tr><th><b>List items</b> ('+items.length+')</th></tr></thead><tbody>';
497         for(var n=0; n<items.length; n++) { 
498             html = html +'<tr><td>'+ items[n][1] + '</td></tr>';
499         }
500         html += '</tbody></table>';
501         
502         jQuery('#'+div+'_div').html(html);
504         jQuery('#public_list_item_dialog_datatable').DataTable({
505             destroy: true,
506             scrollY:        '30vh',
507             scrollCollapse: true,
508             paging:         false,
509         });
510     },
512     existsList: function(name) { 
513         var list_id = 0;
514         jQuery.ajax( { 
515             url: '/list/exists',
516             async: false,
517             data: { 'name': name },
518             success: function(response) { 
519                 list_id = response.list_id;
520             }
521         });
522         return list_id;
523     },
525     existsItem: function(list_id, name) { 
526         var list_item_id =0;
527         jQuery.ajax( { 
528             url: '/list/exists_item',
529             async: false,
530             data: { 'list_id' : list_id, 'name':name },
531             success: function(response) { 
532                 list_item_id = response.list_item_id;
533             }
534         });
535         return list_item_id;
536     },
537     
538     addToList: function(list_id, text) { 
539         if (! text) { 
540             return;
541         }
542         var list = text.split("\n");
543         var duplicates = [];
544         
545         var info = this.addBulk(list_id, list);
546         
547         return info;
548         
549     },
551     /* listSelect: Creates an html select with lists of requested types.
553        Parameters: 
554          div_name: The div_name where the select should appear
555          types: a list of list types that should be listed in the menu
556          add_empty_element: text. if present, add an empty element with the
557            provided text as description
558     */
559     
560     listSelect: function(div_name, types, empty_element) {      
561         var lists = new Array();
563         if (types) {
564             for (var n=0; n<types.length; n++) { 
565                 var more = this.availableLists(types[n]);
566                 if (more) { 
567                     for (var i=0; i<more.length; i++) { 
568                         lists.push(more[i]);
569                     }
570                 }
571             }
572         }
573         else { 
574             lists = this.availableLists();
575         }
577         var html = '<select class="form-control input-sm" id="'+div_name+'_list_select" name="'+div_name+'_list_select" >';
578         if (empty_element) { 
579             html += '<option value="">'+empty_element+'</option>\n';
580         } 
581         for (var n=0; n<lists.length; n++) {
582             html += '<option value='+lists[n][0]+'>'+lists[n][1]+'</option>';
583         }
584         html = html + '</select>';
585         return html;
586     },
588     updateName: function(list_id, new_name) { 
589         jQuery.ajax( { 
590             url: '/list/name/update',
591             async: false,
592             data: { 'name' : new_name, 'list_id' : list_id },
593             success: function(response) { 
594                 if (response.error) { 
595                     alert(response.error);
596                     return;
597                 }
598                 else { 
599                     alert("The name of the list was changed to "+new_name);
600                 }
601             },
602             error: function(response) { alert("An error occurred."); }
603         });
604         this.renderLists('list_dialog');
605     },
607     validate: function(list_id, type, non_interactive) { 
608         var missing = new Array();
609         var error = 0;
610         jQuery.ajax( { 
611             url: '/list/validate/'+list_id+'/'+type,
612             async: false,
613             success: function(response) { 
614                 if (response.error) { 
615                     alert(response.error);
616                 }
617                 else { 
618                     missing = response.missing;
619                 }
620             },
621             error: function(response) { alert("An error occurred while validating the list "+list_id); error=1; }
622         });
624         if (error === 1 ) { return; }
626         if (missing.length==0) { 
627             if (!non_interactive) { alert("This list passed validation."); } 
628             return 1;
629         }
630         else { 
631             alert("List validation failed. Elements not found: "+ missing.join(","));
632             return 0;
633         }
634     },
636     transform: function(list_id, transform_name) { 
637         var transformed = new CXGN.List();
638         jQuery.ajax( { 
639             url: '/list/transform/'+list_id+'/'+transform_name,
640             async: false,
641             success: function(response) { 
642                 if (response.error) { 
643                     alert(response.error);
644                 }
645                 else { 
646                     transformed = response.transform;
647                 }
648             },
649             error: function(response) { alert("An error occurred while validating the list "+list_id); }
650         });
651     },
653     transform2Ids: function(list_id) { 
654         var list_type = this.getListType(list_id);
655         var new_type;
656         if (list_type == 'traits') { new_type = 'trait_ids'; }
657         if (list_type == 'locations') { new_type = 'location_ids'; }
658         if (list_type == 'trials') { new_type = 'project_ids'; }
659         if (list_type == 'projects') { new_type = 'project_ids'; }
660         if (list_type == 'plots') { new_type = 'plot_ids'; }
661         if (list_type == 'accessions') { new_type = 'accession_ids'; }
662         
663         if (! new_type) { 
664             return { 'error' : "cannot convert the list because of unknown type" };
665         }
667         var transformed = this.transform(list_id, new_type);
668         
669         return { 'transformed' : transformed };
670             
672     }
675 function setUpLists() {  
676     jQuery("button[name='lists_link']").click(
677         function() { show_lists(); }
678     );
682 function show_lists() {     
683     jQuery('#list_dialog').modal("show");
684     
685     var l = new CXGN.List();
686     l.renderLists('list_dialog');
689 /* deprecated */
690 function pasteListMenu (div_name, menu_div, button_name) { 
691     var lo = new CXGN.List();
693     var html='';
695     if (button_name === undefined) { 
696         button_name = 'paste';
697     }
699     html = lo.listSelect(div_name);
700     html = html + '<button class="btn btn-info btn-sm" type="button" value="'+button_name+'" onclick="javascript:pasteList(\''+div_name+'\')" >'+button_name+'</button>';
701     
702     jQuery('#'+menu_div).html(html);
705 function pasteList(div_name) { 
706     var lo = new CXGN.List();
707     var list_name = jQuery('#'+div_name+'_list_select').val();
708     var list_content = lo.getList(list_name);
709     
710     // textify list
711     var list_text = '';
712     for (var n=0; n<list_content.length; n++) { 
713         list_text = list_text + list_content[n][1]+"\r\n";
714     }
715     jQuery('#'+div_name).text(list_text);
719   addToListMenu
721   Parameters: 
722   * listMenuDiv - the name of the div where the menu will be displayed
723   * dataDiv - the div from which the data will be copied (can be a div, textarea, or html select
724   * options - optional hash with the following keys:
725     - selectText: if the dataDiv is an html select and selectText is true, the text and not the value will be copied into the list
726     - listType: the type of lists to display in the menu
727     - typesSourceDiv: obtain the type from this source div
732 function addToListMenu(listMenuDiv, dataDiv, options) { 
733     var lo = new CXGN.List();
735     var html;
736     var selectText;
737     var listType;
738     var typeSourceDiv; 
739     var type; 
741     if (options) { 
742         if (options.selectText) { 
743             selectText = options.selectText;
744         }
745         if (options.typeSourceDiv) { 
746             var sourcetype = getData(options.typeSourceDiv, selectText);
747             if (sourcetype) { 
748                 type = sourcetype.replace(/(\n|\r)+$/, '');
749             }
750         }
751         if (options.listType) { 
752             type = options.listType;
753         }
754     }
755     html = '<div class="row"><div class="col-sm-6" style="margin-right:0px; padding-right:0px;"><input class="form-control input-sm" type="text" id="'+dataDiv+'_new_list_name" placeholder="New list..." />';
756     html += '</div><div class="col-sm-6" style="margin-left:0px; padding-left:0px; margin-right:0px; padding-right:0px;"><input type="hidden" id="'+dataDiv+'_list_type" value="'+type+'" />';
757     html += '<input class="btn btn-primary btn-sm" id="'+dataDiv+'_add_to_new_list" type="button" value="add to new list" /></div></div><br />';
759     html += '<div class="row"><div class="col-sm-6" style="margin-right:0px; padding-right:0px;">'+lo.listSelect(dataDiv, [ type ]);
761     html += '</div><div class="col-sm-6" style="margin-left:0px; padding-left:0px; margin-right:0px; padding-right:0px;"><input class="btn btn-primary btn-sm" id="'+dataDiv+'_button" type="button" value="add to list" /></div></div>';
762    
763     jQuery('#'+listMenuDiv).html(html);
765     var list_id = 0;
767     jQuery('#'+dataDiv+'_add_to_new_list').click(
768         function() { 
769             var lo = new CXGN.List();
770             var new_name = jQuery('#'+dataDiv+'_new_list_name').val();
771             var type = jQuery('#'+dataDiv+'_list_type').val();
772                     
773             var data = getData(dataDiv, selectText);
774             
775             list_id = lo.newList(new_name);
776             if (list_id > 0) { 
777                 var elementsAdded = lo.addToList(list_id, data);
778                 if (type) { lo.setListType(list_id, type); }
779                 alert("Added "+elementsAdded+" list elements to list "+new_name+" and set type to "+type);
780             }
781         }
782     );
783         
784     jQuery('#'+dataDiv+'_button').click( 
785         function() { 
786             var data = getData(dataDiv, selectText);
787             list_id = jQuery('#'+dataDiv+'_list_select').val();
788             var lo = new CXGN.List();
789             var elementsAdded = lo.addToList(list_id, data);
791             alert("Added "+elementsAdded+" list elements");
792             return list_id;
793         }
794     );
795     
797    
800 function getData(id, selectText) { 
801     var divType = jQuery("#"+id).get(0).tagName;
802     var data; 
803     
804     if (divType == 'DIV' || divType =='SPAN' || divType === undefined) { 
805         data = jQuery('#'+id).html();
806     }
807     if (divType == 'SELECT' && selectText) {
808         if (jQuery.browser.msie) {
809             // Note: MS IE unfortunately removes all whitespace
810             // in the jQuery().text() call. Program it out...
811             //
812             var selectbox = document.getElementById(id);
813             var datalist = new Array();
814             for (var n=0; n<selectbox.length; n++) { 
815                 if (selectbox.options[n].selected) { 
816                     var x=selectbox.options[n].text;
817                     datalist.push(x);
818                 }
819             }
820             data = datalist.join("\n");
821             //alert("data:"+data);
822             
823         }
824         else { 
825             data = jQuery('#'+id+" option:selected").text();
826         }
828     }
829     if (divType == 'SELECT' && ! selectText) { 
830         var return_data = jQuery('#'+id).val();
832         if (return_data instanceof Array) { 
833             data = return_data.join("\n");
834         }
835         else { 
836             data = return_data;
837         }
838     }
839     if (divType == 'TEXTAREA') { 
840         data = jQuery('textarea#'+id).val();
841     }
842     return data;
844   
846 /* deprecated */         
847 function addTextToListMenu(div) { 
848     var lo = new CXGN.List();
849     var html = lo.listSelect(div);
850     html = html + '<input id="'+div+'_button" type="button" value="add to list" />';
851     
852     document.write(html);
853     
854     jQuery('#'+div+'_button').click( 
855         function() { 
856             var text = jQuery('textarea#div').val();
857             var list_id = jQuery('#'+div+'_list_select').val();
858             lo.addToList(list_id, text);
859             lo.renderLists('list_dialog');
860         }
861     );
864 /* deprecated */
865 function addSelectToListMenu(div) { 
866     var lo = new CXGN.List();
867     var html = lo.listSelect(div);
868     html = html + '<input id="'+div+'_button" type="button" value="add to list" />';
869     
870     document.write(html);
871     
872     jQuery('#'+div+'_button').click( 
873         function() { 
874             var selected_items = jQuery('#'+div).val();
875             var list_id = jQuery('#'+div+'_list_select').val();
876             addArrayToList(selected_items, list_id);
877             lo.renderLists('list_dialog');
878         }
879     );
883 /* deprecated */
884 // add the text in a div to a list
885 function addDivToList(div_name) { 
886     var list_id = jQuery('#'+div_name+'_list_select').val();
887     var lo = new CXGN.List();
888     var list = jQuery('#'+div_name).val();
889     var items = list.split("\n");
891     for(var n=0; n<items.length; n++) { 
892         var added = lo.addItem(list_id, items[n]);
893         if (added > 0) { }
894     }
897 /* deprecated */
898 function addTextToList(div, list_id) { 
899     var lo = new CXGN.List();
900     var item = jQuery('#'+div).val();
901     var id = lo.addItem(list_id, item);
902     if (id == 0) { 
903         alert('Item "'+item+'" was not added because it already exists');
904     }
905     lo.renderLists('list_dialog');
908 /* deprecated */
909 function addMultipleItemsToList(div, list_id) { 
910     var lo = new CXGN.List();
911     var content = jQuery('#'+div).val();
912     if (content == '') { 
913         alert("No items - Please enter items to add to the list.");
914 return;
915     }
916 //    var items = content.split("\n");
917     
918   //  var duplicates = new Array();
919     var items = content.split("\n");
920     lo.addBulk(list_id, items);
921    // for (var n=0; n<items.length; n++) { 
922 //      var id = lo.addItem(list_id, items[n]);
923 //      if (id == 0) { 
924 //          duplicates.push(items[n]);
925 //      }
926   //  }
927     //if (duplicates.length >0) { 
928 //      alert("The following items were not added because they are already in the list: "+ duplicates.join(", "));
929   //  }
930 lo.renderLists('list_dialog');
933 /* deprecated */
934 function addArrayToList(items, list_id) { 
935 var lo = new CXGN.List();
936    var duplicates = new Array();
937     for (var n=0; n<items.length; n++) { 
938         var id = lo.addItem(list_id, items[n]);
939         if (id == 0) { 
940             duplicates.push(items[n]);
941         }
942     }
943     if (duplicates.length >0) { 
944         alert("The following items were not added because they are already in the list: "+ duplicates.join(", "));
945     }
948 function deleteList(list_id) { 
949     var lo = new CXGN.List();
950     var list_name = lo.listNameById(list_id);
951     if (confirm('Delete list "'+list_name+'"? (ID='+list_id+'). This cannot be undone.')) { 
952         lo.deleteList(list_id);
953         lo.renderLists('list_dialog');
954         alert('Deleted list '+list_name);
955     }
958 function togglePublicList(list_id) { 
959     $.ajax({
960         "url": "/list/public/toggle",
961         "type": "POST",
962         "data": {'list_id': list_id},
963         success: function(r) {
964             var lo = new CXGN.List();
965             if (r.error) {
966                 alert(r.error);
967             } else if (r.r == 1) {
968                 alert("List set to Private");
969             } else if (r.r == 0) {
970                 alert("List set to Public");
971             }
972             lo.renderLists('list_dialog');
973         },
974         error: function() {
975             alert("Error Setting List to Public! List May Not Exist.");
976         }
977     });
978     var lo = new CXGN.List();
979     lo.renderLists('list_dialog');
982 function makePublicList(list_id) { 
983     $.ajax({
984         "url": "/list/public/true",
985         "type": "POST",
986         "data": {'list_id': list_id},
987         success: function(r) {
988             var lo = new CXGN.List();
989             if (r.error) {
990                 alert(r.error);
991             }
992         },
993         error: function() {
994             alert("Error Setting List to Public! List May Not Exist.");
995         }
996     });
999 function makePrivateList(list_id) { 
1000     $.ajax({
1001         "url": "/list/public/false",
1002         "type": "POST",
1003         "data": {'list_id': list_id},
1004         success: function(r) {
1005             var lo = new CXGN.List();
1006             if (r.error) {
1007                 alert(r.error);
1008             }
1009         },
1010         error: function() {
1011             alert("Error Setting List to Private! List May Not Exist.");
1012         }
1013     });
1016 function copyPublicList(list_id) { 
1017     $.ajax({
1018         "url": "/list/public/copy",
1019         "type": "POST",
1020         "data": {'list_id': list_id},
1021         success: function(r) {
1022             if (r.error) {
1023                 alert(r.error);
1024             } else if (r.success == 'true') {
1025                 alert("Public List Copied to Your Lists.");
1026             }
1027         },
1028         error: function() {
1029             alert("Error Copying Public List! List May Not Exist.");
1030         }
1031     });
1032     var lo = new CXGN.List();
1033     lo.renderLists('list_dialog');
1035         
1036 function deleteItemLink(list_item_id) { 
1037     var lo = new CXGN.List();
1038     lo.deleteItem(list_item_id);
1039     lo.renderLists('list_dialog');
1041         
1042 function showListItems(div, list_id) { 
1043     var l = new CXGN.List();
1044     jQuery('#'+div).modal("show");
1045     l.renderItems(div, list_id);
1048 function showPublicListItems(div, list_id) { 
1049     var l = new CXGN.List();
1050     jQuery('#'+div).modal("show");
1051     l.renderPublicItems(div, list_id);
1054 function addNewList(div_id) { 
1055     var lo = new CXGN.List();
1056     var name = jQuery('#'+div_id).val();
1057     
1058     if (name == '') { 
1059         alert("Please specify a name for the list.");
1060         return;
1061     }
1062     
1063     var list_id = lo.existsList(name);
1064     if (list_id > 0) {
1065         alert('The list '+name+' already exists. Please choose another name.');
1066         return;
1067     }
1068     lo.newList(name);
1069     lo.renderLists('list_item_dialog');
1072 function changeListType(html_select_id, list_id) { 
1073     var type = jQuery('#'+html_select_id).val();
1074     var l = new CXGN.List();
1075     l.setListType(list_id, type);
1076     l.renderLists('list_dialog');
1079 /* 
1080    validateList - check if all the elements in a list are of the correct type
1082    Parameters: 
1083    * list_id: the id of the list
1084    * html_select_id: the id of the html select containing the type list
1085    
1088 function validateList(list_id, html_select_id) { 
1089     var lo = new CXGN.List();
1090     var type = jQuery('#'+html_select_id).val();
1091     lo.validate(list_id, type);
1094 function deleteSelectedListGroup(list_ids) {
1095     var arrayLength = list_ids.length;
1096     if (confirm('Delete the selected lists? This cannot be undone.')) {
1097         for (var i=0; i<arrayLength; i++) {
1098             var lo = new CXGN.List();
1099             lo.deleteList(list_ids[i]);
1100         }
1101         lo.renderLists('list_dialog');
1102     }
1105 function makePublicSelectedListGroup(list_ids) {
1106     var arrayLength = list_ids.length;
1107     if (confirm('Make selected lists public?')) {
1108         for (var i=0; i<arrayLength; i++) {
1109             makePublicList(list_ids[i]);
1110         }
1111         var lo = new CXGN.List();
1112         lo.renderLists('list_dialog');
1113     }
1116 function makePrivateSelectedListGroup(list_ids) {
1117     var arrayLength = list_ids.length;
1118     if (confirm('Make selected lists private?')) {
1119         for (var i=0; i<arrayLength; i++) {
1120             makePrivateList(list_ids[i]);
1121         }
1122         var lo = new CXGN.List();
1123         lo.renderLists('list_dialog');
1124     }
1127 function combineSelectedListGroup(list_ids) {
1128     var arrayLength = list_ids.length;
1129         var list_name = jQuery('#new_combined_list_name').val();
1130     if (confirm('Combine selected lists into a new list called '+list_name+'?')) {
1131                 var lo = new CXGN.List();
1132                 var new_list_id = lo.newList(list_name);
1133                 for (var i=0; i<arrayLength; i++) {
1134                         list = lo.getListData(list_ids[i]);
1135                         var numElements = list.elements.length;
1136                         var arrayItems = [];
1137                         for (var j=0; j<numElements; j++) {
1138                                 arrayItems.push(list.elements[j][1]);
1139                         }
1140                         lo.addBulk(new_list_id, arrayItems);
1141                 }
1142         lo.renderLists('list_dialog');
1143     }