Having a registration form at the foot of every page

Permalink
Hi there,

I'm trying to work out the best place for a registration form that will appear at the foot of every page. It will be placed absolutely on the page - so I don't want it within the footer.

As part of registration on my site I need users to input their addresses along with some other user attributes. Users can currently register successfully thru my main registration page - and I'd like to be able post the form to the same url.

My question is how do I do this? I've tried for ages with out success, I keep running into problems with the js for the address user attribute not being linked to on the page.

Any help would be greatly appreciated,

Cheers,
Gordon

 
JohntheFish replied on at Permalink Reply
JohntheFish
gogza replied on at Permalink Reply
Thanks John,

So the static footer looks the part - however it looks like it only accepts the standard Content block. I've sent the developers an email asking if it would holding a registration form.

And to be honest, I can do the static footer piece. What I can't seem to do is put a registration form (with an address user attribute) in the footer.php (not inside the footer's block) - the js for the address attribute is not added to the head when the page is rendered.

Cheers,
Gordon
JohntheFish replied on at Permalink Reply
JohntheFish
Here's another way, though not as good if the visitor disables javascript.

Put your form anywhere on the page and check it works without the following hack.

Put a <div id="where_you_want_it"></div> and otherwise empty content or html block where you want the form to be (or hard code in the footer).

Put a 3rd html block anywhere containing some script (with a conditional to not do it in edit mode):
$('#where_you_want_it').append($('#original_form_block_container_id'));


So you put the form wherever convenient on the page, then move it to where you want it when the page is viewed.

I have not done this with forms, but it works for other blocks, so I can't see why it shouldn't work.
see http://api.jquery.com/append/
mkly replied on at Permalink Reply 1 Attachment
mkly
Ok, so you you want to recreate the main registration form(all the same data) everywhere on the site?

I attached a quick block I made by copying the registration page view and a little bit of the from the controller. It doesn't have any styling or fancy bits, but I'm sure you can add that. You can place this anywhere you want and it just posts to the main registration.

To put a block on every page I usually add it to the global scrapbook and call it from the theme page_type or footer with
$block = Block::getByName('My Global Scrapbook Block Name');
if( is_object($block) ) $block->display();

Remember this is the name you give the block in the global scrapbook not the name of the block.


EDIT: I should add that if you are new to concrete5 I would check out near the bottom of view.php(line 33-39) to see how you can output attributes for a form. Attributes should have built in methods to display themselves in a form to do some of the lifting for you.
gogza replied on at Permalink Reply
Thanks mkly,

So your block renders my registration form perfectly except ...

The state/province drop-down on my address User attribute doesn't work. The browser throws a js exception:

Uncaught ReferenceError: ccm_setupAttributeTypeAddressSetupStateProvinceSelector is not defined

And that's because the country_state.js file is not linked in the header (or anywhere). Why does the country_state.js not get added to the header?

Now although I went a completely different route, its the exact same problem I had!

Any ideas?

Thanks again,
Gordon
mkly replied on at Permalink Reply
mkly
Yes I see that now. Thanks for the information. I'm working on a fix right now.
mkly replied on at Permalink Reply 1 Attachment
mkly
Ok I think I have it sorted. Thanks again for letting me know about the issue. Hopefully this new one will work better. You can just copy this on over the old one.
gogza replied on at Permalink Reply
Fantastic mkly!

Works like a charm.

So its all about the on_page_view method of the Block controller.

public function on_page_view() {                                        
                Loader::model('attribute/categories/user');                     
                $attribs = UserAttributeKey::getRegistrationList();             
                foreach($attribs as $ak) {                                      
                        $akc = $ak->getController();                            
                        $akc->form();                                           
                }                                                               
        }


I'd like to understand what's happening here. Please correct me if I got it wrong.

1. on_page_view is called before the page is rendered hence we can add to the header.
2. It loads the user attributes models.
3. It gets the attributes required for registration.
4. We get the controller for each attribute and execute the controller's form method. And this adds the required js to the header!

