MyBB Community Forums

Full Version: inline moderation JS makes tableless themes difficult to implement #850
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
As of 1.8b2 the inline moderation javascript relies on a specific structure using tables to highlight rows. Instead, search for a certain class such as .thread and add the .trow_selected class to elements containing it.
Yes I plan on working on this, as mentioned here: https://github.com/mybb/mybb/issues/700

I believe the only file with the issue is inline_moderation.js, I've looked through the other files and can't find any element selectors. If anyone finds any others please post them.
If I might make a suggestion:

1) Instead of looking for a parent "tr" look for a parent ".thread"
2) Add/Remove the .trow_selected class to that
3) change the default css to div.trow_selected,tr.trow_selected td{/*style*/}

A quick update gives me this:
forumdisplay_thread template:
<tr class="thread">
	<td align="center" class="{$bgcolor}{$thread_type_class}" width="2%"><span class="thread_status {$folder}" title="{$folder_label}">&nbsp;</span></td>
	<td align="center" class="{$bgcolor}{$thread_type_class}" width="2%">{$icon}</td>
	<td class="{$bgcolor}{$thread_type_class}">
		{$attachment_count}
		<div>
          <span>{$prefix} {$gotounread}{$thread['threadprefix']}<span class="{$inline_edit_class} {$new_class}" id="tid_{$inline_edit_tid}"><a href="{$thread['threadlink']}">{$thread['subject']}</a></span>{$thread['multipage']}</span>
			<div class="author smalltext">{$thread['profilelink']}</div>
		</div>
	</td>
	<td align="center" class="{$bgcolor}{$thread_type_class}"><a href="javascript:MyBB.whoPosted({$thread['tid']});">{$thread['replies']}</a>{$unapproved_posts}</td>
	<td align="center" class="{$bgcolor}{$thread_type_class}">{$thread['views']}</td>
	{$rating}
	<td class="{$bgcolor}{$thread_type_class}" style="white-space: nowrap; text-align: right;">
		<span class="lastpost smalltext">{$lastpostdate}<br />
		<a href="{$thread['lastpostlink']}">{$lang->lastpost}</a>: {$lastposterlink}</span>
	</td>
{$modbit}
</tr>

