Skip to content

Commit

Permalink
OUBlog: Pick from available tags #10687
Browse files Browse the repository at this point in the history
  • Loading branch information
jason-platts authored and sammarshallou committed Jul 29, 2014
1 parent 580eb68 commit 8b2b4f7
Show file tree
Hide file tree
Showing 11 changed files with 510 additions and 2 deletions.
17 changes: 17 additions & 0 deletions editpost.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@
$post->post = $post->id;
$post->general = $streditpost;
$post->tags = oublog_get_tags_csv($post->id);
// Add a trailing comma for autocompletion support.
if (!empty($post->tags)) {
$post->tags .= ', ';
}
} else {
$post = new stdClass;
$post->general = $straddpost;
Expand Down Expand Up @@ -163,6 +167,19 @@
$renderer = $PAGE->get_renderer('mod_oublog');
echo $renderer->render_pre_postform($oublog, $cm);
$mform->display();
// Add tagselector yui mod - autocomplete of tags.
$curindividual = -1;
$curgroup = false;
if ($oublog->individual) {
$curindividual = isset($oubloginstance->userid) ? $oubloginstance->userid : $USER->id;
} else {
$curgroup = isset($post->groupid) ? $post->groupid : $currentgroup;
}

$PAGE->requires->yui_module('moodle-mod_oublog-tagselector', 'M.mod_oublog.tagselector.init',
array('id_tags', oublog_get_tag_list($oublog, $curgroup, $cm,
$oublog->global ? $oubloginstance->id : null, $curindividual)));
$PAGE->requires->string_for_js('numposts', 'oublog');

echo $OUTPUT->footer();

Expand Down
51 changes: 51 additions & 0 deletions internaldoc/testcase.basic.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Initial setup
This test case requires:

- a user with administration rights
- a user with student rights
- a test course.

The test server must have debugging set to DEVELOPER level and to display
Expand All @@ -24,6 +25,10 @@ CRE01 / admin.
Create a blog called CRE01 which is a whole-course blog (no groups) and
visible to anyone in the world.

CRE02 / admin.
Enter test course and turn editing on.
Create a blog called CRE02 which should have individual mode set to 'Separate individual blogs'.

INT Testing Intro display
(Requires CRE)
=========================
Expand Down Expand Up @@ -86,6 +91,52 @@ COM03 / admin
-- Verify returned to blog main view and post COM1 has a '1 comment' link.


TAG Testing post tags
(Requires CRE)
=====================

TAG01 / admin
Enter blog 'CRE01'.
Select the 'New blog post' button.
Enter 'TAG1' into the title field.
Enter some text into message field and "tag1, tag2" into the tags field.
Select 'Add post' button to save the new post and return to main blog view.
-- Verify 'tag1 (1)' and 'tag2 (1)' are now shown in the 'tags' tag cloud.

TAG02 / admin
Select 'edit' link for post TAG1 to edit the post just created.
Select the tags field.
-- Verify no tag choices are shown on field focus.
Delete all text in the tags field.
-- Verify tag choice 'tag1 [1 posts]' and 'tag2 [1 posts]' is shown.
Select 'tag1 [1posts]'
-- Verify tags field now contains 'tag1, ' and tag choice is now showing as 'tag2 [1 posts]'.

TAG03 / admin
Enter blog 'CRE02'.
Select the 'New blog post' button.
Enter 'ADMIN_TAG1' into the title field.
Enter some text into message field and "tag3, tag4" into the tags field.
Select 'Add post' button to save the new post and return to main blog view.
-- Verify 'tag3 (1)' and 'tag4 (1)' are now shown in the 'tags' tag cloud.
Select the 'New blog post' button.
Select the tags field.
-- Verify tag choice 'tag3 [1 posts]' and 'tag4 [1 posts]' is shown.
Type 'ta' into tags field.
-- Verify tag choice 'tag3 [1 posts]' and 'tag4 [1 posts]' is shown.
Type 'tag3' into tags field.
-- Verify tag choice 'tag3 [1 posts]' is shown.
Select tag 'tag3'.
-- Verify tags field contains 'tag3, ' and tag choice 'tag4 [1 posts]' is shown.
Select tag 'tag4'.
-- Verify tags field contains 'tag3, tag4, ' and no tag choice is shown.

TAG04 / student [change]
Enter blog 'CRE02'.
Select the 'New blog post' button.
Select the tags field.
-- Verify no tag choices are shown on field focus.

PAG Testing blog display pagination.
===================================

Expand Down
14 changes: 13 additions & 1 deletion locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,19 @@ function oublog_get_tag_cloud($baseurl, $oublog, $groupid, $cm, $oubloginstancei
return($cloud);
}


/**
* Gets tags available to choose from
* @param object $oublog
* @param int $groupid
* @param object $cm
* @param int $oubloginstanceid
* @param int $individualid
* @return array of tag objects
*/
function oublog_get_tag_list($oublog, $groupid, $cm, $oubloginstanceid = null, $individualid=-1) {
$tags = oublog_get_tags($oublog, $groupid, $cm, $oubloginstanceid, $individualid);
return $tags;
}

/**
* Translate a visibility number into a language string
Expand Down
27 changes: 27 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -624,3 +624,30 @@ ul.oublog-accordion li .oublog_statsview_content {
label[for=oublog_searchquery] {
display: inline;
}
/** Tag selector **/
#page-mod-oublog-editpost .yui3-aclist-content {
height: 200px;
overflow-y: auto;
}
div.tagselector_result {
position: relative;
}
div.tagselector_result .tagselector_result_title {
display: inline;
}
div.tagselector_result .tagselector_result_info {
position: relative;
padding: 1px;
padding-left: 4px;
padding-right: 4px;
background-color: #f2f2f2;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
margin-left: .25em;
display: inline-block;
white-space: nowrap;
}
.yui3-aclist-item-active div.tagselector_result .tagselector_result_info {
color: black;
}
47 changes: 46 additions & 1 deletion tests/locallib_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ class oublog_locallib_test extends oublog_test_lib {
* Adding comments
* Getting a single post
* Getting a list of posts
* Tags
// TODO: Unit tests do NOT cover:
* Personal blog auto creation on install has worked
* Access permissions (oublog_check_view_permissions + oublog_can_view_post, oublog_can_post + oublog_can_comment)
* Tags
* Post edits (+ history)
* oublog_get_typical_approval_time() + oublog_too_many_comments_from_ip() [moderated comments]
* Usage stats block functions
Expand Down Expand Up @@ -539,4 +539,49 @@ public function test_oublog_get_posts_pagination() {
// Number of posts returned that were expected?.
$this->assertEquals($postcount - $offset, count($posts));
}

public function test_oublog_tags() {
global $USER, $DB;
$this->resetAfterTest(true);
$this->setAdminUser();


$course = $this->get_new_course();
$stud1 = $this->get_new_user('student', $course->id);
$group1 = $this->get_new_group($course->id);
$this->get_new_group_member($group1->id, $stud1->id);

// Whole course blog.
$oublog = $this->get_new_oublog($course->id);
$cm = get_coursemodule_from_id('oublog', $oublog->cmid);

$post = $this->get_post_stub($oublog->id);
$post->tags = array('1', 'new', 'new', 'new2', 'a space');
$postid = oublog_add_post($post, $cm, $oublog, $course);

$tags = oublog_get_tags($oublog, 0, $cm, null, -1);

foreach ($tags as $tag) {
$this->assertEquals(1, $tag->count);
$this->assertContains($tag->tag, $post->tags);
}

// Individual blog.
$oublog = $this->get_new_oublog($course->id, array('individual' => OUBLOG_VISIBLE_INDIVIDUAL_BLOGS));
$cm = get_coursemodule_from_id('oublog', $oublog->cmid);

$post = $this->get_post_stub($oublog->id);
$post->tags = array('1', 'new', 'new', 'new2', 'a space');
$postid = oublog_add_post($post, $cm, $oublog, $course);

$tags = oublog_get_tags($oublog, 0, $cm, null, $stud1->id);

$this->assertEmpty($tags);

// Group blog.
$oublog = $this->get_new_oublog($course->id, array('groupmode' => VISIBLEGROUPS));
$cm = get_coursemodule_from_id('oublog', $oublog->cmid);

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
YUI.add('moodle-mod_oublog-tagselector', function (Y, NAME) {

M.mod_oublog = M.mod_oublog || {};
M.mod_oublog.tagselector = {
/**
* Initialise the tag selector.
*
* @method init
* @param {String} fieldId id of text field/area to make autocomplete
* @param {Array} tags Array of tag objects (tag,count,label properties)
*/
init: function(fieldId, tags) {
var inputNode = Y.one('form #' + fieldId);
if (tags && typeof tags === 'object') {
// Convert object into array.
var tags2 = [];
for (var key in tags) {
tags2.push(tags[key]);
}
tags = tags2;
}
if (inputNode) {
inputNode.plug(Y.Plugin.AutoComplete, {
minQueryLength: 0,
queryDelay: 100,
queryDelimiter: ',',
allowTrailingDelimiter: true,
source: tags,
width: 'auto',
scrollIntoView: true,
circular: false,
resultTextLocator: 'tag',
resultHighlighter: 'startsWith',

// Chain together a startsWith filter followed by a custom
// result filter
// that only displays tags that haven't already been selected.
resultFilters: ['startsWith', function(query, results) {
// Split the current input value into an array based on
// comma delimiters.
var selected = '';
var lastComma = inputNode.get('value').lastIndexOf(',');
if (lastComma > 0) {
// Ignore tag currently being typed.
selected = inputNode.get('value').substring(0, lastComma).split(/\s*,\s*/);
}

// Convert the array into a hash for faster lookups.
selected = Y.Array.hash(selected);

// Filter out any results that are already selected, then
// return the
// array of filtered results.
var newResults = Y.Array.filter(results, function(result) {
return !selected.hasOwnProperty(result.text);
});
// Always sort by tag text to ensure correct.
function compareResults(a, b) {
if (a.raw.tag < b.raw.tag) {
return -1;
}
if (a.raw.tag > b.raw.tag) {
return 1;
}
return 0;
}
return newResults.sort(compareResults);
}],
// Custom result formatter to show tag info.
resultFormatter: function(query, results) {
return Y.Array.map(results, function(result) {
var out = '<div class="tagselector_result"><span class="tagselector_result_title">' +
result.highlighted + '</span>';
if (result.raw.label) {
out += ' <span class="tagselector_result_info tagselector_result_info_label">' +
result.raw.label + '</span>';
}
out += ' <span class="tagselector_result_info">' +
M.util.get_string('numposts', 'oublog', result.raw.count) +
'</span>' + '</div>';
return out;
});
}
});

// When the input node receives focus, send an empty query to
// display the full list of tag suggestions.
inputNode.on('focus', function() {
inputNode.ac.sendRequest('');
});

// After a tag is selected, send an empty query to update the list of tags.
inputNode.ac.after('select', function(e) {
// On select the browser (chrome) is scrolled to input node so you can't see list.
// See https://github.com/yui/yui3/issues/958
// Work-around: scroll down by (hard-coded) list height + text area height.
if (Y.UA.chrome) {
window.scrollBy(0, parseInt(inputNode.getStyle('height')) + 200);
}
// Send the query on the next tick to ensure that the input node's blur
// handler doesn't hide the result list right after we show it.
setTimeout(function() {
inputNode.ac.sendRequest('');
inputNode.ac.show();
}, 1);
});

}
}
};


}, '@VERSION@', {"requires": ["base", "node", "autocomplete", "autocomplete-filters", "autocomplete-highlighters"]});

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8b2b4f7

Please sign in to comment.