diff --git a/openbis_ng_ui/src/js/common/messages.js b/openbis_ng_ui/src/js/common/messages.js
index 6eddc08919826d02a485a64d49720c631d04ae30..208b7da10abcb4d7633221a663c45a06098b358e 100644
--- a/openbis_ng_ui/src/js/common/messages.js
+++ b/openbis_ng_ui/src/js/common/messages.js
@@ -102,6 +102,7 @@ const keys = {
   LABEL: 'LABEL',
   LAST_NAME: 'LAST_NAME',
   LAST_PAGE: 'LAST_PAGE',
+  LESS: 'LESS',
   LEVEL: 'LEVEL',
   LOGIN: 'LOGIN',
   MAIN_DATA_SET_PATH: 'MAIN_DATA_SET_PATH',
@@ -110,6 +111,7 @@ const keys = {
   MATERIAL_TYPE: 'MATERIAL_TYPE',
   MATERIAL_TYPES: 'MATERIAL_TYPES',
   META_DATA: 'META_DATA',
+  MORE: 'MORE',
   NAME: 'NAME',
   NEW_COLLECTION_TYPE: 'NEW_COLLECTION_TYPE',
   NEW_DATA_SET_TYPE: 'NEW_DATA_SET_TYPE',
@@ -336,6 +338,7 @@ const messages_en = {
   [keys.LABEL]: 'Label',
   [keys.LAST_NAME]: 'Last Name',
   [keys.LAST_PAGE]: 'Last Page',
+  [keys.LESS]: 'Less',
   [keys.LEVEL]: 'Level',
   [keys.LOGIN]: 'Login',
   [keys.MAIN_DATA_SET_PATH]: 'Main Data Set Path',
@@ -344,6 +347,7 @@ const messages_en = {
   [keys.MATERIAL_TYPES]: 'Material Types',
   [keys.MATERIAL_TYPE]: 'Material Type',
   [keys.META_DATA]: 'Meta Data',
+  [keys.MORE]: 'More',
   [keys.NAME]: 'Name',
   [keys.NEW_COLLECTION_TYPE]: 'New Collection Type',
   [keys.NEW_DATA_SET_TYPE]: 'New Data Set Type',
diff --git a/openbis_ng_ui/src/js/components/common/grid/GridCell.jsx b/openbis_ng_ui/src/js/components/common/grid/GridCell.jsx
index 0e3b2dbb8f273dd54acb113a368c3769abc622ba..8a2fa7e31dcc828955594c96cbaf11e3ffc27404 100644
--- a/openbis_ng_ui/src/js/components/common/grid/GridCell.jsx
+++ b/openbis_ng_ui/src/js/components/common/grid/GridCell.jsx
@@ -2,8 +2,12 @@ import _ from 'lodash'
 import React from 'react'
 import { withStyles } from '@material-ui/core/styles'
 import TableCell from '@material-ui/core/TableCell'
+import Link from '@material-ui/core/Link'
+import messages from '@src/js/common/messages.js'
 import logger from '@src/js/common/logger.js'
 
+const TRUNCATE_HEIGHT = 50
+
 const styles = theme => ({
   cell: {
     paddingTop: theme.spacing(1),
@@ -15,50 +19,63 @@ const styles = theme => ({
       content: '"\\a0"'
     }
   },
-  wrap: {
-    whiteSpace: 'normal'
-  },
   nowrap: {
     whiteSpace: 'nowrap'
+  },
+  truncate: {
+    maxHeight: TRUNCATE_HEIGHT + 'px',
+    overflow: 'hidden'
   }
 })
 
 class GridCell extends React.PureComponent {
   constructor(props) {
     super(props)
+
+    this.state = {
+      renderMore: false,
+      moreOpen: false
+    }
     this.ref = React.createRef()
+    this.handleMoreClick = this.handleMoreClick.bind(this)
   }
 
   componentDidMount() {
     this.renderDOMValue()
+    this.maybeScheduleRenderMore()
   }
 
-  componentDidUpdate() {
-    this.renderDOMValue()
+  handleMoreClick() {
+    this.setState(state => ({
+      moreOpen: !state.moreOpen
+    }))
   }
 
   render() {
     logger.log(logger.DEBUG, 'GridCell.render')
 
     const { column, className, classes } = this.props
+    const { moreOpen } = this.state
 
     const cellClasses = [classes.cell]
-    if (column.wrappable) {
-      cellClasses.push(classes.wrap)
-    } else {
-      cellClasses.push(classes.nowrap)
-    }
     if (className) {
       cellClasses.push(className)
     }
 
+    const divClasses = []
+    if (column.nowrap) {
+      divClasses.push(classes.nowrap)
+    }
+    if (column.truncate && !moreOpen) {
+      divClasses.push(classes.truncate)
+    }
+
     return (
-      <TableCell
-        ref={this.ref}
-        key={column.name}
-        classes={{ root: cellClasses.join(' ') }}
-      >
-        {column.renderDOMValue ? null : this.renderValue()}
+      <TableCell key={column.name} classes={{ root: cellClasses.join(' ') }}>
+        <div ref={this.ref} className={divClasses.join(' ')}>
+          {column.renderDOMValue ? null : this.renderValue()}
+        </div>
+        {this.renderMore()}
       </TableCell>
     )
   }
@@ -97,6 +114,35 @@ class GridCell extends React.PureComponent {
       })
     }
   }
+
+  renderMore() {
+    const { renderMore, moreOpen } = this.state
+
+    if (!renderMore) {
+      return null
+    }
+
+    return (
+      <div>
+        <Link onClick={this.handleMoreClick}>
+          {moreOpen ? messages.get(messages.LESS) : messages.get(messages.MORE)}
+        </Link>
+      </div>
+    )
+  }
+
+  maybeScheduleRenderMore() {
+    const { column } = this.props
+    if (
+      column.truncate &&
+      this.ref.current &&
+      this.ref.current.scrollHeight > TRUNCATE_HEIGHT
+    ) {
+      setTimeout(() => {
+        this.setState({ renderMore: true })
+      }, 1)
+    }
+  }
 }
 
 export default withStyles(styles)(GridCell)
diff --git a/openbis_ng_ui/src/js/components/common/grid/GridController.js b/openbis_ng_ui/src/js/components/common/grid/GridController.js
index 6c7a4df5e86524e47ab53054079255121c13fcf7..1870d74fd491c657887be90db0b9cbd06dbe1254 100644
--- a/openbis_ng_ui/src/js/components/common/grid/GridController.js
+++ b/openbis_ng_ui/src/js/components/common/grid/GridController.js
@@ -365,10 +365,11 @@ export default class GridController {
       sortable: column.sortable === undefined ? true : column.sortable,
       filterable: column.filterable === undefined ? true : column.filterable,
       visible: column.visible === undefined ? true : column.visible,
-      wrappable: column.wrappable === undefined ? true : column.wrappable,
       configurable:
         column.configurable === undefined ? true : column.configurable,
       exportable: column.exportable === undefined ? true : column.exportable,
+      nowrap: column.nowrap === undefined ? false : column.nowrap,
+      truncate: column.truncate === undefined ? false : column.truncate,
       metadata: column.metadata === undefined ? {} : column.metadata
     }
   }
diff --git a/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx b/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx
index 97f4a0c49a3d0a5d2d8881a27147214716bcdb2b..b247f9558d5974521bcc67034830be54072e128d 100644
--- a/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx
+++ b/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx
@@ -49,7 +49,7 @@ class UsersGrid extends React.PureComponent {
           {
             name: 'email',
             label: messages.get(messages.EMAIL),
-            wrappable: false,
+            nowrap: true,
             getValue: ({ row }) => row.email.value
           },
           {
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js
index cf496c14ff8e4e937ae52fe030cf935b7d3033c7..0c6d163cbffc9137686d27fc97ee1d0f9b4d04cd 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js
@@ -2285,47 +2285,6 @@ var FormUtil = new function() {
 		return id;
 	}
 
-    this.renderTruncatedGridValue = function(container, value){
-        var MAX_HEIGHT = 100
-
-        var $value = $("<div>")
-        $value.css("max-height", MAX_HEIGHT + "px")
-        $value.css("overflow", "hidden")
-
-        if(_.isString(value)){
-            $value.text(value)
-        }else{
-            $value.append(value)
-        }
-
-        $value.css("min-width", Math.min($value.text().length / 5, 15) + "em")
-
-        if(container === null ||  container === undefined){
-            return $value
-        }
-
-        $value.css("visibility", "hidden").appendTo(container)
-        var valueHeight = $value.get(0).scrollHeight
-        $value.remove()
-        $value.css("visibility", "")
-
-        if(valueHeight > MAX_HEIGHT){
-            var $toggle = $("<a>").text("more")
-            $toggle.click(function(){
-                if($toggle.text() === "more"){
-                    $value.css("max-height", "")
-                    $toggle.text("less")
-                }else{
-                    $value.css("max-height", MAX_HEIGHT + "px")
-                    $toggle.text("more")
-                }
-            })
-            return $("<div>").append($value).append($toggle)
-        }else{
-            return $value
-        }
-    }
-
     this.renderMultilineVarcharGridValue = function(row, params, propertyType){
         return this.renderCustomWidgetGridValue(row, params, propertyType)
     }
@@ -2359,8 +2318,7 @@ var FormUtil = new function() {
                         return $tooltip
                     }
                 }else{
-                    $value  = $("<div>").html(FormUtil.sanitizeRichHTMLText(value))
-                    return this.renderTruncatedGridValue(params.container, $value)
+                    return $("<div>").html(FormUtil.sanitizeRichHTMLText(value))
                 }
             }else if(customWidget === 'Spreadsheet'){
                 $value = $("<img>", { src : "./img/table.svg", "width": "16px", "height": "16px"})
@@ -2374,7 +2332,7 @@ var FormUtil = new function() {
                 value.split('\n').forEach(function(line){
                     $("<div>").text(line).appendTo($value)
                 })
-                return this.renderTruncatedGridValue(params.container, $value)
+                return $value
             }
 
             $value.tooltipster({
@@ -2398,7 +2356,7 @@ var FormUtil = new function() {
             value.split('\n').forEach(function(line){
                 $("<div>").text(line).appendTo($value)
             })
-            return this.renderTruncatedGridValue(params.container, $value)
+            return $value
         }
     }
 
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/AdvancedSearch/AdvancedSearchView.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/AdvancedSearch/AdvancedSearchView.js
index bf7be122f376168a2a914687e9b2dbfae13a982c..b97773a19fa73cbd54ec3bdc2b6bd115f11378bc 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/AdvancedSearch/AdvancedSearchView.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/AdvancedSearch/AdvancedSearchView.js
@@ -1124,7 +1124,7 @@ function AdvancedSearchView(advancedSearchController, advancedSearchModel) {
 						render: renderValue,
 						renderFilter: renderFilter,
 						sortable : !isGlobalSearch && propertyType.dataType !== "XML",
-						truncate: propertyType.dataType === "VARCHAR",
+						truncate: true,
 						metadata: {
 							dataType: propertyType.dataType
 						}
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController.js
index 05e2163cb2a6249e3629e761acba46343d21fb04..9da148d5242b0a5d75fb7940cbc6ddd0020300da 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController.js
@@ -158,9 +158,6 @@ function DataGridController(
                     if(value === null || value === undefined || value === ""){
                         return
                     }else{
-                        if(column.truncate){
-                            value = FormUtil.renderTruncatedGridValue(params.container, value)
-                        }
                         if(_.isString(value)){
                             $(params.container).empty().text(value)
                         }else{
@@ -194,6 +191,7 @@ function DataGridController(
                         index === columns.length - 1),
                 configurable: !column.hide && !column.canNotBeHidden,
                 exportable: column.isExportable,
+                truncate: column.truncate,
                 metadata: column.metadata,
             }
         })
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/ExperimentDataGridUtil.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/ExperimentDataGridUtil.js
index c30326d7cb0a77dcb1e72108e61678c654ae27a1..ffed04c1ce53d048e9a46f3f6c0dc7286193a710 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/ExperimentDataGridUtil.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/ExperimentDataGridUtil.js
@@ -146,7 +146,7 @@ var ExperimentDataGridUtil = new function() {
 					property : propertyCodes[idx],
 					isExportable: true,
 					sortable : true,
-					truncate: propertyType.dataType === "VARCHAR",
+					truncate: true,
 					render: renderValue
 				});
 			}
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/SampleDataGridUtil.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/SampleDataGridUtil.js
index bfe1f947426e83eff495351def0f89cc5a545d13..b54df5203f67aa1da858d40030bfc8173f13d8f0 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/SampleDataGridUtil.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/SampleDataGridUtil.js
@@ -250,7 +250,7 @@ var SampleDataGridUtil = new function() {
 						isExportable: true,
 						filterable : true,
 						sortable : propertyType.dataType !== "XML",
-						truncate: propertyType.dataType === "VARCHAR",
+						truncate: true,
 						metadata: {
 							dataType: propertyType.dataType
 						},