2011-04-05 13:36:42 +09:00
var QnA = {
// @fixme: Should use ID
close : function ( closeButt ) {
2011-04-18 18:27:56 +09:00
var notice = $ ( closeButt ) . closest ( 'li.hentry.notice.question' ) ;
console . log ( "close" ) ;
notice . find ( 'input#qna-best-answer,#qna-question-close' ) . hide ( ) ;
2011-04-12 18:22:47 +09:00
notice . find ( 'textarea' ) . hide ( ) ;
2011-04-18 18:27:56 +09:00
var list = notice . find ( 'ul' ) ;
console . log ( "found this many uls: " + list . length ) ;
notice . find ( 'ul > li.notice-answer-placeholder' ) . remove ( ) ;
notice . find ( 'ul > li.notice-answer' ) . remove ( ) ;
2011-04-05 13:36:42 +09:00
} ,
init : function ( ) {
2011-04-12 18:22:47 +09:00
QnA . NoticeInlineAnswerSetup ( ) ;
2011-04-18 18:27:56 +09:00
$ ( 'form.form_question_show' ) . live ( 'submit' , function ( ) {
QnA . close ( this ) ;
2011-04-05 13:36:42 +09:00
} ) ;
2011-04-18 18:27:56 +09:00
$ ( 'form.form_answer_show' ) . live ( 'click' , function ( ) {
QnA . close ( this ) ;
2011-04-05 13:36:42 +09:00
} ) ;
2011-04-19 05:48:35 +09:00
2011-04-12 18:22:47 +09:00
} ,
/ * *
* Open up a question ' s inline answer box .
*
* @ param { jQuery } notice : jQuery object containing one notice
* /
NoticeInlineAnswerTrigger : function ( notice ) {
2011-04-16 11:50:05 +09:00
// Find the notice we're replying to...
2011-04-12 18:22:47 +09:00
var id = $ ( $ ( '.notice_id' , notice ) [ 0 ] ) . text ( ) ;
2011-04-19 05:48:35 +09:00
console . log ( "NoticeInlineAnswerTrigger - answering notice " + id ) ;
2011-04-12 18:22:47 +09:00
2011-04-16 11:50:05 +09:00
var parentNotice = notice ;
2011-04-12 18:22:47 +09:00
2011-04-16 11:50:05 +09:00
// Find the threaded replies view we'll be adding to...
var list = notice . closest ( '.notices' ) ;
2011-04-18 18:27:56 +09:00
2011-04-16 11:50:05 +09:00
if ( list . hasClass ( 'threaded-replies' ) ) {
console . log ( "NoticeInlineAnswerTrigger - there's already a threaded-replies ul above me" ) ;
// We're replying to a reply; use reply form on the end of this list.
// We'll add our form at the end of this; grab the root notice.
parentNotice = list . closest ( '.notice' ) ;
2011-04-19 05:48:35 +09:00
console . log ( "NoticeInlineAnswerTrigger - trying to find the closest .notice above me" ) ;
2011-04-16 11:50:05 +09:00
if ( parentNotice . length > 0 ) {
2011-04-18 18:27:56 +09:00
console . log ( "NoticeInlineAnswerTrigger - found that closest .notice - length = " + parentNotice . length ) ;
2011-04-16 11:50:05 +09:00
}
2011-04-12 18:22:47 +09:00
} else {
2011-04-16 11:50:05 +09:00
console . log ( "NoticeInlineAnswerTrigger - this notice does not have a threaded-reples ul" ) ;
// We're replying to a parent notice; pull its threaded list
// and we'll add on the end of it. Will add if needed.
list = $ ( 'ul.threaded-replies' , notice ) ;
2011-04-12 18:22:47 +09:00
}
2011-04-18 18:27:56 +09:00
// See if the form's already open...
var answerForm = $ ( '.qna_answer_form' , list ) ;
2011-04-12 18:22:47 +09:00
2011-04-19 05:48:35 +09:00
var hideReplyPlaceholders = function ( notice ) {
// Do we still have a dummy answer placeholder? If so get rid of
// reply place holders for this question. If the current user hasn't
// answered the question we want to direct her to providing an
// answer. She can still reply by hitting the reply button if she
// really wants to.
var dummyAnswer = $ ( 'ul.qna-dummy' , notice ) ;
if ( dummyAnswer . length > 0 ) {
console . log ( "hiding any reply placeholders" ) ;
notice . find ( 'li.notice-reply-placeholder' ) . hide ( ) ;
}
}
2011-04-12 18:22:47 +09:00
var nextStep = function ( ) {
2011-04-16 11:50:05 +09:00
console . log ( "NoticeInlineAnswerTrigger (nextStep) - begin" ) ;
2011-04-12 18:22:47 +09:00
2011-04-19 05:48:35 +09:00
var dummyAnswer = $ ( 'ul.qna-dummy' , notice ) ;
dummyAnswer . hide ( ) ;
2011-04-18 18:27:56 +09:00
// Set focus...
2011-04-12 18:22:47 +09:00
var text = answerForm . find ( 'textarea' ) ;
if ( text . length == 0 ) {
throw "No textarea" ;
}
2011-04-18 18:27:56 +09:00
text . focus ( ) ;
2011-04-16 11:50:05 +09:00
console . log ( "NoticeInlineAnswerTrigger (nextStep) - setting up body click handler to hide open form when clicking away" ) ;
2011-04-12 18:22:47 +09:00
$ ( 'body' ) . click ( function ( e ) {
2011-04-16 11:50:05 +09:00
console . log ( "body click handler - got click" ) ;
2011-04-12 18:22:47 +09:00
2011-04-19 05:48:35 +09:00
hideReplyPlaceholders ( notice ) ;
2011-04-18 18:27:56 +09:00
2011-04-12 18:22:47 +09:00
var openAnswers = $ ( 'li.notice-answer' ) ;
if ( openAnswers . length > 0 ) {
2011-04-16 11:50:05 +09:00
console . log ( "body click handler - Found one or more open answer forms to close" ) ;
2011-04-12 18:22:47 +09:00
var target = $ ( e . target ) ;
2011-04-18 18:27:56 +09:00
2011-04-12 18:22:47 +09:00
openAnswers . each ( function ( ) {
2011-04-16 11:50:05 +09:00
console . log ( "body click handler - found an open answer form" ) ;
2011-04-12 18:22:47 +09:00
// Did we click outside this one?
var answerItem = $ ( this ) ;
2011-04-18 18:27:56 +09:00
var parentNotice = answerItem . closest ( 'li.notice' ) ;
2011-04-19 05:48:35 +09:00
2011-04-12 18:22:47 +09:00
if ( answerItem . has ( e . target ) . length == 0 ) {
var textarea = answerItem . find ( '.notice_data-text:first' ) ;
var cur = $ . trim ( textarea . val ( ) ) ;
// Only close if there's been no edit.
if ( cur == '' || cur == textarea . data ( 'initialText' ) ) {
2011-04-16 11:50:05 +09:00
console . log ( "body click handler - no text in answer form, closing it" ) ;
2011-04-12 18:22:47 +09:00
answerItem . remove ( ) ;
2011-04-18 18:27:56 +09:00
console . log ( "body click handler - showing dummy placeholder" ) ;
2011-04-19 05:48:35 +09:00
dummyAnswer . show ( ) ;
2011-04-18 18:27:56 +09:00
2011-04-16 11:50:05 +09:00
} else {
console . log ( "body click handler - there is text in the answer form, wont close it" ) ;
2011-04-12 18:22:47 +09:00
}
}
} ) ;
}
2011-04-18 18:27:56 +09:00
console . log ( 'body click handler - exit' ) ;
} ) ;
2011-04-12 18:22:47 +09:00
} ;
2011-04-16 11:50:05 +09:00
// See if the form's already open...
2011-04-18 18:27:56 +09:00
2011-04-16 11:50:05 +09:00
if ( answerForm . length > 0 ) {
console . log ( "NoticeInlineAnswerTrigger - found an open .notice-answer-form - doing nextStep()" ) ;
2011-04-12 18:22:47 +09:00
nextStep ( ) ;
} else {
2011-04-19 05:48:35 +09:00
console . log ( "NoticeInlineAnswerTrigger - hiding the dummy placeholder" ) ;
2011-04-18 18:27:56 +09:00
var placeholder = list . find ( 'li.qna-dummy-placeholder' ) . hide ( ) ;
2011-04-16 11:50:05 +09:00
// Create the answer form entry at the end
2011-04-12 18:22:47 +09:00
2011-04-16 11:50:05 +09:00
var answerItem = $ ( 'li.notice-answer' , list ) ;
if ( answerItem . length > 0 ) {
2011-04-18 18:27:56 +09:00
console . log ( "NoticeInlineAnswerTrigger - Found " + answerItem . length + " answer items (notice-answer li)" ) ;
2011-04-16 11:50:05 +09:00
}
if ( answerItem . length == 0 ) {
console . log ( "NoticeInlineAnswerTrigger - no answer item (notice-answer li)" ) ;
2011-04-12 18:22:47 +09:00
answerItem = $ ( '<li class="notice-answer"></li>' ) ;
var intermediateStep = function ( formMaster ) {
2011-04-18 18:27:56 +09:00
// cache it
2011-04-19 05:48:35 +09:00
//if (!QnA.AnswerFormMaster) {
// QnA.AnswerFormMaster = formMaster;
//}
2011-04-18 18:27:56 +09:00
2011-04-16 11:50:05 +09:00
console . log ( "NoticeInlineAnswerTrigger - (intermediate) step begin" ) ;
2011-04-12 18:22:47 +09:00
var formEl = document . _importNode ( formMaster , true ) ;
2011-04-18 18:27:56 +09:00
2011-04-16 11:50:05 +09:00
console . log ( "NoticeInlineAnswerTrigger - (intermediate step) appending answer form to answer item" ) ;
2011-04-19 05:48:35 +09:00
$ ( formEl ) . data ( 'NoticeFormSetup' , true ) ;
2011-04-12 18:22:47 +09:00
answerItem . append ( formEl ) ;
2011-04-19 05:48:35 +09:00
2011-04-16 11:50:05 +09:00
console . log ( "NoticeInlineAnswerTrigger - (intermediate step) appending answer to replies list, after placeholder" ) ;
2011-04-19 05:48:35 +09:00
list . prepend ( answerItem ) ; // *before* the placeholder
2011-04-12 18:22:47 +09:00
var form = answerForm = $ ( formEl ) ;
2011-04-16 11:50:05 +09:00
console . log ( "NoticeInlineAnswerTrigger - (intermediate step) calling QnA.AnswerFormSetup on the form" )
2011-04-12 18:22:47 +09:00
QnA . AnswerFormSetup ( form ) ;
2011-04-16 11:50:05 +09:00
console . log ( "NoticeInlineAnswerTrigger - (intermediate step) calling nextstep()" ) ;
2011-04-12 18:22:47 +09:00
nextStep ( ) ;
} ;
if ( QnA . AnswerFormMaster ) {
2011-04-16 11:50:05 +09:00
console . log ( "NoticeInlineAnswerTrigger - found a cached copy of the answer form" ) ;
2011-04-12 18:22:47 +09:00
// We've already saved a master copy of the form.
// Clone it in!
2011-04-16 11:50:05 +09:00
console . log ( "NoticeInlineAnswerTrigger - calling intermediateStep with cached form" ) ;
2011-04-12 18:22:47 +09:00
intermediateStep ( QnA . AnswerFormMaster ) ;
} else {
// Fetch a fresh copy of the answer form over AJAX.
// Warning: this can have a delay, which looks bad.
// @fixme this fallback may or may not work
var url = $ ( '#answer-action' ) . attr ( 'value' ) ;
2011-04-16 11:50:05 +09:00
console . log ( "NoticeInlineAnswerTrigger - fetching new form via HXR" ) ;
2011-04-12 18:22:47 +09:00
$ . get ( url , { ajax : 1 } , function ( data , textStatus , xhr ) {
2011-04-16 11:50:05 +09:00
console . log ( "NoticeInlineAnswerTrigger - got a new form via HXR, calling intermediateStep" ) ;
2011-04-12 18:22:47 +09:00
intermediateStep ( $ ( 'form' , data ) [ 0 ] ) ;
} ) ;
}
}
}
console . log ( 'NoticeInlineAnswerTrigger - exit' ) ;
} ,
/ * *
* Setup function -- DOES NOT apply immediately .
*
* Sets up event handlers for inline reply mini - form placeholders .
* Uses 'live' rather than 'bind' , so applies to future as well as present items .
* /
NoticeInlineAnswerSetup : function ( ) {
console . log ( "NoticeInlineAnswerSetup - begin" ) ;
2011-04-18 18:27:56 +09:00
$ ( 'li.qna-dummy-placeholder input.placeholder' )
2011-04-12 18:22:47 +09:00
. live ( 'focus' , function ( ) {
var notice = $ ( this ) . closest ( 'li.notice' ) ;
QnA . NoticeInlineAnswerTrigger ( notice ) ;
return false ;
} ) ;
console . log ( "NoticeInlineAnswerSetup - exit" ) ;
2011-04-16 07:07:17 +09:00
} ,
AnswerFormSetup : function ( form ) {
console . log ( "AnswerFormSetup" ) ;
2011-04-19 05:48:35 +09:00
form . find ( 'textarea' ) . focus ( ) ;
2011-04-16 11:50:05 +09:00
2011-04-19 05:48:35 +09:00
if ( ! form . data ( 'NoticeFormSetup' ) ) {
alert ( 'gargargar' ) ;
}
2011-04-16 11:50:05 +09:00
2011-04-19 05:48:35 +09:00
if ( ! form . data ( 'AnswerFormSetup' ) ) {
//SN.U.NoticeLocationAttach(form);
QnA . FormAnswerXHR ( form ) ;
//SN.U.FormNoticeEnhancements(form);
//SN.U.NoticeDataAttach(form);
form . data ( 'NoticeFormSetup' , true ) ;
}
2011-04-18 18:27:56 +09:00
} ,
2011-04-16 07:07:17 +09:00
/ * *
* Setup function -- DOES NOT trigger actions immediately .
*
* Sets up event handlers for special - cased async submission of the
2011-04-19 05:48:35 +09:00
* answer - posting form , including some pre - post validation .
2011-04-16 07:07:17 +09:00
*
2011-04-19 05:48:35 +09:00
* @ fixme geodata
* @ fixme refactor and unify with FormNoticeXHR in util . js
2011-04-16 07:07:17 +09:00
*
* @ param { jQuery } form : jQuery object whose first element is a form
*
* @ access public
* /
FormAnswerXHR : function ( form ) {
console . log ( "FormAanwerXHR - begin" ) ;
//SN.C.I.NoticeDataGeo = {};
form . append ( '<input type="hidden" name="ajax" value="1"/>' ) ;
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerXHR - appended ajax flag to form" ) ;
2011-04-16 07:07:17 +09:00
// Make sure we don't have a mixed HTTP/HTTPS submission...
form . attr ( 'action' , SN . U . RewriteAjaxAction ( form . attr ( 'action' ) ) ) ;
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerXHR rewrote action so we don't have a mixed HTTP/HTTPS submission" ) ;
2011-04-16 07:07:17 +09:00
/ * *
* Show a response feedback bit under the new - notice dialog .
*
* @ param { String } cls : CSS class name to use ( 'error' or 'success' )
* @ param { String } text
* @ access private
* /
var showFeedback = function ( cls , text ) {
form . append (
$ ( '<p class="form_response"></p>' )
. addClass ( cls )
. text ( text )
) ;
} ;
/ * *
* Hide the previous response feedback , if any .
* /
var removeFeedback = function ( ) {
form . find ( '.form_response' ) . remove ( ) ;
} ;
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerXHR - doing ajaxForm call" ) ;
2011-04-16 07:07:17 +09:00
form . ajaxForm ( {
dataType : 'xml' ,
timeout : '60000' ,
2011-04-19 05:48:35 +09:00
2011-04-16 07:07:17 +09:00
beforeSend : function ( formData ) {
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerXHR - beforeSend" ) ;
2011-04-16 07:07:17 +09:00
if ( form . find ( '.notice_data-text:first' ) . val ( ) == '' ) {
form . addClass ( SN . C . S . Warning ) ;
return false ;
}
form
. addClass ( SN . C . S . Processing )
. find ( '.submit' )
. addClass ( SN . C . S . Disabled )
. attr ( SN . C . S . Disabled , SN . C . S . Disabled ) ;
return true ;
} ,
error : function ( xhr , textStatus , errorThrown ) {
form
. removeClass ( SN . C . S . Processing )
. find ( '.submit' )
. removeClass ( SN . C . S . Disabled )
. removeAttr ( SN . C . S . Disabled , SN . C . S . Disabled ) ;
removeFeedback ( ) ;
if ( textStatus == 'timeout' ) {
// @fixme i18n
showFeedback ( 'error' , 'Sorry! We had trouble sending your notice. The servers are overloaded. Please try again, and contact the site administrator if this problem persists.' ) ;
}
else {
var response = SN . U . GetResponseXML ( xhr ) ;
if ( $ ( '.' + SN . C . S . Error , response ) . length > 0 ) {
form . append ( document . _importNode ( $ ( '.' + SN . C . S . Error , response ) [ 0 ] , true ) ) ;
}
else {
if ( parseInt ( xhr . status ) === 0 || jQuery . inArray ( parseInt ( xhr . status ) , SN . C . I . HTTP20x30x ) >= 0 ) {
form
. resetForm ( )
. find ( '.attach-status' ) . remove ( ) ;
SN . U . FormNoticeEnhancements ( form ) ;
}
else {
// @fixme i18n
showFeedback ( 'error' , '(Sorry! We had trouble sending your notice (' + xhr . status + ' ' + xhr . statusText + '). Please report the problem to the site administrator if this happens again.' ) ;
}
}
}
} ,
success : function ( data , textStatus ) {
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerHXR - success" ) ;
2011-04-16 07:07:17 +09:00
removeFeedback ( ) ;
var errorResult = $ ( '#' + SN . C . S . Error , data ) ;
if ( errorResult . length > 0 ) {
showFeedback ( 'error' , errorResult . text ( ) ) ;
}
else {
// New notice post was successful. If on our timeline, show it!
var notice = document . _importNode ( $ ( 'li' , data ) [ 0 ] , true ) ;
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerXHR - loaded the notice, now trying to insert it somewhere" ) ;
2011-04-16 07:07:17 +09:00
var notices = $ ( '#notices_primary .notices:first' ) ;
2011-04-16 11:50:05 +09:00
2011-04-19 05:48:35 +09:00
console . log ( "FormAnswerXHR - looking for the closest notice with a notice-answer li" ) ;
2011-04-16 11:50:05 +09:00
2011-04-19 05:48:35 +09:00
var answerItem = form . closest ( 'li.notice-answer' ) ;
2011-04-18 18:27:56 +09:00
var questionItem = form . closest ( 'li.question' ) ;
2011-04-19 05:48:35 +09:00
var dummyAnswer = form . find ( 'ul.qna-dummy' ) . remove ( ) ;
if ( answerItem . length > 0 ) {
console . log ( "FormAnswerXHR - I found the answer li to append to" ) ;
2011-04-16 07:07:17 +09:00
// If this is an inline reply, remove the form...
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerXHR - looking for the closest .threaded-replies ul" )
2011-04-16 07:07:17 +09:00
var list = form . closest ( '.threaded-replies' ) ;
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerXHR - search list for the answer placeholder" )
2011-04-19 05:48:35 +09:00
2011-04-16 07:07:17 +09:00
var id = $ ( notice ) . attr ( 'id' ) ;
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerXHR - the new notice id is: " + id ) ;
2011-04-19 05:48:35 +09:00
2011-04-16 07:07:17 +09:00
if ( $ ( "#" + id ) . length == 0 ) {
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerXHR - the notice is not there already so realtime hasn't inserted it before us" ) ;
console . log ( "FormAnswerXHR - inserting new notice before placeholder" ) ;
2011-04-19 05:48:35 +09:00
$ ( notice ) . insertBefore ( answerItem ) ;
answerItem . remove ( ) ;
2011-04-18 18:27:56 +09:00
SN . U . NoticeInlineReplyPlaceholder ( questionItem ) ;
2011-04-16 11:50:05 +09:00
2011-04-16 07:07:17 +09:00
} else {
// Realtime came through before us...
}
2011-04-16 11:50:05 +09:00
2011-04-16 07:07:17 +09:00
} else if ( notices . length > 0 && SN . U . belongsOnTimeline ( notice ) ) {
2011-04-16 11:50:05 +09:00
console . log ( 'FormAnswerXHR - there is at least one notice on the timeline and the new notice should be added to the list' ) ;
// Not a reply. If on our timeline, show it at the
2011-04-16 07:07:17 +09:00
if ( $ ( '#' + notice . id ) . length === 0 ) {
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerXHR - The notice is not yet on the timeline." )
2011-04-16 07:07:17 +09:00
var notice _irt _value = form . find ( '#inreplyto' ) . val ( ) ;
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerXHR - getting value from #inreplyto inside the form: " + notice _irt _value ) ;
2011-04-16 07:07:17 +09:00
var notice _irt = '#notices_primary #notice-' + notice _irt _value ;
2011-04-16 11:50:05 +09:00
console . log ( "notice_irt selector = " + notice _irt _value ) ;
2011-04-16 07:07:17 +09:00
if ( $ ( 'body' ) [ 0 ] . id == 'conversation' ) {
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerXHR - we're on a conversation page" ) ;
2011-04-16 07:07:17 +09:00
if ( notice _irt _value . length > 0 && $ ( notice _irt + ' .notices' ) . length < 1 ) {
$ ( notice _irt ) . append ( '<ul class="notices"></ul>' ) ;
}
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerXHR - appending notice after notice_irt selector" ) ;
2011-04-16 07:07:17 +09:00
$ ( $ ( notice _irt + ' .notices' ) [ 0 ] ) . append ( notice ) ;
}
else {
2011-04-16 11:50:05 +09:00
console . log ( "FormAnswerXHR prepending notice to top of the notice list" ) ;
2011-04-16 07:07:17 +09:00
notices . prepend ( notice ) ;
}
$ ( '#' + notice . id )
. css ( { display : 'none' } )
. fadeIn ( 2500 ) ;
}
2011-04-16 11:50:05 +09:00
// realtime injected the notice first
2011-04-16 07:07:17 +09:00
} else {
// Not on a timeline that this belongs on?
// Just show a success message.
// @fixme inline
showFeedback ( 'success' , $ ( 'title' , data ) . text ( ) ) ;
}
//form.resetForm();
//SN.U.FormNoticeEnhancements(form);
}
} ,
complete : function ( xhr , textStatus ) {
form
. removeClass ( SN . C . S . Processing )
. find ( '.submit' )
. removeAttr ( SN . C . S . Disabled )
. removeClass ( SN . C . S . Disabled ) ;
}
} ) ;
2011-04-05 13:36:42 +09:00
}
2011-04-12 18:22:47 +09:00
2011-04-05 13:36:42 +09:00
} ;
$ ( document ) . ready ( function ( ) {
QnA . init ( ) ;
} ) ;