Fix #31: Replace notify with gritter. Also solved a problem with the div
[e_cidadania.git] / src / apps / ecidadania / debate / static / js / debate_board.js
blob4fc9b011d56162ae7233bd05a8218cb520bf20a7
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 strings 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');
24 var view = gettext('View');
25 var edit = gettext('Edit');
26 var remove = gettext('Delete note');
29     NOTE FUNCTIONS
32 function showControls() {
33     /*
34      showControls() - Hides the edit and delete controls from the notes. If the
35      users hovers over a note created by himself, the note shows the controls.
36      */
37     $(".note").hover(function(){
38             $(this).find(".deletenote").show();
39             $(this).find("#edit-note").show();
40             $(this).find("#view-note").show();
41         },
42         function() {
43             $(this).find(".deletenote").hide();
44             $(this).find("#edit-note").hide();
45             $(this).find("#view-note").hide();
46         }
47     );
50 function createNote() {
51     /*
52         createNote() - Creates a new note related with the debate. Frist the
53         function creates the note in the server and after that we create a "fake"
54         note in the debate board with the data returned by the view. If for some
55         reason the user creates the note and leaves it before moving or editing the
56         note is positioned in position [1,1].
57     */
59     var request = $.ajax({
60         type:"POST",
61         url:"../create_note/",
62         data:{
63             debateid:$('#debate-number').text(),
64             title: newTitle,
65             message: newMessage,
66             column:1,
67             row:1
68         }
69     });
71     request.done(function (note) {
72         var newNote = $("#sortable-dispatcher").append("<div id='" + note.id + "' style='display:hidden;' class='note mine'>" +
73             "<div class='handler'><span id='view-note' style='float:left;'>" +
74             "<a href='#' class='nounderline' onclick='viewNote(this)' data-toggle='modal' data-target='#view-current-note' title='" + view + "'><i class='icon-eye-open' style='font-size:12px;''></i></a>" +
75             "</span><div class='deletenote' style='float:right;'><a href='#' onclick='deleteNote(this)' id='deletenote' title='" + remove + "'><i class='icon-remove' style='font-size:12px;'></i></a></div>" +
76             "<span id='edit-note' style='float:right;'>" +
77             "<a href='#'' class='nounderline' onclick='editNote(this)' data-toggle='modal' data-target='#edit-current-note' title='" + edit + "'><i class='icon-pencil' style='font-size:12px;'></i></a>" +
78             "</span></div><p class='note-text'>" + note.title + "</p>");
79         newNote.show("slow");
80         showControls();
81     });
83     request.fail(function (jqXHR, textStatus) {
84         $.gritter.add({
85             title: errorMsg,
86             text: errorCreate + ' ' + textStatus,
87             image: 'http://i.imgur.com/gqh6G5l.png'
88         });
89     });
92 function viewNote(obj) {
93     /*
94         editNote(obj) - This function detects the note the user clicked and raises
95         a modal dialog, after that it checks the note in the server and returns
96         it's data, prepopulating the fields.
97     */
98     var noteID = $(obj).parents('.note').attr('id');
100     var request = $.ajax({
101         url: "../update_note/",
102         data: { noteid: noteID }
103     });
105     request.done(function(note) {
106         $('h3#view-note-title').text(note.title);
107         $('p#view-note-desc').html(note.message);
108         $('span#view-note-author').text(note.author.name);
110         var html = '';
111         var comment_count = "<h5 class='note-comment-title'>" + comment + " (" + note.comments.length + ")</h5>";
112         for(var i=0; i<note.comments.length; i++) {
113             var item = note.comments[i];
114             html += "<div class='comment-bubble' id='comment" + i +"'>" + "<p id='username' class='viewer'>"+ item.username + "</p>";
115             html += "<p id='date' class='viewer-date'>"+ item.submit_date +"</p>";
116             html += "<p id='comments" + i + "' class='viewer-comment'>" + item.comment +"</p><img src='/static/img/arrow-2.png' width='20' height='21'></div>";
117         }
118         $('div#comments').html(html);
119         $('span#num-comments').html(comment_count);
120         $('form#form_comments div.kopce').html(note.form_html);
121    });
123     request.fail(function (jqXHR, textStatus) {
124         $('#view-current-note').modal('hide');
125         $.gritter.add({
126             title: errorMsg,
127             text: errorGetNote + ' ' + textStatus,
128             image: 'http://i.imgur.com/gqh6G5l.png'
129         });
130     });
133 function editNote(obj) {
134     /*
135         editNote(obj) - This function detects the note the user clicked and raises
136         a modal dialog, after that it checks the note in the server and returns
137         it's data, prepopulating the fields.
138     */
139     var noteID = $(obj).parents('.note').attr('id');
141     var request = $.ajax({
142         url: "../update_note/",
143         data: { noteid: noteID }
144     });
146     request.done(function(note) {
147         $("input[name='notename']").val(note.title);
148         wysieditor.data("wysihtml5").editor.setValue(note.message, true);
149         // If for some reason the WYSIHTML5 editor fails, it will fallback
150         // into a simple textarea that gets shown
151         $("textarea#id_note_message").val(note.message);
152         $("#last-edited-note").text(noteID);
153     });
155     request.fail(function (jqXHR, textStatus) {
156         $('#edit-current-note').modal('hide');
157         $.gritter.add({
158             title: errorMsg,
159             text: errorGetNote + ' ' + textStatus,
160             image: 'http://i.imgur.com/gqh6G5l.png'
161         });
162     });
165 function saveNote() {
166     /*
167         saveNote() - Saves the current edited note, only the title and message
168         field, since the other fields are managed through makeSortable() or by
169         django itself.
170     */
171     var noteID = $('#last-edited-note').text();
173     var request = $.ajax({
174         type: "POST",
175         url: "../update_note/",
176         data: {
177             noteid: noteID,
178             title: $("input[name='notename']").val(),
179             message: $("textarea#id_note_message").val()
180 //            message: $("td#cke_contents_id_note_message .cke_show_borders").text()
181         }
182     });
184     request.done(function(msg) {
185         $('#edit-current-note').modal('hide');
186         var newTitle = $("input[name='notename']").val();
187         $("div#" + noteID + " > p").text(newTitle);
188     });
190     request.fail(function(jqXHR, textStatus) {
191         $('#edit-current-note').modal('hide');
192         $.gritter.add({
193             title: errorMsg,
194             text: errorSave + ' ' + textStatus,
195             image: 'http://i.imgur.com/gqh6G5l.png'
196         });
197     })
200 function deleteNote(obj) {
201     /*
202         deleteNote() - Delete a note making an AJAX call. This function is called
203         through getClickedNote(). We locate the note ID, and post it to django,
204         after that we hide the note from the board and when it's hidden we remove it
205         from the DOM.
206     */
207     var noteID = $(obj).parents('.note').attr('id');
208     var answer = confirm(confirmDelete);
210     if (answer) {
211         var request = $.ajax({
212             type: "POST",
213             url: "../delete_note/",
214             data: { noteid: noteID }
215         });
217         request.done(function(msg) {
218            $('#' + noteID).hide("normal", function() {
219                $('#' + noteID).remove();
220            });
221         });
223         request.fail(function(jqXHR, textStatus) {
224             $.gritter.add({
225                 title: errorMsg,
226                 text: errorDelete + ' ' + textStatus,
227                 image: 'http://i.imgur.com/gqh6G5l.png'
228             });
229         });
230     }
233 function makeSortable() {
234     /*
235         makeSortable() - Makes every element with id starting by 'sortable'
236         sortable through the connectedSortable class lists. It uses jQuery
237         Sortable. This function has to be called whenever a new element is on
238         the page (note, table column or row) to make the new elements sortable.
239     */
240     
241     // Get all the div elements starting by sortable
242     $("[id^=sortable]").sortable({
243         connectWith: ".connectedSortable",
244         cancel: ".disabled",
245         cursor: "move",
246         placeholder: "note-alpha",
247         start: function(e,ui) { 
248             $(ui.placeholder).hide("slow"); // Remove popping
249         },
250         change: function(e,ui) {
251             $(ui.placeholder).hide().show("normal");
252         },
253         stop: function(e,ui) {
254             var noteObj = ui.item;
255             var noteID = noteObj.attr('id');
256             var position = noteObj.parent().attr('headers').split("-");
258             $.ajax({
259                 type: "POST",
260                 url: "../update_position/",
261                 data: {
262                     noteid: noteID,
263                     column: position[0],
264                     row: position[1]
265                 }
266             }).fail(function(jqXHR, textStatus) {
267                 $.gritter.add({
268                     title: errorMsg,
269                     text: errorSavePos + ' ' + textStatus,
270                     image: 'http://i.imgur.com/gqh6G5l.png'
271                 });
272             });
273         }
274     }).disableSelection();
277 /* DEBATE CREATION */
279 var tdlength = 0;
281 function addTableColumn() {
282     /*
283         addTableColumn() - Create a new column ny creating a new sortable TD in
284         all the rows.
285     */
286     var tableID = $('table').attr('id');
287     var inputs = $('#' + tableID + ' input').length;
288     var tdlength = $('#' + tableID + ' td').length;
289     var criteriacount = $('#' + tableID + ' th[id^=debate-vcriteria]').length;
290     var formCount = parseInt($('#id_colform-TOTAL_FORMS').val());
292     if (criteriacount >= 10) return false;
293     $('#' + 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>");
294     $('#' + tableID + ' tbody tr').each(function(){
295         //var tdlength = $('#' + tableID + ' td').length;
296         $(this).append("<td id='sortable" + (tdlength) + "-" + tableID + "' class='connectedSortable'></td>").fadeIn("slow");
297         tdlength += 1;
298     });
299     $('#id_colform-TOTAL_FORMS').val(formCount + 1);
300     makeSortable();
303 function addTableRow() {
304     var tableID =$('table').attr('id');
305     var criteriacount = $('#' + tableID + ' th[id^=debate-vcriteria]').length;
306     var tdlength = $('#' + tableID + 'td').length;
307     var formCount_row = parseInt($('#id_rowform-TOTAL_FORMS').val());
309     var t = $('table');
310     var numColumns = $('th[id^=debate-vcriteria]', t).length;
311     var numRows = $('td[class=criteria-htitle]', t).length;
312     if (numRows >= 10) return false;
314     var tr = $('<tr>');
315     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>");
316     $('#id_rowform-TOTAL_FORMS').val(formCount_row + 1);
317     for (i=0; i<numColumns; i++) {
318         tr.append('<td>');
319     }
320     t.append(tr);
324 function removeTableRow() {
325     var t = $('table');
326     var numRows = $('td[class=criteria-htitle]', t).length;
327     var formCount_row = parseInt($('#id_rowform-TOTAL_FORMS').val());
328     if (numRows < 2) return false;
329     $('tbody tr:last-child').fadeOut("fast", function() {
330         $(this).remove();
331     $('#id_rowform-TOTAL_FORMS').val(formCount_row - 1);
333     });
337 function removeTableColumn() {
338     /*
339         removeTableColumn() - Deletes the last column (all the last TDs).
340     */
341     var tableID = $('table').attr('id');
342     var formCount = parseInt($('#id_colform-TOTAL_FORMS').val());
343     var columns = $('#' + tableID+ ' tr:last td').length;
344     if (columns > 2) {
345         $('#' + tableID + ' th:last-child, #' + tableID + ' td:last-child').fadeOut("fast", function() {
346             $(this).remove();
347         $('#id_colform-TOTAL_FORMS').val(formCount - 1);
349         });
350     } 
351     else {
352         $('#jsnotify').notify("create", {
353             title: "Can't delete column",
354             text: "There must be at least one column in the table.",
355             icon: "alert.png"
356         });
357     }
360 function saveTable() {
361     /*
362         saveTable() - Saves the table data. Instead of using a standard form,
363         we submite the data trough ajax post, and treat it as a form in the
364         django view.
365     */
366     $('#ajaxform').submit( function(e) {
367         var tableID = $('table').attr('id');
369         var xvalues = [];
370       //  var xfields = $('th.criteria-vtitle :input');
371       //  $.each(xfields, function(i, field){
372       //      xvalues.push(field.value);
373       //  });
374         $('#id_columns').val(xvalues);
375         var sortable = [];
376         var rows = $('#' + tableID + ' tbody tr');
377         $.each(rows, function(i, field) {
378             var rowID = this.attr('id');
379             $(rowID + ' td').each(function() {
380                 sortable.push($(this).attr('id'));
381             })
382     //        alert('Estos son los sortables: ' + sortable[0]);
383             $(this).val(sortable);
384             sortable.length = 0;
385         });
386     });
389 /*******************
390     MAIN LOOP
391 ********************/
393 $(document).ready(function() {
394     // Activate sortables
395     makeSortable();
396     // Show controls for some notes
397     showControls();
398     saveTable();