Answers.Body: <p>Looks like you have to do a bit of fudging if your running the $model->validate() function in your controller. assetId has to be set correctly before it jumps over to Service.</p>
  
  <p>I still run the following in my <strong>Controller</strong></p>
  
  <pre><code>$reorder = craft()-&gt;request-&gt;getPost('assetId', $model-&gt;assetId);
  $model-&gt;assetId = (!empty($reorder) ? $reorder[0] : null);
  </code></pre>
  
  <p>Then I run this in my <strong>Service</strong></p>
  
  <pre><code>$record-&gt;assetId = $model-&gt;assetId;
  </code></pre>
  
  <p>Tell me if I've missed something here.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-28T00:33:28.847Z
Answers.LastActivityDate: 2014-07-28T00:33:28.847Z
Answers.UserDisplayName: Adam McCombs
Answers.Body: <p>I did this recently with my <a href="https://www.doublesecretagency.com/plugins/ad-wizard" rel="nofollow noreferrer">Ad Wizard</a> plugin... There are several different parts which need to be brought together to make it work:</p>
  
  <hr>
  
  <p>In your <strong>Record</strong> file, add this to <code>defineRelations</code>:</p>
  
  <pre><code>'asset' =&gt; array(static::BELONGS_TO, 'AssetFileRecord')
  </code></pre>
  
  <hr>
  
  <p>In your <strong>Model</strong> file, add this to <code>defineAttributes</code>:</p>
  
  <pre><code>'assetId' =&gt; AttributeType::Number
  </code></pre>
  
  <hr>
  
  <p>Whichever <strong>template</strong> is responsible for editing that data will need something like this:</p>
  
  <pre><code>&lt;div class="field" id="assetId-field"&gt;
      &lt;div class="heading"&gt;
          &lt;label for="assetId"&gt;Image&lt;/label&gt;
      &lt;/div&gt;
      &lt;div class="input"&gt;
          {% if assetsSourceExists %}
              {{ forms.elementSelect({
                  elements: elements,
                  id: 'assetId',
                  name: 'assetId',
                  elementType: elementType,
                  criteria: {"kind":[],"localeEnabled":null,"locale":"en_us"},
                  sourceElementId: assetId,
                  jsClass: 'Craft.AssetSelectInput',
                  addButtonLabel: 'Select Image',
                  limit: 1,
              }) }}
          {% else %}
              &lt;p class="error"&gt;No assets sources currently exist. &lt;a href="{{ newAssetsSourceUrl }}"&gt;Create one now...&lt;/a&gt;&lt;/p&gt;
          {% endif %}
      &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>You'll notice in the Twig code above, I set references to the following variables:</p>
  
  <ul>
  <li><code>assetId</code></li>
  <li><code>elements</code></li>
  <li><code>elementType</code></li>
  <li><code>assetsSourceExists</code></li>
  <li><code>newAssetsSourceUrl</code></li>
  </ul>
  
  <p>These variable were set in the <code>actionEditMyElement</code> method of the <strong>Controller</strong> prior to loading the template:</p>
  
  <pre><code>// Set assetId
  $variables['assetId'] = $myModel-&gt;assetId;
  
  // Set elements
  if ($variables['assetId']) {
      $asset = craft()-&gt;elements-&gt;getElementById($variables['assetId']);
      $variables['elements'] = array($asset);
  } else {
      $variables['elements'] = array();
  }
  
  // Set elementType
  $variables['elementType'] = craft()-&gt;elements-&gt;getElementType(ElementType::Asset);
  
  // Set assetsSourceExists
  $sources = craft()-&gt;assets-&gt;findFolders();
  $variables['assetsSourceExists'] = count($sources);
  
  // Set newAssetsSourceUrl
  $variables['newAssetsSourceUrl'] = UrlHelper::getUrl('settings/assets/sources/new');
  
  // Render the template!
  $this-&gt;renderTemplate('myplugin/_edit', $variables);
  </code></pre>
  
  <hr>
  
  <p>Your <strong>Controller</strong> will probably have something like this in your <code>actionSaveMyElement</code> method:</p>
  
  <pre><code>$myModel-&gt;assetId = craft()-&gt;request-&gt;getPost('assetId', $myModel-&gt;assetId);
  </code></pre>
  
  <hr>
  
  <p>Your <strong>Service</strong> file will probably have something like this to save your record:</p>
  
  <pre><code>$assetId = (!empty($myModel-&gt;assetId) ? $myModel-&gt;assetId[0] : null);
  $myRecord-&gt;assetId = $assetId;
  ...
  $myRecord-&gt;save();
  </code></pre>
  
  <hr>
  
  <p>Hope that helps, let me know if I missed anything!</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-06-25T01:00:59.320Z
