diff --git a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs
index 58e8e2ca9e..353185f498 100644
--- a/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs
+++ b/frontend/rust-lib/flowy-grid/src/services/block_meta_editor.rs
@@ -148,9 +148,10 @@ impl GridBlockMetaEditorManager {
     }
 
     // Optimization: Using the shared memory(Arc, Cow,etc.) to reduce memory usage.
+    #[allow(dead_code)]
     pub async fn get_cell_metas(
         &self,
-        block_ids: Option<String>,
+        block_ids: Vec<String>,
         field_id: &str,
         row_ids: Option<Vec<String>>,
     ) -> FlowyResult<Vec<CellMeta>> {
diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs
index 3611f5a0db..84d693edd0 100644
--- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs
+++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs
@@ -1,11 +1,12 @@
 use crate::impl_type_option;
 use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
-use crate::services::row::CellDataSerde;
+use crate::services::row::{CellDataSerde, TypeOptionCellData};
 use bytes::Bytes;
 use flowy_derive::ProtoBuf;
 use flowy_error::FlowyError;
 use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry};
 use serde::{Deserialize, Serialize};
+use std::str::FromStr;
 
 #[derive(Default)]
 pub struct CheckboxTypeOptionBuilder(CheckboxTypeOption);
@@ -36,17 +37,30 @@ pub struct CheckboxTypeOption {
 }
 impl_type_option!(CheckboxTypeOption, FieldType::Checkbox);
 
+const YES: &str = "Yes";
+const NO: &str = "No";
+
 impl CellDataSerde for CheckboxTypeOption {
-    fn deserialize_cell_data(&self, data: String) -> String {
-        data
+    fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String {
+        if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) {
+            if !type_option_cell_data.is_text() || !type_option_cell_data.is_checkbox() {
+                return String::new();
+            }
+            let cell_data = type_option_cell_data.data;
+            if cell_data == YES || cell_data == NO {
+                return cell_data;
+            }
+        }
+
+        String::new()
     }
 
     fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError> {
         let s = match string_to_bool(data) {
-            true => "No",
-            false => "Yes",
+            true => YES,
+            false => NO,
         };
-        Ok(s.to_owned())
+        Ok(TypeOptionCellData::new(s, self.field_type()).json())
     }
 }
 