Perfect - thanks for taking the time out to help me solve this. The best thing is I've learned a little but more about Concrete5.

Cheers,
Gordon
gogza replied on at Permalink Reply
So it works like a charm when you add it to an Area but ...

I want to insert it in a pop-up toolbar at the bottom of the page. I don't want editors to be able to remove accidentally so I thought I'd be able to add it to a global scrapbook and call it from code in my footer.php file (as below)

<div id="toolbar">                                                            
    <h1>Apply now</h1>                                                          
    <div class="form-container">                                                
      <p class="button cancel">hide</p>                                         
<?php                                                                           
          $b = Block::getByName("RegistrationAnywhere")->display();             
?>                                                                              
    </div>                                                                      
  </div>


But execution doesn't get past the following line inside the block's view.php:

$attribs = UserAttributeKey::getRegistrationList();


Why would it work fine as a block in an Area but not pulled from the Scrapbook?

Thanks for you time,
Gordon
mkly replied on at Permalink Reply
mkly
Yes this makes sense. I didn't think of that. Calling it from the theme like that would make it too late to add anything to the header. I think I'll make a function to place in the head. Be back in a bit.
mkly replied on at Permalink Best Answer Reply 1 Attachment
mkly
You know I almost gave up for a second. But I have it sorted(I hope). Thanks again for the communication. You seem like part of this is your curiosity so I'll explain a little.

When you add a Global Scrapbook Block the rendering is already done with the header items so if any attributes need to add anything to the header with an addHeaderItem() call then it won't get there. So on_page_view() won't work.

Then there is actually a second problem. Most attributes form() methods output actual forms(like print $form->text). This isn't so good in the header. :) So I wrapped it in ob_start() and ob_end_clean() to suppress the output and just add the header items.

soooooo....
If you use it in the Global Scrapbook you need to add this to the header of the theme before Loader::element('header_required')
<?php 
  $bl = Block::getByName("My Global SB Block Name");
  if(is_object($bl)) $bl->getController()
    ->addRegistrationAnywhereHeaderItems();
?>


Let me know if you have anymore questions or if I screwed anything else up ;)

Best Regards,
Mike
gogza replied on at Permalink Reply
Well done Mike,

It works great - the only change I had to make was alter the url of the form action. I have different types of user and hence different registration urls.

Thanks for all your help, I would never have worked out what to do. And thanks for explaining what's going on too - I've learned about on_page_view, ob_start & ob_end_clean.

I'll let you know when its in production.

Cheers,
Gordon
mkly replied on at Permalink Reply
mkly
Awesome. I'd glad it's working now. That was the first time I deal with adding header elements in that manner so I definitely learned some new things as well.

Best Regards,
Mike
mkly replied on at Permalink Reply
mkly
That sounds about right.
JohntheFish replied on at Permalink Reply
JohntheFish
I've been following this because mkly's block solution looked more complete than my off-the-cuff ideas. Interestingly it has provided me with some ideas for solving a problem I was having with a permissions editing popup. Thanks for all the work you have put into this.

Anyway, now you have a solution that works as a block in a normal area on the page, maybe putting the form where it renders with C5 and then moving it to where you want it using jQuery could be worth revisiting.
SpencerC replied on at Permalink Reply
SpencerC
Hello,

This is very helpful (I think) for what I want to do. Any chance someone could take a moment to explain what you did here for someone who knows his way around the Concrete5 backend a bit, but doesn't know PHP at all?

I am not exactly sure what you put where.

Thanks,
Spencer
SpencerC replied on at Permalink Reply
SpencerC
Hello,

This is very helpful (I think) for what I want to do. Any chance someone could take a moment to explain what you did here for someone who knows his way around the Concrete5 backend a bit, but doesn't know PHP at all?

I am not exactly sure what you put where.

Thanks,
Spencer