Answers.Text: Thanks Lindsey. This is great. I'll need to contemplate this for a moment!  Are you allowing the user to select any asset folder?  Do you have any Asset field settings in your own plugin, or just let the user interact with all asset folders and such via the Asset Element Selector Modal?
Answers.UserDisplayName: Ben Parizek
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-06-25T05:22:28.757Z
Answers.Text: The way I've got it setup, the user can select from any existing assets folder. I didn't need to lock it to a single folder for this plugin. Other than borrowing the Twig code which triggers the Asset Element Selector Modal, I tried to let Craft deal with the assets as natively as possible.
Answers.UserDisplayName: Lindsey D
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-06-25T08:58:30.437Z
Answers.Text: @LindseyD Is there a technical reason you specify it in the php-file, or is it just preference? I tried to keep it as much in Twig as possible: http://craftb.in/xepeqosupa are there any downsides to this?
Answers.UserDisplayName: Victor
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-06-25T16:15:30.947Z
Answers.Text: @VictorIn It's a little bit of personal preference... I generally try to put as much logic as reasonably possible into the PHP, to save Twig the hassle of parsing it later.
Answers.UserDisplayName: Lindsey D
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-06-30T11:49:12.387Z
Answers.Text: Thanks for the detailed description Lindsey. This came together nicely and I've now got multiple image fields working as needed.
Answers.UserDisplayName: Ben Parizek
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-06-30T16:15:12.517Z
Answers.Text: Excellent, glad to hear it Ben! There was a lot to include, glad I didn't miss anything. :)
Answers.UserDisplayName: Lindsey D
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-27T23:54:53.547Z
Answers.Text: @LindseyD wins the internet again.
Answers.UserDisplayName: Adam McCombs
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-06-25T00:55:32.043Z
Answers.LastActivityDate: 2018-02-20T22:43:53.443Z
Answers.LastEditDate: 2018-02-20T22:43:53.443Z
Answers.UserDisplayName: Lindsey D
Body: <p>We've got a plugin.  It doesn't have the ability to add custom field types.  We're pre-defining all of the fields.  One of the fields needs to be an Asset field.  A user should be able to upload an Asset using the native Craft Asset UI, store that Asset locally or on Amazon or any supported cloud platforms.</p>
  
  <p>How do we do this?</p>
  
  <p>Where do we create the relationship between the uploaded Asset and the database record we want the Asset related to?</p>
  
  <p>If we were allowing custom fields we could have our custom table relate to a Field Layout ID, and have any number of fields relate to that Field Layout.  But in our case, we're defining all of the columns we need in our template, in our own record, and don't really need to create any fields within Craft's fields table as we're setting them all up beforehand.</p>
  
  <p>Do we need a Field Layout in this situation?  Do we need to create a Field within Craft under our own context (like Matrix blocks) to be able to control the settings such as where to upload the assets to, and whether to restrict the upload to a single folder, or single image?</p>
  
  <p>I feel I have lots of pieces of the puzzle, but can't yet see how they fit together.</p>
  
