Index: frontends/php/app/views/monitoring.widget.system.view.php
===================================================================
--- frontends/php/app/views/monitoring.widget.system.view.php	(revision 60417)
+++ frontends/php/app/views/monitoring.widget.system.view.php	(revision 60585)
@@ -19,11 +19,12 @@
 **/
 
 
-$table = make_system_status($data['filter'], 'zabbix.php?action=dashboard.view');
+$widget_data = make_system_status($data['filter'], 'zabbix.php?action=dashboard.view');
 
 $output = [
 	'header' => _('System status'),
 	'body' => (new CDiv([getMessages(), $table]))->toString(),
+	'data' => $widget_data,
 	'footer' => (new CListItem(_s('Updated: %s', zbx_date2str(TIME_FORMAT_SECONDS))))->toString()
 ];
 
Index: frontends/php/app/views/monitoring.widget.system.view.js.php
===================================================================
--- frontends/php/app/views/monitoring.widget.system.view.js.php	(revision 0)
+++ frontends/php/app/views/monitoring.widget.system.view.js.php	(revision 60585)
@@ -0,0 +1,100 @@
+<script type="text/x-jquery-tmpl" id="systemStatusTable">
+	<table class="list-table" id="syssum_table">
+		<thead>
+			<tr/>
+		</thead>
+		<tbody/>
+	</table>
+</script>
+
+<script type="text/x-jquery-tmpl" id="systemStatusCell">
+	<span class="link-action" onMouseOver="hintBox.HintWraper(event, this, jQuery(#{table_id}), '', '')"
+		onClick="hintBox.showStaticHint(event, this, jQuery(#{table_id}), '', false, '')">
+		#{count}
+	</span>
+</script>
+
+<script type="text/x-jquery-tmpl" id="systemStatusPopupTable">
+	<table class="list-table" id="#{table_id}">
+		<thead>
+			<tr>
+				<th>Host</th>
+				<th>Issue</th>
+				<th>Age</th>
+				<th>Info</th>
+				<th>Ack</th>
+				<th>Actions</th>
+			</tr>
+		</thead>
+		<tbody/>
+	</table>
+</script>
+
+<script>
+function syssumParser(data) {
+	var i, header, group, tpl;
+
+	tpl = new Template(jQuery('#systemStatusTable').html());
+	jQuery('#syssum').html(tpl.evaluate());
+
+	for (i = 0; i < data.header.length; i++) {
+		header = data.header[i];
+		jQuery('#syssum_table > thead > tr').append('<th>'+header+'</th>');
+	}
+
+	for (i = 0; i < data.groups.length; i++) {
+		var j, span, popupTable, row;
+
+		group = data.groups[i];
+
+		row = jQuery('<tr/>')
+			.append('<td><a href="'+group.name.attributes.href+'">'+group.name.items[0]+'</a></td>');
+
+		span = new Template(jQuery('#systemStatusCell').html());
+		popupTable = new Template(jQuery('#systemStatusPopupTable').html());
+
+		for (j = 0; j < group.severities.length; j++) {
+			var severity, cell;
+
+			severity = group.severities[j];
+
+			cell = jQuery('<td/>')
+				.addClass(severity.style);
+
+			if (typeof severity.popup_unack !== 'undefined' && severity.popup_unack.length > 0) {
+				severity.table_id = 't2_'+i+'_'+j;
+				cell
+					.append(span.evaluate({count:severity.count_unack, table_id:severity.table_id}))
+					.append(
+						jQuery('<span style="display:none;"/>')
+							.append(
+								jQuery(popupTable.evaluate(severity))
+									.append(severity.popup_unack)
+							)
+					);
+			}
+
+			if (severity.popup.length > 0) {
+				severity.table_id = 't1_'+i+'_'+j;
+				cell
+					.append(span.evaluate(severity))
+					.append(
+						jQuery('<span style="display:none;"/>')
+							.append(
+								jQuery(popupTable.evaluate(severity))
+									.append(severity.popup)
+							)
+					);
+			}
+			else {
+				cell.append(severity.count);
+			}
+
+			row.append(cell);
+		}
+
+		jQuery('#syssum_table > tbody').append(row);
+	}
+}
+
+</script>

