This may be super minor, but it's so trivial to implement it's worth implementing. Right now it's impossible (without a #process function) to set the "size" attribute on file upload fields within a #type = 'managed_file' element. We should allow a #size property on the parent element and pass it to the child upload field, such as this:

$element['upload'] = array(
  '#title' => t('Upload'),
  '#type' => 'managed_file',
  '#size' => 30,
);

Right now our #size property is unnecessarily hard-coded at "22". Considering the width of file elements can't easily be affected by CSS (http://www.quirksmode.org/dom/inputfile.html), this could be a boon to form designers and themers.

Patch with test included.

Comments

kyle_mathews’s picture

FWIW, I couldn't get #process to work correctly. When I'd set a #process function, the form would just refuse to generate. Not sure if that's a bug or just me not doing something correctly.

I did have better luck using #post_process and using regex to change the #size property.

quicksketch’s picture

FWIW, I couldn't get #process to work correctly. When I'd set a #process function, the form would just refuse to generate. Not sure if that's a bug or just me not doing something correctly.

That's because if you set #process, you override the #process properties already set in hook_element_info(), so none of the normal processing occurs. This is different from Drupal 6, where additional #process properties would just get appended to the end (don't ask me how we ended up like this). See this issue: #914792: Custom element properties entirely override default element info properties. I love rfay's ending comment: "We need to get this in or it will haunt us forever. The current arrangement is quite simply broken." Classic.

Anyway, I think that issue is unrelated to this one. This is specifically about passing #size down to the child element. It's possible in custom/contrib modules but it's super ugly. Something like this:

// In your form alter:
$form['upload']['#process'] => array_merge(array('my_process'), element_info_property('managed_file', '#process', array()));

// In your #process function
function my_process($element, $form_state) {
  $element['upload']['#size'] = $element['#size'];
  return $element;
}

Or use a #post_process or some other "unclaimed" property like you recommend, but really you should do the crazy element_info_property() mess anytime you form_alter().

dave reid’s picture

managed_file_size_property.patch queued for re-testing.

dave reid’s picture

+++ b/core/modules/file/tests/file.testundefined
@@ -239,6 +239,10 @@ class FileManagedFileElementTestCase extends FileFieldTestCase {
+    // Check that $element['#size'] is passed to the child upload element.
+    $this->drupalGet('file/test');
+    $this->assertRaw('size="13"', t('The custom #size attribute is passed to the child upload element.'));

This should probably use xpath just in case there's something else on the page in the future that uses size=13? The t() call in assertRaw is unnecessary as well.

quicksketch’s picture

StatusFileSize
new2.12 KB

- Using XPath now to verify the field width.
- Removed the t() from around the assert message.

xjm’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs backport to D7

#5 looks great to me. Also, I think we can backport this. Yay!

webchick’s picture

Status: Reviewed & tested by the community » Fixed

Looks good for backport!

Committed and pushed to 7.x. Thanks! :)

xjm’s picture

Status: Fixed » Reviewed & tested by the community

Hm did this go into 8.x? I don't see it there.

webchick’s picture

Status: Reviewed & tested by the community » Fixed

Uh, oops. Thought I did that but alas, no.

Committed and pushed to 8.x as well. :) Thank you!

quicksketch’s picture

Sweet, thanks!

Automatically closed -- issue fixed for 2 weeks with no activity.