Tags: <plugin-development><assets><field>
Title: How do we create a pre-defined Asset upload field in a plugin that integrates with the native Craft Assets file manager?
ThreadText: # How do we create a pre-defined Asset upload field in a plugin that integrates with the native Craft Assets file manager?
  
  (Asked by: username_0 on 2014-06-24)
  
  We've got a plugin. It doesn't have the ability to add custom field types. We're pre-defining all of the fields. One of the fields needs to be an Asset field. A user should be able to upload an Asset using the native Craft Asset UI, store that Asset locally or on Amazon or any supported cloud platforms.
  
  How do we do this?
  
  Where do we create the relationship between the uploaded Asset and the database record we want the Asset related to?
  
  If we were allowing custom fields we could have our custom table relate to a Field Layout ID, and have any number of fields relate to that Field Layout. But in our case, we're defining all of the columns we need in our template, in our own record, and don't really need to create any fields within Craft's fields table as we're setting them all up beforehand.
  
  Do we need a Field Layout in this situation? Do we need to create a Field within Craft under our own context (like Matrix blocks) to be able to control the settings such as where to upload the assets to, and whether to restrict the upload to a single folder, or single image?
  
  I feel I have lots of pieces of the puzzle, but can't yet see how they fit together.
  
  **Tags:** plugin-development, assets, field
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_2 on 2014-06-25. Score: 16 | Accepted answer
  
  I did this recently with my [Ad Wizard](https://www.doublesecretagency.com/plugins/ad-wizard) plugin... There are several different parts which need to be brought together to make it work:
  
  ---
  
  In your **Record** file, add this to `defineRelations`:
  
  ```
  'asset' => array(static::BELONGS_TO, 'AssetFileRecord')
  
  ```
  
  ---
  
  In your **Model** file, add this to `defineAttributes`:
  
  ```
  'assetId' => AttributeType::Number
  
  ```
  
  ---
  
  Whichever **template** is responsible for editing that data will need something like this:
  
  ```
  <div class="field" id="assetId-field">
      <div class="heading">
          <label for="assetId">Image</label>
      </div>
      <div class="input">
          {% if assetsSourceExists %}
              {{ forms.elementSelect({
                  elements: elements,
                  id: 'assetId',
                  name: 'assetId',
                  elementType: elementType,
                  criteria: {"kind":[],"localeEnabled":null,"locale":"en_us"},
                  sourceElementId: assetId,
                  jsClass: 'Craft.AssetSelectInput',
                  addButtonLabel: 'Select Image',
                  limit: 1,
              }) }}
          {% else %}
              <p class="error">No assets sources currently exist. <a href="{{ newAssetsSourceUrl }}">Create one now...</a></p>
          {% endif %}
      </div>
  </div>
  
  ```
  
  You'll notice in the Twig code above, I set references to the following variables:
  
  * `assetId`
  * `elements`
  * `elementType`
  * `assetsSourceExists`
  * `newAssetsSourceUrl`
  
  These variable were set in the `actionEditMyElement` method of the **Controller** prior to loading the template:
  
  ```
  // Set assetId
  $variables['assetId'] = $myModel->assetId;
  
  // Set elements
  if ($variables['assetId']) {
      $asset = craft()->elements->getElementById($variables['assetId']);
      $variables['elements'] = array($asset);
  } else {
      $variables['elements'] = array();
  }
  
  // Set elementType
  $variables['elementType'] = craft()->elements->getElementType(ElementType::Asset);
  
  // Set assetsSourceExists
  $sources = craft()->assets->findFolders();
  $variables['assetsSourceExists'] = count($sources);
  
  // Set newAssetsSourceUrl
  $variables['newAssetsSourceUrl'] = UrlHelper::getUrl('settings/assets/sources/new');
  
  // Render the template!
  $this->renderTemplate('myplugin/_edit', $variables);
  
  ```
  
  ---
  
  Your **Controller** will probably have something like this in your `actionSaveMyElement` method:
  
  ```
  $myModel->assetId = craft()->request->getPost('assetId', $myModel->assetId);
  
  ```
  
  ---
  
  Your **Service** file will probably have something like this to save your record:
  
  ```
  $assetId = (!empty($myModel->assetId) ? $myModel->assetId[0] : null);
  $myRecord->assetId = $assetId;
  ...
  $myRecord->save();
  
  ```
  
  ---
  
  Hope that helps, let me know if I missed anything!
  
  > **Comments:**
  > **username_0**: Thanks username_2. This is great. I'll need to contemplate this for a moment!  Are you allowing the user to select any asset folder?  Do you have any Asset field settings in your own plugin, or just let the user interact with all asset folders and such via the Asset Element Selector Modal?  
  > **username_2**: The way I've got it setup, the user can select from any existing assets folder. I didn't need to lock it to a single folder for this plugin. Other than borrowing the Twig code which triggers the Asset Element Selector Modal, I tried to let Craft deal with the assets as natively as possible.  
  > **username_3**: @username_2 Is there a technical reason you specify it in the php-file, or is it just preference? I tried to keep it as much in Twig as possible: http://craftb.in/xepeqosupa are there any downsides to this?  
  > **username_2**: @VictorIn It's a little bit of personal preference... I generally try to put as much logic as reasonably possible into the PHP, to save Twig the hassle of parsing it later.  
  > **username_0**: Thanks for the detailed description username_2. This came together nicely and I've now got multiple image fields working as needed.  
  > **username_2**: Excellent, glad to hear it Ben! There was a lot to include, glad I didn't miss anything. :)  
  > **username_1**: @username_2 wins the internet again.  
  
  ---
  
  ### Answer by username_1 on 2014-07-28. Score: 2
  
  Looks like you have to do a bit of fudging if your running the $model->validate() function in your controller. assetId has to be set correctly before it jumps over to Service.
  
  I still run the following in my **Controller**
  
  ```
  $reorder = craft()->request->getPost('assetId', $model->assetId);
  $model->assetId = (!empty($reorder) ? $reorder[0] : null);
  
  ```
  
  Then I run this in my **Service**
  
  ```
  $record->assetId = $model->assetId;
  
  ```
  
  Tell me if I've missed something here.
  
  
  ---
  
  