diff --git a/openbis_ng_ui/src/components/types/objectType/ObjectType.jsx b/openbis_ng_ui/src/components/types/objectType/ObjectType.jsx
index edafa1d119ebed6936f709822d13e7f2875a67ed..8ec183dacc9f8dfed42da8bfd63a4c771493ae26 100644
--- a/openbis_ng_ui/src/components/types/objectType/ObjectType.jsx
+++ b/openbis_ng_ui/src/components/types/objectType/ObjectType.jsx
@@ -54,7 +54,8 @@ class ObjectType extends React.Component {
   loadObjectType(objectTypeId){
     let id = new dto.EntityTypePermId(objectTypeId)
     let fo = new dto.SampleTypeFetchOptions()
-    fo.withPropertyAssignments().withPropertyType()
+    fo.withPropertyAssignments().withPropertyType().withMaterialType()
+    fo.withPropertyAssignments().withPropertyType().withVocabulary()
     fo.withPropertyAssignments().sortBy().code()
 
     return facade.getSampleTypes([id], fo).then(map => {
@@ -81,6 +82,7 @@ class ObjectType extends React.Component {
     let criteria = new dto.PropertyTypeSearchCriteria()
     let fo = new dto.PropertyTypeFetchOptions()
     fo.withVocabulary().withTerms()
+    fo.withMaterialType()
 
     return facade.searchPropertyTypes(criteria, fo).then(result => {
       return result.objects
diff --git a/openbis_ng_ui/src/components/types/objectType/ObjectTypePropertyPreview.jsx b/openbis_ng_ui/src/components/types/objectType/ObjectTypePropertyPreview.jsx
index 8f31eebb101cc50236ad8070e57cf5d1ccafdc8c..4ff1651daccf58719ddc0349d20ebd93fc998be8 100644
--- a/openbis_ng_ui/src/components/types/objectType/ObjectTypePropertyPreview.jsx
+++ b/openbis_ng_ui/src/components/types/objectType/ObjectTypePropertyPreview.jsx
@@ -7,6 +7,7 @@ import Checkbox from '@material-ui/core/Checkbox'
 import InfoIcon from '@material-ui/icons/InfoOutlined'
 import Tooltip from '@material-ui/core/Tooltip'
 import {withStyles} from '@material-ui/core/styles'
+import {facade, dto} from '../../../services/openbis.js'
 import logger from '../../../common/logger.js'
 
 const styles = () => ({
@@ -25,21 +26,53 @@ class ObjectTypePropertyPreview extends React.Component {
   constructor(props){
     super(props)
     this.state = {
-      values: {
-        vocabulary: '',
+      vocabularyValue: '',
+      materialValue: '',
+    }
+    this.setMaterial = this.setMaterial.bind(this)
+    this.setVocabulary = this.setVocabulary.bind(this)
+  }
+
+  static getDerivedStateFromProps(props, state) {
+    if(props.property !== state.property){
+      return {
+        loaded: false,
+        property: props.property,
+        vocabularyTerms: [],
+        materials: []
       }
+    }else{
+      return null
     }
   }
 
-  handleChange(name){
-    return (event) => {
-      this.setState((prevState) => ({
-        ...prevState,
-        values: {
-          ...prevState.values,
-          [name]: _.has(event.target, 'checked') ? event.target.checked : event.target.value
-        }
-      }))
+  componentDidMount(){
+    this.load()
+  }
+
+  componentDidUpdate(){
+    this.load()
+  }
+
+  load(){
+    if(this.state.loaded){
+      return
+    }
+
+    const {propertyType} = this.state.property
+
+    switch(propertyType.dataType){
+      case 'CONTROLLEDVOCABULARY':
+        this.loadVocabulary()
+        return
+      case 'MATERIAL':
+        this.loadMaterial()
+        return
+      default:
+        this.setState(() => ({
+          loaded: true
+        }))
+        return
     }
   }
 
@@ -49,7 +82,7 @@ class ObjectTypePropertyPreview extends React.Component {
     const {classes} = this.props
 
     return (
-      <div className={classes.container}>
+      <div className={classes.container} onClick={(event) => {event.stopPropagation()}}>
         {this.renderField()}
         <Tooltip title={this.getDescription()}>
           <InfoIcon />
@@ -59,7 +92,7 @@ class ObjectTypePropertyPreview extends React.Component {
   }
 
   renderField(){
-    const {propertyType} = this.props
+    const {propertyType} = this.state.property
 
     switch(propertyType.dataType){
       case 'BOOLEAN':
@@ -73,6 +106,8 @@ class ObjectTypePropertyPreview extends React.Component {
         return this.renderNumber()
       case 'CONTROLLEDVOCABULARY':
         return this.renderVocabulary()
+      case 'MATERIAL':
+        return this.renderMaterial()
       default:
         return this.renderUnsupported()
     }
@@ -120,44 +155,105 @@ class ObjectTypePropertyPreview extends React.Component {
     )
   }
 
+  loadVocabulary(){
+    let criteria = new dto.VocabularyTermSearchCriteria()
+    let fo = new dto.VocabularyTermFetchOptions()
+
+    criteria.withVocabulary().withCode().thatEquals(this.state.property.propertyType.vocabulary.code)
+
+    return facade.searchVocabularyTerms(criteria, fo).then(result => {
+      this.setState(() => ({
+        loaded: true,
+        vocabularyTerms: result.objects
+      }))
+    })
+  }
+
+  getVocabulary(){
+    return this.state.vocabularyValue
+  }
+
+  setVocabulary(event){
+    this.setState(() => ({
+      vocabularyValue: event.target.value
+    }))
+  }
+
   renderVocabulary(){
     return (
       <TextField
         select
         label={this.getLabel()}
-        value={this.getValue('vocabulary')}
-        onChange={this.handleChange('vocabulary')}
+        value={this.getVocabulary()}
+        onChange={this.setVocabulary}
         fullWidth={true}
         variant="filled"
       >
         <MenuItem value=""></MenuItem>
-        {this.getTerms().map(term => (
+        {this.state.vocabularyTerms.map(term => (
           <MenuItem key={term.code} value={term.code}>{term.label || term.code}</MenuItem>
         ))}
       </TextField>
     )
   }
 
-  renderUnsupported(){
-    return (<div>unsupported</div>)
+  loadMaterial(){
+    let criteria = new dto.MaterialSearchCriteria()
+    let fo = new dto.MaterialFetchOptions()
+
+    let materialType = this.state.property.propertyType.materialType
+    if(materialType){
+      criteria.withType().withId().thatEquals(materialType.permId)
+    }
+
+    return facade.searchMaterials(criteria, fo).then(result => {
+      this.setState(() => ({
+        loaded: true,
+        materials: result.objects
+      }))
+    })
   }
 
-  getValue(field){
-    return this.state.values[field]
+  getMaterial(){
+    return this.state.materialValue
+  }
+
+  setMaterial(event){
+    this.setState(() => ({
+      materialValue: event.target.value
+    }))
+  }
+
+  renderMaterial(){
+    return (
+      <TextField
+        select
+        label={this.getLabel()}
+        value={this.getMaterial()}
+        onChange={this.setMaterial}
+        fullWidth={true}
+        variant="filled"
+      >
+        <MenuItem value=""></MenuItem>
+        {this.state.materials.map(material => (
+          <MenuItem key={material.code} value={material.code}>{material.code}</MenuItem>
+        ))}
+      </TextField>
+    )
+  }
+
+  renderUnsupported(){
+    return (<div>unsupported</div>)
   }
 
   getLabel(){
-    let mandatory = this.props.property.mandatory
-    let label = this.props.propertyType.label
+    let mandatory = this.state.property.mandatory
+    let label = this.state.property.propertyType.label
     return mandatory ? label + '*' : label
   }
 
   getDescription(){
-    return this.props.propertyType.description
-  }
-
-  getTerms(){
-    return this.props.propertyType.vocabulary.terms
+    return this.state.property.propertyType.description
   }
 
 }
diff --git a/openbis_ng_ui/src/components/types/objectType/ObjectTypePropertyRow.jsx b/openbis_ng_ui/src/components/types/objectType/ObjectTypePropertyRow.jsx
index d1ce770022af8c5b1adebfc9993c9d4ec67eb233..02b723a71801be1fa4b29195c239263138aa0065 100644
--- a/openbis_ng_ui/src/components/types/objectType/ObjectTypePropertyRow.jsx
+++ b/openbis_ng_ui/src/components/types/objectType/ObjectTypePropertyRow.jsx
@@ -130,14 +130,11 @@ class ObjectTypeTableRow extends React.Component {
   }
 
   renderPreview(){
-    const {property, propertyTypes} = this.props
+    const {property} = this.props
 
     if(property.propertyType){
-      const propertyType = _.find(propertyTypes, propertyType => {
-        return propertyType.code === property.propertyType.code
-      })
       return (
-        <ObjectTypePropertyPreview property={property} propertyType={propertyType} />
+        <ObjectTypePropertyPreview property={property} />
       )
     }else{
       return (<div></div>)
diff --git a/openbis_ng_ui/src/services/openbis/dto.js b/openbis_ng_ui/src/services/openbis/dto.js
index aad2c2c5bdf8e334f39b3a4ec4b3ef3e18e4ba34..267f7e28cf3a6f460bde71c21f7ffaaf493f34b2 100644
--- a/openbis_ng_ui/src/services/openbis/dto.js
+++ b/openbis_ng_ui/src/services/openbis/dto.js
@@ -16,7 +16,12 @@ const CLASS_FULL_NAMES = [
   'as/dto/material/fetchoptions/MaterialTypeFetchOptions',
   'as/dto/property/PropertyType',
   'as/dto/property/search/PropertyTypeSearchCriteria',
-  'as/dto/property/fetchoptions/PropertyTypeFetchOptions'
+  'as/dto/property/fetchoptions/PropertyTypeFetchOptions',
+  'as/dto/property/fetchoptions/PropertyTypeFetchOptions',
+  'as/dto/material/fetchoptions/MaterialFetchOptions',
+  'as/dto/material/search/MaterialSearchCriteria',
+  'as/dto/vocabulary/search/VocabularyTermSearchCriteria',
+  'as/dto/vocabulary/fetchoptions/VocabularyTermFetchOptions'
 ]
 
 class Dto {
diff --git a/openbis_ng_ui/src/services/openbis/facade.js b/openbis_ng_ui/src/services/openbis/facade.js
index fc8747dc58a0f479e826dd2128099157becf7837..2a8835d79ebbccffc992122eefbeb7413116dde0 100644
--- a/openbis_ng_ui/src/services/openbis/facade.js
+++ b/openbis_ng_ui/src/services/openbis/facade.js
@@ -36,6 +36,14 @@ export class Facade {
     return this.v3.searchPropertyTypes(criteria, fo)
   }
 
+  searchMaterials(criteria, fo) {
+    return this.v3.searchMaterials(criteria, fo)
+  }
+
+  searchVocabularyTerms(criteria, fo) {
+    return this.v3.searchVocabularyTerms(criteria, fo)
+  }
+
   searchPersons(criteria, fo) {
     return this.v3.searchPersons(criteria, fo)
   }