Changing tag list to load content by ajax (fix #49) and updating the default sort order of backend lists (fix #49)

This commit is contained in:
Jason Williams 2020-10-28 17:53:41 -06:00
parent a50c117a98
commit e576e8f566
8 changed files with 165 additions and 133 deletions

View File

@ -0,0 +1,9 @@
$(() => {
var obj = {};
if (typeof tagPartial !== 'string') obj = { '@tags': '#taglist' }
else obj[tagPartial] = '#taglist'
$.request('TagList::onAjaxDataRequested', {
complete: (data) => { $(window).trigger('tagsLoaded', data) }
})
})

View File

@ -1,26 +1,32 @@
<?php namespace JasonWilliams\Feed\Components; <?php namespace JasonWilliams\Feed\Components;
use Db; use Db;
use Cms\Classes\ComponentBase; use Cms\Classes\ComponentBase;
use JasonWilliams\Feed\Models\Tags; use JasonWilliams\Feed\Models\Tags;
class TagList extends ComponentBase class TagList extends ComponentBase
{ {
public function componentDetails() public function componentDetails()
{ {
return [ return [
'name' => 'Tag List', 'name' => 'Tag List',
'description' => 'Displays a list of feed tags.' 'description' => 'Displays a list of feed tags.'
]; ];
} }
public function defineProperties() public function defineProperties()
{ {
return []; return [];
} }
public function onRun() public function onRun()
{ {
$this->page['tags'] = Tags::groupBy('tag')->select(Db::raw('tag, count(*) as count'))->orderBy('count', 'desc')->get(); $this->page['renderPartial'] = $this->property('tagPartial');
} $this->addJs('/plugins/jasonwilliams/feed/assets/javascript/loadtaglist.js');
} }
public function onAjaxDataRequested()
{
return Tags::groupBy('tag')->select(Db::raw('tag, count(*) as count'))->orderBy('count', 'desc')->get();
}
}

View File

@ -1,5 +1 @@
<ul> <div id="tagcloud">Loading...</div>
{% for tag in tags %}
<li><a href="{{ tag.tag }}">{{ tag.tag }}</a></li>
{% endfor %}
</ul>

View File

@ -1,12 +1,15 @@
title: Channels title: Channels
modelClass: jasonwilliams\feed\Models\Channels modelClass: jasonwilliams\feed\Models\Channels
list: $/jasonwilliams/feed/models/channels/columns.yaml list: $/jasonwilliams/feed/models/channels/columns.yaml
recordUrl: 'jasonwilliams/feed/channels/update/:id' recordUrl: 'jasonwilliams/feed/channels/update/:id'
noRecordsMessage: 'backend::lang.list.no_records' noRecordsMessage: 'backend::lang.list.no_records'
recordsPerPage: 20 recordsPerPage: 20
showSetup: true defaultSort:
showCheckboxes: true column: id
toolbar: direction: asc
buttons: list_toolbar showSetup: false
search: showCheckboxes: true
prompt: 'backend::lang.list.search_prompt' toolbar:
buttons: list_toolbar
search:
prompt: 'backend::lang.list.search_prompt'

View File

@ -1,12 +1,15 @@
title: Feed title: Feed
modelClass: jasonwilliams\feed\Models\FeedItem modelClass: jasonwilliams\feed\Models\FeedItem
list: $/jasonwilliams/feed/models/feeditem/columns.yaml list: $/jasonwilliams/feed/models/feeditem/columns.yaml
recordUrl: 'jasonwilliams/feed/feed/update/:id' recordUrl: 'jasonwilliams/feed/feed/update/:id'
noRecordsMessage: 'backend::lang.list.no_records' noRecordsMessage: 'backend::lang.list.no_records'
recordsPerPage: 20 recordsPerPage: 20
showSetup: true defaultSort:
showCheckboxes: true column: timestamp
toolbar: direction: desc
buttons: list_toolbar showSetup: true
search: showCheckboxes: true
prompt: 'backend::lang.list.search_prompt' toolbar:
buttons: list_toolbar
search:
prompt: 'backend::lang.list.search_prompt'

View File

@ -1,10 +1,10 @@
columns: columns:
id: id:
label: 'Channel ID' label: 'Channel ID'
type: number type: number
sortable: true sortable: true
title: title:
label: Title label: Title
type: text type: text
searchable: true searchable: true
sortable: false sortable: true

View File

@ -1,45 +1,64 @@
(function($) { (function($) {
"use strict"; // Start of use strict "use strict"; // Start of use strict
// If the feed is loaded immediadely on page load (i.e. we're not using ajax), reset the layout on each image load // If the feed is loaded immediadely on page load (i.e. we're not using ajax), reset the layout on each image load
$('.masonry img').each(function() { $('.masonry img').each(function() {
$(this).one('load', () => { $(this).one('load', () => {
$('.masonry').masonry() $('.masonry').masonry()
}) })
}) })
// Apply masonry layout to feed cards after content (including images) has been loaded // Apply masonry layout to feed cards after content (including images) has been loaded
$(window).on('feedLoaded', function() { $(window).on('feedLoaded', function() {
if (!feedItemClass) feedItemClass = 'col-sm-12 col-md-6 col-xl-4' if (!feedItemClass) feedItemClass = 'col-sm-12 col-md-6 col-xl-4'
$('.masonry-item').addClass(feedItemClass) $('.masonry-item').addClass(feedItemClass)
$('.show-onfeedloaded').removeClass('d-none') $('.show-onfeedloaded').removeClass('d-none')
$('.masonry').masonry('reloadItems') $('.masonry').masonry('reloadItems')
$('.masonry').masonry() $('.masonry').masonry()
// Every time an image loads, reset the layout // Every time an image loads, reset the layout
$('.masonry img').each(function() { $('.masonry img').each(function() {
$(this).one('load', () => { $(this).one('load', () => {
$('.masonry').masonry() $('.masonry').masonry()
}) })
}) })
}) })
// If there's tag data set once the page is loaded, create a tag cloud // Render the tag cloud if/when tag data is loaded by the component
$(function() { $(window).on('tagsLoaded', function(event, data) {
if(typeof tagData !== 'undefined') { console.log(data.responseJSON)
var cloudWords = []
var cloudWords = []
tagData.forEach((tag) => {
cloudWords.push({text: tag.tag, weight: tag.count, link: '/feed/all/' + tag.tag}) data.responseJSON.forEach((tag) => {
}) cloudWords.push({text: tag.tag, weight: tag.count, link: '/feed/all/' + tag.tag})
})
$('#tagcloud').jQCloud(cloudWords, {
autoResize: true, $('#tagcloud').html('').height($('#tagcloud').width() * 4/3)
removeOverflowing: true,
delay: 2 $('#tagcloud').jQCloud(cloudWords, {
}) autoResize: true,
} removeOverflowing: true,
}) delay: 2
})
})
// If there's tag data set once the page is loaded, create a tag cloud
$(function() {
if(typeof tagData !== 'undefined') {
var cloudWords = []
tagData.forEach((tag) => {
cloudWords.push({text: tag.tag, weight: tag.count, link: '/feed/all/' + tag.tag})
})
$('#tagcloud').jQCloud(cloudWords, {
autoResize: true,
removeOverflowing: true,
delay: 2
})
}
})
})(jQuery); // End of use strict })(jQuery); // End of use strict

View File

@ -14,30 +14,26 @@ includeEmpty = 0
[TagList] [TagList]
== ==
<?php <?php
function onStart() function onStart()
{ {
$this->addJs('https://cdnjs.cloudflare.com/ajax/libs/jqcloud/1.0.3/jqcloud.min.js'); $this->addJs('https://cdnjs.cloudflare.com/ajax/libs/jqcloud/1.0.3/jqcloud.min.js');
$this->addJs('assets/javascript/feedlayout.js'); $this->addJs('assets/javascript/feedlayout.js');
//$this->addCss('https://cdnjs.cloudflare.com/ajax/libs/jqcloud/1.0.3/jqcloud.min.css'); //$this->addCss('https://cdnjs.cloudflare.com/ajax/libs/jqcloud/1.0.3/jqcloud.min.css');
} }
?> ?>
== ==
<div class="row"> <div class="row">
<div class="col-lg-9"> <div class="col-lg-9">
<h1>Feed</h1> <h1>Feed</h1>
<div id="feedarea" class="col-container masonry"> <div id="feedarea" class="col-container masonry">
{% partial 'feed/template' feeditemclass='col-sm-12 col-md-6 col-xl-4' %} {% partial 'feed/template' feeditemclass='col-sm-12 col-md-6 col-xl-4' %}
</div> </div>
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<h2>Channels</h2> <h2>Channels</h2>
{% component 'ChannelList' %} {% component 'ChannelList' %}
<h2>Tags</h2> <h2>Tags</h2>
<div id="tagcloud" style="height: 500px;"></div> <div id="tagcloud"><img src="{{ 'assets/images/loading.svg' | theme }}"></div>
</div> </div>
</div> </div>
{% put scripts %}
<script type="text/javascript">const tagData = {{ tags | raw }};</script>
{% endput %}