/************************************************/ /* IPB3 Javascript */ /* -------------------------------------------- */ /* ips.poll.js - Poll code */ /* (c) IPS, Inc 2008 */ /* -------------------------------------------- */ /* Author: Rikki Tissier */ /************************************************/ var _poll = window.IPBoard; _poll.prototype.poll = { maxQuestions: 0, maxChoices: 0, questions: $H(), choices: $H(), _choices: $H(), votes: $H(), multi: $H(), popup: false, effectDuration: 0.3, /*------------------------------*/ /* Constructor */ init: function() { Debug.write("Initializing ips.poll.js"); document.observe("dom:loaded", function(){ ipb.poll.initPoll(); }); }, /* ------------------------------ */ /** * Initialize the poll, mainly to check * for an existing poll */ initPoll: function() { ipb.poll.popup = new ipb.Popup( 'poll_popup', { type: 'pane', initial: $('poll_wrap'), modal: true, hideAtStart: true, hideClose: true, defer: false, w: '700px', h: 300, evalScript: false }); //if( $('check_public_poll') ){ $('check_public_poll').tooltip(); } //if( $('check_poll_only') ){ $('check_poll_only').tooltip(); } // Are there any questions so far? if( ipb.poll.questions.size() > 0 ) { // Build the choices array ipb.poll.choices.each( function( c ) { var match = c.key.match(/([0-9]+)_([0-9]+)/); if( Object.isUndefined( match[1] ) || Object.isUndefined( match[2] ) ){ return false; } if( !Object.isHash( ipb.poll._choices.get( match[1] ) ) ){ ipb.poll._choices.set( parseInt( match[1] ), $H() ); } var votes = ipb.poll.votes.get( match[0] ) || 0; ipb.poll._choices.get( parseInt( match[1] ) ).set( parseInt( match[2] ), $H({ value: c.value, votes: votes }) ); }); // Now parse questions ipb.poll.questions.each( function( q ) { var qid = q.key; var question = q.value; // Get the choices var html = ipb.templates['poll_question'].evaluate( { qid: qid, value: question } ); $( 'poll_container' ).insert( html ); Debug.write( $('poll_container').innerHTML ); // Allowing multiple choice? if( ipb.poll.multi.get( qid ) == 1 ){ $('multi_' + qid).checked = true; } var choices = ipb.poll._choices.get( qid ); choices.each( function( c ) { var item = ipb.templates['poll_choice'].evaluate( { qid: qid, cid: c.key, choice: c.value.get('value'), votes: c.value.get('votes') } ); $('choices_for_' + qid).insert( item ); // Add Events $('remove_' + qid + '_' + c.key).observe('click', ipb.poll.removeChoice.bindAsEventListener( this, qid, c.key )); if( !ipb.poll.isMod || ipb.poll.isPublicPoll ){ $('poll_' + qid + '_' + c.key + '_votes').remove(); } // And display $('poll_' + qid + '_' + c.key + '_wrap').show(); }); // Add events on the question wrap if( $('add_choice_' + qid ) ) { if( choices.size() >= ipb.poll.maxChoices ){ $('add_choice_' + qid).hide(); } else { $('add_choice_' + qid).observe('click', ipb.poll.addChoice.bindAsEventListener( this, qid ) ); } } if( $('remove_question_' + qid) ) { $('remove_question_' + qid).observe('click', ipb.poll.removeQuestion.bindAsEventListener( this, qid ) ); } $('question_' + qid + '_wrap').show(); }); } // Update our text ipb.poll.updateStatus(); if( $('add_new_question') ){ $('add_new_question').on('click', ipb.poll.addQuestion ); } $('add_poll').observe('click', ipb.poll.toggleForm); $('close_poll').observe('click', ipb.poll.toggleForm); // We need to hook an event onto the form for this poll, // so we can make sure they have entered enough choices var form = $('add_poll').up('form'); if( !Object.isUndefined( form ) ){ $( form ).observe('submit', ipb.poll.submitCheckPoll ); } }, /* ------------------------------ */ /** * Checks poll pre-submit to ensure proper choices * are entered. * * @param {event} e The event */ submitCheckPoll: function(e) { var stop = false; var reason = 'choices'; if( ipb.poll._choices.size() > 0 ) { ipb.poll._choices.each( function( q ){ if( q.value.size() < 2 ){ stop = true; return; } // Bug #31129 - check for filled values var filled_values = q.value.select( function( c ){ if( $('poll_' + q.key + '_' + c.key) ){ return !$('poll_' + q.key + '_' + c.key).value.empty(); } }); if( filled_values.length < 2 ){ stop = true; return; } if ( ! $('question_' + q.key + '_wrap').down('input.input_text').value ) { stop = true; reason = 'questions'; return; } }); if( stop == true ) { ipb.poll.popup.show(); alert( ( reason == 'choices' ) ? ipb.lang['poll_not_enough_choices'] : ipb.lang['poll_questions_missing'] ); Event.stop(e); return false; } } // Move the popup contents back into the form try { $('poll_wrap').hide(); $('add_poll').insert({ after: $('poll_wrap') }); } catch(err){ } }, /* ------------------------------ */ /** * Updates the status text */ updateStatus: function() { if( !$('poll_stats') ){ return; } if( !ipb.lang['poll_stats'] ){ $('poll_stats').remove(); } var questions = parseInt( ipb.poll.maxQuestions ) - ipb.poll._choices.size(); var choices = parseInt( ipb.poll.maxChoices ); var string = ipb.lang['poll_stats'].gsub(/\[\q\]/, questions).gsub(/\[c\]/, choices); $('poll_stats').update( string ); }, /* ------------------------------ */ /** * Toggle the poll form */ toggleForm: function(e) { Event.stop(e); if( ipb.poll.popup.getObj().visible() ){ ipb.poll.popup.hide(); } else { // Add a default question if( ipb.poll._choices.size() == 0 ){ ipb.poll.addQuestion( e, 1 ); } ipb.poll.popup.show(); } }, /* ------------------------------ */ /** * Destroy poll */ destroyPoll: function( e ) { //ipb.poll.removeQuestion }, /* ------------------------------ */ /** * Add a new choice * * @param {event} event The event * @param {int} qid The question ID * @param {boolean} instant Slide down or show instantly? */ addChoice: function(e, qid, instant) { Event.stop(e); if( !qid || !$('choices_for_' + qid) ){ return; } var newid = ipb.poll.getNextID( 'c', qid ); if( ipb.poll._choices.get( qid ).size() >= ipb.poll.maxChoices ){ alert( ipb.lang['poll_no_more_choices'] ); return; } var choice = ipb.templates['poll_choice'].evaluate( { qid: qid, cid: newid, choice: '', votes: 0 } ); $('choices_for_' + qid ).insert( choice ); // Remove votes if( !ipb.poll.isMod || ipb.poll.isPublicPoll ) { $('poll_' + qid + '_' + newid + '_votes').remove(); } // Time to show if( instant ){ $('poll_' + qid + '_' + newid + '_wrap').show(); } else { new Effect.BlindDown( $('poll_' + qid + '_' + newid + '_wrap'), { duration: ipb.poll.effectDuration } ); } // Add event if( $('remove_' + qid + '_' + newid) ){ $('remove_' + qid + '_' + newid ).observe('click', ipb.poll.removeChoice.bindAsEventListener( this, qid, newid ) ); } // Add to array ipb.poll._choices.get( qid ).set( newid, $H({ value: '', votes: 0 }) ); ipb.poll.updateStatus(); }, /* ------------------------------ */ /** * Removes a choice * * @param {event} e The event * @param {int} qid The question ID * @param {int} cid The choice ID */ removeChoice: function(e, qid, cid) { Event.stop(e); if( !qid || Object.isUndefined( cid ) || !$('poll_' + qid + '_' + cid) ){ return; } // If theres a value, check they want to delete if( !$F('poll_' + qid + '_' + cid).blank() ) { if( !confirm( ipb.lang['delete_confirm'] ) ) { return; } } // Hide it new Effect.BlindUp( $('poll_' + qid + '_' + cid + '_wrap' ), { duration: ipb.poll.effectDuration, afterFinish: function(){ $('poll_' + qid + '_' + cid + '_wrap').remove(); } } ); // remove it from array ipb.poll._choices.get( qid ).unset( cid ); ipb.poll.updateStatus(); }, /* ------------------------------ */ /** * Add a new question * * @param {event} e The event * @param {boolean} instant Show instantly? */ addQuestion: function(e, instant) { Debug.write("Here"); Event.stop(e); if( ipb.poll._choices.size() >= ipb.poll.maxQuestions ){ alert( ipb.lang['poll_no_more_q'] ); return; } var newid = ipb.poll.getNextID('q'); var item = ipb.templates['poll_question'].evaluate( { qid: newid, value: '' } ); $( 'poll_container' ).insert( item ); if( $('remove_question_' + newid) ){ $('remove_question_' + newid).observe('click', ipb.poll.removeQuestion.bindAsEventListener( this, newid ) ); } // Show it if( instant ){ $('question_' + newid + '_wrap').show(); } else { new Effect.BlindDown( $('question_' + newid + '_wrap'), { duration: ipb.poll.effectDuration } ); } // Add it to array ipb.poll._choices.set( newid, $H() ); // Lets add a choice to start them off ipb.poll.addChoice(e, newid, 1); // Add events on the question wrap if( $('add_choice_' + newid ) ) { $('add_choice_' + newid).observe('click', ipb.poll.addChoice.bindAsEventListener( this, newid ) ); } ipb.poll.updateStatus(); }, /* ------------------------------ */ /** * Removes a question * * @param {event} e The event * @param {int} qid */ removeQuestion: function(e, qid, force) { Event.stop(e); if( !$('question_' + qid + '_wrap') ){ return; } if( !force ) { // Confirm it if( !confirm( ipb.lang['delete_confirm'] ) ) { return; } // Well, ok then... new Effect.BlindUp( $('question_' + qid + '_wrap'), { duration: ipb.poll.effectDuration, afterFinish: function(){ $('question_' + qid + '_wrap').remove(); } } ); } else { $('question_' + qid + '_wrap').remove(); } // Remove from array ipb.poll._choices.unset( qid ); ipb.poll.updateStatus(); }, /* ------------------------------ */ /** * Returns the next highest ID * * @param {string} type Type of ID, either q for question or c for choice * @param {int} qid Question ID if type is c */ getNextID: function( type, qid ) { //Debug.dir( ipb.poll._choices ); if( type == 'q' ) { if( Object.isUndefined( ipb.poll._choices ) ){ var max = 1; } else { var max = parseInt( ipb.poll._choices.max( function(q){ return parseInt( q.key ); }) ) + 1; if ( isNaN( max ) ) { var max = 1; } } } else { if( Object.isUndefined( qid ) ){ return false; } if( Object.isUndefined( ipb.poll._choices.get( qid ) ) ){ var max = 0; } else { var max = parseInt( ipb.poll._choices.get( qid ).max( function(c){ return parseInt( c.key ); }) ) + 1; if( isNaN( max ) ){ max = 1; } } } Debug.write( max ); return max; } }; ipb.poll.init();