Property changes on: frontends/php/app/views/monitoring.widget.system.view.js.php
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: frontends/php/app/views/monitoring.dashboard.view.php
===================================================================
--- frontends/php/app/views/monitoring.dashboard.view.php	(revision 60417)
+++ frontends/php/app/views/monitoring.dashboard.view.php	(revision 60585)
@@ -20,6 +20,7 @@
 
 
 $this->addJSfile('js/class.pmaster.js');
+$this->includeJSfile('app/views/monitoring.widget.system.view.js.php');
 
 $dashboard = (new CWidget())
 	->setTitle(_('Dashboard'))
Index: frontends/php/js/class.pmaster.js
===================================================================
--- frontends/php/js/class.pmaster.js	(revision 60417)
+++ frontends/php/js/class.pmaster.js	(revision 60585)
@@ -333,10 +333,17 @@
 			}
 			else
 			{
+				// Dashboard widget data comes in JSON
 				var debug = is_null(resp.responseJSON.debug) ? '' : resp.responseJSON.debug;
 
-				// Dashboard widget data comes in JSON
-				this._domobj.html(resp.responseJSON.body + debug);
+				if (is_null(resp.responseJSON.data)) {
+					this._domobj.html(resp.responseJSON.body);
+				}
+				else {
+					window[this._domid + 'Parser'](resp.responseJSON.data);
+				}
+
+				this._domobj.append(debug);
 				this._domobj_header.html(resp.responseJSON.header);
 				this._domobj_footer.html(resp.responseJSON.footer);
 			}