inline_moderation.js:
var inlineModeration = {
	init: function()
	{
		inlineModeration.inlineCount = 0;
		if(!inlineType || !inlineId)
		{
			return false;
		}

		inlineModeration.cookieName = "inlinemod_"+inlineType+inlineId;
		inputs = $("input");

		if(!inputs)
		{
			return false;
		}

		inlineCookie = $.cookie(inlineModeration.cookieName);

		if(inlineCookie)
		{
			inlineIds = inlineCookie.split("|");
		}
		
		$(inputs).each(function() {
			var element = $(this);
			if((element.attr('name') != "allbox") && (element.attr('type') == "checkbox") && (element.attr('id')) && (element.attr('id').split("_")[0] == "inlinemod"))
			{
				$(element).click(inlineModeration.checkItem);
			}

			if(inlineCookie && element.attr('id'))
			{
				inlineCheck = element.attr('id').split("_");
				id = inlineCheck[1];

				if(inlineIds.indexOf('ALL') != -1)
				{
					inlineModeration.clearChecked();
					inlineCookie = null;
				}
				else if(inlineIds.indexOf(id) != -1)
				{
					element.prop('checked', true);
					var post = element.parents('div.post_content');
          var thread = element.parents('.thread');
					var fieldset = element.parents('fieldset');
					if(post.length > 0)
					{
						post.addClass('trow_selected');
					}
          else if(thread.length > 0)
          {
            thread.addClass('trow_selected');
          }
					else if(fieldset.length > 0)
					{
						fieldset.addClass('inline_selected');	
					}

				}
				else
				{
					element.prop('checked', false);
					var post = element.parents('div.post_content');
          var thread = element.parents('.thread');
					if(post.length > 0)
					{
						post.removeClass('trow_selected');
					}
          else if(thread.length > 0)
          {
            thread.removeClass('trow_selected');
          }
				}
			}
		});
		
		if(inlineCookie)
		{
			goButton = $("#inline_go");
			if(inlineIds)
			{
				var inlineCount = 0;
				$.each(inlineIds, function(index, item) {
					if(item != '') inlineCount++;
				});
				inlineModeration.inlineCount = inlineCount;
			}
			goButton.val(go_text+" ("+(inlineModeration.inlineCount)+")");
		}
		return true;
	},

	checkItem: function()
	{
		element = $(this);

		if(!element || !element.attr('id'))
		{
			return false;
		}

		inlineCheck = element.attr('id').split("_");
		id = inlineCheck[1];

		if(!id)
		{
			return false;
		}

		var newIds = new Array();
		var remIds = new Array();
		inlineCookie = $.cookie(inlineModeration.cookieName);

		if(inlineCookie)
		{
			inlineIds = inlineCookie.split("|");
			$.each(inlineIds, function(index, item) {
				if(item != "" && item != null)
				{
					if(item != id)
					{
						newIds[newIds.length] = item;
					}
				}
			});
		}

		if(element.prop('checked') == true)
		{
			inlineModeration.inlineCount++;
			newIds[newIds.length] = id;

			var post = element.parents('div.post_content');
			var thread = element.parents('.thread');
			if(post.length > 0)
			{
				post.addClass('trow_selected');
			}
      else if(thread.length > 0)
			{
				thread.addClass('trow_selected');
			}
		}
		else
		{
			inlineModeration.inlineCount--;
			var post = element.parents('div.post_content');
      var thread = element.parents('.thread');
			if(post.length > 0)
			{
				post.removeClass('trow_selected');
			}
      else if(thread.length > 0)
      {
        thread.removeClass('trow_selected');
      }

			if(inlineCookie && inlineCookie.indexOf("ALL") != -1)
			{
				// We've already selected all threads, add this to our "no-go" cookie
				remIds[remIds.length] = id;
			}
		}

		goButton = $("#inline_go");
    
    var date = new Date();
    date.setTime(date.getTime() + (60 * 60 * 1000));

		if(remIds.length)
		{
			inlineData = "|"+remIds.join("|")+"|";
			$.cookie(inlineModeration.cookieName + '_removed', inlineData, { expires: date });

			// Get the right count for us
			var count = goButton.val().replace(/[^\d]/g, '');
			inlineModeration.inlineCount = count;
			inlineModeration.inlineCount--;
		}
		else
		{
			inlineData = "|"+newIds.join("|")+"|";
			$.cookie(inlineModeration.cookieName, inlineData, { expires: date });
		}

		if(inlineModeration.inlineCount < 0)
		{
			inlineModeration.inlineCount = 0;
		}

		goButton.val(go_text+" ("+inlineModeration.inlineCount+")");

		return true;
	},

	clearChecked: function()
	{
		var selectRow = $("#selectAllrow");
		if(selectRow)
		{
			selectRow.css('display', "none");
		}
		
		var allSelectedRow = $("#allSelectedrow");
		if(allSelectedRow)
		{
			allSelectedRow.css('display', "none");
		}
		
		inputs = $("input");

		if(!inputs)
		{
			return false;
		}

		$(inputs).each(function() {
			var element = $(this);
			if(!element.val()) return;
			if(element.attr('type') == "checkbox" && ((element.attr('id') && element.attr('id').split("_")[0] == "inlinemod") || element.attr('name') == "allbox"))
			{
				element.prop('checked', false);
			}
		});

		$('div.trow_selected').each(function() {
			$(this).removeClass('trow_selected');
		});

		$('td.trow_selected').each(function() {
			$(this).removeClass('trow_selected');
		});

		$('fieldset.inline_selected').each(function() {
			$(this).removeClass('inline_selected');
		});

		inlineModeration.inlineCount = 0;
		goButton = $("#inline_go");
		goButton.val(go_text+" (0)");
		$.removeCookie(inlineModeration.cookieName);
		$.removeCookie(inlineModeration.cookieName + '_removed');

		return true;
	},

	checkAll: function(master)
	{
		inputs = $("input");
    master = $(master);

		if(!inputs)
		{
			return false;
		}

		inlineCookie = $.cookie(inlineModeration.cookieName);

		if(inlineCookie)
		{
			inlineIds = inlineCookie.split("|");
		}

		var newIds = new Array();
		$(inputs).each(function() {
			var element = $(this);
			if(!element.val() || !element.attr('id')) return;
			inlineCheck = element.attr('id').split("_");
			if((element.attr('name') != "allbox") && (element.attr('type') == "checkbox") && (inlineCheck[0] == "inlinemod"))
			{
				id = inlineCheck[1];
				var changed = (element.prop('checked') != master.prop('checked'));
				element.prop('checked', master.prop('checked'));

				var post = element.parents('div.post_content');
				var fieldset = element.parents('fieldset');
        var thread = element.parents('.thread');
				if(post.length > 0)
        {
          if(master.prop('checked') == true)
          {
            post.addClass('trow_selected');
          }
          else
          {
            post.removeClass('trow_selected');
          }
        }
        else if(thread.length > 0)
        {
          if(master.prop('checked') == true)
          {
            thread.addClass('trow_selected');
          }
          else
          {
            thread.removeClass('trow_selected');
          }
        }
				else if(fieldset.length > 0)
				{
					if(master.prop('checked') == true)
					{
						fieldset.addClass('inline_selected');
					}
					else
					{
						fieldset.removeClass('inline_selected');
					}
				}
				
				if(changed)
				{
					if(master.prop('checked') == true)
					{
						inlineModeration.inlineCount++;
						newIds[newIds.length] = id;
					}
					else
					{
						inlineModeration.inlineCount--;
					}
				}
			}
		});

		inlineData = "|"+newIds.join("|")+"|";
		goButton = $("#inline_go");

		if(inlineModeration.inlineCount < 0)
		{
			inlineModeration.inlineCount = 0;
		}
		
		if(inlineModeration.inlineCount < all_text)
		{
			var selectRow = $("#selectAllrow");
			if(selectRow)
			{
				if(master.prop('checked') == true)
				{
					selectRow.css('display', "table-row");
				}
				else
				{
					selectRow.css('display', "none");
				}
			}
		}
		
		goButton.val(go_text+" ("+inlineModeration.inlineCount+")");
    
    var date = new Date();
    date.setTime(date.getTime() + (60 * 60 * 1000));
		$.cookie(inlineModeration.cookieName, inlineData, { expires: date });
	},
		
	selectAll: function()
	{
		goButton.val(go_text+" ("+all_text+")");
    var date = new Date();
    date.setTime(date.getTime() + (60 * 60 * 1000));
		$.cookie(inlineModeration.cookieName, "|ALL|", { expires: date });
		
		var selectRow = $("#selectAllrow");
		if(selectRow)
		{
			selectRow.css('display', "none");
		}
		
		var allSelectedRow = $("#allSelectedrow");
		if(allSelectedRow)
		{
			allSelectedRow.css('display', "table-row");
		}
	}
};
$(inlineModeration.init);

