Posts Tagged ‘Placeholder’

Some new crazy (Cake)PHP tricks

01 Mar

Crazy – because these tips are not used that often probably. But for some rare occasions they might come in handy.

Inserting some rows into an array

$array = array(
$newValue = 'one-point-five';
//with 0 as 3rd arg we can actually add values at the position of arg 2
array_splice($array, 1, 0, array($newValue));

Note that the 4th argument must be an array for this to work.

Using the same value for multiple select options

With a simpel key/value list and select() you won’t get far. You cannot use the same key twice in an array. That is a common beginner mistake.
To overcome this you need a bit more verbose array here:

$options = array(
 	array('name' => 'United states', 'value' => 'USA'),
	array('name' => 'USA', 'value' => 'USA'),
 echo $this->Form->input('test', array('type'=>'select', 'options'=>$options));

This will then print

<option value="USA">United states</option>
<option value="USA">USA</option>

See the docs for more infos on select().

Setting additional attributes for some select options

You might want set some option elements to a specific class. The FormHelper::select() is powerful enough to support this:

// normal options
$options = array(1 => 'One', 2 => 'Two', 3 => 'Three');
// advanced (second elements has a class "extra")
$options = array(
	1 => 'One', 
	2 => array('name' => 'Two', 'value' => 2,  'class' => 'extra'), 
	3 => 'Three');
echo $this->Form->input('test', array('type' => 'select', 'options' => $options));

The result:

<div class="input select">
	<label for="ModelTest">Test</label>
	<select name="data[Model][test]" id="ModelTest">
		<option value="1">One</option>
		<option value="2" class="extra">Two</option>
		<option value="3">Three</option>

You might want to check this site here if the styles you want to apply work in all browsers. Usually only some styles like background-color are apply-able cross-browser.


Not so much CakePHP as maybe HTML5 – but pretty useful for login forms:

echo $this->Form->input('login', array('autofocus'=>'autofocus'));

All new browsers support it out of the box. The user can start typing right away (no additional click necessary).

More HTML5 out-of-the-box

In general HTML5 is great, but still not fully supported by all browsers – or users just don’t update to a new version.
So we shouldn’t completely rely on those features. But where – as the above autofocus – the absence in unsupportive browsers doesn’t bother anyone we can easily apply those features for users with modern browsers.

Additionally, we can use fallback-js to "simulate" the behavior if not natively supported. I put together a well-working HTML5-fallback script for jquery. It checks if the browser supports a certain feature and if not it creates a JS workaround.

I bet there are lots of other similar implementations. The important part for those placeholders is that on submit the content needs to be cleared again. The placeholders must not be posted (otherwise your validation rules might not work as expected anymore). I used the $('form').live('submit', function() {} event to clear the forms in time.

echo $this->Form->input('url', array('placeholder'=>'http://'));

All these snippets work in all browsers. In those modern ones a little bit faster. But that’s about all. You can already use it without any worries. And some day you can just turn of the fallback.

Structure your controllers

UsersController is often one of the most bloated controllers having tons of actions and views.
At some point this might get very confusing with so much code in a single file.

You don’t have to put all 40ish actions that are related to the User model in a single UsersController. Divide them to keep things clean and clear. So for me this worked pretty well:

  • AccountController (login, logout, register, change_pw, edit, …): $uses = array('User')
  • MembersController (index, search, profile, mail, friend, …, admin backend actions): $uses = array('User')
  • OverviewController (index, admin index, … – specially routed): $uses = array('User')

As you can see they all use the user model but they separate the actions by category. This way the file stays kinda short and is better understandable in the long run. Imagine all those actions in a single controller. No way 🙂

But also bear in mind that you should not start dividing everything into tiny little pieces. Only do it where it makes sense.

Controllers without models

Until today you coudn’t just set $uses to false in Cake2. What used to work in 1.3 will fail hard in 2.x. It was a pretty annoying problem I reported right away (but it needed a second one to actually get things into motion). If you just used isset($this->Model) it would try to load a non-existent model and die. The current head now contains the new fixed version which works now the way one would expect it to work:

  • true Use the default inflected model name.
  • array() Use only models defined in the parent class.
  • false Use no models at all, do not merge with parent class either.
  • array('Post', 'Comment') Use only the Post and Comment models. Models will also be merged with the parent class.

The default value is true.

So basically, if we don’t want to use any models (or at least no default model):

class TestController extends AppController {
	public $uses = array();

Note: only use false if you are certain the extended controllers (the AppController usually) don’t rely on any models. Otherwise it will break this functionality. That is why array() usually suffices.


Posted in CakePHP


Web Development Snippets

06 Mar

A couple of useful snippets for web developing. The list will grow over the years.

Jumping to anchors with JS

If we want to jump to an anchor dynamically (using javascript):

/* dont use this!!! */
//location.href = location.href  + '#searchbox';
/* and not this either: */
/* this is the correct way to go */
window.location.hash = "searchbox";

This has still some flaws if you click the anchor multiple times.
This worked for me:

var destinationLink = document.getElementById('targetId');
var destx = destinationLink.offsetLeft;  
var desty = destinationLink.offsetTop;
scrollTo(destx, desty);

So the above method should be used to set the hash of the page. The below one for jumping to anchors.

Prevent Right Click

This should be used wisely and only where it makes sense. It it neither waterproof nor convenient in most cases. Simply by displaying the source code the content can still be accessed (Shortcuts like STRG+U).

<body oncontextmenu="return false">

I like the browser solution more than the js solutions out there 🙂

Get HTML5 ready

<input name="url" placeholder="http://"/>

This is only one example of many. The Google Chrome browser already understands it as well as some beta browsers like FF4 etc.
Combine this with a javascript/jquery fallback and you have a nice (placeholder) functionality that will some day run natively in all user browsers.

And some more snippets from different external sources:

Forcing long strings to wrap