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;
122 alert('An error occurred. Cannot determine type. ');
129 setListType: function(list_id, type) {
132 url: '/list/type/'+list_id+'/'+type,
134 success: function(response) {
135 if (response.error) {
136 alert(response.error);
139 //alert('Type of list '+list_id+' set to '+type);
146 allListTypes: function() {
149 url: '/list/alltypes',
151 success: function(response) {
152 if (response.error) {
153 alert(response.error);
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" ';
173 html += '<option name="'+types[i][1]+'"'+selected_html+'>'+types[i][1]+'</option>';
179 newList: function(name) {
180 var oldListId = this.existsList(name);
184 alert('Please provide a name for the new list.');
188 if (oldListId === null) {
192 data: { 'name': name },
193 success: function(response) {
194 if (response.error) {
195 alert(response.error);
198 newListId=response.list_id;
205 alert('A list with name "'+ name + '" already exists. Please choose another list name.');
208 alert("An error occurred. Cannot create new list right now.");
212 availableLists: function(list_type) {
215 url: '/list/available',
216 data: { 'type': list_type },
218 success: function(response) {
219 if (response.error) {
220 //alert(response.error); //do not alert here
224 error: function(response) {
225 alert("An error occurred");
231 publicLists: function(list_type) {
234 url: '/list/available_public',
235 data: { 'type': list_type },
237 success: function(response) {
238 if (response.error) {
239 alert(response.error);
243 error: function(response) {
244 alert("An error occurred");
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 ) {
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);
266 var new_list_item_id = this.existsItem(list_id,item);
267 return new_list_item_id;
272 addBulk: function(list_id, items) {
273 var elements = items.join("\t");
279 url: '/list/add/bulk',
280 data: { 'list_id': list_id, 'elements': elements },
281 success: function(response) {
282 if (response.error) {
283 alert(response.error);
286 if (response.duplicates) {
287 alert("The following items are already in the list and were not added: "+response.duplicates.join(", "));
289 count = response.success;
292 error: function(response) {
293 alert("ERROR: "+response);
299 removeItem: function(list_id, item_id) {
302 url: '/list/item/remove',
303 data: { 'list_id': list_id, 'item_id': item_id }
307 updateItem: function(list_id, item_id, content) {
310 url: '/list/item/update',
311 data: { 'list_id': list_id, 'item_id': item_id, 'content':content }
315 deleteList: function(list_id) {
319 data: { 'list_id': list_id }
323 renderLists: function(div) {
324 var lists = this.availableLists();
326 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/>';
328 if (lists.length===0) {
329 html = html + "None";
330 jQuery('#'+div+'_div').html(html);
333 html += '<table class="table table-hover table-condensed">';
334 html += '<thead><tr><th> </th><th>List Name</th><th>Count</th><th>Type</th><th colspan="4">Actions</th></tr></thead><tbody>';
335 for (var i = 0; i < lists.length; i++) {
336 html += '<tr><td><input type="checkbox" id="list_select_checkbox_'+lists[i][0]+'" name="list_select_checkbox" value="'+lists[i][0]+'"/></td>';
337 html += '<td><b>'+lists[i][1]+'</b></td>';
338 html += '<td>'+lists[i][3]+'</td>';
339 html += '<td>'+lists[i][5]+'</td>';
340 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>';
341 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>';
342 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>';
343 if (lists[i][6] == 0){
344 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>';
345 } else if (lists[i][6] == 1){
346 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>';
349 html = html + '</tbody></table>';
350 html += '<div id="list_group_select_action"></div>';
352 jQuery('#'+div+'_div').html(html);
354 jQuery('#add_list_button').click(function() {
355 var lo = new CXGN.List();
357 var name = jQuery('#add_list_input').val();
363 jQuery('#view_public_lists_button').click(function() {
364 jQuery('#public_list_dialog').modal('show');
365 var lo = new CXGN.List();
366 lo.renderPublicLists('public_list_dialog_div');
369 jQuery("input[name='list_select_checkbox']").click(function() {
370 var total=jQuery("input[name='list_select_checkbox']:checked").length;
371 var list_group_select_action_html='';
373 list_group_select_action_html += '';
376 jQuery("input:checkbox:checked").each(function() {
377 selected.push(jQuery(this).attr('value'));
380 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">';
382 list_group_select_action_html += '<a id="delete_selected_list_group" class="btn btn-primary btn-sm" style="color:white" href="javascript:deleteSelectedListGroup(['+selected+'])">Delete</a> <a id="make_public_selected_list_group" class="btn btn-primary btn-sm" style="color:white" href="javascript:makePublicSelectedListGroup(['+selected+'])">Make Public</a> <a id="make_private_selected_list_group" class="btn btn-primary btn-sm" style="color:white" href="javascript:makePrivateSelectedListGroup(['+selected+'])">Make Private</a>';
383 } else if (total > 1) {
384 list_group_select_action_html += '<a id="delete_selected_list_group" class="btn btn-primary btn-sm" style="color:white" href="javascript:deleteSelectedListGroup(['+selected+'])">Delete</a> <a id="make_public_selected_list_group" class="btn btn-primary btn-sm" style="color:white" href="javascript:makePublicSelectedListGroup(['+selected+'])">Make Public</a> <a id="make_private_selected_list_group" class="btn btn-primary 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 id="combine_selected_list_group" class="btn btn-primary btn-sm" style="color:white" href="javascript:combineSelectedListGroup(['+selected+'])">Combine</a></span></div>';
386 list_group_select_action_html += '</div></div>';
388 jQuery("#list_group_select_action").html(list_group_select_action_html);
392 renderPublicLists: function(div) {
393 var lists = this.publicLists();
396 html += '<table id="public_list_data_table" class="table table-hover table-condensed">';
397 html += '<thead><tr><th>List Name</th><th>Count</th><th>Type</th><th>Actions</th><th> </th><th> </th></tr></thead><tbody>';
398 for (var i = 0; i < lists.length; i++) {
399 html += '<tr><td><b>'+lists[i][1]+'</b></td>';
400 html += '<td>'+lists[i][3]+'</td>';
401 html += '<td>'+lists[i][5]+'</td>';
402 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>';
403 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>';
404 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>';
406 html = html + '</tbody></table>';
408 jQuery('#'+div).html(html);
410 jQuery('#public_list_data_table').DataTable({
412 "columnDefs": [ { "orderable": false, "targets": [3,4,5] } ]
416 listNameById: function(list_id) {
417 lists = this.availableLists();
418 for (var n=0; n<lists.length; n++) {
419 if (lists[n][0] == list_id) { return lists[n][1]; }
423 publicListNameById: function(list_id) {
424 lists = this.publicLists();
425 for (var n=0; n<lists.length; n++) {
426 if (lists[n][0] == list_id) { return lists[n][1]; }
430 renderItems: function(div, list_id) {
432 var list_data = this.getListData(list_id);
433 var items = list_data.elements;
434 var list_type = list_data.type_name;
435 var list_name = this.listNameById(list_id);
438 html += '<table class="table"><tr><td>List ID</td><td id="list_id_div">'+list_id+'</td></tr>';
439 html += '<tr><td>List name:<br/><input type="button" class="btn btn-primary btn-xs" id="updateNameButton" value="Update" /></td>';
440 html += '<td><input class="form-control" type="text" id="updateNameField" size="10" value="'+list_name+'" /></td></tr>';
441 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>';
442 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>';
444 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> </th></tr></thead><tbody>';
446 for(var n=0; n<items.length; n++) {
447 html = html +'<tr><td id="list_item_toggle_edit_div_'+items[n][0]+'" ><div name="list_item_toggle_edit" data-listitemdiv="list_item_toggle_edit_div_'+items[n][0]+'" data-listitemid="'+items[n][0]+'" data-listitemname="'+items[n][1]+'" >'+ items[n][1] + '</div></td><td><input id="'+items[n][0]+'" type="button" class="btn btn-default btn-xs" value="Remove" /></td></tr>';
449 html += '</tbody></table>';
451 jQuery('#'+div+'_div').html(html);
453 jQuery('#list_item_dialog_datatable').DataTable({
456 scrollCollapse: true,
460 for (var n=0; n<items.length; n++) {
461 var list_item_id = items[n][0];
463 jQuery('#'+items[n][0]).click(
465 var lo = new CXGN.List();
466 var i = lo.availableLists();
468 lo.removeItem(list_id, this.id );
469 lo.renderItems(div, list_id);
470 lo.renderLists('list_dialog');
474 jQuery('#dialog_add_list_item_button').click(
476 addMultipleItemsToList('dialog_add_list_item', list_id);
477 var lo = new CXGN.List();
478 lo.renderItems(div, list_id);
482 jQuery('#updateNameButton').click(
484 var lo = new CXGN.List();
485 var new_name = jQuery('#updateNameField').val();
486 var list_id = jQuery('#list_id_div').html();
487 lo.updateName(list_id, new_name);
488 alert("Changed name to "+new_name+" for list id "+list_id);
492 jQuery('div[name="list_item_toggle_edit"]').click(function() {
493 var list_item_id = jQuery(this).data('listitemid');
494 var list_item_name = jQuery(this).data('listitemname');
495 var list_item_div = jQuery(this).data('listitemdiv');
496 var list_item_edit_html = '<div class="input-group"><input type="text" class="form-control" value="'+list_item_name+'" placeholder="'+list_item_name+'" id="list_item_edit_input_'+list_item_id+'" data-listitemid="'+list_item_id+'" /><span class="input-group-btn"><button class="btn btn-default" type="button" name="list_item_edit_submit" data-inputid="list_item_edit_input_'+list_item_id+'">Ok</button></span></div>';
497 jQuery("#"+list_item_div).empty().html(list_item_edit_html);
500 jQuery(document).on('click', 'button[name="list_item_edit_submit"]', function() {
501 var lo = new CXGN.List();
502 var list_id = jQuery('#list_id_div').html();
503 var input_id = jQuery(this).data('inputid');
504 lo.updateItem(list_id, jQuery("#"+input_id).data('listitemid'), jQuery("#"+input_id).val());
505 lo.renderItems(div, list_id);
509 renderPublicItems: function(div, list_id) {
510 var list_data = this.getListData(list_id);
511 var items = list_data.elements;
512 var list_type = list_data.type_name;
513 var list_name = this.publicListNameById(list_id);
516 html += '<table class="table"><tr><td>List ID</td><td id="list_id_div">'+list_id+'</td></tr>';
517 html += '<tr><td>List name:</td>';
518 html += '<td>'+list_name+'</td></tr>';
519 html += '<tr><td>Type:</td><td>'+list_type+'</td></tr>';
521 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>';
522 for(var n=0; n<items.length; n++) {
523 html = html +'<tr><td>'+ items[n][1] + '</td></tr>';
525 html += '</tbody></table>';
527 jQuery('#'+div+'_div').html(html);
529 jQuery('#public_list_item_dialog_datatable').DataTable({
532 scrollCollapse: true,
537 existsList: function(name) {
542 data: { 'name': name },
543 success: function(response) {
544 list_id = response.list_id;
550 existsItem: function(list_id, name) {
553 url: '/list/exists_item',
555 data: { 'list_id' : list_id, 'name':name },
556 success: function(response) {
557 list_item_id = response.list_item_id;
563 addToList: function(list_id, text) {
567 var list = text.split("\n");
570 var info = this.addBulk(list_id, list);
576 addCrossProgenyToList: function(list_id, text) {
580 var list = text.split("\n");
581 list = list.filter(function(n){ return n != '' });
585 url: '/list/add_cross_progeny',
587 data: { 'list_id':list_id, 'cross_id_list' : JSON.stringify(list) },
588 success: function(response) {
589 console.log(response);
590 addeditems = response.success.count;
593 //var info = this.addBulk(list_id, list);
598 /* listSelect: Creates an html select with lists of requested types.
601 div_name: The div_name where the select should appear
602 types: a list of list types that should be listed in the menu
603 add_empty_element: text. if present, add an empty element with the
604 provided text as description
607 listSelect: function(div_name, types, empty_element, refresh) {
608 var lists = new Array();
611 for (var n=0; n<types.length; n++) {
612 var more = this.availableLists(types[n]);
614 for (var i=0; i<more.length; i++) {
621 lists = this.availableLists();
624 var html = '<select class="form-control input-sm" id="'+div_name+'_list_select" name="'+div_name+'_list_select" >';
626 html += '<option value="">'+empty_element+'</option>\n';
628 for (var n=0; n<lists.length; n++) {
629 html += '<option value='+lists[n][0]+'>'+lists[n][1]+'</option>';
632 if (types.length > 1) { types = types.join(',') };
633 html = '<div class="input-group">'+html+'</select><span class="input-group-btn"><button class="btn btn-default" type="button" id="'+div_name+'_list_refresh" title="Refresh lists" onclick="refreshListSelect(\''+div_name+'_list_select\',\''+types+'\',\'Options refreshed.\')"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span></button></span></div>';
637 html = html + '</select>';
642 updateName: function(list_id, new_name) {
644 url: '/list/name/update',
646 data: { 'name' : new_name, 'list_id' : list_id },
647 success: function(response) {
648 if (response.error) {
649 alert(response.error);
653 alert("The name of the list was changed to "+new_name);
656 error: function(response) { alert("An error occurred."); }
658 this.renderLists('list_dialog');
661 validate: function(list_id, type, non_interactive) {
662 var missing = new Array();
665 url: '/list/validate/'+list_id+'/'+type,
667 success: function(response) {
668 //console.log(response);
669 if (response.error) {
670 alert(response.error);
672 missing = response.missing;
675 error: function(response) {
676 alert("An error occurred while validating the list "+list_id);
681 if (error === 1 ) { return; }
683 if (missing.length==0) {
684 if (!non_interactive) { alert("This list passed validation."); }
688 if (type == 'accessions') {
689 jQuery("#validate_accession_error_display tbody").html('');
691 var missing_accessions_html = "<div class='well well-sm'><h3>Add the missing accessions to a list</h3><div id='validate_stock_missing_accessions' style='display:none'></div><div id='validate_stock_add_missing_accessions'></div><hr><h4>Go to <a href='/breeders/accessions'>Manage Accessions</a> to add these new accessions.</h4></div><br/>";
694 jQuery("#validate_stock_add_missing_accessions_html").html(missing_accessions_html);
696 var missing_accessions_vals = '';
697 for(var i=0; i<missing.length; i++) {
698 missing_accessions_vals = missing_accessions_vals + missing[i] + '\n';
701 jQuery("#validate_stock_missing_accessions").html(missing_accessions_vals);
702 addToListMenu('validate_stock_add_missing_accessions', 'validate_stock_missing_accessions', {
704 listType: 'accessions'
707 jQuery("#validate_accession_error_display tbody").append(missing.join(","));
708 jQuery('#validate_accession_error_display').modal("show");
710 //alert("List validation failed. Elements not found: "+ missing.join(","));
713 alert('List did not pass validation because of these items: '+missing.join(", "));
719 transform: function(list_id, transform_name) {
720 var transformed = new CXGN.List();
721 var ajaxResponse = [];
723 url: '/list/transform/'+list_id+'/'+transform_name,
725 success: function(response) {
726 if (response.error) {
727 alert(response.error);
730 ajaxResponse = response;
731 //console.log("transformed="+ajaxResponse);
734 error: function(response) { alert("An error occurred while validating the list "+list_id); }
736 return ajaxResponse.transform;
739 transform2Ids: function(list_id, data) {
740 if (data === undefined) var data = this.getListData(list_id);
741 //console.log("data ="+JSON.stringify(data));
742 var list_type = data.type_name;
748 new_type = 'traits_2_trait_ids';
751 new_type = 'locations_2_location_ids';
754 case "breeding_programs":
755 new_type = 'projects_2_project_ids';
758 new_type = 'accessions_2_accession_ids';
761 new_type = 'plots_2_plot_ids';
764 return { 'error' : "cannot convert the list because of unknown type" };
766 //if (window.console) console.log("new type = "+new_type);
767 var transformed = this.transform(list_id, new_type);
768 //if (window.console) console.log("transformed="+JSON.stringify(transformed));
774 function setUpLists() {
775 jQuery("button[name='lists_link']").click(
776 function() { show_lists(); }
781 function show_lists() {
782 jQuery('#list_dialog').modal("show");
784 var l = new CXGN.List();
785 l.renderLists('list_dialog');
789 function pasteListMenu (div_name, menu_div, button_name) {
790 var lo = new CXGN.List();
794 if (button_name === undefined) {
795 button_name = 'paste';
798 html = lo.listSelect(div_name);
799 html = html + '<button class="btn btn-info btn-sm" type="button" value="'+button_name+'" onclick="javascript:pasteList(\''+div_name+'\')" >'+button_name+'</button>';
801 jQuery('#'+menu_div).html(html);
804 function pasteList(div_name) {
805 var lo = new CXGN.List();
806 var list_id = jQuery('#'+div_name+'_list_select').val();
807 console.log(list_id);
808 var list = lo.getList(list_id);
812 for (var n=0; n<list.length; n++) {
813 list_text = list_text + list[n]+"\r\n";
815 console.log(list_text);
816 jQuery('#'+div_name).val(list_text);
819 /* refreshListSelect: refreshes an html select with lists of requested types.
822 div_name: The div_name where the select should appear
823 types: a list of list types that should be listed in the menu
824 add_empty_element: text. if present, add an empty element with the
825 provided text as description
828 function refreshListSelect(div_name, types, empty_element) {
829 var lo = new CXGN.List();
830 var lists = new Array();
831 var types = types.split(",");
832 //console.log("types = "+types);
833 if (types.length > 0) {
834 for (var n=0; n<types.length; n++) {
835 //console.log("retrieving lists of type: "+types[n]+"\n");
836 var more = lo.availableLists(types[n]);
838 for (var i=0; i<more.length; i++) {
845 lists = lo.availableLists();
850 html += '<option value="">'+empty_element+'</option>\n';
852 for (var n=0; n<lists.length; n++) {
853 html += '<option value='+lists[n][0]+'>'+lists[n][1]+'</option>';
855 jQuery('#'+div_name).html(html);
863 * listMenuDiv - the name of the div where the menu will be displayed
864 * dataDiv - the div from which the data will be copied (can be a div, textarea, or html select
865 * options - optional hash with the following keys:
866 - selectText: if the dataDiv is an html select and selectText is true, the text and not the value will be copied into the list
867 - listType: the type of lists to display in the menu
868 - typesSourceDiv: obtain the type from this source div
873 function addToListMenu(listMenuDiv, dataDiv, options) {
874 var lo = new CXGN.List();
884 if (options.selectText) {
885 selectText = options.selectText;
887 if (options.typeSourceDiv) {
888 var sourcetype = getData(options.typeSourceDiv, selectText);
890 type = sourcetype.replace(/(\n|\r)+$/, '');
893 if (options.listType) {
894 type = options.listType;
896 if (options.additionType) {
897 addition_type = options.additionType;
901 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..." />';
902 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+'_addition_type" value="'+addition_type+'" /><input type="hidden" id="'+dataDiv+'_list_type" value="'+type+'" />';
903 html += '<input class="btn btn-primary btn-sm" id="'+dataDiv+'_add_to_new_list" type="button" value="add to new list" /></div></div><br />';
905 html += '<div class="row"><div class="col-sm-6" style="margin-right:0px; padding-right:0px;">'+lo.listSelect(dataDiv, [ type ]);
907 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>';
909 jQuery('#'+listMenuDiv).html(html);
913 jQuery('#'+dataDiv+'_add_to_new_list').click( function() {
914 var lo = new CXGN.List();
915 var new_name = jQuery('#'+dataDiv+'_new_list_name').val();
916 var type = jQuery('#'+dataDiv+'_list_type').val();
917 var addition_type = jQuery('#'+dataDiv+'_addition_type').val();
919 var data = getData(dataDiv, selectText);
920 list_id = lo.newList(new_name);
923 if (addition_type == 'cross_progeny') {
924 elementsAdded = lo.addCrossProgenyToList(list_id, data);
926 elementsAdded = lo.addToList(list_id, data);
929 lo.setListType(list_id, type);
931 alert("Added "+elementsAdded+" list elements to list "+new_name+" and set type to "+type);
935 jQuery('#'+dataDiv+'_button').click(
937 var data = getData(dataDiv, selectText);
938 list_id = jQuery('#'+dataDiv+'_list_select').val();
939 var lo = new CXGN.List();
940 var elementsAdded = lo.addToList(list_id, data);
942 alert("Added "+elementsAdded+" list elements");
951 function getData(id, selectText) {
952 var divType = jQuery("#"+id).get(0).tagName;
955 if (divType == 'DIV' || divType =='SPAN' || divType === undefined) {
956 data = jQuery('#'+id).html();
958 if (divType == 'SELECT' && selectText) {
959 if (jQuery.browser.msie) {
960 // Note: MS IE unfortunately removes all whitespace
961 // in the jQuery().text() call. Program it out...
963 var selectbox = document.getElementById(id);
964 var datalist = new Array();
965 for (var n=0; n<selectbox.length; n++) {
966 if (selectbox.options[n].selected) {
967 var x=selectbox.options[n].text;
971 data = datalist.join("\n");
972 //alert("data:"+data);
976 data = jQuery('#'+id+" option:selected").text();
980 if (divType == 'SELECT' && ! selectText) {
981 var return_data = jQuery('#'+id).val();
983 if (return_data instanceof Array) {
984 data = return_data.join("\n");
990 if (divType == 'TEXTAREA') {
991 data = jQuery('textarea#'+id).val();
998 function addTextToListMenu(div) {
999 var lo = new CXGN.List();
1000 var html = lo.listSelect(div);
1001 html = html + '<input id="'+div+'_button" type="button" value="add to list" />';
1003 document.write(html);
1005 jQuery('#'+div+'_button').click(
1007 var text = jQuery('textarea#div').val();
1008 var list_id = jQuery('#'+div+'_list_select').val();
1009 lo.addToList(list_id, text);
1010 lo.renderLists('list_dialog');
1016 function addSelectToListMenu(div) {
1017 var lo = new CXGN.List();
1018 var html = lo.listSelect(div);
1019 html = html + '<input id="'+div+'_button" type="button" value="add to list" />';
1021 document.write(html);
1023 jQuery('#'+div+'_button').click(
1025 var selected_items = jQuery('#'+div).val();
1026 var list_id = jQuery('#'+div+'_list_select').val();
1027 addArrayToList(selected_items, list_id);
1028 lo.renderLists('list_dialog');
1035 // add the text in a div to a list
1036 function addDivToList(div_name) {
1037 var list_id = jQuery('#'+div_name+'_list_select').val();
1038 var lo = new CXGN.List();
1039 var list = jQuery('#'+div_name).val();
1040 var items = list.split("\n");
1042 for(var n=0; n<items.length; n++) {
1043 var added = lo.addItem(list_id, items[n]);
1049 function addTextToList(div, list_id) {
1050 var lo = new CXGN.List();
1051 var item = jQuery('#'+div).val();
1052 var id = lo.addItem(list_id, item);
1054 alert('Item "'+item+'" was not added because it already exists');
1056 lo.renderLists('list_dialog');
1060 function addMultipleItemsToList(div, list_id) {
1061 var lo = new CXGN.List();
1062 var content = jQuery('#'+div).val();
1063 if (content == '') {
1064 alert("No items - Please enter items to add to the list.");
1067 // var items = content.split("\n");
1069 // var duplicates = new Array();
1070 var items = content.split("\n");
1071 lo.addBulk(list_id, items);
1072 // for (var n=0; n<items.length; n++) {
1073 // var id = lo.addItem(list_id, items[n]);
1075 // duplicates.push(items[n]);
1078 //if (duplicates.length >0) {
1079 // alert("The following items were not added because they are already in the list: "+ duplicates.join(", "));
1081 //lo.renderLists('list_dialog');
1085 function addArrayToList(items, list_id) {
1086 var lo = new CXGN.List();
1087 var duplicates = new Array();
1088 for (var n=0; n<items.length; n++) {
1089 var id = lo.addItem(list_id, items[n]);
1091 duplicates.push(items[n]);
1094 if (duplicates.length >0) {
1095 alert("The following items were not added because they are already in the list: "+ duplicates.join(", "));
1099 function deleteList(list_id) {
1100 var lo = new CXGN.List();
1101 var list_name = lo.listNameById(list_id);
1102 if (confirm('Delete list "'+list_name+'"? (ID='+list_id+'). This cannot be undone.')) {
1103 lo.deleteList(list_id);
1104 lo.renderLists('list_dialog');
1105 alert('Deleted list '+list_name);
1109 function togglePublicList(list_id) {
1111 "url": "/list/public/toggle",
1113 "data": {'list_id': list_id},
1114 success: function(r) {
1115 var lo = new CXGN.List();
1118 } else if (r.r == 1) {
1119 alert("List set to Private");
1120 } else if (r.r == 0) {
1121 alert("List set to Public");
1123 lo.renderLists('list_dialog');
1126 alert("Error Setting List to Public! List May Not Exist.");
1129 var lo = new CXGN.List();
1130 lo.renderLists('list_dialog');
1133 function makePublicList(list_id) {
1135 "url": "/list/public/true",
1137 "data": {'list_id': list_id},
1138 success: function(r) {
1139 var lo = new CXGN.List();
1145 alert("Error Setting List to Public! List May Not Exist.");
1150 function makePrivateList(list_id) {
1152 "url": "/list/public/false",
1154 "data": {'list_id': list_id},
1155 success: function(r) {
1156 var lo = new CXGN.List();
1162 alert("Error Setting List to Private! List May Not Exist.");
1167 function copyPublicList(list_id) {
1169 "url": "/list/public/copy",
1171 "data": {'list_id': list_id},
1172 success: function(r) {
1175 } else if (r.success == 'true') {
1176 alert("Public List Copied to Your Lists.");
1180 alert("Error Copying Public List! List May Not Exist.");
1183 var lo = new CXGN.List();
1184 lo.renderLists('list_dialog');
1187 function deleteItemLink(list_item_id) {
1188 var lo = new CXGN.List();
1189 lo.deleteItem(list_item_id);
1190 lo.renderLists('list_dialog');
1193 function working_modal_show() {
1194 jQuery("#working_modal").modal('show');
1197 function working_modal_hide() {
1198 jQuery("#working_modal").modal('hide');
1201 function showListItems(div, list_id) {
1202 working_modal_show();
1203 var l = new CXGN.List();
1204 l.renderItems(div, list_id);
1205 jQuery('#'+div).modal("show");
1206 working_modal_hide();
1209 function showPublicListItems(div, list_id) {
1210 var l = new CXGN.List();
1211 jQuery('#'+div).modal("show");
1212 l.renderPublicItems(div, list_id);
1215 function addNewList(div_id) {
1216 var lo = new CXGN.List();
1217 var name = jQuery('#'+div_id).val();
1220 alert("Please specify a name for the list.");
1224 var list_id = lo.existsList(name);
1226 alert('The list '+name+' already exists. Please choose another name.');
1230 lo.renderLists('list_item_dialog');
1233 function changeListType(html_select_id, list_id) {
1234 var type = jQuery('#'+html_select_id).val();
1235 var l = new CXGN.List();
1236 l.setListType(list_id, type);
1237 l.renderLists('list_dialog');
1241 validateList - check if all the elements in a list are of the correct type
1244 * list_id: the id of the list
1245 * html_select_id: the id of the html select containing the type list
1249 function validateList(list_id, html_select_id) {
1250 var lo = new CXGN.List();
1251 var type = jQuery('#'+html_select_id).val();
1252 lo.validate(list_id, type);
1255 function deleteSelectedListGroup(list_ids) {
1256 var arrayLength = list_ids.length;
1257 if (confirm('Delete the selected lists? This cannot be undone.')) {
1258 for (var i=0; i<arrayLength; i++) {
1259 var lo = new CXGN.List();
1260 lo.deleteList(list_ids[i]);
1262 lo.renderLists('list_dialog');
1266 function makePublicSelectedListGroup(list_ids) {
1267 var arrayLength = list_ids.length;
1268 if (confirm('Make selected lists public?')) {
1269 for (var i=0; i<arrayLength; i++) {
1270 makePublicList(list_ids[i]);
1272 var lo = new CXGN.List();
1273 lo.renderLists('list_dialog');
1277 function makePrivateSelectedListGroup(list_ids) {
1278 var arrayLength = list_ids.length;
1279 if (confirm('Make selected lists private?')) {
1280 for (var i=0; i<arrayLength; i++) {
1281 makePrivateList(list_ids[i]);
1283 var lo = new CXGN.List();
1284 lo.renderLists('list_dialog');
1288 function combineSelectedListGroup(list_ids) {
1289 var arrayLength = list_ids.length;
1290 var list_name = jQuery('#new_combined_list_name').val();
1291 if (confirm('Combine selected lists into a new list called '+list_name+'?')) {
1292 var arrayItems = [];
1293 var lo = new CXGN.List();
1294 var first_list_type = lo.getListType(list_ids[0]);
1295 var same_list_types = true;
1296 for (var i=0; i<arrayLength; i++) {
1297 var list_type = lo.getListType(list_ids[i]);
1298 if (list_type != first_list_type) {
1299 same_list_types = false;
1300 if (!confirm('Are you sure you want to combine these list types: '+first_list_type+' and '+list_type)) {
1305 var new_list_id = lo.newList(list_name);
1306 if (same_list_types == true) {
1307 lo.setListType(new_list_id, first_list_type);
1309 for (var i=0; i<arrayLength; i++) {
1310 list = lo.getListData(list_ids[i]);
1311 var numElements = list.elements.length;
1312 for (var j=0; j<numElements; j++) {
1313 arrayItems.push(list.elements[j][1]);
1316 lo.addBulk(new_list_id, arrayItems);
1317 lo.renderLists('list_dialog');