@@ -66,11 +80,15 @@ fn string_to_bool(bool_str: &str) -> bool {
 #[cfg(test)]
 mod tests {
     use crate::services::field::CheckboxTypeOption;
+    use crate::services::field::FieldBuilder;
     use crate::services::row::CellDataSerde;
+    use flowy_grid_data_model::entities::FieldType;
 
     #[test]
     fn checkout_box_description_test() {
         let type_option = CheckboxTypeOption::default();
+        let field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build();
+
         assert_eq!(type_option.serialize_cell_data("true").unwrap(), "1".to_owned());
         assert_eq!(type_option.serialize_cell_data("1").unwrap(), "1".to_owned());
         assert_eq!(type_option.serialize_cell_data("yes").unwrap(), "1".to_owned());
@@ -79,6 +97,9 @@ mod tests {
         assert_eq!(type_option.serialize_cell_data("no").unwrap(), "0".to_owned());
         assert_eq!(type_option.serialize_cell_data("123").unwrap(), "0".to_owned());
 
-        assert_eq!(type_option.deserialize_cell_data("1".to_owned()), "1".to_owned());
+        assert_eq!(
+            type_option.deserialize_cell_data("1".to_owned(), &field_meta),
+            "1".to_owned()
+        );
     }
 }
diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs
index 86c15e13c5..5dd88a4a67 100644
--- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs
+++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs
@@ -1,5 +1,5 @@
 use crate::impl_type_option;
-use crate::services::row::CellDataSerde;
+use crate::services::row::{CellDataSerde, TypeOptionCellData};
 use bytes::Bytes;
 use chrono::format::strftime::StrftimeItems;
 use chrono::NaiveDateTime;
@@ -7,6 +7,7 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
 use flowy_error::FlowyError;
 use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry};
 use serde::{Deserialize, Serialize};
+use std::str::FromStr;
 
 use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
 use strum_macros::EnumIter;
@@ -32,25 +33,34 @@ impl DateTypeOption {
     fn today_from_native(&self, naive: chrono::NaiveDateTime) -> String {
         let utc: chrono::DateTime<chrono::Utc> = chrono::DateTime::from_utc(naive, chrono::Utc);
         let local: chrono::DateTime<chrono::Local> = chrono::DateTime::from(utc);
-
-        let fmt_str = format!("{} {}", self.date_format.format_str(), self.time_format.format_str());
-        let output = format!("{}", local.format_with_items(StrftimeItems::new(&fmt_str)));
+        let output = format!("{}", local.format_with_items(StrftimeItems::new(&self.fmt_str())));
         output
     }
+
+    fn fmt_str(&self) -> String {
+        format!("{} {}", self.date_format.format_str(), self.time_format.format_str())
+    }
 }
 
 impl CellDataSerde for DateTypeOption {
-    fn deserialize_cell_data(&self, data: String) -> String {
-        match data.parse::<i64>() {
-            Ok(timestamp) => {
-                let native = NaiveDateTime::from_timestamp(timestamp, 0);
-                self.today_from_native(native)
+    fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String {
+        if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) {
+            if !type_option_cell_data.is_date() {
+                return String::new();
             }
-            Err(e) => {
-                tracing::debug!("DateDescription format {} fail. error: {:?}", data, e);
-                String::new()
+
+            let cell_data = type_option_cell_data.data;
+            if let Ok(timestamp) = cell_data.parse::<i64>() {
+                let native = NaiveDateTime::from_timestamp(timestamp, 0);
+                return self.today_from_native(native);
+            }
+
+            if NaiveDateTime::parse_from_str(&cell_data, &self.fmt_str()).is_ok() {
+                return cell_data;
             }
         }
+
+        String::new()
     }
 
     fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError> {
@@ -58,7 +68,8 @@ impl CellDataSerde for DateTypeOption {
             tracing::error!("Parse {} to i64 failed: {}", data, e);
             return Err(FlowyError::internal().context(e));
         };
-        Ok(data.to_owned())
+
+        Ok(TypeOptionCellData::new(data, self.field_type()).json())
     }
 }
 
@@ -172,56 +183,59 @@ impl std::default::Default for TimeFormat {
 
 #[cfg(test)]
 mod tests {
+    use crate::services::field::FieldBuilder;
     use crate::services::field::{DateFormat, DateTypeOption, TimeFormat};
-    use crate::services::row::CellDataSerde;
+    use crate::services::row::{CellDataSerde, TypeOptionCellData};
+    use flowy_grid_data_model::entities::FieldType;
     use strum::IntoEnumIterator;
 
     #[test]
-    fn date_description_date_format_test() {
-        let mut description = DateTypeOption::default();
-        let _timestamp = 1647251762;
+    fn date_description_invalid_input_test() {
+        let type_option = DateTypeOption::default();
+        let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build();
+        assert_eq!(
+            "".to_owned(),
+            type_option.deserialize_cell_data("1e".to_owned(), &field_meta)
+        );
+    }
 
+    #[test]
+    fn date_description_date_format_test() {
+        let mut type_option = DateTypeOption::default();
+        let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build();
         for date_format in DateFormat::iter() {
-            description.date_format = date_format;
+            type_option.date_format = date_format;
             match date_format {
                 DateFormat::Friendly => {
                     assert_eq!(
                         "Mar 14,2022 17:56".to_owned(),
-                        description.today_from_timestamp(1647251762)
+                        type_option.deserialize_cell_data(data("1647251762"), &field_meta)
                     );
                     assert_eq!(
                         "Mar 14,2022 17:56".to_owned(),
-                        description.deserialize_cell_data("1647251762".to_owned())
+                        type_option.deserialize_cell_data(data("Mar 14,2022 17:56"), &field_meta)
                     );
                 }
                 DateFormat::US => {
                     assert_eq!(
                         "2022/03/14 17:56".to_owned(),
-                        description.today_from_timestamp(1647251762)
+                        type_option.deserialize_cell_data(data("1647251762"), &field_meta)
                     );
                     assert_eq!(
                         "2022/03/14 17:56".to_owned(),
-                        description.deserialize_cell_data("1647251762".to_owned())
+                        type_option.deserialize_cell_data(data("2022/03/14 17:56"), &field_meta)
                     );
                 }
                 DateFormat::ISO => {
                     assert_eq!(
                         "2022-03-14 17:56".to_owned(),
-                        description.today_from_timestamp(1647251762)
-                    );
-                    assert_eq!(
-                        "2022-03-14 17:56".to_owned(),
-                        description.deserialize_cell_data("1647251762".to_owned())
+                        type_option.deserialize_cell_data(data("1647251762"), &field_meta)
                     );
                 }
                 DateFormat::Local => {
                     assert_eq!(
                         "2022/03/14 17:56".to_owned(),
-                        description.today_from_timestamp(1647251762)
-                    );
-                    assert_eq!(
-                        "2022/03/14 17:56".to_owned(),
-                        description.deserialize_cell_data("1647251762".to_owned())
+                        type_option.deserialize_cell_data(data("1647251762"), &field_meta)
                     );
                 }
             }
@@ -230,28 +244,29 @@ mod tests {
 
     #[test]
     fn date_description_time_format_test() {
-        let mut description = DateTypeOption::default();
+        let mut type_option = DateTypeOption::default();
+        let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build();
         for time_format in TimeFormat::iter() {
-            description.time_format = time_format;
+            type_option.time_format = time_format;
             match time_format {
                 TimeFormat::TwentyFourHour => {
                     assert_eq!(
                         "Mar 14,2022 17:56".to_owned(),
-                        description.today_from_timestamp(1647251762)
+                        type_option.today_from_timestamp(1647251762)
                     );
                     assert_eq!(
                         "Mar 14,2022 17:56".to_owned(),
-                        description.deserialize_cell_data("1647251762".to_owned())
+                        type_option.deserialize_cell_data(data("1647251762"), &field_meta)
                     );
                 }
                 TimeFormat::TwelveHour => {
                     assert_eq!(
                         "Mar 14,2022 05:56:02 PM".to_owned(),
-                        description.today_from_timestamp(1647251762)
+                        type_option.today_from_timestamp(1647251762)
                     );
                     assert_eq!(
                         "Mar 14,2022 05:56:02 PM".to_owned(),
-                        description.deserialize_cell_data("1647251762".to_owned())
+                        type_option.deserialize_cell_data(data("1647251762"), &field_meta)
                     );
                 }
             }
@@ -264,4 +279,8 @@ mod tests {
         let type_option = DateTypeOption::default();
         type_option.serialize_cell_data("he").unwrap();
     }
+
+    fn data(s: &str) -> String {
+        TypeOptionCellData::new(s, FieldType::DateTime).json()
+    }
 }
diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs
index 7e557955df..7cee8a3b39 100644
--- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs
+++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs
@@ -1,10 +1,10 @@
 use crate::impl_type_option;
-use crate::services::row::CellDataSerde;
+use crate::services::row::{CellDataSerde, TypeOptionCellData};
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
 use flowy_error::FlowyError;
 use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry};
 use lazy_static::lazy_static;
-use rust_decimal::prelude::Zero;
+
 use rust_decimal::Decimal;
 use rusty_money::iso::{Currency, CNY, EUR, USD};
 use serde::{Deserialize, Serialize};
@@ -76,6 +76,42 @@ pub struct NumberTypeOption {
 }
 impl_type_option!(NumberTypeOption, FieldType::Number);
 
+impl CellDataSerde for NumberTypeOption {
+    fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String {
+        if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) {
+            if type_option_cell_data.is_date() {
+                return String::new();
+            }
+
+            let cell_data = type_option_cell_data.data;
+            match self.format {
+                NumberFormat::Number => {
+                    if cell_data.parse::<i64>().is_ok() {
+                        cell_data
+                    } else {
+                        String::new()
+                    }
+                }
+                NumberFormat::USD => self.money_from_str(&cell_data, USD),
+                NumberFormat::CNY => self.money_from_str(&cell_data, CNY),
+                NumberFormat::EUR => self.money_from_str(&cell_data, EUR),
+            }
+        } else {
+            String::new()
+        }
+    }
+
+    fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError> {
+        let data = self.strip_symbol(data);
+
+        if !data.chars().all(char::is_numeric) {
+            return Err(FlowyError::invalid_data().context("Should only contain numbers"));
+        }
+
+        Ok(TypeOptionCellData::new(&data, self.field_type()).json())
+    }
+}
+
 impl std::default::Default for NumberTypeOption {
     fn default() -> Self {
         let format = NumberFormat::default();
@@ -96,22 +132,21 @@ impl NumberTypeOption {
         self.symbol = format.symbol();
     }
 
-    fn decimal_from_str(&self, s: &str) -> Decimal {
-        let mut decimal = Decimal::from_str(s).unwrap_or_else(|_| Decimal::zero());
-        match decimal.set_scale(self.scale) {
-            Ok(_) => {}
-            Err(e) => {
-                tracing::error!("Set decimal scale failed: {:?}", e);
-            }
-        }
-        decimal.set_sign_positive(self.sign_positive);
-        decimal
-    }
-
     fn money_from_str(&self, s: &str, currency: &'static Currency) -> String {
-        let decimal = self.decimal_from_str(s);
-        let money = rusty_money::Money::from_decimal(decimal, currency);
-        money.to_string()
+        match Decimal::from_str(s) {
+            Ok(mut decimal) => {
+                match decimal.set_scale(self.scale) {
+                    Ok(_) => {}
+                    Err(e) => {
+                        tracing::error!("Set decimal scale failed: {:?}", e);
+                    }
+                }
+                decimal.set_sign_positive(self.sign_positive);
+                let money = rusty_money::Money::from_decimal(decimal, currency);
+                money.to_string()
+            }
+            Err(_) => String::new(),
+        }
     }
 
     fn strip_symbol(&self, s: &str) -> String {
@@ -158,26 +193,6 @@ impl NumberFormat {
     }
 }
 
-impl CellDataSerde for NumberTypeOption {
-    fn deserialize_cell_data(&self, data: String) -> String {
-        match self.format {
-            NumberFormat::Number => data,
-            NumberFormat::USD => self.money_from_str(&data, USD),
-            NumberFormat::CNY => self.money_from_str(&data, CNY),
-            NumberFormat::EUR => self.money_from_str(&data, EUR),
-        }
-    }
-
-    fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError> {
-        let data = self.strip_symbol(data);
-
-        if !data.chars().all(char::is_numeric) {
-            return Err(FlowyError::invalid_data().context("Should only contain numbers"));
-        }
-        Ok(data)
-    }
-}
-
 fn make_strip_symbol() -> Vec<String> {
     let mut symbols = vec![",".to_owned(), ".".to_owned()];
     for format in NumberFormat::iter() {
@@ -188,41 +203,60 @@ fn make_strip_symbol() -> Vec<String> {
 
 #[cfg(test)]
 mod tests {
+    use crate::services::field::FieldBuilder;
     use crate::services::field::{NumberFormat, NumberTypeOption};
-    use crate::services::row::CellDataSerde;
+    use crate::services::row::{CellDataSerde, TypeOptionCellData};
+    use flowy_grid_data_model::entities::FieldType;
     use strum::IntoEnumIterator;
 
+    #[test]
+    fn number_description_invalid_input_test() {
+        let type_option = NumberTypeOption::default();
+        let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build();
+        assert_eq!("".to_owned(), type_option.deserialize_cell_data(data(""), &field_meta));
+        assert_eq!(
+            "".to_owned(),
+            type_option.deserialize_cell_data(data("abc"), &field_meta)
+        );
+    }
+
     #[test]
     fn number_description_test() {
         let mut type_option = NumberTypeOption::default();
-        assert_eq!(type_option.serialize_cell_data("¥18,443").unwrap(), "18443".to_owned());
-        assert_eq!(type_option.serialize_cell_data("$18,443").unwrap(), "18443".to_owned());
-        assert_eq!(type_option.serialize_cell_data("€18.443").unwrap(), "18443".to_owned());
+        let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build();
+        assert_eq!(type_option.strip_symbol("¥18,443"), "18443".to_owned());
+        assert_eq!(type_option.strip_symbol("$18,443"), "18443".to_owned());
+        assert_eq!(type_option.strip_symbol("€18.443"), "18443".to_owned());
 
         for format in NumberFormat::iter() {
             type_option.format = format;
             match format {
                 NumberFormat::Number => {
                     assert_eq!(
-                        type_option.deserialize_cell_data("18443".to_owned()),
+                        type_option.deserialize_cell_data(data("18443"), &field_meta),
                         "18443".to_owned()
                     );
                 }
                 NumberFormat::USD => {
                     assert_eq!(
-                        type_option.deserialize_cell_data("18443".to_owned()),
+                        type_option.deserialize_cell_data(data("18443"), &field_meta),
                         "$18,443".to_owned()
                     );
+                    assert_eq!(type_option.deserialize_cell_data(data(""), &field_meta), "".to_owned());
+                    assert_eq!(
+                        type_option.deserialize_cell_data(data("abc"), &field_meta),
+                        "".to_owned()
+                    );
                 }
                 NumberFormat::CNY => {
                     assert_eq!(
-                        type_option.deserialize_cell_data("18443".to_owned()),
+                        type_option.deserialize_cell_data(data("18443"), &field_meta),
                         "¥18,443".to_owned()
                     );
                 }
                 NumberFormat::EUR => {
                     assert_eq!(
-                        type_option.deserialize_cell_data("18443".to_owned()),
+                        type_option.deserialize_cell_data(data("18443"), &field_meta),
                         "€18.443".to_owned()
                     );
                 }
@@ -230,37 +264,42 @@ mod tests {
         }
     }
 
+    fn data(s: &str) -> String {
+        TypeOptionCellData::new(s, FieldType::Number).json()
+    }
+
     #[test]
     fn number_description_scale_test() {
         let mut type_option = NumberTypeOption {
             scale: 1,
             ..Default::default()
         };
+        let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build();
 
         for format in NumberFormat::iter() {
             type_option.format = format;
             match format {
                 NumberFormat::Number => {
                     assert_eq!(
-                        type_option.deserialize_cell_data("18443".to_owned()),
+                        type_option.deserialize_cell_data(data("18443"), &field_meta),
                         "18443".to_owned()
                     );
                 }
                 NumberFormat::USD => {
                     assert_eq!(
-                        type_option.deserialize_cell_data("18443".to_owned()),
+                        type_option.deserialize_cell_data(data("18443"), &field_meta),
                         "$1,844.3".to_owned()
                     );
                 }
                 NumberFormat::CNY => {
                     assert_eq!(
-                        type_option.deserialize_cell_data("18443".to_owned()),
+                        type_option.deserialize_cell_data(data("18443"), &field_meta),
                         "¥1,844.3".to_owned()
                     );
                 }
                 NumberFormat::EUR => {
                     assert_eq!(
-                        type_option.deserialize_cell_data("18443".to_owned()),
+                        type_option.deserialize_cell_data(data("18443"), &field_meta),
                         "€1.844,3".to_owned()
                     );
                 }
@@ -274,31 +313,32 @@ mod tests {
             sign_positive: false,
             ..Default::default()
         };
+        let field_meta = FieldBuilder::from_field_type(&FieldType::Number).build();
 
         for format in NumberFormat::iter() {
             type_option.format = format;
             match format {
                 NumberFormat::Number => {
                     assert_eq!(
-                        type_option.deserialize_cell_data("18443".to_owned()),
+                        type_option.deserialize_cell_data(data("18443"), &field_meta),
                         "18443".to_owned()
                     );
                 }
                 NumberFormat::USD => {
                     assert_eq!(
-                        type_option.deserialize_cell_data("18443".to_owned()),
+                        type_option.deserialize_cell_data(data("18443"), &field_meta),
                         "-$18,443".to_owned()
                     );
                 }
                 NumberFormat::CNY => {
                     assert_eq!(
-                        type_option.deserialize_cell_data("18443".to_owned()),
+                        type_option.deserialize_cell_data(data("18443"), &field_meta),
                         "-¥18,443".to_owned()
                     );
                 }
                 NumberFormat::EUR => {
                     assert_eq!(
-                        type_option.deserialize_cell_data("18443".to_owned()),
+                        type_option.deserialize_cell_data(data("18443"), &field_meta),
                         "-€18.443".to_owned()
                     );
                 }
diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs
index abc9c81288..5768a92f70 100644
--- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs
+++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs
@@ -1,6 +1,6 @@
 use crate::impl_type_option;
 use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
-use crate::services::row::CellDataSerde;
+use crate::services::row::{CellDataSerde, TypeOptionCellData};
 use crate::services::util::*;
 use bytes::Bytes;
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
@@ -8,6 +8,7 @@ use flowy_error::{FlowyError, FlowyResult};
 use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry};
 use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
 use serde::{Deserialize, Serialize};
+use std::str::FromStr;
 use uuid::Uuid;
 
 pub const SELECTION_IDS_SEPARATOR: &str = ",";
@@ -24,12 +25,25 @@ pub struct SingleSelectTypeOption {
 impl_type_option!(SingleSelectTypeOption, FieldType::SingleSelect);
 
 impl CellDataSerde for SingleSelectTypeOption {
-    fn deserialize_cell_data(&self, data: String) -> String {
-        data
+    fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String {
+        if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) {
+            if !type_option_cell_data.is_single_select() || !type_option_cell_data.is_multi_select() {
+                return String::new();
+            }
+
+            let option_id = type_option_cell_data.data;
+            match self.options.iter().find(|option| option.id == option_id) {
+                None => String::new(),
+                Some(option) => option.name.clone(),
+            }
+        } else {
+            String::new()
+        }
     }
 
     fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError> {
-        single_select_option_id_from_data(data.to_owned())
+        let data = single_select_option_id_from_data(data.to_owned())?;
+        Ok(TypeOptionCellData::new(&data, self.field_type()).json())
     }
 }
 
@@ -67,12 +81,32 @@ pub struct MultiSelectTypeOption {
 impl_type_option!(MultiSelectTypeOption, FieldType::MultiSelect);
 
 impl CellDataSerde for MultiSelectTypeOption {
-    fn deserialize_cell_data(&self, data: String) -> String {
-        data
+    fn deserialize_cell_data(&self, data: String, _field_meta: &FieldMeta) -> String {
+        if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) {
+            if !type_option_cell_data.is_single_select() || !type_option_cell_data.is_multi_select() {
+                return String::new();
+            }
+
+            match select_option_ids(type_option_cell_data.data) {
+                Ok(option_ids) => {
+                    //
+                    self.options
+                        .iter()
+                        .filter(|option| option_ids.contains(&option.id))
+                        .map(|option| option.name.clone())
+                        .collect::<Vec<String>>()
+                        .join(SELECTION_IDS_SEPARATOR)
+                }
+                Err(_) => String::new(),
+            }
+        } else {
+            String::new()
+        }
     }
 
     fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError> {
-        multi_select_option_id_from_data(data.to_owned())
+        let data = multi_select_option_id_from_data(data.to_owned())?;
+        Ok(TypeOptionCellData::new(&data, self.field_type()).json())
     }
 }
 
diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs
index 6bffc8606f..87434a3cdb 100644
--- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs
+++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs
@@ -1,11 +1,12 @@
 use crate::impl_type_option;
 use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
-use crate::services::row::CellDataSerde;
+use crate::services::row::{deserialize_cell_data, CellDataSerde, TypeOptionCellData};
 use bytes::Bytes;
 use flowy_derive::ProtoBuf;
 use flowy_error::FlowyError;
 use flowy_grid_data_model::entities::{FieldMeta, FieldType, TypeOptionDataEntity, TypeOptionDataEntry};
 use serde::{Deserialize, Serialize};
+use std::str::FromStr;
 
 #[derive(Default)]
 pub struct RichTextTypeOptionBuilder(RichTextTypeOption);
@@ -30,8 +31,20 @@ pub struct RichTextTypeOption {
 impl_type_option!(RichTextTypeOption, FieldType::RichText);
 
 impl CellDataSerde for RichTextTypeOption {
-    fn deserialize_cell_data(&self, data: String) -> String {
-        data
+    fn deserialize_cell_data(&self, data: String, field_meta: &FieldMeta) -> String {
+        if let Ok(type_option_cell_data) = TypeOptionCellData::from_str(&data) {
+            if type_option_cell_data.is_date()
+                || type_option_cell_data.is_single_select()
+                || type_option_cell_data.is_multi_select()
+                || type_option_cell_data.is_number()
+            {
+                deserialize_cell_data(data, field_meta).unwrap_or_else(|_| "".to_owned())
+            } else {
+                type_option_cell_data.data
+            }
+        } else {
+            String::new()
+        }
     }
 
     fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError> {
@@ -39,7 +52,68 @@ impl CellDataSerde for RichTextTypeOption {
         if data.len() > 10000 {
             Err(FlowyError::text_too_long().context("The len of the text should not be more than 10000"))
         } else {
-            Ok(data)
+            Ok(TypeOptionCellData::new(&data, self.field_type()).json())
         }
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use crate::services::field::FieldBuilder;
+    use crate::services::field::*;
+    use crate::services::row::{CellDataSerde, TypeOptionCellData};
+    use flowy_grid_data_model::entities::FieldType;
+
+    #[test]
+    fn text_description_test() {
+        let type_option = RichTextTypeOption::default();
+
+        // date
+        let date_time_field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build();
+        let data = TypeOptionCellData::new("1647251762", FieldType::DateTime).json();
+        assert_eq!(
+            type_option.deserialize_cell_data(data, &date_time_field_meta),
+            "Mar 14,2022 17:56".to_owned()
+        );
+
+        // Single select
+        let done_option = SelectOption::new("Done");
+        let done_option_id = done_option.id.clone();
+        let single_select = SingleSelectTypeOptionBuilder::default().option(done_option);
+        let single_select_field_meta = FieldBuilder::new(single_select).build();
+        let data = TypeOptionCellData::new(&done_option_id, FieldType::SingleSelect).json();
+        assert_eq!(
+            type_option.deserialize_cell_data(data, &single_select_field_meta),
+            "Done".to_owned()
+        );
+
+        // Multiple select
+        let google_option = SelectOption::new("Google");
+        let google_option_id = google_option.id.clone();
+        let facebook_option = SelectOption::new("Facebook");
+        let face_option_id = facebook_option.id.clone();
+        let multi_select = MultiSelectTypeOptionBuilder::default()
+            .option(google_option)
+            .option(facebook_option)
+            .option(SelectOption::new("Twitter"));
+        let multi_select_field_meta = FieldBuilder::new(multi_select).build();
+        let data = TypeOptionCellData::new(
+            &vec![google_option_id, face_option_id].join(SELECTION_IDS_SEPARATOR),
+            FieldType::SingleSelect,
+        )
+        .json();
+        assert_eq!(
+            type_option.deserialize_cell_data(data, &multi_select_field_meta),
+            "Google,Facebook".to_owned()
+        );
+
+        //Number
+        let number = NumberTypeOptionBuilder::default().set_format(NumberFormat::USD);
+        let number_field_meta = FieldBuilder::new(number).build();
+        let data = TypeOptionCellData::new("18443", FieldType::Number).json();
+        assert_eq!(
+            type_option.deserialize_cell_data(data, &number_field_meta),
+            "$18,443".to_owned()
+        );
+    }
+}
diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs
index fbba14feab..8b13789179 100644
--- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs
+++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/type_option_data.rs
@@ -1,5 +1 @@
-// #[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)]
-// pub struct TypeOptionData {
-//     #[pb(index = 1)]
-//     pub map: HashMap<FieldType, String>,
-// }
+
diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
index 88738aa082..e7d57634b8 100644
--- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
+++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
@@ -114,7 +114,16 @@ impl ClientGridEditor {
     }
 
     pub async fn switch_to_field_type(&self, field_id: &str, field_type: &FieldType) -> FlowyResult<()> {
-        // let cell_metas = self.block_meta_manager.get_cell_metas(None, field_id, None).await?;
+        // let block_ids = self
+        //     .get_block_metas()
+        //     .await?
+        //     .into_iter()
+        //     .map(|block_meta| block_meta.block_id)
+        //     .collect();
+        // let cell_metas = self
+        //     .block_meta_manager
+        //     .get_cell_metas(block_ids, field_id, None)
+        //     .await?;
 
         let type_option_json_builder = |field_type: &FieldType| -> String {
             return default_type_option_builder_from_type(field_type).entry().json_str();
@@ -290,15 +299,16 @@ impl ClientGridEditor {
     }
 
     pub async fn grid_block_snapshots(&self, block_ids: Option<Vec<String>>) -> FlowyResult<Vec<GridBlockSnapshot>> {
-        let block_ids = block_ids.unwrap_or(
-            self.pad
+        let block_ids = match block_ids {
+            None =>  self.pad
                 .read()
                 .await
                 .get_block_metas()
                 .into_iter()
                 .map(|block_meta| block_meta.block_id)
                 .collect::<Vec<String>>(),
-        );
+            Some(block_ids) => block_ids,
+        };
         let snapshots = self.block_meta_manager.make_block_snapshots(block_ids).await?;
         Ok(snapshots)
     }
diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs
index 1e60583df8..259e052ab7 100644
--- a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs
+++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_serde.rs
@@ -1,12 +1,65 @@
 use crate::services::field::*;
 use flowy_error::FlowyError;
 use flowy_grid_data_model::entities::{FieldMeta, FieldType};
+use serde::{Deserialize, Serialize};
 
 pub trait CellDataSerde {
-    fn deserialize_cell_data(&self, data: String) -> String;
+    fn deserialize_cell_data(&self, data: String, field_meta: &FieldMeta) -> String;
     fn serialize_cell_data(&self, data: &str) -> Result<String, FlowyError>;
 }
 
+#[derive(Serialize, Deserialize)]
+pub struct TypeOptionCellData {
+    pub data: String,
+    pub field_type: FieldType,
+}
+
+impl std::str::FromStr for TypeOptionCellData {
+    type Err = FlowyError;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        let type_option_cell_data: TypeOptionCellData = serde_json::from_str(s)?;
+        Ok(type_option_cell_data)
+    }
+}
+
+impl TypeOptionCellData {
+    pub fn new(data: &str, field_type: FieldType) -> Self {
+        TypeOptionCellData {
+            data: data.to_owned(),
+            field_type,
+        }
+    }
+
+    pub fn json(&self) -> String {
+        serde_json::to_string(self).unwrap_or_else(|_| "".to_owned())
+    }
+
+    pub fn is_number(&self) -> bool {
+        self.field_type == FieldType::Number
+    }
+
+    pub fn is_text(&self) -> bool {
+        self.field_type == FieldType::RichText
+    }
+
+    pub fn is_checkbox(&self) -> bool {
+        self.field_type == FieldType::Checkbox
+    }
+
+    pub fn is_date(&self) -> bool {
+        self.field_type == FieldType::DateTime
+    }
+
+    pub fn is_single_select(&self) -> bool {
+        self.field_type == FieldType::SingleSelect
+    }
+
+    pub fn is_multi_select(&self) -> bool {
+        self.field_type == FieldType::MultiSelect
+    }
+}
+
 #[allow(dead_code)]
 pub fn serialize_cell_data(data: &str, field_meta: &FieldMeta) -> Result<String, FlowyError> {
     match field_meta.field_type {
@@ -21,12 +74,12 @@ pub fn serialize_cell_data(data: &str, field_meta: &FieldMeta) -> Result<String,
 
 pub fn deserialize_cell_data(data: String, field_meta: &FieldMeta) -> Result<String, FlowyError> {
     let s = match field_meta.field_type {
-        FieldType::RichText => RichTextTypeOption::from(field_meta).deserialize_cell_data(data),
-        FieldType::Number => NumberTypeOption::from(field_meta).deserialize_cell_data(data),
-        FieldType::DateTime => DateTypeOption::from(field_meta).deserialize_cell_data(data),
-        FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).deserialize_cell_data(data),
-        FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).deserialize_cell_data(data),
-        FieldType::Checkbox => CheckboxTypeOption::from(field_meta).deserialize_cell_data(data),
+        FieldType::RichText => RichTextTypeOption::from(field_meta).deserialize_cell_data(data, field_meta),
+        FieldType::Number => NumberTypeOption::from(field_meta).deserialize_cell_data(data, field_meta),
+        FieldType::DateTime => DateTypeOption::from(field_meta).deserialize_cell_data(data, field_meta),
+        FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).deserialize_cell_data(data, field_meta),
+        FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).deserialize_cell_data(data, field_meta),
+        FieldType::Checkbox => CheckboxTypeOption::from(field_meta).deserialize_cell_data(data, field_meta),
     };
     Ok(s)
 }
diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs
index edb5236139..a543085a78 100644
--- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs
+++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs
@@ -246,6 +246,7 @@ impl TryInto<FieldChangesetParams> for FieldChangesetPayload {
 #[derive(
     Debug, Clone, PartialEq, Eq, ProtoBuf_Enum, EnumCountMacro, EnumString, EnumIter, Display, Serialize, Deserialize,
 )]
+#[repr(u8)]
 pub enum FieldType {
     RichText = 0,
     Number = 1,
@@ -278,18 +279,6 @@ impl FieldType {
         let ty = self.clone();
         format!("{}", ty as u8)
     }
-
-    pub fn from_type_id(type_id: &str) -> Result<FieldType, String> {
-        match type_id {
-            "0" => Ok(FieldType::RichText),
-            "1" => Ok(FieldType::Number),
-            "2" => Ok(FieldType::DateTime),
-            "3" => Ok(FieldType::SingleSelect),
-            "4" => Ok(FieldType::MultiSelect),
-            "5" => Ok(FieldType::Checkbox),
-            _ => Err(format!("Invalid type_id: {}", type_id)),
-        }
-    }
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)]
diff --git a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs
index 0b9459a625..c0b86ac4af 100644
--- a/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs
+++ b/shared-lib/flowy-sync/src/client_grid/grid_block_meta_pad.rs
@@ -5,7 +5,7 @@ use flowy_grid_data_model::entities::{CellMeta, GridBlockMetaData, RowMeta, RowM
 use lib_infra::uuid;
 use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder};
 use serde::{Deserialize, Serialize};
-use std::borrow::Cow;
+
 use std::collections::HashMap;
 use std::sync::Arc;