I'm building a website and the menu is up there, working fine.
However, for it to be more user-friendly, I thought maybe I could put the login/logout button all the way to the right.
But there's a problem since I'm using Zend Framework, I can't assign a class to the <li> element, only to the <a> element.
As a normal working process, this list item is already always the last one, which makes it much easier to work with! I guess I could go ahead with some jQuery to detect this element and work around my problem, but then I discovered the "last-child" selector.
In my CSS file, I just added this:
#navigation UL LI:last-child {
float: right;
}
The "last-child" selector will make the last element of the selected type (here, li) follow the defined styles.
And there we have it. Instead of the element always being last but anywhere on the menu tabs, now the login (or logout) tab is always all the way to the far right!
Note that this is not supported in all browsers, but it simply won't change anything in others. Just a little bonus for those users who can keep their stuff updated!
Monday, August 1, 2011
Friday, July 22, 2011
[ZF] Marking navigation tab as active with GET data in request
So I have a contract that I want to edit for a customer. I happily click on the "EDIT" link and the form appears, but wait a minute, something's wrong! The "contract" tab in my menu isn't showing up as the active tab anymore.
The main contract page showed the active class with this in the navigation XML file:
<contract>
<label>Contracts</label>
<uri>/contract/</uri>
<resource>contract</resource>
<privilege>index</privilege>
</contract>
...and to view a contract, I simply use (as a page of the "contract" section):
<contract-view>
<label>View contract</label>
<uri>/contract/view/</uri>
<visible>0</visible>
</contract-view>
But if I want to view a contract, the ID goes through the url, as such: http://www.example.com/contract/view/123/
And when this happens, the navigation file doesn't detect that the current page is the one I want. To counter this, all you have to do is use the alternate method, which is a little longer but prevents any problem:
<contract-view>
<label>View contract</label>
<controller>contract</controller>
<action>view</action>
<visible>0</visible>
</contract-view>
When you specify the action and controller directly, the framework will take care of the rest, and even if you're using routes, everything will display smoothly. This is what I've set up for an URL like http://www.example.com/contract/123/view/
- in the navigation file:
<contract-view>
<label>View contract</label>
<controller>contract</controller>
<action>view</action>
<visible>0</visible>
</contract-view>
- in the routes.ini file:
routes.contractview.route = contract/:id/view
routes.contractview.defaults.controller = contract
routes.contractview.defaults.action = view
routes.contractview.defaults.id = 0
And there you have it! The Zend navigation and router will take care of the rest for you. Now it will detect the page you're on regardless of the URL, as long as the correct controller and action are defined in the configuration files. The beautiful tab is glowing as it should!
The main contract page showed the active class with this in the navigation XML file:
<contract>
<label>Contracts</label>
<uri>/contract/</uri>
<resource>contract</resource>
<privilege>index</privilege>
</contract>
...and to view a contract, I simply use (as a page of the "contract" section):
<contract-view>
<label>View contract</label>
<uri>/contract/view/</uri>
<visible>0</visible>
</contract-view>
But if I want to view a contract, the ID goes through the url, as such: http://www.example.com/contract/view/123/
And when this happens, the navigation file doesn't detect that the current page is the one I want. To counter this, all you have to do is use the alternate method, which is a little longer but prevents any problem:
<contract-view>
<label>View contract</label>
<controller>contract</controller>
<action>view</action>
<visible>0</visible>
</contract-view>
When you specify the action and controller directly, the framework will take care of the rest, and even if you're using routes, everything will display smoothly. This is what I've set up for an URL like http://www.example.com/contract/123/view/
- in the navigation file:
<contract-view>
<label>View contract</label>
<controller>contract</controller>
<action>view</action>
<visible>0</visible>
</contract-view>
- in the routes.ini file:
routes.contractview.route = contract/:id/view
routes.contractview.defaults.controller = contract
routes.contractview.defaults.action = view
routes.contractview.defaults.id = 0
And there you have it! The Zend navigation and router will take care of the rest for you. Now it will detect the page you're on regardless of the URL, as long as the correct controller and action are defined in the configuration files. The beautiful tab is glowing as it should!
Monday, July 18, 2011
[ZF] Merging multiple Zend_Form into one
So you want to merge two or more of your Zend forms into one, right?
This is really easy to do, actually...
First of all, get a blank form:
$form = new Application_Form_UserInformation();
Then, get the other form(s):
$form_append = new Application_Form_UserAddress();
All you have to do is take all the elements from the other form(s) and add them to the first one!
$form->addElements($form_append->getElements());
You can still remove elements or add any by using addElement() or removeElement(). However, watch out for element names! If elements from two separate forms have the same one, the first you set will overwrite the others. This is useful for submit buttons, for example.
Be sure to always have your submission button at the end of your form, before sending it to your view:
$form->submit->setOrder(999);
$this->view->form = $form;
Piece of cake, told you so!
This is really easy to do, actually...
First of all, get a blank form:
$form = new Application_Form_UserInformation();
Then, get the other form(s):
$form_append = new Application_Form_UserAddress();
All you have to do is take all the elements from the other form(s) and add them to the first one!
$form->addElements($form_append->getElements());
You can still remove elements or add any by using addElement() or removeElement(). However, watch out for element names! If elements from two separate forms have the same one, the first you set will overwrite the others. This is useful for submit buttons, for example.
Be sure to always have your submission button at the end of your form, before sending it to your view:
$form->submit->setOrder(999);
$this->view->form = $form;
Piece of cake, told you so!
Monday, June 20, 2011
[ZF] Adding ("current/active/highlight" and/or other) class to menu item
So I had this menu that finally decided to generate correctly from an XML file, cool. Now I thought of the two following thigs:
1. Adding CSS class to current menu element
For the first item, nothing better than to head over to Stack Overflow, as usual. As you can see in there, all you need is:
$uri = $this->_request->getPathInfo();
$active_nav = $this->view->navigation()->findByUri($uri);
$active_nav->active = true;
$active_nav->setClass("active");
However, this won't work in the bootstrap because the request parameters aren't available yet. If you have a menu generating like this, it's very likely you already have a method for generating it in your bootstrap file (e.g.: _initNavigation()). To access the request parameters and find the path info, add this beforehand:
$this->bootstrap('frontController');
$front = $this->getResource('frontController');
$front->setRequest(new Zend_Controller_Request_Http());
Then, just arrange the previous code to find the correct data:
$uri = $front->getRequest()->getPathInfo();
And there we go, the "active" class will be added to whichever tab you are on.
But wait, what if I wanted to add custom icons for each tab?
2. Adding icons to menu tabs
So you've tried adding the image to the label, like so:
<label><img src="/image/nav-1.png" alt="nav-1" />User</label>
... but it doesn't work.
The trick is rather easy, just add some stuff in your CSS file as a class, and add the following node to your XML file (I guess you could easily adapt it if you're loading data from an array):
<class>nav-1</class>
Only there's a slight problem: if you are on the active tab, the bootstrap will override the class and set it to "active".
I've actually found the solution on the first try (nice guess, I admit). In the bootstrap (see code above), just get the tab's current class and add "active" to it:
$current_class = $active_nav->getClass() . ' ';
$active_nav->setClass($current_class . 'active');
That's all there is to it, you can now have a dynamic and beautiful menu!
- Show which tab is active depending on the page
- Add icons to the tabs
1. Adding CSS class to current menu element
For the first item, nothing better than to head over to Stack Overflow, as usual. As you can see in there, all you need is:
$uri = $this->_request->getPathInfo();
$active_nav = $this->view->navigation()->findByUri($uri);
$active_nav->active = true;
$active_nav->setClass("active");
However, this won't work in the bootstrap because the request parameters aren't available yet. If you have a menu generating like this, it's very likely you already have a method for generating it in your bootstrap file (e.g.: _initNavigation()). To access the request parameters and find the path info, add this beforehand:
$this->bootstrap('frontController');
$front = $this->getResource('frontController');
$front->setRequest(new Zend_Controller_Request_Http());
Then, just arrange the previous code to find the correct data:
$uri = $front->getRequest()->getPathInfo();
And there we go, the "active" class will be added to whichever tab you are on.
But wait, what if I wanted to add custom icons for each tab?
2. Adding icons to menu tabs
So you've tried adding the image to the label, like so:
<label><img src="/image/nav-1.png" alt="nav-1" />User</label>
... but it doesn't work.
The trick is rather easy, just add some stuff in your CSS file as a class, and add the following node to your XML file (I guess you could easily adapt it if you're loading data from an array):
<class>nav-1</class>
Only there's a slight problem: if you are on the active tab, the bootstrap will override the class and set it to "active".
I've actually found the solution on the first try (nice guess, I admit). In the bootstrap (see code above), just get the tab's current class and add "active" to it:
$current_class = $active_nav->getClass() . ' ';
$active_nav->setClass($current_class . 'active');
That's all there is to it, you can now have a dynamic and beautiful menu!
[ZF] Hiding navigation elements
If you're building an XML file to create a menu/breadcrumb/sitemap and wish to hide elements from, let's say, the menu, here is what you can do:
Add <visible>0</visible> to your node
You can then use the usual <?php echo $this->navigation()->menu(); ?> to generate your menu.
Also note that making a node invisible will make all its children invisible as well. Duh.
Add <visible>0</visible> to your node
You can then use the usual <?php echo $this->navigation()->menu(); ?> to generate your menu.
Also note that making a node invisible will make all its children invisible as well. Duh.
Finally.
So I've been thinking about creating a blog for a long time now, to share anything I can find that seems interesting and out of the usual programming routine. If ever I discover anything, be it myself or from another source, I'll try to remember to share it with you!
Subscribe to:
Posts (Atom)