0
votes

I'd like to tweak the Illuminate\Html\FormBuilder class in Laravel 4 to automatically include a CSS class with each input, corresponding to the type of input, e.g. <input type="radio" class="radio" />

I've created my own class, which extends the original:

namespace Shady;

class FormBuilder extends Illuminate\Html\FormBuilder {

    public function input($type, $name, $value = null, $options = array()) {
        $options['class'] = isset($options['class'])
                ? implode(' ', array_unique(array_merge(array($type), explode(' ', $options['class']))))
                : $type;

        parent::input($type, $name, $value, $options);
    }
}

Now, the question is, how do I get Laravel 4 to use it?

I've had a look in app/config/app.php, and there's only a reference to the HTML Fascade class. I'm not sure how or where that translates into the Illuminate\Support\ServiceProvider\HtmlServiceProvider class, but that class hard-codes the FormBuilder class, ala

protected function registerFormBuilder()
{
    $this->app['form'] = $this->app->share(function($app)
    {
        $form = new FormBuilder($app['html'], $app['url'], $app['session']->getToken());

        return $form->setSessionStore($app['session']);
    });
}

I'm wondering whether I can either trick it into loading my version of the class somehow? Or if not, how else do I add in this functionality smoothly and neatly? Cheers.

3
It seems like a lot of extra work just to get this to work, when you could easily use CSS selectors to find these types of inputs. Is it really necessary?Rob W
In this case, I am an idiot and didn't realise CSS selectors could do that (that's what happens when you step out of development for 18 months). But as a principle I'd like to know how it's done so I can do it for other things too. CheersJamShady
At that level in the framework, I don't think you'd want to override any of the methods. Instead, use HTML::macro() to define your own method. Hope this helps!Rob W

3 Answers

1
votes

There's a new section in the docs about extending Laravel that should help: http://laravel.com/docs/extending

1
votes

I also tried battling this issue as I wanted to do exactly the same as you, partly out of interest of extending core classes but also to stop repeating myself (DRY) from passing the same two classes in the second (options) array parameter each time I wanted a submit button, but to no avail.

Instead, I opted in the end to make a HTML macro, as others suggested above but here's an actual example for others who might come across this.

Example:

Save the following code to app/macros.php (this file doesn't exist by default so create it):

HTML::macro( 'submit', function( $value = null, $options = array() )
{
    $options = array_merge( $options, array( 'class' => 'btn btn-info' ) );
    return Form::input( 'submit', null, $value, $options );
});

Now include macros.php by adding require app_path().'/macros.php'; to the bottom of app/start/global.php.

And now in your views, instead of:

Form::submit( 'Submit', array( 'class' => 'btn btn-info' ) );

Use:

HTML::submit( 'Submit' );

And it will produce the same submit button, allowing the same parameters as Laravel by default but will automatically add btn and btn-info classes to the button, without you needing to repeat yourself each time. Hope this helps someone. =)

0
votes

It's unnecessary to extend the HTML helper class. Instead, use CSS selectors to pick the elements.

As for making your own methods, you can use the HTML::macro()

See: http://laravel.com/api/source-class-Illuminate.Html.HtmlBuilder.html#32

And: http://laravel.com/api/source-class-Illuminate.Html.HtmlBuilder.html#390