Minor style fixes in debates. Refactored proposal URLS. Splitted proposal
[e_cidadania.git] / src / apps / ecidadania / debate / static / js / debate_board.js
blob1530fe299e35b4c9e95fad8d7440dc62d43a55d1
1 /*
2     debate_board.js - Javascript containing the engine for the debate
3                            system.
4                            
5     License: GPLv3
6     Copyright: 2011 Cidadania S. Coop. Galega
7     Author: Oscar Carballal Prego <info@oscarcp.com>
8 */
10 // We put here the string for translation. This is meant to be translated by
11 // django jsi18n
12 var newTitle = gettext('Write here your title');
13 var newMessage = gettext('Write here your message');
14 var editString = gettext('Edit');
15 var viewString = gettext('View');
16 var errorMsg = gettext('There has been an error.');
17 var errorCreate = gettext("Couldn't create note.");
18 var errorGetNote = gettext("Couldn't get note data.");
19 var errorSave = gettext("Couldn't save note.");
20 var errorSavePos = gettext("Couldn't save note position.");
21 var errorDelete = gettext("Couldn't delete note.");
22 var confirmDelete = gettext('Are you sure?');
23 var comment = gettext('Comment');
26     NOTE FUNCTIONS
29 function showControls() {
30     /*
31      showControls() - Hides the edit and delete controls from the notes. If the
32      users hovers over a note created by himself, the note shows the controls.
33      */
34     $(".note").hover(function(){
35             $(this).find(".deletenote").show();
36             $(this).find("#edit-note").show();
37             $(this).find("#view-note").show();
38         },
39         function() {
40             $(this).find(".deletenote").hide();
41             $(this).find("#edit-note").hide();
42             $(this).find("#view-note").hide();
43         }
44     );
47 function createNote() {
48     /*
49         createNote() - Creates a new note related with the debate. Frist the
50         function creates the note in the server and after that we create a "fake"
51         note in the debate board with the data returned by the view. If for some
52         reason the user creates the note and leaves it before moving or editing the
53         note is positioned in position [1,1].
54     */
56     var request = $.ajax({
57         type:"POST",
58         url:"../create_note/",
59         data:{
60             debateid:$('#debate-number').text(),
61             title: newTitle,
62             message: newMessage,
63             column:1,
64             row:1
65         }
66     });
68     request.done(function (note) {
69         var newNote = $("#sortable-dispatcher").append("<div id='" + note.id + "' style='display:hidden;' class='note mine'>" +
70             "<div class='handler'><span id='view-note' style='float:left;'>" +
71             "<a href='#' class='nounderline' onclick='viewNote(this)' data-toggle='modal' data-target='#view-current-note' title='{% trans 'View' %}'><i class='icon-eye-open' style='font-size:12px;''></i></a>" +
72             "</span><div class='deletenote' style='float:right;'><a href='#' onclick='deleteNote(this)' id='deletenote' title='{% trans 'Delete note' %}'><i class='icon-remove' style='font-size:12px;'></i></a></div>" +
73             "<span id='edit-note' style='float:right;'>" +
74             "<a href='#'' class='nounderline' onclick='editNote(this)' data-toggle='modal' data-target='#edit-current-note' title='{% trans 'Edit' %}'><i class='icon-pencil' style='font-size:12px;'></i></a>" +
75             "</span></div><p class='note-text'>" + note.title + "</p>");
76         newNote.show("slow");
77         showControls();
78     });
80     request.fail(function (jqXHR, textStatus) {
81         $('#jsnotify').notify("create", {
82             title: errorCreate,
83             text: errorMsg + textStatus,
84             icon:"alert.png"
85         });
86     });
88     // Activate control show/hide for the new note
91 function viewNote(obj) {
92     /*
93         editNote(obj) - This function detects the note the user clicked and raises
94         a modal dialog, after that it checks the note in the server and returns
95         it's data, prepopulating the fields.
96     */
97     var noteID = $(obj).parents('.note').attr('id');
99     var request = $.ajax({
100         url: "../update_note/",
101         data: { noteid: noteID }
102     });
104     request.done(function(note) {
105         $('h3#view-note-title').text(note.title);
106         $('p#view-note-desc').html(note.message);
107         $('span#view-note-author').text(note.author.name);
109         var html = '';
110         var comment_count = "<h5 class='note-comment-title'>" + comment + " (" + note.comments.length + ")</h5>";
111         for(var i=0; i<note.comments.length; i++) {
112             var item = note.comments[i];
113             html += "<div class='comment-bubble' id='comment" + i +"'>" + "<p id='username' class='viewer'>"+ item.username + "</p>";
114             html += "<p id='date' class='viewer-date'>"+ item.submit_date +"</p>";
115             html += "<p id='comments" + i + "' class='viewer-comment'>" + item.comment +"</p><img src='/static/img/arrow-2.png' width='20' height='21'></div>";
116         }
117         $('div#comments').html(html);
118         $('span#num-comments').html(comment_count);
119         $('form#form_comments div.kopce').html(note.form_html);
120    });
122     request.fail(function (jqXHR, textStatus) {
123         $('#view-current-note').modal('hide');
124         $('#jsnotify').notify("create", {
125             title: errorGetNote,
126             text: errorMsg + textStatus,
127             icon:"alert.png"
128         });
129     });
132 function editNote(obj) {
133     /*
134         editNote(obj) - This function detects the note the user clicked and raises
135         a modal dialog, after that it checks the note in the server and returns
136         it's data, prepopulating the fields.
137     */
138     var noteID = $(obj).parents('.note').attr('id');
140     var request = $.ajax({
141         url: "../update_note/",
142         data: { noteid: noteID }
143     });
145     request.done(function(note) {
146         $("input[name='notename']").val(note.title);
147         wysieditor.data("wysihtml5").editor.setValue(note.message, true);
148         // If for some reason the WYSIHTML5 editor fails, it will fallback
149         // into a simple textarea that gets shown
150         $("textarea#id_note_message").val(note.message);
151         $("#last-edited-note").text(noteID);
152     });
154     request.fail(function (jqXHR, textStatus) {
155         $('#edit-current-note').modal('hide');
156         $('#jsnotify').notify("create", {
157             title: errorGetNote,
158             text: errorMsg + textStatus,
159             icon:"alert.png"
160         });
161     });
164 function saveNote() {
165     /*
166         saveNote() - Saves the current edited note, only the title and message
167         field, since the other fields are managed through makeSortable() or by
168         django itself.
169     */
170     var noteID = $('#last-edited-note').text();
172     var request = $.ajax({
173         type: "POST",
174         url: "../update_note/",
175         data: {
176             noteid: noteID,
177             title: $("input[name='notename']").val(),
178             message: $("textarea#id_note_message").val()
179 //            message: $("td#cke_contents_id_note_message .cke_show_borders").text()
180         }
181     });
183     request.done(function(msg) {
184         $('#edit-current-note').modal('hide');
185         var newTitle = $("input[name='notename']").val();
186         $("div#" + noteID + " > p").text(newTitle);
187     });
189     request.fail(function(jqXHR, textStatus) {
190         $('#edit-current-note').modal('hide');
191         $('#jsnotify').notify("create", {
192             title: errorSave,
193             text: errorMsg + textStatus,
194             icon:"alert.png"
195         });
196     })
199 function deleteNote(obj) {
200     /*
201         deleteNote() - Delete a note making an AJAX call. This function is called
202         through getClickedNote(). We locate the note ID, and post it to django,
203         after that we hide the note from the board and when it's hidden we remove it
204         from the DOM.
205     */
206     var noteID = $(obj).parents('.note').attr('id');
207     var answer = confirm(confirmDelete);
209     if (answer) {
210         var request = $.ajax({
211             type: "POST",
212             url: "../delete_note/",
213             data: { noteid: noteID }
214         });
216         request.done(function(msg) {
217            $('#' + noteID).hide("normal", function() {
218                $('#' + noteID).remove();
219            });
220         });
222         request.fail(function(jqXHR, textStatus) {
223             $('#jsnotify').notify("create", {
224                 title: errorDelete,
225                 text: errorMsg + textStatus,
226                 icon:"alert.png"
227             });
228         });
229     }
232 function makeSortable() {
233     /*
234         makeSortable() - Makes every element with id starting by 'sortable'
235         sortable through the connectedSortable class lists. It uses jQuery
236         Sortable. This function has to be called whenever a new element is on
237         the page (note, table column or row) to make the new elements sortable.
238     */
239     
240     // Get all the div elements starting by sortable
241     $('#[id^=sortable]').sortable({
242         connectWith: ".connectedSortable",
243         cancel: ".disabled",
244         cursor: "move",
245         placeholder: "note-alpha",
246         start: function(e,ui) { 
247             $(ui.placeholder).hide("slow"); // Remove popping
248         },
249         change: function(e,ui) {
250             $(ui.placeholder).hide().show("normal");
251         },
252         stop: function(e,ui) {
253             var noteObj = ui.item;
254             var noteID = noteObj.attr('id');
255             var position = noteObj.parent().attr('headers').split("-");
257             $.ajax({
258                 type: "POST",
259                 url: "../update_position/",
260                 data: {
261                     noteid: noteID,
262                     column: position[0],
263                     row: position[1]
264                 }
265             }).fail(function(jqXHR, textStatus) {
266                 $('#jsnotify').notify("create", {
267                     title: errorSavePos,
268                     text: errorMsg + textStatus,
269                     icon:"alert.png"
270                 });
271             });
272         }
273     }).disableSelection();
276 /* DEBATE CREATION */
278 var tdlength = 0;
280 function addTableColumn() {
281     /*
282         addTableColumn() - Create a new column ny creating a new sortable TD in
283         all the rows.
284     */
285     var tableID = $('table').attr('id');
286     var inputs = $('#' + tableID + ' input').length;
287     var tdlength = $('#' + tableID + ' td').length;
288     var criteriacount = $('#' + tableID + ' th[id^=debate-vcriteria]').length;
289     var formCount = parseInt($('#id_colform-TOTAL_FORMS').val());
291     if (criteriacount >= 10) return false;
292     $('#' + tableID + ' tr:first').append("<th id='debate-vcriteria" + (criteriacount+1) + "' class='criteria-vtitle'><input id='" + tableID + "-criteria" + (inputs+1) + "' name='colform-" + (criteriacount) + "-criteria' type='text' class='small'></th>");
293     $('#' + tableID + ' tbody tr').each(function(){
294         //var tdlength = $('#' + tableID + ' td').length;
295         $(this).append("<td id='sortable" + (tdlength) + "-" + tableID + "' class='connectedSortable'></td>").fadeIn("slow");
296         tdlength += 1;
297     });
298     $('#id_colform-TOTAL_FORMS').val(formCount + 1);
299     makeSortable();
302 function addTableRow() {
303     var tableID =$('table').attr('id');
304     var criteriacount = $('#' + tableID + ' th[id^=debate-vcriteria]').length;
305     var tdlength = $('#' + tableID + 'td').length;
306     var formCount_row = parseInt($('#id_rowform-TOTAL_FORMS').val());
308     var t = $('table');
309     var numColumns = $('th[id^=debate-vcriteria]', t).length;
310     var numRows = $('td[class=criteria-htitle]', t).length;
311     if (numRows >= 10) return false;
313     var tr = $('<tr>');
314     tr.append("<td class='criteria-htitle'><div id='debate-ttitle'><input style='width:100px;' id='" + tableID + "-criteria" + (numRows) + "' name='rowform-" + (numRows) + "-criteria' type='text'></div></td>");
315     $('#id_rowform-TOTAL_FORMS').val(formCount_row + 1);
316     for (i=0; i<numColumns; i++) {
317         tr.append('<td>');
318     }
319     t.append(tr);
323 function removeTableRow() {
324     var t = $('table');
325     var numRows = $('td[class=criteria-htitle]', t).length;
326     var formCount_row = parseInt($('#id_rowform-TOTAL_FORMS').val());
327     if (numRows < 2) return false;
328     $('tbody tr:last-child').fadeOut("fast", function() {
329         $(this).remove();
330     $('#id_rowform-TOTAL_FORMS').val(formCount_row - 1);
332     });
336 function removeTableColumn() {
337     /*
338         removeTableColumn() - Deletes the last column (all the last TDs).
339     */
340     var tableID = $('table').attr('id');
341     var formCount = parseInt($('#id_colform-TOTAL_FORMS').val());
342     var columns = $('#' + tableID+ ' tr:last td').length;
343     if (columns > 2) {
344         $('#' + tableID + ' th:last-child, #' + tableID + ' td:last-child').fadeOut("fast", function() {
345             $(this).remove();
346         $('#id_colform-TOTAL_FORMS').val(formCount - 1);
348         });
349     } 
350     else {
351         $('#jsnotify').notify("create", {
352             title: "Can't delete column",
353             text: "There must be at least one column in the table.",
354             icon: "alert.png"
355         });
356     }
359 function saveTable() {
360     /*
361         saveTable() - Saves the table data. Instead of using a standard form,
362         we submite the data trough ajax post, and treat it as a form in the
363         django view.
364     */
365     $('#ajaxform').submit( function(e) {
366         var tableID = $('table').attr('id');
368         var xvalues = [];
369       //  var xfields = $('th.criteria-vtitle :input');
370       //  $.each(xfields, function(i, field){
371       //      xvalues.push(field.value);
372       //  });
373         $('#id_columns').val(xvalues);
374         var sortable = [];
375         var rows = $('#' + tableID + ' tbody tr');
376         $.each(rows, function(i, field) {
377             var rowID = this.attr('id');
378             $(rowID + ' td').each(function() {
379                 sortable.push($(this).attr('id'));
380             })
381     //        alert('Estos son los sortables: ' + sortable[0]);
382             $(this).val(sortable);
383             sortable.length = 0;
384         });
385     });
388 /*******************
389     MAIN LOOP
390 ********************/
392 $(document).ready(function() {
393     // Activate javascript notifications.
394     $('#jsnotify').notify();
395     // Activate sortables
396     makeSortable();
397     // Show controls for some notes
398     showControls();
399     saveTable();