Brickrouge from me

Brickrouge is an object-oriented toolkit for PHP5.3+ that helps you create inputs, widgets, forms and many other common elements, with all the CSS and JavaScript needed to make them beautiful and magical.

Brickrouge uses Bootstrap from twitter for its style, and MooTools for its magic. Ready in a minute, you'll have everything you need to create beautiful and clean webapps.

Together with ICanBoogie, Brickrouge is one of the precious components that make the CMS Icybee, but it remains a standalone project for everyone to enjoy!

View project on GitHub Download as a Phar

Feature highlights

  • Standalone and patchable
  • Compatible with Bootstrap
  • Support localization
  • Is a Composer package
  • Object-oriented
  • Create any kind of element
  • Populate and validate forms

Take a look at our next features!

Calendar
{
    "minimum-stability": "dev",
    "require": {
        "brickrouge/brickrouge": "2.x"
    }
}

The form here against is entirely created, filled and validated using Brickrouge.

Every elements of the form are objects instanciated from the Element class or one of its subclasses.

Submit the form and see how it repopulates its fields with the values you submited, and how it handles errors.

The source code of the form is available here after.

Basics
With a small snippet of help text
Block of help text to describe the field above if need be.
Required and validated
YYYY-MM-DD
We can validate patterns with the string validator.
Between 3 and 6 characters
We can also validate the number of characters with the string validator.
Example form legend
Note: Labels surround all the options for much larger click areas and a more usable form.
This group is disabled.
This group is disabled.
 
<?php

namespace Brickrouge;

use ICanBoogie\Errors;

