tweak presentation of lists.
[sgn.git] / js / CXGN / List.js
blob4f95a4ce0e49451af4479b9fdaa779b7084e32f1
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)
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.
21 =head1 AUTHOR
23 Lukas Mueller <lam87@cornell.edu>
25 =cut
30 JSAN.use('jqueryui');
32 if (!CXGN) CXGN = function () { };
34 CXGN.List = function () { 
35     this.list = [];
38 CXGN.List.prototype = { 
39     
41     // deprecated. Use getListData.
42     //
43     getList: function(list_id) { 
44         
45         var list;
46         
47         jQuery.ajax( { 
48             url: '/list/get',
49             async: false,
50             data: { 'list_id':list_id },
51             success: function(response) { 
52                 if (response.error) { 
53                     alert(response.error);
54                 }
55                 else { 
56                     list = response.elements;
57                 }
58                 
59             }
60         });
61         return list;
63     },
66     // this function also returns some metadata about
67     // list, namely its type.
68     //
69     getListData: function(list_id) { 
70         var list;
71         
72         jQuery.ajax( { 
73             url: 'list/data',
74             async: false,
75             data: { 'list_id': list_id },
76             success: function(response) { 
77                 if (response.error) { 
78                     alert(response.error);
79                 }
80                 else { 
81                     list = response;
82                 }
83             }
84         });
85         
86         return list;
87     },
89     getListType: function(list_id) { 
90         var type;
92         jQuery.ajax( { 
93             url: '/list/type',
94             async: false,
95             data: { 'list_id':list_id },
96             success: function(response) { 
97                 if (response.error) { 
98                     alert(response.error);
99                 }
100                 else { 
101                     type = response;
102                 }
103             },
104             error: alert('An error occurred.')
105         });
106         return type;
107     },
108             
109     setListType: function(list_id, type_id) { 
110         
111         jQuery.ajax( { 
112             url: '/list/type',
113             async: false,
114             data: { 'list_id': list_id, 'type_id':type_id },
115             success: function(response) { 
116                 if (response.error) { 
117                     alert(response.error);
118                 }
119                 else { 
120                     alert('Type of list '+list_id+' set to '+type_id);
121                 }
122             }
123             
124         });
126     },
128     allListTypes: function() { 
129         var types;
130         jQuery.ajax( { 
131             url: '/list/alltypes',
132             async: false,
133             success: function(response) { 
134                 if (response.error) { 
135                     alert(response.error);
136                 }
137                 else { 
138                     types = response;
139                 }
140             }
141         });
142         return types;
143                      
144     },
145     
146     typesHtmlSelect: function(id, selected) { 
147         var types = this.allListTypes();
148         var html = '<select id="'+id+'" >';
150         for (var i=0; i<types.length; i++) { 
151             var selected_html = '';
152             if (types[i][0] == selected) { 
153                 selected_html = ' selected="selected" ';
154             }
155             html += '<option name="'+types[i][0]+'"'+selected_html+'>'+types[i][1]+'</option>';
156         }
157         html += '</select>';
158         alert(html);
159         return html;
160     },
162     newList: function(name) { 
163         var oldListId = this.existsList(name);
164         var newListId = 0;
165         
166         if (name == '') { 
167             alert('Please enter a name for the new list.');
168             return 0;
169         }
171         if (oldListId === null) { 
172             jQuery.ajax( { 
173                 url: '/list/new',
174                 async: false,
175                 data: { 'name': name },
176                 success: function(response) { 
177                     if (response.error) { 
178                         alert(response.error);
179                     }
180                     else { 
181                         newListId=response.list_id;
182                     }
183                 }
184             });
185             return newListId;
186         }
187         else { 
188             alert('A list with name "'+ name + '" already exists. Please choose another list name.');
189             return 0;
190         }
191         alert("an error occurred");
192         return 0;
193     },
195     availableLists: function() { 
196         var lists = [];
197         jQuery.ajax( { 
198             url: '/list/available',
199             async: false,
200             success: function(response) { 
201                 if (response.error) { 
202                     alert(response.error);
203                 }
204                 lists = response;
205             }
206         });
207         return lists;
208     },
210     //return the newly created list_item_id or 0 if nothing was added
211     //(due to duplicates)
212     addItem: function(list_id, item) { 
213         var exists_item_id = this.existsItem(list_id,item);
214         if (exists_item_id ===0 ) { 
215             jQuery.ajax( { 
216                 async: false,
217                 url: '/list/item/add',
218                 data:  { 'list_id': list_id, 'element': item }
219             });
220             var new_list_item_id = this.existsItem(list_id,item);
221             return new_list_item_id;
222         }
223         else { return 0; }
224     },
227     removeItem: function(list_id, item_id) {
228         jQuery.ajax( {
229             async: false,
230             url: '/list/item/remove',
231             data: { 'list_id': list_id, 'item_id': item_id }
232         });
233     },
234     
236     deleteList: function(list_id) { 
237         jQuery.ajax( { 
238             url: '/list/delete',
239             async: false,
240             data: { 'list_id': list_id }
241         });
242     },
244     renderLists: function(div) { 
245         var lists = this.availableLists();
246         var html = '';
247         html = html + '<input id="add_list_input" type="text" /><input id="add_list_button" type="button" value="new list" /><br />';
248         
249         if (lists.length===0) { 
250             html = html + "None";
251             jQuery('#'+div).html(html);
252         }
254         html += '<table border="0" title="Available lists">';
255         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'; 
256         for (var i = 0; i < lists.length; i++) { 
257             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';
258             
259             //var items = this.getList(lists[i][0]);
260             
262             
263             
264         }
265         html = html + '</table>';
266         jQuery('#'+div).html(html);
268         jQuery('#add_list_button').click( 
269             function() { 
270                 var lo = new CXGN.List();
271                 
272                 var name = jQuery('#add_list_input').val();
274                 lo.newList(name);
275                 lo.renderLists(div);
276             });
278         
279         
280     },
281     
282     listNameById: function(list_id) { 
283         lists = this.availableLists();
284         for (var n=0; n<lists.length; n++) { 
285             if (lists[n][0] == list_id) { return lists[n][1]; }
286         }
287     },
289     renderItems: function(div, list_id) { 
291         var list_data = this.getListData(list_id);
292         var items = list_data.elements;
293         var list_type = list_data.type_name;
294         var list_name = this.listNameById(list_id);
296         var html = 'List name <b>'+list_name+'</b><br />Type '+this.typesHtmlSelect('type_select')+'   <input type="button" value="validate" /><br />';
298         html += 'New elements: <br /><textarea id="dialog_add_list_item" ></textarea><input id="dialog_add_list_item_button" type="submit" value="Add" /><br />';
300         html += '<b>List elements:</b><br />';
301         
302         for(var n=0; n<items.length; n++) { 
303             html = html + items[n][1] + '   <input id="'+items[n][0]+'" type="button" value="remove" /><br />';
304             
305         }
306         
307         jQuery('#'+div).html(html);
310         for (var n=0; n<items.length; n++) { 
311             var list_item_id = items[n][0];
313             jQuery('#'+items[n][0]).click(
314                 function() { 
315                     var lo = new CXGN.List();
316                     var i = lo.availableLists();
317                     
318                     lo.removeItem(list_id, this.id );
319                     lo.renderItems(div, list_id);
320                     lo.renderLists('list_dialog');
321                 });
322         }
323         
324         jQuery('#dialog_add_list_item_button').click(
325             function() { 
326                 addMultipleItemsToList('dialog_add_list_item', list_id);
327                 var lo = new CXGN.List();
328                 lo.renderItems(div, list_id);
329             }
330         );
331     },
332     
333     existsList: function(name) { 
334         var list_id = 0;
335         jQuery.ajax( { 
336             url: '/list/exists',
337             async: false,
338             data: { 'name': name },
339             success: function(response) { 
340                 list_id = response.list_id;
341             }
342         });
343         return list_id;
344     },
346     existsItem: function(list_id, name) { 
347         var list_item_id =0;
348         jQuery.ajax( { 
349             url: '/list/exists_item',
350             async: false,
351             data: { 'list_id' : list_id, 'name':name },
352             success: function(response) { 
353                 list_item_id = response.list_item_id;
354             }
355         });
356         return list_item_id;
357     },
358     
359     addToList: function(list_id, text) { 
360         var list = text.split("\n");
361         var duplicates = [];
362         for(var n=0; n<list.length; n++) { 
363             var id = this.addItem(list_id, list[n]);
364             if (id == 0) { 
365                 duplicates.push(list[n]);
366             }
367         }
369         if (duplicates.length > 0) { 
370             alert('Duplicate items ('+ duplicates.join(",") + ') were not stored');
371         }
372         return list.length - duplicates.length;
373     },
375     listSelect: function(div_name) { 
376         var lists = this.availableLists();
377         var html = '<select id="'+div_name+'_list_select">';
378         for (var n=0; n<lists.length; n++) { 
379             html = html + '<option value='+lists[n][0]+'>'+lists[n][1]+'</option>';
380         }
381         html = html + '</select>';
382         return html;
383     }
386 function setUpLists() { 
387     jQuery('#list_dialog').dialog( {
388         height: 300,
389         width: 500,
390         autoOpen: false,
391         title: 'Available lists',
392         buttons: { "Done" :  function() { 
393             jQuery('#list_dialog').dialog("close"); }
394                  },
395         modal: true 
396     });
397     
398     jQuery('#list_item_dialog').dialog( { 
399         height: 300,
400         width: 300,
401         autoOpen: false,
402         buttons: { 
403                 "Done": function() { 
404                     jQuery('#list_item_dialog').dialog("close"); }
405         },
406         modal: true,
407       title: 'List contents'
408     });
409     
410     jQuery('#lists_link').click(
411         function() { show_lists(); }
412     );
416 function show_lists() {     
417     jQuery('#list_dialog').dialog("open");
418     
419     var l = new CXGN.List();
420     l.renderLists('list_dialog');
424 function pasteListMenu (div_name, menu_div) { 
425     var lo = new CXGN.List();
427     var html='';
429     if (jQuery.cookie("sgn_session_id")) {
430         html = lo.listSelect(div_name);
431         html = html + '<input type="button" value="paste" onclick="javascript:pasteList(\''+div_name+'\')" /><br />';
432     }
433     else { 
434         html = html + 'please log in for lists';
435     }
436     jQuery('#'+menu_div).html(html);
439 function pasteList(div_name) { 
440     var lo = new CXGN.List();
441     var list_name = jQuery('#'+div_name+'_list_select').val();
442     var list_content = lo.getList(list_name);
443     
444     // textify list
445     var list_text = '';
446     for (var n=0; n<list_content.length; n++) { 
447         list_text = list_text + list_content[n][1]+"\r\n";
448     }
449     jQuery('#'+div_name).text(list_text);
452 function addToListMenu(listMenuDiv, dataDiv) { 
453     var lo = new CXGN.List();
454     
455     var html = '<input type="text" id="'+dataDiv+'_new_list_name" size="8" /><input id="'+dataDiv+'_add_to_new_list" type="button" value="add to new list" /><br />';
456     html += lo.listSelect(dataDiv);
458     html += '<input id="'+dataDiv+'_button" type="button" value="add to list" />';
459     
460     jQuery('#'+listMenuDiv).html(html);
461     
462     var list_id = 0;
464     jQuery('#'+dataDiv+'_add_to_new_list').click(
465         function() { 
466             var lo = new CXGN.List();
467             var new_name = jQuery('#'+dataDiv+'_new_list_name').val();
468             
469             var data = getData(dataDiv);
470             list_id = lo.newList(new_name);
471             if (list_id > 0) { 
472                 var elementsAdded = lo.addToList(list_id, data);
473                 alert("Added "+elementsAdded+" list elements to list "+new_name);
474             }
475         }
476     );
478     jQuery('#'+dataDiv+'_button').click( 
479         function() { 
480             var data = getData(dataDiv);
481             list_id = jQuery('#'+dataDiv+'_list_select').val();
482             var elementsAdded = lo.addToList(list_id, data);
483             alert("Added "+elementsAdded+" list elements.");
484         }
485     );
488 function getData(id) { 
489     var divType = jQuery("#"+id).get(0).tagName;
491     if (divType == 'DIV' || divType =='SPAN' ||  divType === undefined) { 
492         data = jQuery('#'+id).html();
493     }
494     if (divType == 'SELECT') { 
495         data = jQuery('#'+id).val().join("\n");
496     }
497     if (divType == 'TEXTAREA') { 
498         data = jQuery('textarea#'+id).val();
499     }
500     return data;
502            
503         
505 function addTextToListMenu(div) { 
506     var lo = new CXGN.List();
507     var html = lo.listSelect(div);
508     html = html + '<input id="'+div+'_button" type="button" value="add to list" />';
509     
510     document.write(html);
511     
512     jQuery('#'+div+'_button').click( 
513         function() { 
514             var text = jQuery('textarea#div').val();
515             var list_id = jQuery('#'+div+'_list_select').val();
516             lo.addToList(list_id, text);
517             lo.renderLists('list_dialog');
518         }
519     );
522 function addSelectToListMenu(div) { 
523     var lo = new CXGN.List();
524     var html = lo.listSelect(div);
525     html = html + '<input id="'+div+'_button" type="button" value="add to list" />';
526     
527     document.write(html);
528     
529     jQuery('#'+div+'_button').click( 
530         function() { 
531             var selected_items = jQuery('#'+div).val();
532             var list_id = jQuery('#'+div+'_list_select').val();
533             addArrayToList(selected_items, list_id);
534             lo.renderLists('list_dialog');
535         }
536     );
540 // add the text in a div to a list
541 function addDivToList(div_name) { 
542     var list_id = jQuery('#'+div_name+'_list_select').val();
543     var lo = new CXGN.List();
544     var list = jQuery('#'+div_name).val();
545     var items = list.split("\n");
547     for(var n=0; n<items.length; n++) { 
548         var added = lo.addItem(list_id, items[n]);
549         if (added > 0) { }
550     }
553 function addTextToList(div, list_id) { 
554     var lo = new CXGN.List();
555     var item = jQuery('#'+div).val();
556     var id = lo.addItem(list_id, item);
557     if (id == 0) { 
558         alert('Item "'+item+'" was not added because it already exists');
559     }
560     lo.renderLists('list_dialog');
563 function addMultipleItemsToList(div, list_id) { 
564     var lo = new CXGN.List();
565     var content = jQuery('#'+div).val();
566     if (content == '') { 
567         alert("No items - Please enter items to add to the list.");
568 return;
569     }
570     var items = content.split("\n");
571     
572     var duplicates = new Array();
573     for (var n=0; n<items.length; n++) { 
574         var id = lo.addItem(list_id, items[n]);
575         if (id == 0) { 
576             duplicates.push(items[n]);
577         }
578     }
579     if (duplicates.length >0) { 
580         alert("The following items were not added because they are already in the list: "+ duplicates.join(", "));
581     }
582 lo.renderLists('list_dialog');
585 function addArrayToList(items, list_id) { 
586 var lo = new CXGN.List();
587    var duplicates = new Array();
588     for (var n=0; n<items.length; n++) { 
589         var id = lo.addItem(list_id, items[n]);
590         if (id == 0) { 
591             duplicates.push(items[n]);
592         }
593     }
594     if (duplicates.length >0) { 
595         alert("The following items were not added because they are already in the list: "+ duplicates.join(", "));
596     }
599 function deleteList(list_id) { 
600     var lo = new CXGN.List();
601     var list_name = lo.listNameById(list_id);
602     if (confirm('Delete list "'+list_name+'"? (ID='+list_id+'). This cannot be undone.')) { 
603         lo.deleteList(list_id);
604         lo.renderLists('list_dialog');
605         alert('Deleted list '+list_name);
606     }
609         
610 function deleteItemLink(list_item_id) { 
611     var lo = new CXGN.List();
612     lo.deleteItem(list_item_id);
613     lo.renderLists('list_dialog');
615         
616 function showListItems(div, list_id) { 
617     var l = new CXGN.List();
618     jQuery('#'+div).dialog("open");
619     l.renderItems('list_item_dialog', list_id);
622 function addNewList(div_id) { 
623     var lo = new CXGN.List();
624     var name = jQuery('#'+div_id).val();
625     
626     if (name == '') { 
627         alert("Please specify a name for the list.");
628         return;
629     }
630     
631     var list_id = lo.existsList(name);
632     if (list_id > 0) {
633         alert('The list '+name+' already exists. Please choose another name.');
634         return;
635     }
636     lo.newList(name);
637     lo.renderLists('list_item_dialog');