Jump to content

Removing "Add new" from PageTable field


moonwhaler
 Share

Recommended Posts

Hi everyone,

after successfully solving the mystery "PageTable", I stumbled upon another one: removing the "add new" button from PageTable (in the template) via hooks.

So, I read about hooks. I never implemented one myself, but tried using the "init" PHP file from the default site, but that didn't work out too well. So again I am a bit stuck in the process. :(

Basically, I check if an array is empty. If it is, the PageTable field on my template shouldn't display the "add new" button. That's about it.

Since PageTable is fairly new, I didn't find too much info about it. Maybe someone of you is able to help me?

Thanks a lot!

Link to comment
Share on other sites

EDIT: Ignore this idea completely - soma's solution hooking into InputfieldButton::render is obviously a much better idea :)

I don't have time right now to put a working solution together, but you'll want to hook into InputfieldPageTable::render and do an $event->replace = true and then scan the content and strip out the add new button. You could do that with a regex, eg:

function strip_selected_tags_by_id_or_class($array_of_id_or_class, $text) 
{ 
   $name = implode('|', $array_of_id_or_class); 
   $regex = '#<(\w+)\s[^>]*(class|id)\s*=\s*[\'"](' . $name . 
            ')[\'"][^>]*>.*</\\1>#isU'; 
   return(preg_replace($regex, '', $text)); 
} 

or perhaps more efficiently with domdocument's removeChild() - eg: http://stackoverflow.com/questions/12903483/remove-a-domnode-with-a-certain-class-in-php

Something like this:

<?php
class RemoveAddButton extends WireData implements Module {

    public static function getModuleInfo() {
        return array(
            'title' => 'Conditionally Remove Page Table Add Button',
            'version' => 1,
            'singular' => true,
            'autoload' => true
            );
    }

    public function init() {
        $this->addHookAfter('InputfieldPageTable::render', $this, 'removeButton');
    }



    public function removeButton(HookEvent $event) {
        $event->replace = true;
        if(count(array)==0){
            $event->return = regex or removechild here to remove button from original $event->return;
        }
    }

Hope that gets you going. Otherwise, I'll put something working together for you tomorrow.

Edited by adrian
Obviously not a good approach to things :)
  • Like 4
Link to comment
Share on other sites

I've to add a few things here. In your other thread we where talking about denying the page creating and your idea now is hiding the button upfront. Both ways to solve your problem should be not that different to implement, as both need just hooks to work. 

Now, after writing the post, came this to my mind: 
InputfieldPageTable::render is only called on, big surprise, page render. So in your usecase, this wouldn't be great, because the limit of pages in your pagetable has to work even if the user doesn't leave the page. So I still think that my suggestion of using Pages::add would be more useful, even if it's a little bit less userfriendly, because the add button will throw an error, instead of simply disappearing.

 
An addition to adrians post: You put your hook in the init.php in the template folder? If so, it can't work because this file is only called if your browsing the frontend. You need your hook to work in the backend. While you can use hooks in template files, we don't change the core admin template files. So the best way to get your hook into the backend is via a small module, like the one adrian posted. This example code with the docs about hooks and modules here on processwire.com should get you at least somewhere.
 
What's missing in the code of adrian, is a condition, when to remove the "add" button. I would limit the check for players / positions to the right template or the right field in the hook and only then do the checkup.

  • Like 3
Link to comment
Share on other sites

Here's an example module that removes "Add New" button(s) on InputfieldPageTable on a condition (here if there's 2 ore more entries).

Hook before InputfieldPageTable::render, then add hook after InputfieldButton::render. Since InputfieldButton is used by PageTable, we just use that hook to empty the returned markup for the button. Then remove that button hook after the InputfieldPageTable rendered.

https://gist.github.com/somatonic/c9db5c43f10d050bb14d

  • Like 9
Link to comment
Share on other sites

