--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/content/js/survey-edit-090627.js Sat Jun 27 09:35:50 2009 +0200
@@ -0,0 +1,715 @@
+ /* Copyright 2009 the Melange authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+*
+* @author <a href="mailto:ajaksu@gmail.com">Daniel Diniz</a>
+* @author <a href="mailto:jamesalexanderlevy@gmail.com">James Levy</a>
+*/
+
+(function ($) {
+
+ var DEFAULT_LONG_ANSWER_TEXT = 'Write a Custom Prompt For This Question...';
+ var DEFAULT_SHORT_ANSWER_TEXT = 'Write a Custom Prompt...';
+
+ $(function () {
+ /*
+ * == Set Selectors ==
+ *
+ */
+ var widget = $('div#survey_widget');
+
+ widget.parents('td.formfieldvalue:first').css({
+ 'float': 'left',
+ 'width': 200
+ });
+
+ /*
+ * == Setup for existing surveys ==
+ *
+ */
+
+ if ($('input#id_title').val() === '' && $('.formfielderror').length < 1) {
+ widget.find('tr').remove();
+ }
+
+ widget.find('table:first').show();
+
+ /*
+ * Restore survey content html from editPost
+ * if POST fails
+ */
+
+ var SURVEY_PREFIX = 'survey__';
+ var del_el = ["<a class='delete'><img '",
+ "src='/soc/content/images/minus.gif'/></a>"].join("");
+ var del_li = ["<a class='delete_item' id='del_",
+ "' ><img src='/soc/content/images/minus.gif'/></a> "];
+
+ var survey_html = $('form').find("#id_survey_html").attr('value');
+
+ function renderHTML() {
+ // render existing survey forms
+ widget.find('td > label').prepend(del_el).end();
+
+ $('ol').find('li').each(
+ function () {
+ $(this).prepend(del_li.join($(this).attr('id'))).end();
+ }
+ );
+ widget.find('.short_answer').each(
+ function () {
+ $(this).attr('name', SURVEY_PREFIX + $(this).getPosition() +
+ 'short_answer__' + $(this).attr('name'));
+ }
+ );
+
+ widget.find('.long_answer').each(
+ function () {
+ $(this).attr('name', SURVEY_PREFIX + $(this).getPosition() +
+ 'long_answer__' + $(this).attr('name'))
+ .attr('overflow', 'auto');
+ // TODO: replace scrollbar with jquery autogrow
+ }
+ );
+ }
+
+ if (survey_html && survey_html.length > 1) {
+ widget.html(survey_html); // we don't need to re-render HTML
+
+ widget.find('.long_answer,input').each(
+ function () {
+ $(this).val($(this).attr('val'));
+ }
+ );
+ }
+ else {
+ renderHTML();
+ }
+
+ var survey = widget.find('tbody:first');
+ var options = widget.find('#survey_options');
+
+ /*
+ * == Handle Enter key on dialogs ==
+ */
+ $('form input, form button, form select').keypress(
+ function (e) {
+ if ((e.which && e.which === 13) || (e.keyCode && e.keyCode === 13)) {
+ $(this).parents('.ui-dialog:first').find(":button:first").click();
+ return false;
+ }
+ }
+ );
+
+ /*
+ * == Display survey answers inline ==
+ */
+ $('a.fetch_answers').click(
+ function () {
+ var user = this.id.replace('results_for_', '');
+ var path = window.location.pathname;
+ path = path.replace('/edit/', '/show/').replace('/results/', '/show/');
+
+ // TODO(ajaksu) add Date().getTime() to query arg if needed
+ var query = '?read_only=true&user_results=' + user;
+ var scrollable = ['<div style="overflow-y: auto; ',
+ 'margin-bottom: 100px;"></div>'].join("");
+ $(scrollable).load(path + query + ' #survey_widget').dialog({
+ title: user,
+ height: 500,
+ width: 700
+ });
+ }
+ );
+
+ /*
+ * == Initiation ==
+ *
+ * Runs on PageLoad and Each Time Field is Added to Survey
+ *
+ */
+
+ survey.bind('init',
+ function () {
+ // TODO(jamslevy) unnecessarily redundant
+ // TODO(jamslevy) This should be refactored as a jQuery function that
+ // acts on only a single field and it should be merged with renderHTML
+ // since they have comparable functionality.
+
+ widget.find('input').each(
+ function () {
+ if (($(this).val().length < 1 ||
+ $(this).val() === DEFAULT_SHORT_ANSWER_TEXT) &&
+ ($(this).attr('type') !== 'hidden')) {
+ $(this).preserveDefaultText(DEFAULT_SHORT_ANSWER_TEXT);
+ }
+ }
+ );
+
+ widget.find('.long_answer').each(
+ function () {
+ if ($(this).val().length < 1 ||
+ $(this).val() === DEFAULT_LONG_ANSWER_TEXT) {
+ $(this).preserveDefaultText(DEFAULT_LONG_ANSWER_TEXT);
+ }
+ $(this).growfield();
+ }
+ );
+
+ widget.find('a.delete img').click(
+ function () {
+ // delete a field
+ var this_field = $(this).parents('tr:first');
+ var deleted_id = $(this_field).find('label').attr('for');
+ var delete_this = confirm(["Deleting this field will remove all ",
+ "answers submitted for this field. ",
+ "Continue?"].join(""));
+ if (delete_this) {
+ var edit_form = $('#EditForm');
+ var deleted_field = $('#__deleted__');
+ if (deleted_field.val()) {
+ deleted_field.val(deleted_field.val() + ',' +
+ deleted_id.replace('id_', '')).end();
+ }
+ else {
+ var deleted_input = $("<input type='hidden' value='" +
+ deleted_id.replace('id_', '') + "' />");
+ deleted_input.attr({'id': '__deleted__'}).attr({
+ 'name': '__deleted__'
+ });
+ edit_form.append(deleted_input);
+ }
+ this_field.remove();
+ }
+ }
+ );
+
+ // Add list/choice-field item to survey
+ $('[name=create-option-button]').each(
+ function () {
+ $(this).click(
+ function () {
+ var new_option_val = $('#new_item_field_ul_id');
+ var new_option_dialog = $("#new_item_dialog");
+
+ new_option_val.val($(this).parents('fieldset').children('ol')
+ .attr('id'));
+
+ new_option_dialog.dialog('open').find('input:first').focus();
+ }
+ )
+ .hover(
+ function () {
+ $(this).addClass("ui-state-hover");
+ },
+ function () {
+ $(this).removeClass("ui-state-hover");
+ }
+ )
+ .mousedown(
+ function () {
+ $(this).addClass("ui-state-active");
+ }
+ )
+ .mouseup(
+ function () {
+ $(this).removeClass("ui-state-active");
+ }
+ );
+ }
+ );
+
+ options.find('.AddQuestion').click(
+ function (e) {
+ // Choose a field type
+ $("#new_question_button_id").val($(this).attr('id'));
+ var question_options_div = $('#question_options_div');
+ if ($(this).attr('id') === 'choice') {
+ question_options_div.show();
+ }
+ else {
+ question_options_div.hide();
+ }
+
+ $("#new_question_dialog").dialog('open').find('input:first')
+ .focus();
+ }
+ );
+ }).trigger('init')
+ .bind('option_init',
+ function () {
+
+ // Delete list/choice-field item from survey
+ widget.find('a.delete_item').click(
+ function () {
+ var to_delete = this.id.replace('del_', '');
+ $('#delete_item_field').val(to_delete);
+ $('#delete_item_dialog').dialog('open');
+ }
+ ).end();
+
+ }
+ ).trigger('option_init');
+
+
+ /* GSOC ROLE-SPECIFIC FIELD PLUGIN
+ * Choice between student/mentor renders required GSOC specific fields
+ */
+
+ var taking_access_field = $('select#id_taking_access');
+
+ var addRoleFields = function (role_type) {
+ // these should ideally be generated with django forms
+ // TODO: apply info tooltips
+ var CHOOSE_A_PROJECT_FIELD = [
+ '<tr class="role-specific"><th><label>Choose Project:</label></th>',
+ '<td> <select disabled=TRUE id="id_survey__NA__selection__project"',
+ ' name="survey__1__selection__see"><option>Survey Taker\'s Projects',
+ 'For This Program</option></select> </td></tr>'
+ ].join("");
+
+ var CHOOSE_A_GRADE_FIELD = [
+ '<tr class="role-specific"><th><label>Assign Grade:</label></th><td>',
+ '<select disabled=TRUE id="id_survey__NA__selection__grade"',
+ 'name="survey__1__selection__see"><option>Pass/Fail</option></select>',
+ '</td></tr>'
+ ].join("");
+
+ // flush existing role-specific fields
+ var role_specific_fields = survey.find('tr.role-specific');
+ role_specific_fields.remove();
+
+ switch (role_type) {
+ case "mentor evaluation":
+ survey.prepend(CHOOSE_A_PROJECT_FIELD);
+ survey.append(CHOOSE_A_GRADE_FIELD);
+ break;
+
+ case "student evaluation":
+ survey.prepend(CHOOSE_A_PROJECT_FIELD);
+ break;
+ }
+ };
+
+ taking_access_field.change(
+ function () {
+ var role_type = $(this).val();
+ addRoleFields(role_type);
+ }
+ );
+
+ addRoleFields(taking_access_field.val());
+
+ /*
+ * == Survey Submission Handler ==
+ */
+ // Bind submit
+ $('form').bind('submit',
+ function () {
+
+ /*
+ * get rid of role-specific fields
+ */
+ survey.find('tr.role-specific').remove();
+
+ /*
+ * Save survey content html from editPost
+ * if POST fails
+ */
+
+ // save field vals
+ widget.find('.long_answer,input').each(
+ function () {
+ $(this).attr('val', $(this).val());
+ }
+ );
+
+ $(this).find("#id_survey_html").attr('value', widget.html());
+
+ // don't save default value
+ widget.find('input').each(
+ function () {
+ if ($(this).val() === DEFAULT_SHORT_ANSWER_TEXT) {
+ $(this).val('');
+ }
+ }
+ );
+
+ // don't save default value
+ widget.find('.long_answer').each(
+ function () {
+ if ($(this).val() === DEFAULT_LONG_ANSWER_TEXT) {
+ $(this).val('');
+ }
+ }
+ );
+
+ // get rid of the options
+ $('input#id_s_html')
+ .val(
+ widget
+ .find(
+ 'div#survey_options'
+ )
+ .remove()
+ .end()
+ .html()
+ );
+ // only needed for HTML
+
+ // Get option order per field
+ survey.find('.sortable').each(
+ function () {
+ $('#order_for_' + this.id)
+ .val(
+ $(this).sortable(
+ 'serialize'
+ )
+ );
+ }
+ );
+ }
+ );
+ });
+}(jQuery));
+
+
+(function ($) {
+ /*
+ * == Utils ==
+ *
+ */
+ jQuery.fn.extend({
+
+ // get position of survey field
+ getPosition: function () {
+ var this_row = $(this).parents('tr:first');
+ var this_table = this_row.parents('table:first');
+ var position = this_table.find('tr').index(this_row) + '__';
+ return position;
+ }
+ });
+}(jQuery));
+
+
+(function ($) {
+ /*
+ * == Sortable options ==
+ */
+ $(function () {
+ $(".sortable").each(
+ function (i, domEle) {
+ $(domEle).sortable().disableSelection().end();
+ }
+ );
+ });
+}(jQuery));
+
+
+(function ($) {
+ /*
+ * == Editable options ==
+ */
+ $(function () {
+ function onSubmitEditable(content) {
+ var id_ = $(this).parent().attr('id').replace('-li-', '_');
+ id_ = id_ + '__field';
+ $('#' + id_).val(content.current);
+ }
+ $('.editable_option').editable({
+ editBy: 'dblclick',
+ submit: 'change',
+ cancel: 'cancel',
+ onSubmit: onSubmitEditable
+ });
+ });
+}(jQuery));
+
+
+(function ($) {
+ $(function () {
+ var del_li = ["<a class='delete_item' id='del_",
+ "' ><img src='/soc/content/images/minus.gif'/></a> "];
+
+ // Confirmation dialog for deleting list/choice-field item from survey
+ $("#delete_item_dialog").dialog({
+ autoOpen: false,
+ bgiframe: true,
+ resizable: false,
+ height: 300,
+ modal: true,
+ overlay: {
+ backgroundColor: '#000',
+ opacity: 0.5
+ },
+ buttons: {
+ 'Delete this item': function () {
+ $('#' + $('#delete_item_field').val()).remove();
+ $('#delete_item_field').val('');
+ $(this).dialog('close');
+ },
+ Cancel: function () {
+ $('#delete_item_field').val('');
+ $(this).dialog('close');
+ }
+ }
+ });
+
+
+ // Dialog for adding list/choice-field item to survey
+ $("#new_item_dialog").dialog({
+ bgiframe: true,
+ autoOpen: false,
+ height: 300,
+ modal: true,
+ buttons: {
+ 'Add option': function () {
+ var ol_id = $('#new_item_field_ul_id').val();
+ var ol = $('#' + ol_id);
+ var name = $('#new_item_name').val();
+ var i = ol.find('li').length;
+ var id_ = 'id_' + ol_id + '_' + i;
+ var option_html = $([
+ '<li id="id-li-', ol_id, '_', i,
+ '" class="ui-state-defaolt sortable_li">',
+ '<span class="ui-icon ui-icon-arrowthick-2-n-s"></span>',
+ '<span id="', id_, '" class="editable_option" name="', id_,
+ '__field">', name, '</span>', '<input type="hidden" id="', id_,
+ '__field" name="', id_, '__field" value="', name, '" >', '</li>'
+ ].join(""));
+
+ ol.append(
+ option_html
+ .prepend(
+ del_li.join(
+ option_html.attr('id')
+ )
+ )
+ );
+ ol.sortable().disableSelection();
+ $('#new_item_name').val('');
+ $('#new_item_field_ol_id').val('');
+ $(this).dialog('close');
+ },
+ Cancel: function () {
+ $('#new_item_name').val('');
+ $('#new_item_field_ul_id').val('');
+ $(this).dialog('close');
+ }
+ }
+ });
+ });
+}(jQuery));
+
+
+(function ($) {
+ $(function () {
+ // Dialog for adding new question to survey
+ var SURVEY_PREFIX = 'survey__';
+ var del_el = ["<a class='delete'><img '",
+ "src='/soc/content/images/minus.gif'/></a>"].join("");
+ var del_li = ["<a class='delete_item' id='del_",
+ "' ><img src='/soc/content/images/minus.gif'/></a> "];
+
+
+ var widget = $('div#survey_widget');
+ var survey = widget.find('tbody:first');
+
+ $("#new_question_dialog").dialog({
+ bgiframe: true,
+ autoOpen: false,
+ height: 400,
+ modal: true,
+ buttons: {
+ 'Add question': function () {
+ var button_id = $("#new_question_button_id").val();
+ var survey_table = $('div#survey_widget').find('tbody:first');
+ $("#new_question_button_id").val('');
+
+ var field_template = $(["<tr><th><label>", del_el,
+ "</label></th><td> </td></tr>"].join(""));
+
+ var field_name = $("#new_question_name").val();
+ var question_content = $("#new_question_content").val();
+ var question_options = $("#new_question_options").val();
+
+ if (field_name !== '') {
+ $("#new_question_name").val('');
+ $("#new_question_content").val('');
+ $("#new_question_options").val('');
+
+ var new_field = false;
+ var type = button_id + "__";
+ var field_count = survey_table.find('tr').length;
+ var new_field_count = field_count + 1 + '__';
+
+ var MIN_ROWS = 10;
+ var MAX_ROWS = MIN_ROWS * 2;
+ var DEFAULT_OPTION_TEXT = 'Add A New Option...';
+ var default_option = ["<option>", DEFAULT_OPTION_TEXT,
+ "</option>"].join("");
+
+ // create the HTML for the field
+ switch (button_id) {
+ case "short_answer":
+ new_field = "<input type='text'/ class='short_answer'>";
+ break;
+ case "long_answer":
+ new_field = ["<textarea cols='40' rows='", MIN_ROWS,
+ "' class='long_answer'/>"].join("");
+ break;
+ case "selection":
+ new_field = ["<select><option></option>", default_option,
+ "</select>"].join("");
+ break;
+ case "pick_multi":
+ new_field = ["<fieldset class='fieldset'><input type='button'",
+ "value='", DEFAULT_OPTION_TEXT, "' /></fieldset>"]
+ .join("");
+ break;
+ case "choice":
+ new_field = ["<fieldset class='fieldset'><input type='button'",
+ "value='", DEFAULT_OPTION_TEXT, "' /></fieldset>"]
+ .join("");
+ break;
+ }
+
+ if (new_field) {
+ var question_for = [
+ '\n <input type="hidden" name="NEW_', field_name,
+ '" id="NEW_', field_name, '" value="', question_content,
+ '"/>'
+ ].join("");
+
+ field_count = survey_table.find('tr').length;
+ new_field_count = field_count + 1 + '__';
+ var formatted_name = (SURVEY_PREFIX + new_field_count + type +
+ field_name);
+ if (button_id === 'choice') {
+ var name = (field_name);
+ new_field = $([
+ '<fieldset>\n <label for="render_for_', name,
+ '">Render as</label>', '\n <select id="render_for_', name,
+ '" name="render_for_', name, '">', '\n <option',
+ 'selected="selected" value="select">select</option>',
+ '\n <option value="checkboxes">checkboxes</option>',
+ '\n <option value="radio_buttons">radio_buttons</option>',
+ '\n </select>', '\n <input type="hidden" id="order_for_',
+ name, '\n " name="order_for_', name, '" value=""/>',
+ '\n <input type="hidden" id="index_for_', name,
+ '\n " name="index_for_', name, '" value="',
+ (field_count + 1), '"/>\n <ol id="', name,
+ '" class="sortable"></ol>',
+ question_for, '\n <button name="create-option-button"',
+ 'id="create-option-button__', name,
+ '" class="ui-button ui-state-default ui-corner-all" value="',
+ name, '" onClick="return false;">Create new option',
+ '</button>\n</fieldset>'
+ ].join(""));
+
+ $(new_field).attr({
+ 'id': 'id_' + formatted_name,
+ 'name': formatted_name
+ });
+ field_template
+ .find(
+ 'label'
+ )
+ .attr(
+ 'for',
+ 'NEW_' + name
+ )
+ .append(question_content).end()
+ .find(
+ 'td'
+ )
+ .append(new_field);
+ survey_table.append(field_template).end();
+
+ if (question_options) {
+
+ var options_array = question_options.split('\n');
+ var ol = $('#' + name);
+ var length = options_array.length;
+ var oname = '';
+ var id_ = '';
+ var option_html = '';
+
+ for (var i = 0; i < length; i = i + 1) {
+ id_ = 'id_' + name + '_' + i;
+ oname = options_array[i];
+ option_html = $([
+ '<li id="id-li-', name, '_', i,
+ '" class="ui-state-defaolt sortable_li">',
+ '<span class="ui-icon ui-icon-arrowthick-2-n-s"></span>',
+ '<span id="' + id_ + '" class="editable_option" name="',
+ id_, '__field">', oname, '</span>', '<input ',
+ 'type="hidden" id="', id_, '__field" name="', id_,
+ '__field" value="', oname, '" >', '</li>'
+ ].join(""));
+ ol.append(option_html.prepend(
+ del_li.join(option_html.attr('id'))));
+ ol.sortable().disableSelection();
+ }
+
+ survey.trigger('option_init');
+ }
+ }
+
+ else {
+ new_field = $(new_field);
+ // maybe the name should be serialized in a more common format
+ $(new_field).attr({
+ 'id': 'id_' + formatted_name,
+ 'name': formatted_name
+ });
+ field_template.find(
+ 'label'
+ )
+ .attr(
+ 'for',
+ 'id_' + formatted_name
+ )
+ .append(question_content + ":").end()
+ .find(
+ 'td'
+ )
+ .append(new_field).append($(question_for));
+
+ survey_table.append(field_template);
+ }
+
+ survey.trigger('init');
+
+ }
+ }
+ $("#new_question_name").val('');
+ $("#new_question_content").val('');
+ $("#new_question_options").val('');
+ $(this).dialog('close');
+ },
+
+ Cancel: function () {
+ $('#new_question_name').val('');
+ $("#new_question_button_id").val('');
+ $("#new_question_content").val('');
+ $("#new_question_options").val('');
+ $(this).dialog('close');
+ }
+ }
+ });
+ });
+}(jQuery));