diff --git a/sohstationviewer/view/plotting/plotting_widget/multi_threaded_plotting_widget.py b/sohstationviewer/view/plotting/plotting_widget/multi_threaded_plotting_widget.py
index c79ceceb20149e73ad0e19a7dde34a495029560a..03028a7ed9e78e634ad1c817fea4007df5a79e1d 100644
--- a/sohstationviewer/view/plotting/plotting_widget/multi_threaded_plotting_widget.py
+++ b/sohstationviewer/view/plotting/plotting_widget/multi_threaded_plotting_widget.py
@@ -1,6 +1,6 @@
 # Define functions to call processor
 
-from typing import Tuple, Union, Dict, List
+from typing import Tuple, Union, Dict, List, Optional
 
 from PySide6 import QtCore
 
@@ -45,6 +45,10 @@ class MultiThreadedPlottingWidget(PlottingWidget):
         # or zoom_markers while plotting
         self.is_working = False
 
+        # List of SOH message lines in RT130 to display in info box when
+        # there're more than 2 lines for one data point clicked
+        self.log_data: Optional[List[str]] = None
+
         self.finished.connect(self.stopped)
         self.notification.connect(
             lambda msg: display_tracking_info(self.tracking_box, msg))
diff --git a/sohstationviewer/view/plotting/state_of_health_widget.py b/sohstationviewer/view/plotting/state_of_health_widget.py
index b850cd7ad51faedfe3b53bad53eb6f1b733fa4f4..1b5b06b549603d69e46f6e3207d78303c27370fe 100644
--- a/sohstationviewer/view/plotting/state_of_health_widget.py
+++ b/sohstationviewer/view/plotting/state_of_health_widget.py
@@ -33,6 +33,12 @@ class SOHWidget(MultiThreadedPlottingWidget):
         self.data_object = d_obj
         self.plotting_data1 = d_obj.soh_data[key] if key else {}
         self.plotting_data2 = d_obj.mass_pos_data[key] if key else {}
+        self.log_data = None
+        if self.data_object.data_type == 'RT130':
+            try:
+                self.log_data = d_obj.log_data[key]['SOH'][0].split('\n')
+            except KeyError:
+                pass
         channel_list = d_obj.soh_data[key].keys() if key else []
         data_time = d_obj.data_time[key] if key else [0, 1]
         ret = super().init_plot(d_obj, data_time, key, start_tm, end_tm,
diff --git a/sohstationviewer/view/search_message/search_message_dialog.py b/sohstationviewer/view/search_message/search_message_dialog.py
index 8aeb3f2b75607af0cdeb3d84d3d6064e8daead31..33046b24a61aa44ba2d70dff8f6d2a54de5521af 100644
--- a/sohstationviewer/view/search_message/search_message_dialog.py
+++ b/sohstationviewer/view/search_message/search_message_dialog.py
@@ -4,7 +4,8 @@ from pathlib import PosixPath, Path
 from typing import Dict, List, Tuple, Callable, Union, Optional
 
 from PySide6 import QtGui, QtCore, QtWidgets
-from PySide6.QtWidgets import QStyle
+from PySide6.QtWidgets import QStyle, QAbstractItemView
+from PySide6.QtGui import QPalette
 
 from sohstationviewer.view.search_message.highlight_delegate import (
     HighlightDelegate)
@@ -394,6 +395,14 @@ class SearchMessageDialog(QtWidgets.QWidget):
         """
         # add 1 extra column to show scroll bar (+ 1)
         table = QtWidgets.QTableWidget(rows, cols + 1)
+
+        # To prevent selected row not grey out. It still gets faded out, but
+        # the color remain blue which is better than grey out.
+        p = table.palette()
+        p.setBrush(QPalette.Inactive, QPalette.Highlight,
+                   p.brush(QPalette.Highlight))
+        table.setPalette(p)
+
         delegate = HighlightDelegate(table, self.display_color)
         table.setItemDelegate(delegate)
         # Hide header cells
@@ -487,9 +496,48 @@ class SearchMessageDialog(QtWidgets.QWidget):
         item : QTableWidgetItem
             A valid QTableWidgetIem
         """
-        self.current_table.scrollToItem(item)
+        self.current_table.scrollToItem(item, QAbstractItemView.PositionAtTop)
         self.current_table.setFocus()
 
+
+    def show_log_entry_from_log_indexes(self, log_indexes: List[int]):
+        """
+        This is called when clicking a clickable data point on a SOH channel
+        of RT130, list of log row indexes will be passed to this method.
+        This method will:
+            + set current tab to soh_table_dict['SOH']
+            + scroll the first indexed row to top of table and highlight all
+             the row in log_indexes
+
+        Parameters
+        ----
+        log_indexes : The list of indexes of log row to be selected
+        """
+        if 'SOH' not in self.soh_tables_dict:
+            return
+        # switch to SOH tab
+        self.tab_widget.setCurrentWidget(self.soh_tables_dict['SOH'])
+        self.current_table.clearSelection()
+        # Allow to select multiple rows
+        self.current_table.setSelectionMode(
+            QAbstractItemView.MultiSelection)
+        # select all rows according to log_indexes
+        for idx in log_indexes:
+            self.current_table.selectRow(idx)
+        # scroll to the first index and place the row at top of the table
+        self.current_table.scrollToItem(
+            self.current_table.item(log_indexes[0], 1),
+            QAbstractItemView.PositionAtTop
+        )
+        # raise the message dialog on top of others
+        self.setWindowState(QtCore.Qt.WindowState.WindowActive)
+        self.raise_()
+        self.activateWindow()
+        self.current_table.setFocus()       # focus row to not faded out
+        # return back to select single row
+        self.current_table.setSelectionMode(
+            QAbstractItemView.SingleSelection)
+
     def show_log_entry_from_data_index(self, data_index: int):
         """
         This is called when clicking a clickable data point on a SOH channel
@@ -632,7 +680,8 @@ class SearchMessageDialog(QtWidgets.QWidget):
         if ret is None:
             return
         self.selected_item, self.search_rowidx = ret
-        self.current_table.scrollToItem(self.selected_item)
+        self.current_table.scrollToItem(self.selected_item,
+                                        QAbstractItemView.PositionAtTop)
 
     def _filter_lines_with_search_text_from_soh_messages(self):
         """