Okay guys I am truly overwhelmed by your support. I think this is VERY rare nowadays.

That really encourages me to support PW even more by buying some Pro modules soon. It's really, really good to have a community like this! :lol:

@adrian: Thank you for you effort. After reading your code it gave me a more deeper understanding on where to put the hooks!

@LostKobrakai: Your dedication is stunning. ;) And you're right: the "init" PHP is only executed front-end wise. Thank you for opening my eyes!

Basically, you're right. Adding this hook globally to all pages might seem too much, but Soma does a little check before doing anything:

if($table->name !== "mypagetable") return;

I think the performance hit (if any) is still bearable.

@Soma: Hero Member really suits you. I just copied your source from Git, installed the module and it worked out of the box! :rolleyes:

I cannot mark two posts as "solved", so the "solved" goes also to yours, adrian!

Just a short follow up to working with classes: since I'm outside the normal scope of the "$pages" object, I have to use the global (ugh) "wire('pages')" inside the class instead, am I right?

  • Like 3
Link to comment
Share on other sites

Obviously a much better approach from Soma! so I definitely don't deserve a "Solved" on this one :)

Of course my original code snippet didn't exclude other fields, but I was thinking something along the lines of checking the name of the field before proceeding - just didn't get that far when posting in a rush yesterday :)

  • Like 1
Link to comment
Share on other sites

  • 1 year later...

Hello @ all,

I read Somas solution how to remove the add button and I have tried to adapt the code for another condition. Soma uses the number of rows as his condition but I want to use the value of a field instead, but I can get it to work.

In my case I want to use a fieldtype option (select) in the page template to remove the add button or not. If option "1" is selected the button should be removed - if option "2" is selected the button should be still there.

Here is what I have tried:

   public function renderPageTable(HookEvent $event){
         // get the table field
        $table = $event->object;
        $page = $event->arguments[0];
        // make sure this is our field
        if($table->name !== "singleeventtable") return;
        // rendered by InputfieldButton::render
        if($page->eventkindchooser == "1") {
            $this->buttonHook = $this->addHookAfter("InputfieldButton::render", null, function(HookEvent $event){
                // overwrite/remove button markup
                $event->return = '';
            });
        }
    }

Eventkindchooser is the name of the option fieldtype.

Can anyone point me into the right direction?

Link to comment
Share on other sites

  • 1 year later...
On 8/31/2014 at 3:44 AM, Soma said:

Here's an example module that removes "Add New" button(s) on InputfieldPageTable on a condition (here if there's 2 ore more entries).

Soma,

Thank you so much for this. It's a fantastic example which I'm using as of yesterday. I particularly appreciate you posting clean code as I find reading code the best way for me to learn how things work.

 

Do you possibly have any examples of a hook in which I could manipulate more of the admin interface? I'd like to do a couple things:

1. Remove the "settings tab" in the iframe that pops up when editing a PageTable entry. Maybe it's possible to do so with roles and permissions or a technique similar to removing the button.

2. Change the function of the "Add New" button completely - don't create/load the iframe and just create a new PageTable entry programmatically.

If there are hooks to point me at I can figure them out. I've spent time with Captain Hook and but am a bit overwhelmed with the sheer number as well as the fact that I don't know much about how the admin interface is constructed.

 

Link to comment
Share on other sites

58 minutes ago, bmacnaughton said:

Remove the "settings tab" in the iframe that pops up when editing a PageTable entry. Maybe it's possible to do so with roles and permissions or a technique similar to removing the button.

I found this in the meantime - thanks for this post as well.

I got the this working by turning on $config->advanced = true; in config.php which allows hiding the settings tab on a per-template basis! Nice.

It seems that the code in the thread turns off the general ProcessWire menus as well:

Before and after shots attached.

Screenshot from 2017-04-23 08-57-52.png

Screenshot from 2017-04-23 08-59-39.png

I'm working on 2) now.

 

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

×
×
  • Create New...