Modifying Checkbox Display Helper

Permalink
Okay, so the current default for displaying a checkbox input renders a div, a label, another div, another label, the checkbox input, and the checkbox description, as shown in my first two attachments. This apparently has been the practice in c5 for quite a long time, but really? How does this make any sense for standards coding and easy usability? It has a label above the box when it should go beside, and a random label element used as a wrapper and a random span used where the label should go. This appears on two main places I've seen so far, the register page, and the edit profile info page.
I want to change this to make it look and behave better, and also because I need to have the checkboxes in a
<p><input></input><label></label></p>
structure to apply some custom form styling I have. I've found the two main areas that need to be overridden, but I don't know how to do it. They are
concrete/helpers/form.php
concrete/helpers/form/attribute.php
The display function in attribute.php seems to be what causes the bloat, but the "<span>Yes</span>" doesn't appear here, so I'm missing something. And if I change anything, it affects the display of other attributes like textbox. On this thread:http://www.concrete5.org/community/forums/customizing_c5/styling-a-...
JordanLev says to view the source of the rendered page and just copy that code to replace the foreach loop which I have done and it works great. But if I add a new attribute then I'd have to update everything manually on every page these attributes show up. At the bottom of the thread, this guy says he made two other methods for checkboxes and text areas while keeping the foreach loop which sounds exactly like what I want to do. I have no idea how though, like how to tell when a checkbox is being passed vs a textbox.

2 Attachments

timtorres
 
jordanlev replied on at Permalink Reply
jordanlev
Yeah, I think most of the markup generated by the core system is horrendous -- I get the sense that there's no "clean markup" advocates on the core team, which is a bummer for designers.

Anywho, I think you're talking about the "boolean attribute", not the form checkbox helper? If you're using Concrete5.6 or later, it's much easier to override stuff in the core now. Create this new file on your server (you'll need to create the subdirectories it's in as well):
/models/attribute/types/boolean/controller.php

(note that this is all under your top-level "models" directory, *NOT* "/concrete/models/").

Then put this code in that new file:
<?php defined('C5_EXECUTE') or die("Access Denied.");
/* Override html output of "boolean/checkbox" attribute type */
class BooleanAttributeTypeController extends Concrete5_Controller_AttributeType_Boolean  {
   public function form() {
      if (is_object($this->attributeValue)) {
         $value = $this->getAttributeValue()->getValue();
         $checked = $value == 1 ? true : false;
      } else {
         $this->load();
         if ($this->akCheckedByDefault) {
            $checked = true;
         }
      }
      $cb = Loader::helper('form')->checkbox($this->field('value'), 1, $checked);
      print '<label>' . $cb . 'Yes</label>'; //<--do your markup here


Hope that helps.

-Jordan
timtorres replied on at Permalink Reply
timtorres
Yes! This is perfect. I guess I missed looking in the model folder. And it isn't really a checkbox helper, it was the attribute helper and I was looking at making a checkboxDisplay method specifically for rendering checkbox attributes. I'll give this a go, but I might opt for doing everything manually so I clean everything up.

The override isn't working, so just to clarify:
I took the changed code from concrete/core/models/attributes/types/boolean.php
public function form() {
      if (is_object($this->attributeValue)) {
         $value = $this->getAttributeValue()->getValue();
         $checked = $value == 1 ? true : false;
      } else {
         $this->load();
         if ($this->akCheckedByDefault) {
            $checked = true;
         }
      }
      $cb = Loader::helper('form')->checkbox($this->field('value'), 1, $checked);
      print $cb;
   }
public function composer() {
      $this->form();

And placed it in models/attributes/types/boolean/controller.php. Nothing changed though. I'm used to overridden files having the same file names, even with the 5.6 update, so I thought that overriding boolean.php with controller.php might be the problem so I renamed it but nothing happened with that either.
timtorres replied on at Permalink Reply
timtorres
And this new override system is really a pain in the butt. I have to go through and redo all of my overrides and a lot of the things aren't the same... I guess that's the nature of a system update
zanedev replied on at Permalink Reply
zanedev
Any idea how to override the controller of a package's attribute type rather than a core attribute type? Tried duplicating it in this similar manner to the top level models folder but no luck.

UPDATE: never mind had a folder named wrong, works fine overriding package attribute types :)
guyDesign replied on at Permalink Reply
Just want to pitch in on how much I agree with jordanlev on the clean markup in the core, it's truly hideous and have not really been resolved all the way into 5.6.3.3 , Not sure about 5.7 I hope it's better