使用JSON來做數據傳輸的動態下拉列表(轉自http://j2ee.blog.sohu.com/68011726.html)

相關JSON的文章請參看http://j2ee.blog.sohu.com/65388567.html。今天就來說下使用JSON來做動態下拉列表的實現。

    動態下拉列表的原理其實很簡單的,當某一下拉列表觸發了onchange事件,然後使用AJAX在後臺向服務器異步請求數據,最後將服務器返回的數據進行解析後動態添加到指定的select上即可!

    首先來看後臺的數據輸出,我們假設服務器傳送給客戶段的JSON數據格式爲如下:

{
    "options" : [
        {"value" : 值,"text" : 文本}, 
        {"value" : 值,"text" : 文本},
        {"value" : 值,"text" : 文本}
        ]
}

    其中options是整個JSON對象的標識符,它是一個數組,該數組中的每一個值表示一個select中的option,當然該值也是一個對象了,有兩個屬性,一個是value,一個是text,分別對應option中的value和顯示的text值。

    有了數據格式,那麼客戶端和服務器端進行交流就方便很多了。我們來先寫客戶端的JS方法。這裏我是提供一個靜態的實用類Select,專門針對select元素的操作方法,如下:

/**-----------------------------------------------------------------------
 * ------------------------針對select操作的實用Select類-------------------
 * -----------------------------------------------------------------------
 */
function Select(){};
/**
 * 根據指定的JSON對象來生成指定的select的options項(清除原來的options).
 */
Select.create = function(/*string*/selectId,/*json object*/json) {
 Select.clear(selectId);
 Select.add(selectId, json);
};
/**
 * 該方法同create,只不過是在原來的基礎上進行追加
 */
Select.add = function(/*string*/selectId,/*json object*/json) {
 try {
  if (!json.options) return;
  for (var i = 0; i < json.options.length; i ++) {
   Select.addOption(selectId,json.options[i].value,json.options[i].text);
  }
 } catch (ex) {
  base.alert('設置select錯誤:指定的JSON對象不符合Select對象的解析要求!');
 }
};
/**
 * 創建一個options並返回
 */
Select.createOption = function(/*string*/value, /*string*/text) {
 var opt = document.createElement('option');
 opt.setAttribute('value', value);
 opt.innerHTML = text;
 return opt;
};
/**
 * 給指定的select添加一個option,並返回當前option對象
 */
Select.addOption = function(/*string*/selectId, /*string*/value, /*string*/text) {
 var opt = Select.createOption(value, text);
 $(selectId).appendChild(opt);
 return opt;
};
/**
 * 獲取指定select的當前被選中的options對象,如果爲多選且有多個被選中則返回數組.
 */
Select.getSelected = function(/*string*/selectId) {
 var slt = $(selectId);
 if (!slt) return null;
 if (slt.type.toLowerCase() == "select-multiple") {
  var len = Select.len(selectId);
  var result = [];
  for (var i = 0; i < len; i ++) {
   if (slt.options[i].selected) result.push(slt.options[i]);
  }
  return result.length > 1 ? result : (result.length == 0 ? null : result[0]);
 } else {
  var index = $(selectId).selectedIndex;
  return $(selectId).options[index];
 }
};
/**
 * 使指定索引位置的option被選中.從0開始.
 */
Select.select = function(/*string*/selectId, /*int*/index) {
 var slt = $(selectId);
 if (!slt) return false;
 for (var i = 0; i < slt.options.length; i ++) {
  if (index == i) {
   slt.options[i].setAttribute("selected", "selected");
   return true;
  }
 }
 return false;
};
/**
 * 選中指定的select的所有option選項,如果支持多選的話
 */
Select.selectAll = function(/*string*/selectId) {
 var len = Select.len(selectId);
 for (var i = 0; i < len; i ++) Select.select(selectId, i);
};
/**
 * 獲取指定select的總的options個數
 */
Select.len = function(/*string*/selectId) {
 return $(selectId).options.length;
};
/**
 * 清除select中滿足條件的options,如果沒有指定處理方法則清除所有options項
 */
Select.clear = function(/*string*/selectId, /*function*/iterator) {
 if (typeof(iterator) != 'function') {
  $(selectId).length = 0;
 } else {
  var slt = $(selectId);
  for (var i = slt.options.length - 1; i >= 0; i --) {
   if (iterator(slt.options[i]) == true) slt.removeChild(slt.options[i]);
  }
 }
};
/**
 * 複製指定的select的option對象到另外一指定的select對象上.如果指定了處理
 * 函數,那麼只有返回true時纔會copy.
 * 函數iterator參數:當前處理的option對象、目標select的options數組
 */
Select.copy = function(/*string*/srcSlt, /*string*/targetSlt, /*function*/iterator) {
 var s = $(srcSlt), t = $(targetSlt);
 for (var i = 0; i < s.options.length; i ++) {
  if (typeof(iterator) == 'function') {
   if (iterator(s.options[i], $(targetSlt).options) == true) {
    t.appendChild(s.options[i].cloneNode(true));
   }
  } else {
   t.appendChild(s.options[i].cloneNode(true));
  }
 }
};

    那麼在回調方法中就可以只要來調用:

……
var jsonString = xmlHttp.responeText; // 獲取服務器返回的json字符串
var jsonObj = null;
try {
   jsonObj = eval('(' + jsonString + ')'); // 將json字符串轉換成對象
} catch (ex) {
   return null;
}
Select.create("你的select的ID", jsonObj); // 執行option的添加
……

    在Select中提供了很多實用的JS方法來方便操作select對象,我們這裏只使用其中的create方法。客戶端有了JS,我們現在來做服務器端的 字符串輸出。這裏我們用到了JSONLib庫,該庫可以很方便的來從現有的javaBean或其他集合對象中來轉換成json字符串。我們這裏也提供一個 公用類如下:

package common.utils.json;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;

/**
 * 下拉列表的JSON對象轉換.
 * 轉換後的字符串是如下格式:
 * {"options" : [ {"value" : 值,"text" : 文本},
 *       {"value" : 值,"text" : 文本},
 *       ……
 *       {"value" : 值,"text" : 文本}
 *              ]
 * }
 * 前臺將利用兩個JS進行轉換和生成:
 * BaseClass對象的json方法將返回的字符串轉換成對象;
 * Select對象的create/add方法將把轉換後的對象添加到指定的select上去。
 *
 * @author 鐵木箱子
 *
 */
public class SelectJSON
{
 /**
  * Logger for this class
  */
 private static final Logger log = Logger.getLogger(SelectJSON.class);

 /**
  * 從指定的map對象中獲取要設置的值後組裝成返回給前臺的JSON對象字符串.
  *
  * 存儲在map中的key-value應該是option中的value和text,即如下的option:
  * <option value="hello">你好</option>
  * 應該使用如下的map對象:
  * map.put("hello", "你好");
  * 注意使用map對象相同key值的將會被後設置的給覆蓋!
  *
  * @param map
  * @return
  */
 public static String fromMap(Map map)
 {
  Iterator it = map.keySet().iterator();
  JSONArray options = new JSONArray();
  while (it.hasNext()) {
   JSONObject option = new JSONObject();
   String key = (String)it.next();
   option.put("value", key);
   option.put("text", map.get(key));
   options.put(option);
  }
  JSONObject result = new JSONObject();
  result.put("options", options.toString());
  return result.toString();
 }
 
 /**
  * 從指定的list中獲取要設置出去JSON對象.
  *
  * 存放在list中的對象應該是滿足JavaBean規範的POJO對象,同時還要指定該對象中的
  * 哪個屬性作爲option的value,哪個屬性作爲option的text。比如有如下一個JavaBean
  * ,其部分屬性如下:
  * ……
  * public String getOptValue()
  * {
  *     return this.optValue;
  * }
  * public String getOptText()
  * {
  *     return this.optText;
  * }
  * ……
  * 如果我們想用optValue作爲option的value屬性,而optText作爲option的text值,那麼
  * 我們就應該傳遞參數分別是:optValue, optText.
  *
  * @param list
  * @param valueProp
  * @param textProp
  * @return
  */
 public static String fromList(List list, String valueProp, String textProp)
 {
  JSONArray options = new JSONArray();
  try {
   for (Object obj : list) {
    JSONObject option = new JSONObject();
    String value = BeanUtils.getProperty(obj, valueProp);
    String text = BeanUtils.getProperty(obj, textProp);
    option.put("value", value);
    option.put("text", text);
    options.put(option);
   }
  } catch (Exception ex) {
   throw new RuntimeException(ex);
  }
  JSONObject result = new JSONObject();
  result.put("options", options.toString());
  return result.toString();
 }
 
 public static void main(String[] args)
 {
  // map 測試
  Map<String,String> tt = new HashMap<String,String>();
  tt.put("value1", "text1");
  tt.put("value2", "text2");
  tt.put("value3", "text3");
  log.info(SelectJSON.fromMap(tt));
 }
}

    在類SelectJSON中提供了兩個方法,一個是從map中來獲取並轉換成json字符串,還一個就是從list中的對象來獲取,這個方法需要使用 BeanUtils工具來輔助獲取JavaBean對象中的指定屬性。當然了,你可以可以寫其他方便發輔助方法來達到這樣的效果。

    比如我們在上面的SelectJSON類中的測試,會輸出:

{"options":[{"value":"value1","text":"text1"},{"value":"value2","text":"text2"},{"value":"value3","text":"text3"}]}

    然後我們再調用上面提到的JS類Select進行操作就可以了,注意,在使用Select類進行操作前,比如先轉換服務器返回的字符串爲js對象,即使用 eval來執行返回字符串即可!好了,關於使用json來做動態下拉列表就說到這裏咯,如有問題,歡迎一起交流~~~ 微笑

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章