Index: frontends/php/include/blocks.inc.php
===================================================================
--- frontends/php/include/blocks.inc.php	(revision 60417)
+++ frontends/php/include/blocks.inc.php	(revision 60585)
@@ -266,23 +266,6 @@
 }
 
 function make_system_status($filter, $backurl) {
-	$config = select_config();
-
-	$table = new CTableInfo();
-
-	// set trigger severities as table header starting from highest severity
-	$header = [];
-
-	for ($severity = TRIGGER_SEVERITY_NOT_CLASSIFIED; $severity < TRIGGER_SEVERITY_COUNT; $severity++) {
-		$header[] = ($filter['severity'] === null || isset($filter['severity'][$severity]))
-			? getSeverityName($severity, $config)
-			: null;
-	}
-	krsort($header);
-	array_unshift($header, _('Host group'));
-
-	$table->setHeader($header);
-
 	// get host groups
 	$groups = API::HostGroup()->get([
 		'groupids' => $filter['groupids'],
@@ -400,14 +383,27 @@
 	}
 	unset($triggers);
 
+	$config = select_config();
+
+	// set trigger severities as table header starting from highest severity
+	$header = [];
+
+	for ($severity = TRIGGER_SEVERITY_NOT_CLASSIFIED; $severity < TRIGGER_SEVERITY_COUNT; $severity++) {
+		$header[] = ($filter['severity'] === null || isset($filter['severity'][$severity]))
+			? getSeverityName($severity, $config)
+			: null;
+	}
+	krsort($header);
+	array_unshift($header, _('Host group'));
+
+	$widget_data = ['header' => $header];
+
 	foreach ($groups as $group) {
-		$groupRow = new CRow();
-
 		$name = new CLink($group['name'], 'tr_status.php?filter_set=1&groupid='.$group['groupid'].'&hostid=0'.
 			'&show_triggers='.TRIGGERS_OPTION_RECENT_PROBLEM
 		);
 
-		$groupRow->addItem($name);
+		$severities = [];
 
 		foreach ($group['tab_priority'] as $severity => $data) {
 			if (!is_null($filter['severity']) && !isset($filter['severity'][$severity])) {
@@ -414,48 +410,67 @@
 				continue;
 			}
 
+			$all_triggers_popup_data = [];
 			$allTriggersNum = $data['count'];
 			if ($allTriggersNum) {
-				$allTriggersNum = (new CSpan($allTriggersNum))
-					->addClass(ZBX_STYLE_LINK_ACTION)
-					->setHint(makeTriggersPopup($data['triggers'], $backurl, $actions, $config));
+				$all_triggers_popup_data = makeTriggersPopupDataArray($data['triggers'], $backurl, $actions, $config);
 			}
 
+			$unack_triggers_popup_data = [];
 			$unackTriggersNum = $data['count_unack'];
 			if ($unackTriggersNum) {
-				$unackTriggersNum = (new CSpan($unackTriggersNum))
-					->addClass(ZBX_STYLE_LINK_ACTION)
-					->setHint(makeTriggersPopup($data['triggers_unack'], $backurl, $actions, $config));
+				$unack_triggers_popup_data = makeTriggersPopupDataArray($data['triggers_unack'], $backurl, $actions, $config);
 			}
 
+			$cell_data = [];
+
 			switch ($filter['extAck']) {
 				case EXTACK_OPTION_ALL:
-					$groupRow->addItem(getSeverityCell($severity, $config, $allTriggersNum, $data['count'] == 0));
+					$cell_data = [
+						'count' => $allTriggersNum,
+						'popup' => $all_triggers_popup_data,
+						'style' => getSeverityStyle($severity, $data['count'] > 0)
+					];
 					break;
 
 				case EXTACK_OPTION_UNACK:
-					$groupRow->addItem(getSeverityCell($severity, $config, $unackTriggersNum,
-						$data['count_unack'] == 0
-					));
+					$cell_data = [
+						'count' => $allTriggersNum,
+						'popup' => $unack_triggers_popup_data,
+						'style' => getSeverityStyle($severity, $data['count_unack'] > 0)
+					];
 					break;
 
 				case EXTACK_OPTION_BOTH:
 					if ($data['count_unack'] != 0) {
-						$groupRow->addItem(getSeverityCell($severity, $config, [
-							$unackTriggersNum, ' '._('of').' ', $allTriggersNum
-						]));
+						$cell_data = [
+							'count' => $allTriggersNum,
+							'popup' => $all_triggers_popup_data,
+							'style' => getSeverityStyle($severity),
+							'count_unack' => $unackTriggersNum.' '._('of').' ',
+							'popup_unack' => $unack_triggers_popup_data
+						];
 					}
 					else {
-						$groupRow->addItem(getSeverityCell($severity, $config, $allTriggersNum, $data['count'] == 0));
+						$cell_data = [
+							'count' => $allTriggersNum,
+							'popup' => $all_triggers_popup_data,
+							'style' => getSeverityStyle($severity, $data['count'] > 0)
+						];
 					}
 					break;
 			}
+
+			$severities[] = $cell_data;
 		}
 
-		$table->addRow($groupRow);
+		$widget_data['groups'][] = [
+			'name' => $name,
+			'severities' => $severities
+		];
 	}
 
-	return $table;
+	return $widget_data;
 }
 
 function make_status_of_zbx() {
@@ -774,7 +789,7 @@
 }
 
 /**
- * Generate table for dashboard triggers popup.
+ * Generate data for dashboard triggers popup.
  *
  * @see make_system_status
  *
@@ -783,18 +798,10 @@
  * @param array $actions
  * @param array $config
  *
- * @return CTableInfo
+ * @return array
  */
-function makeTriggersPopup(array $triggers, $backurl, array $actions, array $config) {
-	$popupTable = (new CTableInfo())
-		->setHeader([
-			_('Host'),
-			_('Issue'),
-			_('Age'),
-			_('Info'),
-			$config['event_ack_enable'] ? _('Ack') : null,
-			_('Actions')
-		]);
+function makeTriggersPopupDataArray(array $triggers, $backurl, array $actions, array $config) {
+	$popup_data = [];
 
 	CArrayHelper::sort($triggers, [['field' => 'lastchange', 'order' => ZBX_SORT_DOWN]]);
 
@@ -825,15 +832,15 @@
 			? $actions[$trigger['event']['eventid']]
 			: '';
 
-		$popupTable->addRow([
-			$trigger['hosts'][0]['name'],
-			getSeverityCell($trigger['priority'], $config, $description),
-			zbx_date2age($trigger['lastchange']),
-			$unknown,
-			$ack,
-			(new CCol($action))->addClass(ZBX_STYLE_NOWRAP)
-		]);
+		$popup_data[] = (new CRow([
+			'hostname' => $trigger['hosts'][0]['name'],
+			'issue' => getSeverityCell($trigger['priority'], $config, $description),
+			'age' => zbx_date2age($trigger['lastchange']),
+			'info' => $unknown,
+			'ack' => $ack,
+			'actions' => (new CCol($action))->addClass(ZBX_STYLE_NOWRAP)
+		]))->toString();
 	}
 
-	return $popupTable;
+	return $popup_data;
 }