$form = new Form
(
    array
    (
        Form::VALUES => $_POST,
        Form::RENDERER => 'Simple',
        Form::ACTIONS => array
        (
            new Button
            (
                'Save Changes', array
                (
                    'type' => 'submit',
                    'class' => 'btn-primary'
                )
            ),

            new Button
            (
                'Cancel', array
                (
                    'type' => 'reset'
                )
            )
        ),

        Element::GROUPS => array
        (
            'one' => array
            (
                'title' => 'Basics'
            ),

            'two' => array
            (
                'title' => 'Required and validated'
            ),

            'three' => array
            (
                'title' => 'Example form legend'
            )
        ),

        Element::CHILDREN => array
        (
            'input' => new Text
            (
                array
                (
                    Form::LABEL => "Input",
                    Element::INLINE_HELP => "With a small snippet of help text",
                    Element::GROUP => 'one'
                )
            ),

            'select' => new Element
            (
                'select', array
                (
                    Form::LABEL => 'Select',
                    Element::GROUP => 'one',
                    Element::OPTIONS => array(1 => 1, 2, 3, 4, 5)
                )
            ),

            new Text
            (
                array
                (
                    Form::LABEL => 'Uneditable Input',
                    Element::GROUP => 'one',

                    'readonly' => true,
                    'value' => 'Some Value Here'
                )
            ),

            'disabledInput' => new Text
            (
                array
                (
                    Form::LABEL => "Disabled Input",
                    Element::GROUP => 'one',

                    'disabled' => true,
                    'placeholder' => "Disabled input here… carry on."
                )
            ),

            'text' => new Element
            (
                'textarea', array
                (
                    Form::LABEL => 'Textarea',
                    Element::GROUP => 'one',
                    Element::DESCRIPTION => "Block of help text to describe the field above if need be.",

                    'rows' => 3,
                    'class' => 'span5'
                )
            ),

            'checkbox' => new Element
            (
                Element::TYPE_CHECKBOX, array
                (
                    Element::LABEL => 'A single checkbox',
                    Element::GROUP => 'one'
                )
            ),

            /*
             * TWO
             */

            'required' => new Text
            (
                array
                (
                    Form::LABEL => 'Required value',
                    Element::GROUP => 'two',
                    Element::REQUIRED => true
                )
            ),

            'email' => new Text
            (
                array
                (
                    Form::LABEL => 'Email',
                    Element::GROUP => 'two',
                    Element::VALIDATOR => array('Brickrouge\Form::validate_email'),
                    Element::DEFAULT_VALUE => 'invalid-email'
                )
            ),

            'url' => new Text
            (
                array
                (
                    Form::LABEL => 'URL',
                    Element::GROUP => 'two',
                    Element::VALIDATOR => array('Brickrouge\Form::validate_url'),
                    Element::DEFAULT_VALUE => 'invalid-url'
                )
            ),

            'birthday' => new Text
            (
                array
                (
                    Form::LABEL => 'Date',
                    Element::GROUP => 'two',
                    Element::VALIDATOR => array('Brickrouge\Form::validate_string', array('regex' => '#^\d{4}-\d{2}-\d{2}$#')),
                    Element::INLINE_HELP => 'YYYY-MM-DD',
                    Element::DESCRIPTION => 'We can validate patterns with the <q>string</q> validator.',
                    Element::DEFAULT_VALUE => 'invalid-birthday'
                )
            ),

            'length-minmax' => new Text
            (
                array
                (
                    Form::LABEL => 'Length min/max',
                    Element::GROUP => 'two',
                    Element::VALIDATOR => array('Brickrouge\Form::validate_string', array('length-min' => 3, 'length-max' => 6)),
                    Element::INLINE_HELP => 'Between 3 and 6 characters',
                    Element::DESCRIPTION => 'We can also validate the number of characters with the <q>string</q> validator.'
                )
            ),

            /*
             * THREE
             */

            'optionsCheckboxes' => new Element
            (
                Element::TYPE_CHECKBOX_GROUP, array
                (
                    Form::LABEL => 'List of Options',
                    Element::DEFAULT_VALUE => array('option1' => true, 'option2' => true, 'option3' => true),
                    Element::DESCRIPTION => '<strong>Note:</strong> Labels surround all the options for much larger click areas and a more usable form.',
                    Element::GROUP => 'three',
                    Element::OPTIONS => array
                    (
                        'option1' => "Option one is this and that—be sure to include why it’s great",
                        'option2' => "Option two can also be checked and included in form results",
                        'option3' => "Option three can—yes, you guessed it—also be checked and included in form results",
                        'option4' => "Option four cannot be checked as it is disabled."
                    ),
                    Element::OPTIONS_DISABLED => array('option4' => true),

                    'class' => 'inputs-list'
                )
            ),

            'disabledOptionsCheckboxes' => new Element
            (
                Element::TYPE_CHECKBOX_GROUP, array
                (
                    Form::LABEL => 'Disabled List of Options',
                    Element::DEFAULT_VALUE => array('option1' => true, 'option2' => true, 'option3' => true),
                    Element::DESCRIPTION => 'This group is disabled.',
                    Element::GROUP => 'three',
                    Element::OPTIONS => array
                    (
                        'option1' => "Option one is this and that—be sure to include why it’s great",
                        'option2' => "Option two can also be checked and included in form results",
                        'option3' => "Option three can—yes, you guessed it—also be checked and included in form results",
                        'option4' => "Option four cannot be checked as it is disabled."
                    ),
                    Element::OPTIONS_DISABLED => array('option4' => true),

                    'class' => 'inputs-list',
                    'disabled' => true
                )
            ),

            'optionsRadios' => new Element
            (
                Element::TYPE_RADIO_GROUP, array
                (
                    Form::LABEL => 'List of Options',
                    Element::DEFAULT_VALUE => 'option2',
                    Element::GROUP => 'three',
                    Element::OPTIONS => array
                    (
                        'option1' => "Option one is this and that&mdash;be sure to include why it’s great",
                        'option2' => "Option two can is something else and selecting it will deselect options 1"
                    ),

                    'class' => 'inputs-list'
                )
            ),

            'disabledOptionsRadios' => new Element
            (
                Element::TYPE_RADIO_GROUP, array
                (
                    Form::LABEL => 'Disabled List of Options',
                    Element::DEFAULT_VALUE => 'option2',
                    Element::DESCRIPTION => 'This group is disabled.',
                    Element::GROUP => 'three',
                    Element::OPTIONS => array
                    (
                        'option1' => "Option one is this and that&mdash;be sure to include why it’s great",
                        'option2' => "Option two can is something else and selecting it will deselect options 1"
                    ),

                    'class' => 'inputs-list',
                    'disabled' => true
                )
            )
        ),

        'class' => 'form-horizontal'
    )
);

Validating a form

You can ask a form to validate the data provided by the user. Errors are collected in a ICanBoogie\Errors object. The method search for required values before validation.

<?php

if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
    $errors = new \ICanBoogie\Errors();
    $form->validate($_POST, $errors);
}

Traversing a form

Forms are traversed recursively. This comes handy when you need to alter a bunch of elements, or simply display their lovely names as the example below.

<?php

foreach ($form as $element)
{
    echo ' ' . ($element['name'] ?: '<em>a nameless element</em>');
}
input select a nameless element disabledInput text checkbox required email url birthday length-minmax optionsCheckboxes disabledOptionsCheckboxes optionsRadios disabledOptionsRadios

Disabling a form and all of its elements

A form and all of its elements can be easily disabled using the disabled attribute:

<?php

$form['disabled'] = true;

Group elements

Usually elements within a form are grouped according to the GROUP attribute. But groups can be as easilly created using the Group class.

The Group class wraps its children in a FIELDSET element, an optionnal legend can be used to provide the group with a title. Each child is wrapped in a DIV.field element and the form label is distinguished from the input itself.

The Group class supports the WEIGHT attribute and displays ordered children.

What's your name ?
<?php

namespace Brickrouge;

echo new Group(array(

    Element::LEGEND => "What's your name ?",
    Element::CHILDREN => array
    (
        'lastname' => new Text(array(

            Form::LABEL => 'Lastname',
            Element::WEIGHT => '1',
            'type' => 'text',
            'value' => 'Laviale'
        )),

        'firstname' => new Text(array(

            Form::LABEL => 'Firstname',
            'type' => 'text',
            'value' => 'Olivier'
        )),

        'salutation' => new Salutation(array(

            Element::WEIGHT => 'firstname:before',
            'value' => 2
        ))
    ),

    'class' => 'form-horizontal'
));

Example forms using just form controls, no extra markup

Basic form

If there is no rendered defined for the form, its children and simply concatened when it's rendered.

<?php

namespace Brickrouge;

echo new Form(array(

    Element::CHILDREN => array
    (
        new Text(array(Element::LABEL => "Label name", Element::LABEL_POSITION => 'above', 'class' => "span3", 'placeholder' => "Type something...")),
        new Element(Element::TYPE_CHECKBOX, array(Element::LABEL => "Check me out")),
        new Button("Submit", array('type' => 'submit'))
    ),

    'class' => "well"
));

Search form

Reflecting default WebKit styles, just add .form-search for extra rounded search fields.

<?php

namespace Brickrouge;

echo new Form(array(

    Element::CHILDREN => array
    (
        new Text(array('class' => 'input-medium search-query')),
        '&nbsp;' .
        new Button("search", array('type' => 'submit'))
    ),

    'class' => "well form-search"
));

Inline form

Inputs are block level to start. For .form-inline and .form-horizontal, we use inline-block.

  
<?php

namespace Brickrouge;

echo new Form(array(

    Element::CHILDREN => array
    (
        new Text(array('class' => 'input-small', 'placeholder' => "Email")), '&nbsp;',
        new Text(array('class' => 'input-small', 'placeholder' => "Password", 'type' => 'password')), '&nbsp;',
        new Button("Go", array('type' => 'submit'))
    ),

    'class' => "well form-inline"
));

Horizontal forms

Controls Bootstrap supports
In addition to freeform text, any HTML5 text-based input appears like so.
 
<?php

namespace Brickrouge;

echo new Form(array(

    Form::ACTIONS => array
    (
        new Button('Save changes', array('type' => 'submit', 'class' => 'btn-primary')),
        new Button('Cancel', array('type' => 'reset'))
    ),

    Element::CHILDREN => array(new Group(array(

        Element::LEGEND => "Controls Bootstrap supports",
        Element::CHILDREN => array
        (
            'input01' => new Text
            (
                array
                (
                    Form::LABEL => "Text input",
                    Element::DESCRIPTION => "In addition to freeform text, any HTML5 text-based input appears like so.",

                    'class' => 'xlarge'
                )
            ),

            'optionsCheckbox' => new Element
            (
                Element::TYPE_CHECKBOX, array
                (
                    Form::LABEL => "Checkbox",
                    Element::LABEL => "Option one is this and that&mdash;be sure to include why it’s great"
                )
            ),

            'select01' => new Element
            (
                'select', array
                (
                    Form::LABEL => "Select list",
                    Element::OPTIONS => array_combine(range(1, 5), range(1, 5))
                )
            ),

            'multiSelect' => new Element
            (
                'select', array
                (
                    Form::LABEL => "Multi-select",
                    Element::OPTIONS => array_combine(range(1, 5), range(1, 5)),

                    'multiple' => true
                )
            ),

            'fileInput' => new Element
            (
                'input', array
                (
                    Form::LABEL => "File input",

                    'type' => 'file',
                    'class' => 'input-file'
                )
            ),

            'textarea' => new Element
            (
                'textarea', array
                (
                    Form::LABEL => "Textarea",

                    'rows' => 3,
                    'class' => 'input-xlarge'
                )
            )
        )))
    ),

    'class' => 'form-horizontal'
));

What's included

Shown on the left are all the default form controls we support. Here's the bulleted list:

  • text inputs (text, password, email, etc)
  • checkbox
  • radio
  • select
  • multiple select
  • file input
  • textarea

Form control states
Something may have gone wrong
Please correct the error
Woohoo!
Woohoo!
 
<?php

namespace Brickrouge;

echo new Form(array(

    Form::ACTIONS => array
    (
        new Button('Save changes', array('type' => 'submit', 'class' => 'btn-primary')),
        new Button('Cancel', array('type' => 'reset'))
    ),

    Element::CHILDREN => array(new Group(array(

        Element::LEGEND => "Form control states",
        Element::CHILDREN => array
        (
            'focusedInput' => new Text
            (
                array
                (
                    Form::LABEL => "Focused input",
                    'class' => 'input-xlarge focused',
                    'value' => "This is focused..."
                )
            ),

            'disabledInput' => new Text
            (
                array
                (
                    Form::LABEL => "Disabled input",
                    'class' => 'input-xlarge disabled',
                    'disabled' => true,
                    'placeholder' => "Disabled input here..."
                )
            ),

            'optionsCheckbox' => new Element
            (
                Element::TYPE_CHECKBOX, array
                (
                    Form::LABEL => "Disabled checkbox",
                    Element::LABEL => "This is a disabled checkbox",
                    'disabled' => true
                )
            ),

            'inputWarning' => new Text
            (
                array
                (
                    Form::LABEL => "Input with warning",
                    Element::INLINE_HELP => "Something may have gone wrong",
                    Element::STATE => 'warning'
                )
            ),

            'inputError' => new Text
            (
                array
                (
                    Form::LABEL => "Input with error",
                    Element::INLINE_HELP => "Please correct the error",
                    Element::STATE => 'error'
                )
            ),

            'inputSuccess' => new Text
            (
                array
                (
                    Form::LABEL => "Input with success",
                    Element::INLINE_HELP => "Woohoo!",
                    Element::STATE => 'success'
                )
            ),

            'selectSuccess' => new Element
            (
                'select', array
                (
                    Form::LABEL => "Input with success",
                    Element::INLINE_HELP => "Woohoo!",
                    Element::STATE => 'success',
                    Element::OPTIONS => array(1 => 1, 2, 3, 4, 5)
                )
            )
        )
    ))),

    'class' => 'form-horizontal'
));

Form validation

The STATE attribute defines state of the input element, possible values are null, error, warning or success. Group elements use the corresponding class to highlight the element.

<?php echo new Text(array(Element::STATE => 'error', Element::INLINE_HELP => "The value should not be blue"));

When the form is validated using its validate() method it automatically sets the state of its elements.


Extending form controls
Use the same .span* classes from the grid system for input sizes.
@
Here's some help text
Here's some help text
Note: Labels surround all the options for much larger click areas and a more usable form.
 

Prepend & append inputs

Text inputs—with appended or prepended text—provide an easy way to give more context for your inputs. Great examples include the @ sign for Twitter usernames or $ for finances.

Use the ADDON attribute to define the add-on text, and the ADDON_POSITION attribute to define its position: before or after the text input.


Checkboxes and radios

Create checkbox groups and radio groups very easily using the TYPE_CHECKBOX_GROUP and TYPE_RADIO_GROUP special types.

Inline checkboxes and radios are also supported. Just add .inline-inputs to the group element and you're done.

<?php

namespace Brickrouge;

echo new Form(array(

    Form::ACTIONS => array(

        new Button('Save changes', array('type' => 'submit', 'class' => 'btn-primary')),
        new Button('Cancel', array('type' => 'reset'))
    ),

    Element::CHILDREN => array(new Group(array(

        Element::LEGEND => "Extending form controls",
        Element::CHILDREN => array(

            new Element('div', array(

                Form::LABEL => "Form sizes",
                Element::CHILDREN => array(

                    new Text(array('placeholder' => ".span2", 'class' => 'span2')),
                    new Text(array('placeholder' => ".span3", 'class' => 'span3')),
                    new Text(array('placeholder' => ".span4", 'class' => 'span4'))
                ),
                Element::DESCRIPTION => "Use the same <code>.span*</code> classes from the grid system for input sizes.",
                'class' => 'docs-input-sizes'
            )),

            'prependedInput' => new Text(array(

                Form::LABEL => "Prepended text",
                Text::ADDON => "@",
                Text::ADDON_POSITION => 'before',
                Element::DESCRIPTION => "Here's some help text",
                'size' => 16
            )),

            'appendedInput' => new Text(array(

                Form::LABEL => "Appended text",
                Text::ADDON => "€",
                Text::ADDON_POSITION => 'after',
                Element::DESCRIPTION => "Here's some help text",
                'size' => 16
            )),


            'inlineCheckbox1' => new Element(Element::TYPE_CHECKBOX_GROUP, array(

                Form::LABEL => "Inline checkboxes",
                Element::OPTIONS => array_combine(range(1, 3), range(1, 3)),

                'class' => 'inline-inputs'
            )),

            'optionsCheckboxes' => new Element(Element::TYPE_CHECKBOX_GROUP, array(

                Form::LABEL => "Checkboxes",
                Element::OPTIONS => array(
                    'option1' => "Option one is this and that&mdash;be sure to include why it’s great",
                    'option2' => "Option two can also be checked and included in form results",
                    'option3' => "Option three can&mdash;yes, you guessed it&mdash;also be checked and included in form results"
                ),
                Element::DESCRIPTION => "<strong>Note:</strong> Labels surround all the options for much larger click areas and a more usable form."
            )),

            'optionsRadios' => new Element(Element::TYPE_RADIO_GROUP, array(

                Form::LABEL => "Radio buttons",
                Element::OPTIONS => array(
                    'option1' => "Option one is this and that&mdash;be sure to include why it’s great",
                    'option2' => "Option two can is something else and selecting it will deselect option one"
                ),

                'value' => 'option1'
            ))

        )
    ))),

    'class' => 'form-horizontal'
));

About popovers

Add small overlays of content to any element for housing secondary information.

Example hover popover

Hover over the button to trigger the popover.

<a href="javascript://" class="btn btn-danger" rel="popover" data-title="A title" data-content="And here's some amazing content. It's very engaging. right?" data-animate="true" data-placement="after">hover for popover</a>

Anchored to an element

Popovers are usually anchored to an element and can follow it on the page, wherever it goes, adjusting their box trying to stay as much visible as possible.

Popover

Etiam porta sem malesuada magna mollis euismod. Maecenas faucibus mollis interdum. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
<?php

namespace Brickrouge;

echo new PopoverWidget
(
    array
    (
        Popover::TITLE => "Popover",
        Popover::INNER_HTML => "Etiam porta sem malesuada magna mollis euismod. Maecenas faucibus mollis interdum. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.",
        Popover::ANCHOR => "popover-anchor-0",
        Popover::PLACEMENT => 'before',
        PopoverWidget::VISIBLE => true
    )
);

Placement

Popover elements can be placed all around their anchor: before, after, above or below.

Popover elements are automatically repositioned to follow their anchor and may change their placement according to the available space around it.

If the there is not enough available space for the right popover it will jump to the left of the anchor.

Popover above, without title.

Popover after

Pellentesque vitae ligula et est consequat accumsan.

Popover below

Morbi convallis vehicula bibendum. Morbi vestibulum, augue a blandit blandit.
<?php

namespace Brickrouge;

echo new PopoverWidget
(
    array
    (
        Popover::INNER_HTML => "Popover above, without title.",
        Popover::ANCHOR => "popover-anchor-1",
        Popover::PLACEMENT => 'above',
        PopoverWidget::VISIBLE => true
    )
);

echo new PopoverWidget
(
    array
    (
        Popover::TITLE => "Popover after",
        Popover::INNER_HTML => "Pellentesque vitae ligula et est consequat accumsan.",
        Popover::ANCHOR => "popover-anchor-1",
        Popover::PLACEMENT => 'after',
        PopoverWidget::VISIBLE => true
    )
);

echo new PopoverWidget
(
    array
    (
        Popover::TITLE => "Popover below",
        Popover::INNER_HTML => "Morbi convallis vehicula bibendum. Morbi vestibulum, augue a blandit blandit.",
        Popover::ANCHOR => "popover-anchor-1",
        Popover::PLACEMENT => 'below',
        PopoverWidget::VISIBLE => true
    )
);

Contrast and actions

Contrast can be used to indicate that the content of the popover is not directly related to the current page.

Popovers can be used to provide a way to edit complex data which are presented more simply on the page.

Caching options

Mo
minutes
 
<?php

namespace Brickrouge;

echo new PopoverWidget
(
    array
    (
        Popover::TITLE => "Caching options",
        Popover::INNER_HTML => new Form
        (
            array
            (
                Form::RENDERER => 'Simple',
                Form::CHILDREN => array
                (
                    new Text
                    (
                        array
                        (
                            Form::LABEL => 'Maximum size of the cache',
                            Text::ADDON => 'Mo',

                            'class' => 'measure',
                            'size' => 4,
                            'value' => 8
                        )
                    ),

                    new Text
                    (
                        array
                        (
                            Form::LABEL => 'Interval between cleanup',
                            Text::ADDON => 'minutes',

                            'class' => 'measure',
                            'size' => 4,
                            'value' => 15
                        )
                    )
                ),

                'class' => 'stacked'
            )
        ),

        Popover::ANCHOR => "popover-anchor-options",
        Popover::ACTIONS => 'boolean',
        PopoverWidget::VISIBLE => true,

        'class' => 'widget-popover popover contrast fit-content'
    )
);

?>

<button class="spinner" id="popover-anchor-options" title="Configure caching options">The cache size is 8Mo and it's cleaned up every 15 minutes</button>

The Button class is used to create buttons. Their label is translated in the button scope. The initial type of the button is button.

The .btn class can be used to make elements such as the <a> element look like buttons. Compared to Bootstrap, <button> elements don't require the .btn class to be styled.

Button Code Description
<?= new Button('Default');
Standard gray button with gradient
<?= new Button('Primary', array('class' => 'btn-primary'));
Provides extra visual weight and identifies the primary action in a set of buttons
<?= new Button('Info', array('class' => 'btn-info'));
Used as an alternate to the default styles
<?= new Button('Success', array('class' => 'btn-success'));
Indicates a successful or positive action
<?= new Button('Warning', array('class' => 'btn-warning'));
Indicates caution should be taken with this action
<?= new Button('Danger', array('class' => 'btn-danger'));
Indicates a dangerous or potentially negative action

Multiple sizes

Fancy larger or smaller buttons? Have at it!

<?= new Button('Primary action', array('class' => 'btn-large btn-primary')) . PHP_EOL . new Button('Action', array('class' => 'btn-large'));

