A Checkboxlist With Attributes From Activerecord Is Possible?

I have in my CustomerExtended - is a Customer Active Record extended - a public attribute called $notifications, witch setted in afterConstruct method:




    class CustomerExtended extends Customer

    {

        public $notifications;


        public function afterConstruct()

        {

            parent::afterConstruct();


            $this->notifications = Array(

                'customer_notify_new_sms',

                'customer_notify_new_pokes',

                'customer_notify_news_by_email',

                'customer_notify_favorite_logged',

                'customer_notify_finantial_response'

            );

        }

    }

And Customer has the following attributes - are concrete attributes from database:




    $customer = new Customer();

    $customer->customer_notify_new_sms; // default is 1 on database

    $customer->customer_notify_new_pokes; // default is 1 on database

    $customer->customer_notify_news_by_email; // default is 1 on database

    $customer->customer_notify_favorite_logged; // default is 1 on database

    $customer->customer_notify_finantial_response; // default is 0 on database

Right, I need that the notification attribute on CustomerExtended be a array representing the concrete attributes - with correspondent names - on Customer Active Record. This is to create a checkboxlist.

I’m trying to found a solution but… I’m trying thus:




    $model = new CustomerExtended();

    $form = new CActiveForm();


    echo $form->checkBoxList($model, 'notifications',

        Array(

            'customer_notify_new_sms' => 'News by SMS',

            'customer_notify_new_pokes' => 'Notify Pokes',

            'customer_notify_news_by_email' => 'Notify by e-mail',

            'customer_notify_favorite_logged' => 'Notify when favorite is logged',

            'customer_notify_finantial_response' => 'Notify finantial reports'

            )

        );

But the result is wrong, 'cause customer_notify_finantial_response attribute is 0 on database and on the checkboxlist is checked by default.

Is there a better way to do this?

I’m new here and I not can post external images to exemplify:(

Hi

Welcome to the forum.

If I understand your problem correctly, I don’t think you can use the checkboxlist to do what you want. If you look at the documentation for checkboxlist, the data for the checkboxlist needs to be in value=>label format. The value is what determines whether the checkbox is checked or not. In your checkboxlist, you are passing the a string not a boolean value (1 or 0) hence the problem you are having.

You can do what you are trying to achieve by using the customer_notify_* attributes (from your Customer class) with the checkbox instead.

With the customer_notify_* attributes, in your view, you could do like so:




 <div class="row">

        <?php echo $form->checkBox($model, 'customer_notify_new_sms'); ?>

 </div>


<div class="row">

        <?php echo $form->checkBox($model, 'customer_notify_new_pokes'); ?>

</div>


<div class="row">

        <?php echo $form->checkBox($model, 'customer_notify_news_by_email'); ?>

</div>


<div class="row">

     <?php echo $form->checkBox($model, 'customer_notify_favorite_logged'); ?>

</div>


<div class="row">

    <?php echo $form->checkBox($model, 'customer_notify_finantial_response'); ?>

</div>



I hope this helps.

Hello,

I’ll explain what I was trying to do, and that is resolved.

I had to write an API to work better with forms. For really sucks trying to keep code clean, testable and maintenance using the forms generated by Gii.

This abstraction allows me to generate forms in which each of these entries are attributes - or not - of one or more Active Record.

The API allows this - why need UserExtended and CustomerExtended is another matter, but that was a very interesting discussion on this link:




public function actionCreate() {

    $user = new UserExtended();

    $customer = new CustomerExtended();


    $form = new CustomerForm(Array($user, $customer));

    $this->render('create', Array('form' => $form));

}



CustomerForm is a AbstractForm - which is part of the API. And gets within a folder /forms for example.

And then in the view we have just that:




<?php

    // ... HTML code above ...

    $form->initWidget();

    $form->displayErrorSummary();

    $form->displayElements();

    $form->endWidget();

    // ... HTML from below ...

?>



So, to the point of checkbox needed generating a checkboxlis an easy way, and got by doing this:




CustomerForm extends AbstractForm {

    // overridden

    public function options()

    {

         $this->customerNotifications();

    }


    private function customerNotifications()

    {

        $checkboxlist = $this->getCustomerNotificationsAsCheckboxList();


        $this->options->notifications = Array(

            'type' => HtmlElement::CHECKBOX_LIST,

            'items' => $checkboxlist['items'],

            'checkedItems' => $checkboxlist['checkedItems'],

            'checkAll' => Yii::t('main', 'Check All'),

            'checkAllLast' => false

        );

    }


    private function getCustomerNotificationsAsCheckboxList()

    {

        $items = Array();

        $checkedItems = Array();

        $notifications = $this->customer->getAllowedNotifications();


        foreach($notifications as $notificationId) {

            $attrLabel = $this->customer->getAttributeLabel($notificationId);

            $items[] = Array('id' => $notificationId, 'name' => $attrLabel);


            $checked = (bool) $this->customer->$notificationId;

            if($checked) {

                $checkedItems[] = Array('id' => $notificationId, 'name' => $attrLabel);

            }

        }

        

        return Array('items' => $items, 'checkedItems' => $checkedItems);

    }

}



All that is set in the options() will be generated in the form - the hard work is for the code that I created to abstract forms, and you only need to access the API this code to generate your forms easily, without knowing about the generation of form.

In section $this->customer->getAllowedNotifications() is where I get an array of notifications that are attributes CustomerExtended.

In the end, I resolved the problem of generating the checkboxlist correctly in method getCustomerNotificationsAsCheckboxList(), more precisely the work of the variable $checkedItems.

So, on the core of abstraction, the value of $checkdedItems is passed to the parameter $select from Chtml::checkBoxList($name, $select, $data, $htmlOptions).

Now fix it in this code snippet:




$checked = (bool) $this->customer->$notificationId;

if($checked) {

    $checkedItems[] = Array('id' => $notificationId, 'name' => $attrLabel);

}



I still have a little work ahead =)