global.css @ 393:
div.trow_selected, tr.trow_selected td {
	background: #FFFBD9;
	color: #333;
	border-right-color: #F7E86A;
	border-bottom-color: #F7E86A;
}

This works for me in both my custom tableless theme and the modified default theme. I'm still futzing around in 1.8b1 but unless things have drastically changed in b2 it should still work.
I was hoping to fix issues like this as well:

        var selectRow = $("#selectAllrow");
        if(selectRow)
        {
            selectRow.css('display', "none");
        }
        
        var allSelectedRow = $("#allSelectedrow");
        if(allSelectedRow)
        {
            allSelectedRow.css('display', "table-row");
        }

It'd preferably use

allSelectedRow.addClass('visibleSelectRow');

So the CSS could be put in it's proper place, the CSS file.
Yeah, I kept the stuff I changed to the trow_selected thing. Now that we have jQuery we can probably trim a lot of this stuff down a bunch and make it more generic.
In this specific case, I ask you that you create a PR and I'll gladly create an issue for more improvements and mark it as related to your PR.
I... have no idea how to do that...
https://windows.github.com
https://mac.github.com

Or if you could make clear required changes that would work here that could help.
Nah, I need to learn to git anyway since I want to use it for personal projects so now's a good chance to learn.

I already have a nice Windows GUI for git, it's just taking me a bit to learn how to use it...

Done! I think...

https://github.com/mybb/mybb/pull/972
Pages: 1 2