<?= new Button('Primary action', array('class' => 'btn-small btn-primary')) . PHP_EOL . new Button('Action', array('class' => 'btn-small'));

Disabled state

For buttons that are not active or are disabled by the app for one reason or another, use the disabled state. That’s .disabled for links and :disabled for <button> elements.

Primary action Action

<?= new A('Primary action', '#', array('class' => 'btn btn-large btn-primary disabled')) . PHP_EOL . new A('Action', '#', array('class' => 'btn btn-large disabled'));

<?= new Button('Primary action', array('class' => 'btn-large btn-primary', 'disabled' => true)) . PHP_EOL . new Button('Action', array('class' => 'large', 'disabled' => true));

Split button dropdowns

Building on the button group styles and markup, we can easily create a split button. Split buttons feature a standard action on the left and a dropdown toggle on the right with contextual links.

Example code

Dropdown menu options are defined using the OPTION attribute, the same way options are defined for select, TYPE_CHECKBOX_GROUP or TYPE_RADIO_GROUP element, the twist is that false options are turned into separators.

<?php

namespace Brickrouge;

echo new SplitButton('Action', array(

    Element::OPTIONS => array
    (
        'Action',
        'Another action',
        'Something else here',
        false,
        'Separated link'
    )
));

Lightweight defaults

Single alert message

For a more durable component with less code, we've removed the differentiating look for block alerts, messages that com with more padding and typically more text. The class also has changed to .alert-block.

Example alerts

Wrap your message and an optional close icon in a div with simple class.

Warning! Best check yo self, you’re not looking too good.
<?php

namespace Brickrouge;

echo new Alert("<strong>Warning!</strong> Best check yo self, you’re not looking too good.");

Goes great with javascript

Brickrouge comes with the Javascript needed to support alert messages. Clicking the close button removes the alert, and if it's attached to a form it also clears the errors on the form.

The field Required is required!

<?php

namespace Brickrouge;

$values = array('input1' => 'Brickrouge');

$form = new Form(array
(
    Element::CHILDREN => array
    (
        'input0' => new Text(array(Form::LABEL => 'Required', 'required' => true)),
        'input1' => new Text(array(Form::LABEL => 'Optionnal'))
    ),

    Form::VALUES => $values,
    Form::RENDERER => 'Simple',

    'class' => 'form-horizontal'
));

$errors = new \ICanBoogie\Errors();
$form->validate($values, $errors);

echo $form;

Heading & multi-line

Easily extend the standard alert message with two optional classes: .alert-block for more padding and text controls and .alert-heading for a matching heading.

Use the HEADING attribute to define the heading. The .alert-block class is automatically added if the HEADING attribute is defined.

Warning!

Best check yo self, you’re not looking too good. Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

<?php

namespace Brickrouge;

echo new Alert
(
    "<p>Best check yo self, you’re not looking too good. Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.</p>", array
    (
        Alert::HEADING => "Warning!"
    )
);

Contextual alternatives Add optional classes to change an alert's connotation

Error or danger

Oh snap! Change a few things up and try submitting again.
<?php

namespace Brickrouge;

echo new Alert("<strong>Oh snap!</strong> Change a few things up and try submitting again.", array(Alert::CONTEXT => 'error'));

Success

Well done! You successfully read this important alert message.
<?php

namespace Brickrouge;

echo new Alert("<strong>Well done!</strong> You successfully read this important alert message.", array(Alert::CONTEXT => 'success'));

Information

Heads up! This alert needs your attention, but it’s not super important.
<?php

namespace Brickrouge;

echo new Alert("<strong>Heads up!</strong> This alert needs your attention, but it’s not super important.", array(Alert::CONTEXT => 'info'));

Error collections

The Alert class can also render error collections.

Login failed!

Unknown username/password combination.

Funny username by the way ;-)

<?php

namespace Brickrouge;

$errors = new \ICanBoogie\Errors();
$errors['username'] = 'Unknown username/password combination.';
$errors['username'] = 'Funny username by the way ;-)';
$errors[] = 'Login failed!';

echo new Alert($errors);
Fork me on GitHub