Skip to content

Instantly share code, notes, and snippets.

@jamierumbelow
Last active January 1, 2016 08:09
Show Gist options
  • Save jamierumbelow/8116402 to your computer and use it in GitHub Desktop.
Save jamierumbelow/8116402 to your computer and use it in GitHub Desktop.
Give your Laravel forms a little jazz! THIS IS A REALLY EARLY PROTOTYPE so don't expect it to work too well. Check out the example view code beneath to see, vaguely, how it works. Outputs Bootstrap 3 friendly HTML.
<form method="POST" action="http://localhost/books/1" accept-charset="UTF-8">
<input name="_token" type="hidden" value="AgJPK6ExWwqNd2X35UJS1sJu3jeEkDKQitNQIfnx">
<div class="form-group">
<label for="book[title]" class="control-label">Title</label>
<input class="form-control" name="book[title]" type="text" value="" id="book[title]">
</div>
<div class="form-group">
<label for="book[author]" class="control-label">Author</label>
<input class="form-control" name="book[author]" type="text" value="" id="book[author]">
</div>
<div class="form-group">
<label for="book[password]" class="control-label">Password</label>
<input class="form-control" name="book[password]" type="password" id="book[password]">
</div>
<input class="btn btn-primary" type="submit" value="Save">
</form>
Route::get('books/new', function()
{
return View::make('exampleView')
->with('book', new Book());
});
Route::post('books', function()
{
$v = Validator::make( Input::get('book') , [ 'name' => 'required' ]);
if ($v->passes())
{
return Redirect::to('books');
}
else
{
return Redirect::to('instances/add')
->withInput()
->withErrors($v->errors());
}
});
<?= Tuxedo::open($book) ?>
<?= Tuxedo::text('title') ?>
<?= Tuxedo::text('author') ?>
<?= Tuxedo::password('password') ?>
<?= Tuxedo::submit() ?>
<?= Tuxedo::close() ?>
<?php
/**
* Tuxedo
* Give your forms a little jazz
*
* @author Jamie Rumbelow <http://jamierumbelow.net>
*/
class Tuxedo {
static protected $_model;
/**
* Analogous to Form::open(), open() generates an opening <form> tag, with a
* key difference: It accepts an Eloquent model as a parameter instead of a string.
* If you do so, the form will automatically guess the URL based on a RESTful
* pattern - pluralising the name and setting it to lowercase.
*
* @param $target string or object Form Action
* @param $extra array Any extra parameters - passed to Form::open()
* @return string
*/
public static function open($target, $extra = array())
{
$options = array();
if (is_object($target))
{
$url = strtolower(Str::plural(get_class($target)));
if (is_subclass_of($target, 'Eloquent'))
{
self::$_model = $target;
if ($target->exists)
$url .= '/' . $target->id;
}
}
else
{
$url = $target;
}
$options = array( 'url' => $url );
$options = array_merge($options, $extra);
return Form::open($options);
}
public static function close()
{
self::$_model = null;
return Form::close();
}
public static function getModel()
{
return self::$_model;
}
public static function common($type, $attribute, $value = null, $label = '', $extra = array(), $tooltip = '')
{
$errors = self::errors();
$label = self::getLabel($attribute, $label);
$name = self::getName($attribute);
$value = self::getValue($attribute, $value, $name);
$extra = array_merge(array( 'class' => 'form-control' ), $extra);
$error = '';
$tooltip = '';
if ($errors && $errors->get($attribute))
{
$error = ' has-error';
$tooltip = '<span class="help-block">' . implode(' ', $errors->get($attribute)) . '</span>' . PHP_EOL;
}
$output = '<div class="form-group' . $error . '">' . PHP_EOL;
$output .= Form::label($name, $label, array( 'class' => 'control-label' )) . PHP_EOL;
$output .= Form::input($type, $name, $value, $extra) . PHP_EOL;
$output .= $tooltip;
$output .= '</div>' . PHP_EOL;
return $output;
}
public static function text($name, $options = array()) { return self::common('text', $name, '', '', $options); }
public static function password($name, $options = array()) { return self::common('password', $name); }
public static function submit($value = 'Save') { return Form::submit($value, array( 'class' => 'btn btn-primary' )); }
protected static function errors()
{
return Session::get('errors');
}
protected static function getName($name)
{
if (self::getModel())
{
if (method_exists(self::getModel(), 'tuxedoFormName'))
{
return strtolower(self::getModel()->tuxedoFormName()) . '[' . $name . ']';
}
else
{
return strtolower(get_class(self::getModel())) . '[' . $name . ']';
}
}
else
{
return $name;
}
}
protected static function getLabel($attribute, $label)
{
return $label ?: ucwords(str_replace(array('_', '[', ']'), ' ', $attribute));
}
protected static function getValue($attribute, $value, $name)
{
$classname = str_replace("[$attribute]", '', $name);
if ($value === FALSE)
{
return '';
}
else
{
return $value ?: (
Input::old("$classname.$attribute") ?: (
isset(self::getModel()->$attribute) ? self::getModel()->$attribute : ''
)
);
}
}
}
<?php
class Eloquent { public $exists = FALSE; }
class TestModel extends Eloquent { }
class TuxedoTest extends TestCase {
public function testOpen()
{
$obj = new stdClass;
$testModel = new TestModel();
// test the target URL is generated appropriately
$this->assertContains('action="http://localhost/stdclasses"', Tuxedo::open($obj));
$this->assertContains('action="http://localhost/stdClasses"', Tuxedo::open('/stdClasses'));
$this->assertContains('action="http://localhost/somethingElse"', Tuxedo::open('/somethingElse'));
$this->assertContains('action="http://localhost/somethingElse"', Tuxedo::open('somethingElse'));
$this->assertContains('action="http://localhost/overridden"', Tuxedo::open('/somethingElse', array( 'url' => 'overridden' )));
// test it generates a <form> tag
$this->assertContains('<form', Tuxedo::open($obj));
$this->assertContains('<form', Tuxedo::open('somewhere'));
// test that it saves the model if it's an Eloquent model
Tuxedo::open($testModel);
$this->assertEquals($testModel, Tuxedo::getModel());
}
public function testClose()
{
Tuxedo::open(new TestModel);
$close = Tuxedo::close();
$this->assertEquals('</form>', $close);
$this->assertNull(Tuxedo::getModel());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment