﻿//-----------------------------------------------------------------------------
// @CLASS	: LiveSelect
// @AUTHOR	: Joe D. Tan
// @REQUIRES: Prototype Library version 1.5 (prototype.js)
// @PURPOSE	: Control that populates a <SELECT> control based on a JSON call
//-----------------------------------------------------------------------------
var LiveSelect = Class.create();
LiveSelect.prototype =
{
	initialize: function(settings)
	{
    this.cache = new Object();
		this.loadSettings(settings);
		this.load(this.dataSourceParam);
	},

	loadSettings: function(settings)
	{
    this.settings = settings;
    this.select = this.get(settings, 'select');
    this.selectId = this.select.id;
    this.defaultOptionId = this.selectId + '_default';
		this.dataSourceUrl = this.get(settings, 'dataSourceUrl');
		this.dataSourceParam = this.get(settings, 'dataSourceParam', '');
		this.dataSourceQueryString = this.get(settings, 'dataSourceQueryString', null);
		this.selectedOption = this.get(settings, 'selectedOption', null);
		this.errorPanelId = this.get(settings, 'errorPanelId', null);
		this.onChange = this.get(settings, 'onChange', null);
		this.lastDataSourceParam = '';
	},

  addOption: function(value, text, id, indent)
  {
    if (this.select)
    {
      var n = document.createElement('option');
      if (id) n.id = id;
      n.value = value;
      if (indent > 0) n.className = 'child';
      n.innerHTML = (indent > 0 ? '&nbsp;&nbsp;&nbsp;&nbsp;' : '') + text;
      this.select.appendChild(n);
      if (this.selectedOption && n.value == this.selectedOption) n.selected = true;
      return n;
    }
    return null;
  },
  
	reset: function(empty)
	{
    if (this.select)
    {
      this.select.innerHTML = '';
      if (!empty) this.addOption('','Loading...',this.defaultOptionId);
      this.select.disabled = true;
    }
	},
	
	load: function(dataSourceParam, selectedOption)
	{
		this.reset();
    this.lastDataSourceParam = dataSourceParam;
    if (selectedOption) this.selectedOption = selectedOption;

		if (typeof(this.cache[dataSourceParam]) == 'string')
      this.populate(this.cache[dataSourceParam]); // Re-populate based on cached data
    else
    {
      var url = this.dataSourceUrl.replace('%1',escape(dataSourceParam));
      var qry = '';
      var dsq = this.dataSourceQueryString;
      if (dsq)
      {
        if (typeof(dsq) == 'function') qry = dsq();
        else qry = dsq;
      }
      qry = qry.replace('%1',escape(dataSourceParam));

      var request = new Ajax.Request(
        url + '?' + qry,			
        {
        method: 'get',
        parameters: '',
        onComplete: function(rs)
        {
          var json = rs.responseText;
          this.populate(json);
          this.cache[this.lastDataSourceParam] = json; // Cache for future use!
        }.bind(this),
        onException: function(ob, ex) { ajaxHelperOnError(ob, ex, this, this.errorPanelId); }.bind(this)
        });
    }
	},

	reload: function()
	{
		this.load(this.lastDataSourceParam);
	},

	populate: function(json)
	{
		var count = 0;
		var items = ajaxHelperLoadJson(json);
		items = (items ? items.data : null);
		this.reset(true);
    this.select.disabled = false;
    
    var o = this.addOption('0', 'Select one...', this.defaultOptionId);
    if (o) o.style.backgroundColor = '#c0c0c0';
		for(var i=0; i<items.length; i++)
		{
        this.addOption(items[i].id, items[i].cn, null, items[i].ic);
        count++;
		}
		
		Event.observe(this.select, 'change', function(e) {
      var elem = Event.element(e);
      var node = elem.options[elem.selectedIndex];
      this.selectedOption = node.value;
      if (this.onChange) this.onChange(node.value);
    }.bind(this));
	},

	get: function(config, member, defaultValue)
	{
		if (config && (member in config))
			return eval('config.' + member); // no default provided, then value is required
		if (typeof(defaultValue) == 'undefined')
			throw 'LiveSelect class configuration must contain a value for ' + member;
		return defaultValue;
	}

}

