QnA - Work on getting questions and answers to appear correctly inline
This commit is contained in:
parent
9346d50102
commit
6bf29ff684
@ -95,6 +95,7 @@ var SN = { // StatusNet
|
|||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
FormNoticeEnhancements: function(form) {
|
FormNoticeEnhancements: function(form) {
|
||||||
|
console.log("FormNoticeEnhancements - begin");
|
||||||
if (jQuery.data(form[0], 'ElementData') === undefined) {
|
if (jQuery.data(form[0], 'ElementData') === undefined) {
|
||||||
MaxLength = form.find('.count').text();
|
MaxLength = form.find('.count').text();
|
||||||
if (typeof(MaxLength) == 'undefined') {
|
if (typeof(MaxLength) == 'undefined') {
|
||||||
@ -320,6 +321,7 @@ var SN = { // StatusNet
|
|||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
FormNoticeXHR: function(form) {
|
FormNoticeXHR: function(form) {
|
||||||
|
console.log("FormNoticeXHR - begin");
|
||||||
SN.C.I.NoticeDataGeo = {};
|
SN.C.I.NoticeDataGeo = {};
|
||||||
form.append('<input type="hidden" name="ajax" value="1"/>');
|
form.append('<input type="hidden" name="ajax" value="1"/>');
|
||||||
|
|
||||||
@ -777,6 +779,7 @@ var SN = { // StatusNet
|
|||||||
* popout before submitting.
|
* popout before submitting.
|
||||||
*
|
*
|
||||||
* Uses 'live' rather than 'bind', so applies to future as well as present items.
|
* Uses 'live' rather than 'bind', so applies to future as well as present items.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
NoticeRepeat: function() {
|
NoticeRepeat: function() {
|
||||||
$('.form_repeat').live('click', function(e) {
|
$('.form_repeat').live('click', function(e) {
|
||||||
|
@ -375,20 +375,10 @@ class QnAPlugin extends MicroAppPlugin
|
|||||||
$question = QnA_Question::getByNotice($notice);
|
$question = QnA_Question::getByNotice($notice);
|
||||||
|
|
||||||
if (!empty($question)) {
|
if (!empty($question)) {
|
||||||
if (empty($user)) {
|
|
||||||
$form = new QnashowquestionForm($out, $question);
|
$form = new QnashowquestionForm($out, $question);
|
||||||
$form->show();
|
$form->show();
|
||||||
} else {
|
|
||||||
$profile = $user->getProfile();
|
|
||||||
$answer = $question->getAnswer($profile);
|
|
||||||
if (empty($answer)) {
|
|
||||||
$form = new QnanewanswerForm($out, $question);
|
|
||||||
$form->show();
|
|
||||||
} else {
|
|
||||||
$form = new QnashowquestionForm($out, $question);
|
|
||||||
$form->show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$out->text(_m('Question data is missing.'));
|
$out->text(_m('Question data is missing.'));
|
||||||
}
|
}
|
||||||
@ -398,6 +388,66 @@ class QnAPlugin extends MicroAppPlugin
|
|||||||
$out->elementStart('div', array('class' => 'entry-content'));
|
$out->elementStart('div', array('class' => 'entry-content'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output the HTML for this kind of object in a list
|
||||||
|
*
|
||||||
|
* @param NoticeListItem $nli The list item being shown.
|
||||||
|
*
|
||||||
|
* @return boolean hook value
|
||||||
|
*
|
||||||
|
* @fixme WARNING WARNING WARNING this closes a 'div' that is implicitly opened in BookmarkPlugin's showNotice implementation
|
||||||
|
*/
|
||||||
|
function onStartShowNoticeItem($nli)
|
||||||
|
{
|
||||||
|
if (!$this->isMyNotice($nli->notice)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$out = $nli->out;
|
||||||
|
$notice = $nli->notice;
|
||||||
|
|
||||||
|
$this->showNotice($notice, $out);
|
||||||
|
|
||||||
|
$nli->showNoticeLink();
|
||||||
|
$nli->showNoticeSource();
|
||||||
|
$nli->showNoticeLocation();
|
||||||
|
$nli->showContext();
|
||||||
|
$nli->showRepeat();
|
||||||
|
|
||||||
|
$out->elementEnd('div');
|
||||||
|
|
||||||
|
$nli->showNoticeOptions();
|
||||||
|
|
||||||
|
if ($notice->object_type == QnA_Question::OBJECT_TYPE) {
|
||||||
|
|
||||||
|
$user = common_current_user();
|
||||||
|
$question = QnA_Question::getByNotice($notice);
|
||||||
|
|
||||||
|
if (!empty($user)) {
|
||||||
|
|
||||||
|
$profile = $user->getProfile();
|
||||||
|
$answer = $question->getAnswer($profile);
|
||||||
|
|
||||||
|
// Output a placeholder input -- clicking on it will
|
||||||
|
// bring up a real answer form
|
||||||
|
if (empty($answer) && empty($question->closed)) {
|
||||||
|
$out->elementStart('ul', 'notices threaded-replies xoxo');
|
||||||
|
$out->elementStart('li', 'notice-answer-placeholder');
|
||||||
|
$out->element(
|
||||||
|
'input',
|
||||||
|
array('class' => 'placeholder', 'value' => 'Answer...')
|
||||||
|
);
|
||||||
|
$out->elementEnd('li');
|
||||||
|
$out->elementEnd('ul');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function showNoticeAnswer($notice, $out)
|
function showNoticeAnswer($notice, $out)
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
$user = common_current_user();
|
||||||
|
@ -93,8 +93,6 @@ class QnanewanswerAction extends Action
|
|||||||
|
|
||||||
$id = substr($this->trimmed('id'), 9);
|
$id = substr($this->trimmed('id'), 9);
|
||||||
|
|
||||||
common_debug("XXXXXXXXXXXXXXXXXX id = " . $id);
|
|
||||||
|
|
||||||
$this->question = QnA_Question::staticGet('id', $id);
|
$this->question = QnA_Question::staticGet('id', $id);
|
||||||
|
|
||||||
if (empty($this->question)) {
|
if (empty($this->question)) {
|
||||||
@ -124,7 +122,7 @@ class QnanewanswerAction extends Action
|
|||||||
if ($this->isPost()) {
|
if ($this->isPost()) {
|
||||||
$this->newAnswer();
|
$this->newAnswer();
|
||||||
} else {
|
} else {
|
||||||
$this->showPage();
|
$this->showForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -147,7 +145,7 @@ class QnanewanswerAction extends Action
|
|||||||
);
|
);
|
||||||
} catch (ClientException $ce) {
|
} catch (ClientException $ce) {
|
||||||
$this->error = $ce->getMessage();
|
$this->error = $ce->getMessage();
|
||||||
$this->showPage();
|
$this->showForm($this->error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ($this->boolean('ajax')) {
|
if ($this->boolean('ajax')) {
|
||||||
@ -230,4 +228,74 @@ class QnanewanswerAction extends Action
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show an Ajax-y error message
|
||||||
|
*
|
||||||
|
* Goes back to the browser, where it's shown in a popup.
|
||||||
|
*
|
||||||
|
* @param string $msg Message to show
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function ajaxErrorMsg($msg)
|
||||||
|
{
|
||||||
|
$this->startHTML('text/xml;charset=utf-8', true);
|
||||||
|
$this->elementStart('head');
|
||||||
|
// TRANS: Page title after an AJAX error occurs on the post answer page.
|
||||||
|
$this->element('title', null, _('Ajax Error'));
|
||||||
|
$this->elementEnd('head');
|
||||||
|
$this->elementStart('body');
|
||||||
|
$this->element('p', array('id' => 'error'), $msg);
|
||||||
|
$this->elementEnd('body');
|
||||||
|
$this->elementEnd('html');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show an Ajax-y answer form
|
||||||
|
*
|
||||||
|
* Goes back to the browser, where it's shown in a popup.
|
||||||
|
*
|
||||||
|
* @param string $msg Message to show
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function ajaxShowForm()
|
||||||
|
{
|
||||||
|
common_debug('ajaxShowForm()');
|
||||||
|
$this->startHTML('text/xml;charset=utf-8', true);
|
||||||
|
$this->elementStart('head');
|
||||||
|
// TRANS: Title for form to send answer to a question.
|
||||||
|
$this->element('title', null, _m('TITLE','Your answer'));
|
||||||
|
$this->elementEnd('head');
|
||||||
|
$this->elementStart('body');
|
||||||
|
|
||||||
|
$form = new QnanewanswerForm($this, $this->question);
|
||||||
|
$form->show();
|
||||||
|
|
||||||
|
$this->elementEnd('body');
|
||||||
|
$this->elementEnd('html');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $msg An error message, if any
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function showForm($msg = null)
|
||||||
|
{
|
||||||
|
common_debug("show form - msg = $msg");
|
||||||
|
if ($this->boolean('ajax')) {
|
||||||
|
if ($msg) {
|
||||||
|
$this->ajaxErrorMsg($msg);
|
||||||
|
} else {
|
||||||
|
$this->ajaxShowForm();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->msg = $msg;
|
||||||
|
$this->showPage();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1 +1,5 @@
|
|||||||
/* stubb for q&a css */
|
/* Why doesn't this work? */
|
||||||
|
input.answer-placeholder {
|
||||||
|
margin-left: 0;
|
||||||
|
width: 95%;
|
||||||
|
}
|
||||||
|
@ -5,21 +5,186 @@ var QnA = {
|
|||||||
|
|
||||||
// @fixme: Should use ID
|
// @fixme: Should use ID
|
||||||
close: function(closeButt) {
|
close: function(closeButt) {
|
||||||
$(closeButt)
|
notice = $(closeButt).closest('li.hentry.notice.question');
|
||||||
.closest('li.hentry.notice.question')
|
notice.find('input[name=best],[name=close]').hide();
|
||||||
.find('input[name=best],[name=close]')
|
notice.find('textarea').hide();
|
||||||
.hide();
|
notice.find('li.notice-answer-placeholder').hide();
|
||||||
|
notice.find('#answer-form').hide();
|
||||||
},
|
},
|
||||||
|
|
||||||
init: function() {
|
init: function() {
|
||||||
|
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
|
QnA.NoticeInlineAnswerSetup();
|
||||||
|
|
||||||
$('input[name=close]').live('click', function() {
|
$('input[name=close]').live('click', function() {
|
||||||
that.close(this);
|
that.close(this);
|
||||||
});
|
});
|
||||||
$('input[name=best]').live('click', function() {
|
$('input[name=best]').live('click', function() {
|
||||||
that.close(this);
|
that.close(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open up a question's inline answer box.
|
||||||
|
*
|
||||||
|
* @param {jQuery} notice: jQuery object containing one notice
|
||||||
|
*/
|
||||||
|
NoticeInlineAnswerTrigger: function(notice) {
|
||||||
|
console.log('NoticeInlineAnswerTrigger - begin');
|
||||||
|
|
||||||
|
// Find the question notice we're answering...
|
||||||
|
var id = $($('.notice_id', notice)[0]).text();
|
||||||
|
console.log("parent notice id = " + id);
|
||||||
|
var parentNotice = notice;
|
||||||
|
|
||||||
|
// See if the form's already there...
|
||||||
|
var answerForm = $('#answer-form', parentNotice);
|
||||||
|
|
||||||
|
if (answerForm) {
|
||||||
|
console.log("Found the answer form.");
|
||||||
|
} else {
|
||||||
|
console.log("Did not find the answer form.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var placeholder = parentNotice.find('li.notice-answer-placeholder');
|
||||||
|
|
||||||
|
// Pull the parents threaded list and we'll add on the end of it.
|
||||||
|
var list = $('ul.threaded-replies', notice);
|
||||||
|
|
||||||
|
if (list) {
|
||||||
|
console.log("Found the " + list.length + " notice place holders.");
|
||||||
|
} else {
|
||||||
|
console.log("Found the notice answer placeholder");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.length == 0) {
|
||||||
|
console.log("list length = 0 adding <ul>");
|
||||||
|
list = $('<ul class="notices threaded-replies xoxo"></ul>');
|
||||||
|
notice.append(list);
|
||||||
|
} else if (list.length == 2) {
|
||||||
|
// remove duplicate ul added by util.js
|
||||||
|
list.last().remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
var answerItem = $('li.notice-answer', list);
|
||||||
|
|
||||||
|
var nextStep = function() {
|
||||||
|
console.log("nextStep - enter");
|
||||||
|
|
||||||
|
// Set focus...
|
||||||
|
var text = answerForm.find('textarea');
|
||||||
|
|
||||||
|
if (text.length == 0) {
|
||||||
|
throw "No textarea";
|
||||||
|
}
|
||||||
|
|
||||||
|
$('body').click(function(e) {
|
||||||
|
console.log("got click");
|
||||||
|
|
||||||
|
var openAnswers = $('li.notice-answer');
|
||||||
|
if (openAnswers.length > 0) {
|
||||||
|
var target = $(e.target);
|
||||||
|
openAnswers.each(function() {
|
||||||
|
// Did we click outside this one?
|
||||||
|
var answerItem = $(this);
|
||||||
|
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')) {
|
||||||
|
var parentNotice = answerItem.closest('li.notice');
|
||||||
|
answerItem.remove();
|
||||||
|
parentNotice.find('li.notice-answer-placeholder').show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
text.focus();
|
||||||
|
};
|
||||||
|
|
||||||
|
placeholder.hide();
|
||||||
|
|
||||||
|
if (answerItem.length > 0) {
|
||||||
|
console.log('answerItem length > 0');
|
||||||
|
// Update the existing form...
|
||||||
|
nextStep();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Create the answer form entry at the end
|
||||||
|
|
||||||
|
if (answerItem.length == 0) {
|
||||||
|
console.log("QQQQQ no notice-answer li");
|
||||||
|
answerItem = $('<li class="notice-answer"></li>');
|
||||||
|
|
||||||
|
var intermediateStep = function(formMaster) {
|
||||||
|
console.log("Intermediate step");
|
||||||
|
var formEl = document._importNode(formMaster, true);
|
||||||
|
answerItem.append(formEl);
|
||||||
|
console.log("appending answerItem");
|
||||||
|
list.append(answerItem); // *after* the placeholder
|
||||||
|
console.log("appended answerItem");
|
||||||
|
console.log(answerItem);
|
||||||
|
var form = answerForm = $(formEl);
|
||||||
|
QnA.AnswerFormSetup(form);
|
||||||
|
|
||||||
|
nextStep();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (QnA.AnswerFormMaster) {
|
||||||
|
// We've already saved a master copy of the form.
|
||||||
|
// Clone it in!
|
||||||
|
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');
|
||||||
|
|
||||||
|
console.log("fetching new form via HXR");
|
||||||
|
|
||||||
|
$.get(url, {ajax: 1}, function(data, textStatus, xhr) {
|
||||||
|
intermediateStep($('form', data)[0]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('NoticeInlineAnswerTrigger - exit');
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
AnswerFormSetup: function(form) {
|
||||||
|
console.log("AnswerFormSetup - begin");
|
||||||
|
if (!form.data('AnswerFormSetup')) {
|
||||||
|
form.data('AnswerFormSetup', true);
|
||||||
|
}
|
||||||
|
console.log("AnswerFormSetup - 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");
|
||||||
|
$('li.notice-answer-placeholder input.placeholder')
|
||||||
|
.live('focus', function() {
|
||||||
|
var notice = $(this).closest('li.notice');
|
||||||
|
QnA.NoticeInlineAnswerTrigger(notice);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
console.log("NoticeInlineAnswerSetup - exit");
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
@ -119,6 +119,15 @@ class QnashowquestionForm extends Form
|
|||||||
'id'
|
'id'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->out->hidden(
|
||||||
|
'answer-action',
|
||||||
|
common_local_url(
|
||||||
|
'qnanewanswer',
|
||||||
|
null,
|
||||||
|
array('id' => 'question-' . $this->question->id)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
$this->out->raw($this->question->asHTML());
|
$this->out->raw($this->question->asHTML());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user