Jump to content

Adding a second set of "Add" buttons on top to PageTable


Recommended Posts

Hi,

I have a client which has a PageTable with a long list of PageTable entries. He feels annoyed that he has to scroll down the whole list in order to see the "Add" buttons at the bottom of the list. I would like to build a module which adds a second set of "Add" buttons at the top of the PageTable. I took a look at InputfieldPageTable.module and can see that the buttons get added in the function "___render" at line 117:

		// render the 'Add New' buttons for each template
		$btn = '';
		foreach($this->rowTemplates as $template) { 
			$button = $this->wire('modules')->get('InputfieldButton'); 
			$button->icon = 'plus-circle';
			$button->value = count($this->rowTemplates) == 1 ? $this->_x('Add New', 'button') : $template->getLabel(); 
	
			$url = $this->wire('config')->urls->admin . "page/add/?modal=1&template_id=$template->id&parent_id=$parentID";
			if($this->nameFormat) $url .= "&name_format=" . $this->wire('sanitizer')->entities($this->nameFormat);
			$btn .= "<span class='InputfieldPageTableAdd' data-url='$url'>" . $button->render() . "</span>";
		}
		$out .= "<div class='InputfieldPageTableButtons ui-helper-clearfix'>$btn</div>";

Since there is no hookable method for adding the buttons alone, I think that there are two routes to take now:

- Replace the whole ___render() method

or

- call the existing render method and parse the $event->return for css class "class='InputfieldPageTableButtons" and copy it on top of $event->return (DOM manipulation)

Both ways feel clumsy and not future-proof in case of PageTable module upgrades.

Is there a better route I should take?

  • Like 1
Link to comment
Share on other sites

You could add them with some JS with Admin Custom Files http://modules.processwire.com/modules/admin-custom-files/

Something like:

$(".InputfieldPageTableButtons").each(function(){
    $myButtons = $(this);
    $myTableContainer = $myButtons.closest(".InputfieldPageTableContainer");
    $myButtons.clone().prependTo($myTableContainer);
});

(written in the browser and not tested)

Edited by diogo
corrected typo
  • Like 4
Link to comment
Share on other sites

  • 2 years later...

Based on @diogo's idea above, I impleneted a version which works for multiple Page Tables of the same Page, and only adds the extra button to the top if the table is not empty (i.e. exists):

$(document).ready(function () {
	/*
	 * Use both clonePageTableAddButton(); and bind("DOMSubtreeModified"... below so that it
	 * works with multiple PageTables on the same page.
	 */
	clonePageTableAddButton();
	//Adds the button again, when AJAX updates the table:
	$(".InputfieldPageTableButtons").closest(".InputfieldPageTableContainer").bind("DOMSubtreeModified", function () {
		clonePageTableAddButton();
	});
});

/*
 * Adds a clone of the PageTable field's Add New button to the top of the table
 */
function clonePageTableAddButton() {
	$(".InputfieldPageTableButtons").each(function () {
		$myButtons = $(this);
		$myTableContainer = $myButtons.closest(".InputfieldPageTableContainer");
		//Only add button when Table is not empty (length != 0) and no button has been added already (length < 2)
		if ($myButtons.closest(".InputfieldPageTableContainer").find(".AdminDataTable").length != 0 &&
				$myTableContainer.find(".InputfieldPageTableButtons").length < 2) {
			$myButtons.clone().prependTo($myTableContainer);
		}
	});
}

I think the non-existence of this button on the top of the table is a major UX issue and it should be treated like a bug in the core. What's your opinion on this?

Edited by szabesz
typo
  • Like 1
Link to comment
Share on other sites

Maybe I am misunderstanding. Does this not do what you need?

$button = $this->modules->get("InputfieldButton"); 
$button->showInHeader();
//$button->setSecondary();
$button->href = "{$this->page->url}whatever"; // ??? execute whatever
$button->icon = 'some_icon';
$button->value = "New Thing";
// output button render
return $button->render();

 

Link to comment
Share on other sites

It isn't part of a PageTable or AdminDataTable. The showInHeader() is part of the header of the current page. It will display like the Add New Template button on the Template page.

// in process execute function:
$table = $this->modules->get('MarkupAdminDataTable');
$table->setEncodeEntities(false);
$table->setSortable(true);
$table->setCaption('Table Caption');
$table->headerRow(['col1', 'col2', '...']);

$button = $this->modules->get("InputfieldButton"); 
$button->showInHeader();
//$button->setSecondary();
$button->href = "{$this->page->url}something";
$button->icon = 'some_icon';
$button->value = "Add New Something";

// $table->row( array() ); // populate table rows loop

return $table->render() . $button->render(); // Button is shown after table list (and in page header)

 

Edited by rick
add example
Link to comment
Share on other sites

Actually, I'm not trying to add some extra functionality, I just need a more UX friendly Page Table setup. There are three types of use cases:

#1 Next page is always added to the bottom of the table:

demo-page-table-ASC.gif.cab8a83b4d04ef838ca4a01679b27130.gif

#2 Next page is always added to the top. Which I prefer by setting sort order to -modified, so that when editing the page, the editor does not have to scroll down at all. This is preferable when the sort order does not matter in any other way (i.e frontend order does not depend on it):

demo-page-table-DESC.gif.758242fec3d00fb7a196c3fdde920c3c.gif

#3 And there are those cases when added pages appear somewhere in-between.

When dealing with a lot of rows/pages in the case of #3 and especially in #2 it is much more preferable to have the Add New button on the top of the page table, not just at the bottom.

I do not see how adding an "Add New" Page Table button to the header could help here.

Link to comment
Share on other sites

szabesz, have you ever tried writing a custom process module? sometimes it's a lot easier to write your own custom admin-interface than modifying the regular page edit form ;)

it's easier than you might think! 

 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...