Creating a File Chooser in Javascript

Hi All. I had to dynamically create a file chooser in javascript (the type that you'd typically create in PHP with

Loader::helper(‘concrete/asset_library’)->file(‘thumbnail’, $fileID, ‘Select Thumbnail’);

It was a bit of a pain and a bit kludgy, so I'm posting what I did in order to help others down that road. To be clear, this could be a lot better and more generic, and might not work out of the box, but at least it's a starting point:

<script type="text/javascript">
var fileChooserCounter = 0;
var template = '<div id="locationfile-[SELECTORID]-fm-selected" onclick="ccm_chooseAsset=false" class="ccm-file-selected-wrapper" style="display: NONE;"><img src="<?php echo ASSETS_URL_IMAGES ?>/throbber_white_16.gif"/></div>' +
                  '<div class="ccm-file-manager-select" id="locationfile-[SELECTORID]-fm-display" ccm-file-manager-field="locationfile-[SELECTORID]" style="display: BLOCK;">' +
                  '<a href="javascript:void(0)" onclick="ccm_chooseAsset=false; ccm_alLaunchSelectorFileManager(\'locationfile-[SELECTORID]\')">Choose File</a>' +
                  '<input type="hidden" class="ccm-file-manager-filter" name="fType" value="<?php echo FileType::T_IMAGE ?>" />' +
               '</div><input id="locationfile-[SELECTORID]-fm-value" type="hidden" name="fID" value="[FID]" />';
function fileChooserHTML(fileID) {
  var sID = fileChooserCounter++;
  var html = template..replace('[FID]', fileID || 0).replace(/\[SELECTORID\]/g, sID);
  if (fileID && fileID != 0) {
         html = html + '<script type="text/javascript">$(function() { ccm_triggerSelectFile(' + fileID + ', \'locationfile-' + sID + '\'); });</sc' + 'ript>';
      return html;

A few notes:
* This is specifically for images. If you dont' want to limit to images, remove the ccm-file-manager-filter hidden input. Alternatively, you can limit it with additional hidden variables.
* It doesn't appear to me that the first div (with the throbber in it) is used at all. It appears to only be used in the PHP as a placeholder while the triggerSelectFile() loads the file based on ID (if it exists). But it requires some logic to manually flip the display style, so I'm not using it.
* The selectorID counter is to ensure that all the IDs are unique if you use this multiple times.
* Otherwise, the function returns HTML that you can drop into the DOM.


View Replies:
JohntheFish replied on at Permalink Reply
Some clever stuff.

My usual approach is to render it to a hidden div in php/html then show that when (and where) I need it. Was it purely a matter of design choice, or is there a reason why the hidden div wouldn't work?
jshannon replied on at Permalink Reply
Yeah. That makes a lot of sense, but I needed 0 - n choosers (in a list, where you could add a new item from javascript).

And if there's already a choice, then you've got to have the javascript to update that, so I decided to just go all the way.