Click here to Skip to main content
15,891,375 members
Articles / Web Development / ASP.NET

ASP.NET/AJAX 3.5 With Aquarium Express

Rate me:
Please Sign up or sign in to vote.
3.60/5 (7 votes)
18 Sep 2008Ms-PL12 min read 35.7K   954   29  
Learn to build modern AJAX and ASP.NET 3.5 applications with free Aquarium Express Framework
/// <reference name="MicrosoftAjax.debug.js" />
/// <reference name="AjaxControlToolkit.ExtenderBase.BaseScripts.js" assembly="AjaxControlToolkit" />
/// <reference name="AjaxControlToolkit.Common.Common.js" assembly="AjaxControlToolkit" />
/// <reference name="AjaxControlToolkit.DropDown.DropDownBehavior.js" assembly="AjaxControlToolkit"/>
/// <reference name="AjaxControlToolkit.ModalPopup.ModalPopupBehavior.js" assembly="AjaxControlToolkit"/>
/// <reference name="AjaxControlToolkit.AlwaysVisibleControl.AlwaysVisibleControlBehavior.js" assembly="AjaxControlToolkit"/>
/// <reference name="AjaxControlToolkit.PopupControl.PopupControlBehavior.js" assembly="AjaxControlToolkit"/>
/// <reference name="AjaxControlToolkit.Calendar.CalendarBehavior.js" assembly="AjaxControlToolkit"/>
/// <reference path="Web.DataViewResources.js"/>

Type.registerNamespace("Web");

Web.DataView = function (element) {
    Web.DataView.initializeBase(this, [element]);
    this._controller = null;
    this._viewId = null;
    this._servicePath = null;
    this._showActionBar = true;
    this._baseUrl = null;
    this._pageIndex = -1;
    this._pageSize = Web.DataViewResources.Pager.PageSizes[0];
    this._sortExpression = null;
    this._filter = [];
    this._externalFilter = [];
    this._categories = null;
    this._fields = null;
    this._allFields = null;
    this._rows = null;
    this._totalRowCount = 0;
    this._firstPageButtonIndex = 0;
    this._pageCount = 0;
    this._views = [];
    this._actionGroups = [];
    this._selectedKey = [];
    this._selectedKeyFilter = []
    this._lastCommandName = null;
    this._lastViewId = null;
    this._lookupField = null;
    this._tabIndex = 0;
    this._filterFields = null;
    this._filterSource = null;
    this._mode = Web.DataViewMode.View;
    this._lookupPostBackExpression = null;
}

Web.DataView.htmlEncode = function(s) { return s ? s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;') : s; }

Web.DataView.htmlAttributeEncode = function(s) { return s ? s.replace(/\x27/g, '&#39;').replace(/\x22/g, '&quot;') : s; }

Web.DataView.isIE6 = this._ie6 = Sys.Browser.agent == Sys.Browser.InternetExplorer && Sys.Browser.version < 7;

Web.DataView.prototype = {

    get_controller: function() {
        return this._controller;
    },
    set_controller: function(value) {
        this._controller = value;
    },
    
    get_viewId: function() {
        if (!this._viewId && this._views.length > 0)
            this._viewId = this._views[0].Id;
        return this._viewId;
    },
    set_viewId: function(value) {
        this._viewId = value;
    },
    
    get_newViewId: function() {
        return this._newViewId;
    },
    set_newViewId: function(value) {
        this._newViewId = value;
    },
    
    get_servicePath: function() {
        return this._servicePath;
    },
    set_servicePath: function set_servicePath(value) {
        this._servicePath = value;
    },
    
    get_baseUrl: function() {
        return this._baseUrl;
    },
    set_baseUrl: function(value) {
        this._baseUrl = value;
    },
    
    get_showActionBar: function() {
        return this._showActionBar;
    },
    set_showActionBar: function(value) {
        this._showActionBar = value;
    },
    
    get_cookie: function() {
        return this._cookie;
    },
    set_cookie: function(value) {
        this._cookie = value;
    },
    
    get_pageIndex: function() {
        return this._isInserting ? 0 : this._pageIndex;
    },
    set_pageIndex:function(value) {
        this._pageIndex = value;
        if (value >= 0) {
            if (value >= this._firstPageButtonIndex + Web.DataViewResources.Pager.PageButtonCount)
                this._firstPageButtonIndex = value;
            else if (value < this._firstPageButtonIndex) {
                this._firstPageButtonIndex -= Web.DataViewResources.Pager.PageButtonCount;
                if (value < this._firstPageButtonIndex)
                    this._firstPageButtonIndex = value;
            }
            if (this._firstPageButtonIndex < 0)
                this._firstPageButtonIndex = 0;
            if (this.get_pageCount() - this._firstPageButtonIndex < Web.DataViewResources.Pager.PageButtonCount)
                this._firstPageButtonIndex = this.get_pageCount() - Web.DataViewResources.Pager.PageButtonCount;
            if (this._firstPageButtonIndex < 0)
                this._firstPageButtonIndex = 0;
        }    
    },
    
    get_pageSize: function() {
        return this._pageSize;
    },
    set_pageSize: function(value) {
        this._pageSize = value;
        if (this._fields != null)
        {
            this.set_pageIndex(-2);
            this._loadPage();
        }
    },
    
    get_sortExpression: function() {
        return this._sortExpression;
    },
    set_sortExpression: function(value) {
        if (!value || value.length == 0)
            this._sortExpression = null;
        else {
            var expression = value.match(/^(\w+)\s*((asc|desc)|$)/)
            if (expression[2].length == 0)
                if (this._sortExpression == null || this._sortExpression.match(/^(\w+)\s/)[1] != expression[1])
                    this._sortExpression = value + ' asc';
                else if (this._sortExpression.endsWith(' asc'))
                    this._sortExpression = value + ' desc';
                else
                    this._sortExpression = value + ' asc';
                  
            else
                this._sortExpression = value;
        }
    },
    
    get_filterSource: function() {
        return this._filterSource;
    },
    set_filterSource: function(value) {
        this._filterSource = value;
    },
    
    get_filterFields: function() {
        return this._filterFields;
    },
    set_filterFields: function(value) {
        this._filterFields = value;
    },
    
    get_filter: function() {
        if (this.get_lookupField() == null && ( this.get_pageIndex() == -1 && !this._allFields || this._externalFilter.length > 0 && this._filter.length == 0)) {
            var params = document.location.href.match(/\?([\s\S]+)/);
            if (params && (this.get_filterSource() != 'None' || this.get_filterSource() == null)) {
                this._externalFilter = [];
                var iterator = /(\w+)=([\S\s]+?)(&|$)/g;
                while (match = iterator.exec(params[1]))
                    Array.add(this._externalFilter, {Name: match[1], Value: match[2]});
            }
            this.applyExternalFilter();
        }
        return this._filter;
    },
    set_filter: function(value) {
        this._filter = value;
    },
    
    get_categories: function() {
        return this._categories;
    },
    
    get_fields: function() {
        return this._fields;
    },
    
    get_rows: function() {
        return this._rows;
    },
    
    get_selectedRow: function() {
        return this._rows[this._selectedRowIndex != null ? this._selectedRowIndex : 0];
    },
    
    get_pageCount: function() {
        return this._pageCount;
    },
    
    get_views: function() {
        return this._views;
    },
    
    get_actionGroups: function(scope, all) {
        var groups = [];
        for (var i = 0; i < this._actionGroups.length; i++)
            if (this._actionGroups[i].Scope == scope) {
                var group = this._actionGroups[i];
                var current = all ? group : null;
                if (!all)
                    for (var j = 0;  j < group.Actions.length; j++)
                        if (this._isActionAvailable(group.Actions[j])) {
                            current = this._actionGroups[i]
                            break;
                        }
                if (current) Array.add(groups, current);
            }
        return groups;
    },
    
    get_actions: function(scope) {
        for (var i = 0; i < this._actionGroups.length; i++)
            if (this._actionGroups[i].Scope == scope)
                return this._actionGroups[i].Actions;
        return [];
    },
    
    get_selectedKey: function() {
        return this._selectedKey;
    },
    
    get_selectedKeyFilter: function() {
        return this._selectedKeyFilter;
    },
    
    get_view: function() {
        if (!this._view || this._view.Id != this.get_viewId())
            for (var i = 0; i < this._views.length; i++)
                if (this._views[i].Id == this.get_viewId()) {
                    if (!this._view && this._views[i].Type == 'Form') { 
                        this._lastCommandName = 'Select';
                        if (this._rows.length > 0) this._selectKeyByRowIndex(this._selectedRowIndex = 0);
                    }
                    this._view = this._views[i];
                    break;
                }
        return this._view;
    },
    
    get_lastCommandName: function() {
        return this._lastCommandName;
    },
    set_lastCommandName: function(value) {
        this._lastCommandName = value;
    },
    
    get_isEditing: function() {
        return this._lastCommandName == 'New' || this._lastCommandName == 'Edit' || this._isInserting == true;
    },
    
    get_isInserting: function() {
        return this.get_lastCommandName() == 'New' || this._isInserting == true;
    },
    set_isInserting: function(value) {
        this._isInserting = value;
    },
    
    get_lookupField: function() {
       return this.get_mode() == Web.DataViewMode.View ? this._lookupField : this._fields[0];
    },
    set_lookupField: function(value) {
        this._lookupField = value;
    },
    
    get_mode: function() {
        return this._mode;
    },
    set_mode: function(value) {
        this._mode = value;
    },
    
    get_lookupValue: function() {
        return this._lookupValue;
    },
    set_lookupValue: function(value) {
        this._lookupValue = value;
    },
    
    get_lookupText: function() {
        return this._lookupText;
    },
    set_lookupText: function(value) {
        this._lookupText = value;
    },
    
    get_lookupPostBackExpression: function() {
        return this._lookupPostBackExpression;
    },
    set_lookupPostBackExpression: function(value) {
        this._lookupPostBackExpression = value;
    },
    
    initialize: function() {
        Web.DataView.callBaseMethod(this, 'initialize');
        this._viewSelectorOnShownHandler = Function.createDelegate(this, this._viewSelectorOnShown);
        this._headerDropDownOnShowingHandler = Function.createDelegate(this, this._headerDropDownOnShowing);
        this._actionBarGroupOnShowingHandler = Function.createDelegate(this, this._actionBarGroupOnShowing);
        this._bodyKeydownHandler = Function.createDelegate(this, this._bodyKeydown);
        this._filterSourceSelectedHandler = Function.createDelegate(this, this._filterSourceSelected);
    },
    
    dispose: function() {
        if (!Sys.Application._disposing) this._detachBehaviors();
        this._lookupField = null;
        this._viewSelectorOnShownHandler = null;
        this._headerDropDownOnShowingHandler = null;
        this._actionBarGroupOnShowingHandler = null;
        this._bodyKeydownHandler = null;
        this._filterSourceSelectedHandler = null;
        Web.DataView.callBaseMethod(this, 'dispose');
    },

    updated: function() {
        Web.DataView.callBaseMethod(this, 'updated');
        if (this._container == null) {
            this.get_element().innerHTML = '';
            this._container = document.createElement('div');
            this._container.className = 'DataViewContainer';
            this.get_element().appendChild(this._container);
        }
        if (this.get_filterSource()) {
            var source = $find(this.get_filterSource());
            if (source) source.add_selected(this._filterSourceSelectedHandler);
            else {
                source = $get(this.get_filterSource());
                if (source) $addHandler(source, 'change', this._filterSourceSelectedHandler);
            }
            this._createExternalFilter();
            this.applyExternalFilter();
        }
        this.loadPage();
    },
    
    loadPage: function(showWait) {
        this._showWait(!this.get_isDisplayed());
        if (this.get_mode() != Web.DataViewMode.View || (this.get_lookupField() || !(this._delayedLoading = !this.get_isDisplayed()))) 
            this._loadPage();
        else if (!Array.contains(Web.DataView._delayedLoadingViews, this))
            Array.add(Web.DataView._delayedLoadingViews, this);
    },
    
    get_isDisplayed: function() {
        var node = this.get_element().parentNode;
        while (node != null) {
            if (node.style && node.style.display == 'none') 
                return false;
            node = node.parentNode;
        }
        return true;
    },
    
    goToPage: function(pageIndex) {
        this.set_pageIndex(pageIndex);
        this._loadPage();
    },
    
    sort: function(sortExpression) {
        this.set_sortExpression(sortExpression);
        this.set_pageIndex(0);
        this._loadPage();
    },
    
    applyFilterByIndex: function(fieldIndex, valueIndex) {
        var filterField = this._allFields[fieldIndex];
        var field = this.findFieldUnderAlias(filterField);
        this.applyFilter(filterField, valueIndex >= 0 ? '=' : null, valueIndex >= 0 ? field._listOfValues[valueIndex] : null);
    },
    
    findFieldUnderAlias: function(aliasField)
    {
        if (aliasField.Hidden)
            for (var i = 0; i < this._allFields.length; i++)
                if (this._allFields[i].AliasIndex == aliasField.Index) return this._allFields[i];
        return aliasField;
    },
    
    removeFromFilter: function(field) {
        for (var i = 0; i < this._filter.length; i++) {
            if (this._filter[i].match(/^(\w+):/)[1] ==  field.Name) {
                Array.removeAt(this._filter, i);
                break;
            }
        }
    },
    
    applyFilter: function(field, operator, value) {
        this.removeFromFilter(field);
        if (operator) Array.add(this._filter, field.Name + ':' + operator + this.convertFieldValueToString(field, value));
        var keepFieldValues = (this._filter.length == 1 && this._filter[0].match(/(\w+):/)[1] == field.Name);
        field = this.findFieldUnderAlias(field);
        for (i = 0; i < this._allFields.length; i++)
            if (!keepFieldValues || this._allFields[i].Name != field.Name) this._allFields[i]._listOfValues = null;
        this.set_pageIndex(-2);
        this._loadPage();
    },
    
    applyExternalFilter: function() {
        this._filter = [];
        this._selectedRowIndex = null;
        for (var i = 0; i < this._externalFilter.length; i++) {
            var filterItem = this._externalFilter[i];
            Array.add(this._filter, filterItem.Name + ':=' + filterItem.Value);
        }
    },
    
    showCustomFilter: function(fieldIndex) {
        var field = this._allFields[fieldIndex];
        var customFilter = null;
        for (var i = 0; i < this._filter.length; i++) {
            var m = this._filter[i].match(/(\w+):([\s\S]*)/);
            if (m[1] == field.Name) {
                customFilter = m[2];
                break;
            }
        }
        if (customFilter && customFilter.indexOf('\0') == -1) customFilter += '\0';
        var panel = this._customFilterPanel = document.createElement('div');
        this.get_element().appendChild(panel);
        panel.className = 'CustomFilterDialog';
        panel.id = this.get_id() + '_CustomFilterPanel';
        var sb = new Sys.StringBuilder();
        sb.append(String.format('<div>{0}</div>', String.format(Web.DataViewResources.HeaderFilter.CustomFilterPrompt, this.get_view().Label, field.Label)));
        sb.append('<table cellpadding="0" cellspacing="0">');
        sb.append(String.format('<tr><td colspan="2"><input type="text" id="{0}_Query" size="70" value="{1}"></input></td></tr>', this.get_id(), customFilter ? Web.DataView.htmlAttributeEncode(customFilter.replace(/\0/g, ', ').replace(/\*|[^<>]=|^=|, $/g, '')) : ''));
        sb.append(String.format('<tr><td></td><td align="right"><button id="{0}Ok">OK</button> <button id="{0}Cancel">Cancel</button></td></tr>', this.get_id()));
        sb.append('</table>');
        panel.innerHTML = sb.toString();
        this._customFilterField = field;
        this._customFilterModalPopupBehavior = $create(AjaxControlToolkit.ModalPopupBehavior, {
            OkControlID: this.get_id() + 'Ok', CancelControlID: this.get_id() + 'Cancel', OnOkScript: String.format('$find("{0}").applyCustomFilter()', this.get_id()), OnCancelScript: String.format('$find("{0}").closeCustomFilter()', this.get_id()),
            PopupControlID: panel.id, DropShadow: true, BackgroundCssClass: 'ModalBackground'}, null, null, $get(this.get_id() + '_CustomFilterOption' + fieldIndex));
        this._customFilterModalPopupBehavior.show();
        $addHandler(document.body, 'keydown', this._bodyKeydownHandler);
        $get(this.get_id() + '_Query').focus();
    },
    
    applyCustomFilter: function() {
        this.removeFromFilter(this._customFilterField);
        var iterator = /\s*(=|<={0,1}|>={0,1}|)\s*([\S\s]+?)\s*(,|$)/g;
        var match = null;
        var filter = this._customFilterField.Name + ':';
        while (match = iterator.exec($get(this.get_id() + '_Query').value))
            filter += (match[1] ? match[1] : (this._customFilterField.Type == 'String' ? '*' : '=')) + match[2] + '\0';
        if (filter.indexOf('\0') > 0) Array.add(this._filter, filter);
        this.set_pageIndex(-2);
        this._loadPage();
        this.closeCustomFilter();
    },
    
    closeCustomFilter: function() {
        if (this._customFilterModalPopupBehavior)  {
            this._customFilterModalPopupBehavior.dispose();
            this._customFilterModalPopupBehavior = null;
            this._customFilterField = null;
        }
        if (this._customFilterPanel) {
            this.get_element().removeChild(this._customFilterPanel);
            this._customFilterPanel = null;
        }
        $removeHandler(document.body, 'keydown', this._bodyKeydownHandler);
    },
    
    convertFieldValueToString: function(field, value) {
        return field.Type == 'DateTime' && field.DataFormatString && field.DataFormatString.length > 0 ? (value == null ? 'null' :String.localeFormat(field.DataFormatString, value)) : value;
    },
    
    goToView: function(viewId) {
        if (viewId == 'form')
            for (var i = 0; i < this.get_views().length; i++)
                if (this.get_views()[i].Type == 'Form') {
                    viewId = this.get_views()[i].Id;
                    break;
                }
        Web.DataView.hideMessage();
        this._detachBehaviors();
        if (this.get_view().Type != 'Form') {
            this._lastViewId = this.get_viewId();
            this._selectedRowIndex = 0;
        }
        this.set_viewId(viewId);
        this.set_pageIndex(-1);
        this.set_filter(this.get_view().Type == 'Form' ? this.get_selectedKeyFilter() : []);
        this.set_sortExpression(null);
        this._loadPage();
    },
    
    filterOf: function(field) {
        var header = (field.AliasName && field.AliasName.length > 0? field.AliasName : field.Name) + ':';
        for (var i = 0; i < this._filter.length; i++)
            if (this._filter[i].startsWith(header))
                return this._filter[i].substr(header.length);
        return null;
    },
    
    findField: function(query) {
        for (var i = 0; i < this._allFields.length; i++) {
            var field = this._allFields[i];
            if (field.Name == query) return field;
        }
        return null;
    },
    
    executeAction: function(scope, actionIndex, rowIndex, groupIndex) {
        if (this._isBusy) return;
        Web.DataView.hideMessage();
        var actions = this.get_lookupField() ? null : (scope == 'ActionBar' ? this.get_actionGroups(scope)[groupIndex].Actions : this.get_actions(scope));
        if (actionIndex < 0 && actions) {
            for (var i = 0; i < actions.length; i++) 
                if (this._isActionAvailable(actions[i], rowIndex)) {
                    actionIndex = i;
                    break;
                }
            if (actionIndex < 0) return;
        }
        var action = actions ? actions[actionIndex] : null;
        if (action && action.Confirmation && action.Confirmation.length > 0 && !confirm(action.Confirmation)) return;
        var command = action ? action.CommandName : 'Select';
        var argument = action ? action.CommandArgument : null;
        this.executeRowCommand(rowIndex, command, argument);
    },
    
    executeRowCommand: function(rowIndex, command, argument) {
        if (rowIndex != null && rowIndex >= 0) {
            this._selectedRowIndex = rowIndex;
            this._selectKeyByRowIndex(rowIndex);
        }
        this.executeCommand({commandName: command, commandArgument: argument ? argument : ''});
        if (command == 'Select' && argument == null) this._render();
    },
    
    executeCommand: function(args) {
        this._hidePopups();
        var a = new Array();
        if (this._isBusy) return;
        switch (args.commandName) {
            case 'Select':
                this.set_lastCommandName(args.commandName);
                if (this.get_lookupField() && args.commandArgument == '') {
                    var values = [];
                    var labels = [];
                    var dataValueField = this.findField(this.get_lookupField().ItemsDataValueField);
                    var dataTextField = this.findField(this.get_lookupField().ItemsDataTextField);
                    if (dataValueField != null) Array.add(values, this.get_selectedRow()[dataValueField.Index]);
                    if (dataTextField != null) Array.add(labels, this.get_selectedRow()[dataTextField.Index]);
                    if (!dataValueField)
                        for (var i = 0; i < this._allFields.length; i++)
                            if (this._allFields[i].IsPrimaryKey)
                                Array.add(values, this.get_selectedRow()[this._allFields[i].Index]);
                    if (!dataTextField)
                        for (i = 0; i < values.length; i++)
                            if (i < this.get_fields().length)
                                Array.add(labels, this.get_selectedRow()[this.get_fields()[i].AliasIndex]);
                    this.get_lookupField()._dataView.changeLookupValue(this.get_lookupField().Index, values.length == 1? values[0] : values, labels.join(';'));
                }
                else {
                    for (i = 0; i < this.get_rows().length; i++) {
                        var row = $get(this.get_id() + '_Row' + i);
                        if (row)
                            if (i == this._selectedRowIndex)
                                Sys.UI.DomElement.addCssClass(row, 'Selected');
                            else 
                                Sys.UI.DomElement.removeCssClass(row, 'Selected');
                    }
                    if (args.commandArgument.length > 0)
                        this.goToView(args.commandArgument);
                }
                break;
            case 'Edit':
            case 'New':
                this.set_lastCommandName(args.commandName);
                if (args.commandArgument.length > 0)
                    this.goToView(args.commandArgument); 
                else 
                    this._render();
                if (args.commandName == 'New') { 
                    Array.clear(this._selectedKey);
                    this.raiseSelected(Sys.EventArgs.Empty);
                }
                break;
            case 'Navigate':
                this.navigate(args.commandArgument);
                break;
            case 'Cancel':
                this.set_lastCommandName(null);
                if (this.get_view().Type == 'Form')
                    this.goToView(this._lastViewId);
                else    
                    this._render();
                break;
            case 'Back':
                history.go(args.commandArgument && args.commandArgument.length > 0 ? parseInt(args.commandArgument) : -1);
                break;
            default:
                values = this._collectFieldValues();
                if (this._validateFieldValues(values))
                    this._execute({CommandName: args.commandName, CommandArgument: args.commandArgument, LastCommandName: this.get_lastCommandName(), Values: values, ContextKey: this.get_id(), Cookie: this.get_cookie(), Controller: this.get_controller(), View: this.get_viewId()});
                break;
                
        }
    },
    
    navigate: function(location, values) {
        if (location) location = location.replace('~/', this.get_baseUrl());
        if (location) {
            var iterator = /([\s\S]*?)\{(\w+)?\}/g;
            var formattedLocation = '';
            var lastIndex = -1;
            var match = iterator.exec(location);
            while (match) {   
                formattedLocation += match[1];
                if (values && this._lastArgs) {
                    for (var i = 0; i < values.length; i++) {
                        var v = values[i];
                        if (v.Name == match[2]) {
                            formattedLocation += this._lastArgs.CommandName.match(/Insert/i) ? v.NewValue : v.OldValue;
                            break;
                        }
                    }
                }
                else {
                    var field = match[2].match(/^\d+$/) ? this.get_fields()[parseInt(match[2])] : this.findField(match[2]);
                    formattedLocation += field ? this.get_selectedRow()[field.Index] : '';
                }
                lastIndex = iterator.lastIndex;
                match = iterator.exec(location);
            }
            if (lastIndex != -1) location = formattedLocation + (lastIndex < location.length ? location.substr(lastIndex) : '');
        }
        var targetView = null;
        for (i = 0; i < this.get_views().length; i++)
            if (this.get_views()[i].Id == location) {
                targetView = this.get_views()[i];
                break;
            }
        if (targetView) 
            this.goToView(location);
        else
            window.location.href = location;
    },
    
    showLookup: function(fieldIndex) {
        var field = this._allFields[fieldIndex];
        if (!field._lookupModalBehavior) {
            var showLink = $get(this.get_id() + '_Item' + field.Index + '_ShowLookupLink');
            if (showLink) {
                var panel = field._lookupModalPanel = document.createElement("div");
                this.get_element().appendChild(panel);
                panel.className = 'ModalPanel';
                panel.id = this.get_id() + '_ItemLookupPanel' + field.Index;
                panel.innerHTML = String.format('<table style="width:100%;height:100%"><tr><td valign="middle" align="center"><table cellpadding="0" cellspacing="0"><tr><td class="ModalTop"><div style="height:1px;font-size:1px"></div></td><td><div style="height:1px;font-size:1px"></div></td></tr><tr><td align="left" valign="top" id="{0}_ItemLookupPlaceholder{1}"  class="ModalPlaceholder"></td><td class="RightSideShadow"></td></tr><tr><td colspan="2"><div class="BottomShadow"></div></td></tr></table></td></tr></table>', this.get_id(), field.Index);
                field._lookupModalBehavior = $create(AjaxControlToolkit.ModalPopupBehavior, {id: this.get_id() + "_ItemLookup" + field.Index, PopupControlID: panel.id, BackgroundCssClass: 'ModalBackground'}, null, null, showLink);
            }
        }
        else
            field._lookupDataControllerBehavior._render();
        if (!field._lookupDataControllerBehavior)
            field._lookupDataControllerBehavior = $create(Web.DataView, {id: this.get_id() + '_LookupView' + fieldIndex, baseUrl: this.get_baseUrl(), pageSize: Web.DataViewResources.Pager.PageSizes[0], servicePath: this.get_servicePath(), controller: field.ItemsDataController, showActionBar: Web.DataViewResources.Lookup.ShowActionBar, lookupField: field}, null, null, $get(this.get_id() + '_ItemLookupPlaceholder' + field.Index));
        this._saveTabIndexes();
        field._lookupModalBehavior.show();
        $addHandler(document.body, 'keydown', field._lookupDataControllerBehavior._bodyKeydownHandler);
        field._lookupDataControllerBehavior._adjustLookupSize();
    },
    
    changeLookupValue: function(fieldIndex, value, text) {
        var field = this._allFields[fieldIndex];
        this._closeLookup(field);
        this._restoreTabIndexes();
        var itemId = this.get_id() + '_Item' + fieldIndex;
        Sys.UI.DomElement.setVisible($get(itemId + '_ClearLookupLink'), true);
        $get(itemId + '_ShowLookupLink').innerHTML = this.htmlEncode(field, text);
        $get(itemId + '_ShowLookupLink').focus();
        $get(itemId).value = value;
        this._updateLookupInfo(value, text);
    },
    
    clearLookupValue: function(fieldIndex) {
        var itemId = this.get_id() + '_Item' + fieldIndex;
        Sys.UI.DomElement.setVisible($get(itemId + '_ClearLookupLink'), false);
        $get(itemId + '_ShowLookupLink').innerHTML = Web.DataViewResources.Lookup.SelectLink;
        $get(itemId + '_ShowLookupLink').focus();
        $get(itemId).value = '';
        this._updateLookupInfo('', Web.DataViewResources.Lookup.SelectLink);
    },
    
    _updateLookupInfo: function(value, text) {
        var lookupText = $get(this.get_id() + '_Text0');
        if (lookupText) {
            lookupText.value = text;
            lookupText.name = lookupText.id;
            var lookupValue = $get(this.get_id() + '_Item0');
            lookupValue.value = value;
            lookupValue.name = lookupValue.id;
            if (this.get_lookupPostBackExpression()) {
                var prm = Sys.WebForms.PageRequestManager.getInstance();
                if (prm) 
                    eval ("Sys.WebForms.PageRequestManager.getInstance()._doPostBack" + this.get_lookupPostBackExpression().match(/\w+(.+)/)[1]);
                else 
                    eval(this.get_lookupPostBackExpression());
            }
        }
    },
    
    createNewLookupValue: function(fieldIndex) {
        var field = this._newLookupValueField = this._allFields[fieldIndex];
        var placeholder = this._createNewElement = document.createElement('div');
        placeholder.id = this.get_id() + 'CreateNewContainer';
        this.get_element().appendChild(placeholder);
        placeholder.className = 'ModalPlaceholder ModalPopup';
        var cb = $common.getClientBounds();
        var width = (document.body.offsetWidth) / 4 * 3;
        if (width > Web.DataViewResources.ModalPopup.MaxWidth) width = Web.DataViewResources.ModalPopup.MaxWidth;
        else if (width > cb.width) width = cb.width / 4 * 3;
        var height = document.body.clientHeight / 4 * 3;
        if (height > Web.DataViewResources.ModalPopup.MaxHeight) height = Web.DataViewResources.ModalPopup.MaxHeight;
        else if (height > cb.height) height = cb.height / 4 * 3;
        placeholder.style.width = width + "px";
        placeholder.innerHTML = String.format('<div id="{0}CreateNew" style="width:{1}px;height:{2}px;overflow:auto;"></div><div class="Buttons" id="Buttons" style="visibility:hidden"><table><tr><td align="left">{5}</td><td align="right"><button onclick="$find(&quot;{0}&quot;).saveNewLookupValue();return false;">{3}</button><button onclick="$find(&quot;{0}&quot;).cancelNewLookupValue();return false;">{4}</button></td></tr></table></div>', this.get_id(), width, height, Web.DataViewResources.ModalPopup.OkButton, Web.DataViewResources.ModalPopup.CancelButton, Web.DataViewResources.Form.RequiredFiledMarkerFootnote);
        this._createNewView = $create(Web.DataView, {id: this.get_id() + 'CreateNewEx', baseUrl: this.get_baseUrl(), pageSize: 0, servicePath: this.get_servicePath(), controller: field.ItemsDataController, viewId: field.ItemsNewDataView, isInserting: true, showActionBar: false}, null, null, $get(this.get_id() + 'CreateNew'));
        this._createNewView.add_executed(Function.createDelegate(this, this._saveNewLookupValueCompleted));  
        this._saveTabIndexes();
        this._modalPopup = $create(AjaxControlToolkit.ModalPopupBehavior, {id: this.get_id() + 'CreateNewExModalPopup', PopupControlID: placeholder.id, DropShadow: true, BackgroundCssClass: 'ModalBackground'}, null, null, $get(String.format('{0}_Item{1}_CreateNewLookupLink', this.get_id(), field.Index)));
    },
    
    saveNewLookupValue: function() {
        this._createNewView.set_lastCommandName('New');
        this._createNewView.executeCommand({commandName: 'Insert'});
    },
    
    _saveNewLookupValueCompleted: function(sender, args) {
        if (args.result.Errors.length > 0) return;
        args.handled = true;
        Web.DataView.hideMessage();
        var v = null;
        if (args.result.Values.length == 0) args.result.Values = sender._lastArgs.Values;
        for (var j = 0; j < args.result.Values.length; j++)
            if (args.result.Values[j].Name == sender._keyFields[0].Name) {
                v = args.result.Values[j].NewValue;
                break;
            }
        var t = null;
        for (i = 0; i < sender._lastArgs.Values.length; i++) {
            if (sender._lastArgs.Values[i].Name == sender._fields[0].Name) {
                t = sender._lastArgs.Values[i].NewValue;
                break;
            }
        }
        if (this._newLookupValueField._lookupDataControllerBehavior) this._newLookupValueField._lookupDataControllerBehavior.goToPage(-1);
        this.cancelNewLookupValue();
        this.changeLookupValue(this._newLookupValueField.Index, v, t);
    },
    
    cancelNewLookupValue: function() {
        this._createNewView.dispose();
        this._modalPopup.dispose();
        this.get_element().removeChild(this._createNewElement);
        this._restoreTabIndexes();
    },
    
    hideLookup: function(fieldIndex) {
        var field = fieldIndex ? this._allFields[fieldIndex] : this.get_lookupField();
        this._closeLookup(field);
            this.get_lookupField()._dataView._restoreTabIndexes();
        $get(this.get_lookupField()._dataView.get_id() + '_Item' + field.Index + '_ShowLookupLink').focus();
    },
    
    htmlEncode: function(field, s) { return this._allFields[field.AliasIndex].Type == 'String' ? Web.DataView.htmlEncode(s) : s; },
    
    filterIsExternal: function() {
        if (this._externalFilter.length == 0) return false;
        for (var i = 0; i < this._filter.length; i++)
            for (var j = 0; j < this._externalFilter.length; j++)
                if (this._externalFilter[j].Name != this._filter[i].match(/(\w+):/)[1])
                    return false;
        return true;
    },
    
    add_selected: function(handler) {
        this.get_events().addHandler('selected', handler);
    },
    remove_selected: function(handler) {
        this.get_events().removeHandler('selected', handler);
    },
    
    raiseSelected: function(eventArgs) {
        var handler = this.get_events().getHandler('selected');
        if (handler) handler(this, eventArgs);
    },
    
    add_executed: function(handler) {
        this.get_events().addHandler('executed', handler);
    },
    remove_executed: function(handler) {
        this.get_events().removeHandler('executed', handler);
    },
    raiseExecuted: function(eventArgs) {
        var handler = this.get_events().getHandler('executed');
        if (handler) handler(this, eventArgs);
    },
    
    _closeLookup: function(field) {
        if (field && field._lookupModalBehavior) {
            field._lookupModalBehavior.hide();
            $removeHandler(document.body, 'keydown', field._lookupDataControllerBehavior._bodyKeydownHandler);
        }
    },
    
    _collectFieldValues: function() {
        var values = new Array();
        var selectedRow = this.get_selectedRow();
        if (!selectedRow && !this.get_isInserting()) return values;
        for (var i = 0; i < this._allFields.length; i++) {
            field = this._allFields[i];
            var element = $get(this.get_id() + '_Item' + i);
            if (field.Items.length > 0 && field.ItemsStyle == 'RadioButtonList') 
                for (var j = 0; j < field.Items.length; j++) {
                    var option = $get(this.get_id() + '_Item' + i + '_' + j);
                    if (option && option.checked) {
                        element = option;
                        break;
                    }
                }
            if (element || field.IsPrimaryKey || !field.ReadOnly)
                Array.add(values, {Name: field.Name, OldValue: this.get_isInserting() ? null : selectedRow[field.Index], NewValue: element && element.value ? element.value : null, Modified: element != null});
        }
        for (i = 0; i < this._externalFilter.length; i++) {
            var filterItem = this._externalFilter[i];
            for (j = 0; j < values.length; j++)
                if (values[j].Name == filterItem.Name && values[j].NewValue == null) {
                    values[j].NewValue = filterItem.Value;
                    values[j].Modified = true;
                    break;
                }
        }
        return values;
    },
    
    _validateFieldValues: function(values) {
        var valid = true;
        var sb = new Sys.StringBuilder();
        for (var i = 0; i < values.length; i++) {
            var v = values[i];
            var field = this.findField(v.Name);
            if (field.Type == 'DateTime' && v.OldValue != null)v.OldValue = new Date(v.OldValue - v.OldValue.getTimezoneOffset() * 60 * 1000);
            var error = null;
            if (v.Modified) {
                // see if the field is blank
                if (!field.AllowNulls && (!field.HasDefaultValue || Web.DataViewResources.Validator.EnforceRequiredFieldsWithDefaultValue))
                    if (!v.NewValue || v.NewValue.toString().match(/^\s*$/))
                        error = Web.DataViewResources.Validator.RequiredField;
                // convert blank values to "null"
                if (!error && v.NewValue && v.NewValue.toString().match(/^\s*$/))
                    v.NewValue = null;
                // convert to the "typed" value
                if (!error && v.NewValue != null) {
                    switch (field.Type) {
                        case 'SByte':
                        case 'Byte':
                        case 'Int16':
                        case 'Int32':
                        case 'UInt32':
                        case 'Int64':
                        case 'Single':
                        case 'Double':
                        case 'Decimal':
                            var newValue = v.NewValue && typeof(v.NewValue) == 'string' ? Number.parseLocale(v.NewValue.replace(Sys.CultureInfo.CurrentCulture.numberFormat.CurrencySymbol, '')) : v.NewValue;
                            if (String.format('{0}', newValue) == 'NaN')
                                error = Web.DataViewResources.Validator.NumberIsExpected;
                            else
                                v.NewValue = newValue;
                            break;
                        case 'Boolean':
                            try {
                                v.NewValue = Boolean.parse(v.NewValue);
                            }
                            catch (e) {
                                error = Web.DataViewResources.Validator.BooleanIsExpected;
                            }
                            break;
                        case 'DateTime':
                            newValue = field.DataFormatString && field.DataFormatString.length ? Date.parseLocale(v.NewValue, field.DataFormatString.match(/\{0:([\s\S]*?)\}/)[1]) : Date.parse(v.NewValue);
                            if (!newValue)
                                error = Web.DataViewResources.Validator.DateIsExpected;
                            else
                                v.NewValue = newValue;
                            if (!error && v.NewValue != null) v.NewValue = new Date(v.NewValue - v.NewValue.getTimezoneOffset() * 60 * 1000);
                            break;
                    }
                }
                // see if the value has been modified
                v.Modified = field.Type == 'DateTime' ? ((v.NewValue == null ? null : v.NewValue.toString()) != (v.OldValue == null ? null : v.OldValue.toString())) : v.NewValue != v.OldValue;
            }
            // display/hide the error as needed
            var errorElement = $get(this.get_id() + '_Item' + field.Index + '_Error');
            if (errorElement)  {
                Sys.UI.DomElement.setVisible(errorElement, error != null);
                errorElement.innerHTML = error;
            }
            if (error) {
                if (valid) {
                    var element = $get(this.get_id() + '_Item' + field.Index);
                    if (element) try { element.focus(); } catch (ex) {}
                }
                valid = false;
                if (!errorElement) sb.append(Web.DataView.formatMessage('Attention', field.Label + ": " + error));
            }
        }
        if (!valid) Web.DataView.showMessage(sb.toString());
        return valid;
    },
    
    _fieldIsInExternalFilter: function(field) {
        return this._findExternalFilterItem(field) != null;
    },
    
    _findExternalFilterItem: function(field) {
        for (var i = 0; i < this._externalFilter.length; i++) {
            var filterItem = this._externalFilter[i];
            if (field.Name == filterItem.Name)
                return filterItem;
        }
        return null;
    },
    
    _focus: function() {
        for (var i = 0; i < this.get_fields().length; i++) {
            var field = this.get_fields()[i];
            if (!field.ReadOnly) {
                var element = $get(this.get_id() + '_Item' + field.Index);
                if (element) try { element.select();element.focus(); } catch (ex) {}
                break;
            }
        }
    },
    
    _saveTabIndexes: function() {
        this._savedTabIndexes = [];
        var tagsWithIndexes = new Array('A','AREA','BUTTON','INPUT','OBJECT','SELECT','TEXTAREA','IFRAME');
        for (var i = 0; i < tagsWithIndexes.length; i++) {
            var tags = document.getElementsByTagName(tagsWithIndexes[i]);
            for (var j = 0; j < tags.length; j++) {
                var elem = tags[j];
                if (elem.tabIndex >= 0) 
                    Array.add(this._savedTabIndexes, {element: elem, tabIndex: elem.tabIndex});
            }
        }
    },
    
    _restoreTabIndexes: function() {
        if (this._savedTabIndexes) {   
            for (var i = 0; i < this._savedTabIndexes.length; i++)
                this._savedTabIndexes[i].element.tabIndex = this._savedTabIndexes[i].tabIndex;
            Array.clear(this._savedTabIndexes);
        }
    },
    
    _selectKeyByRowIndex: function(rowIndex) {
        var oldKey = this._selectedKey;
        this._selectedKey = [];
        this._selectedKeyFilter = []
        for (var i=0; i < this._keyFields.length; i++) {
            var field = this._keyFields[i];
            Array.add(this._selectedKey, this._rows[rowIndex][field.Index]);
            Array.add(this._selectedKeyFilter, field.Name + ':=' + this.convertFieldValueToString(field, this._rows[rowIndex][field.Index]));
            if (oldKey && (oldKey.length < i || (oldKey[i] != this._selectedKey[i]))) oldKey = null;
        }
        if (!oldKey) this.raiseSelected(Sys.EventArgs.Empty);
    },
    
    _showWait: function(force) {
        if (this.get_fields() == null || force)
            this._container.innerHTML = Web.DataViewResources.Common.WaitHtml;
        else {
            var wait = $get(this.get_id() + '_Wait');
            if (wait) {
                this._oldWaitHTML = wait.innerHTML;
                wait.innerHTML = Web.DataViewResources.Common.WaitHtml;
            }
        }
    },
    
    _hideWait: function() {
        if (this._oldWaitHTML) {
            var waitElement = $get(this.get_id() + '_Wait');
            if (waitElement) waitElement.innerHTML = this._oldWaitHTML;
        }
    },
    
    _get_colSpan: function() {
        return this.get_view().Type == 'Form' ? 2 : this.get_fields().length;
    },
    
    _renderCreateNewBegin: function(sb, field) { if (field.ItemsNewDataView && field.ItemsNewDataView > '') sb.append('<table cellpadding="0" cellspacing="0"><tr><td>'); },
    _renderCreateNewEnd: function(sb, field) {
        if (field.ItemsNewDataView && field.ItemsNewDataView > '') {
            sb.append('</td><td>');
            sb.append(String.format('<a href="#" class="CreateNew" onclick="$find(\'{0}\').createNewLookupValue({1});return false" id="{0}_Item{1}_CreateNewLookupLink" title="{2}"{3}>&nbsp;</a>', 
                this.get_id(), field.Index, String.format(Web.DataViewResources.Lookup.NewToolTip, field.Label), this._tabIndex > 0 ? String.format(' tabindex="{0}"', this._tabIndex++) : ''));
            sb.append('</td></tr></table>');
        }
    },
    
    _render: function() {
        var sb = new Sys.StringBuilder();
        if (this.get_mode() == Web.DataViewMode.Lookup) {
            var field = this._fields[0];
            var v = this.get_lookupText();
            if (v == null) v = Web.DataViewResources.Lookup.SelectLink;
            var s = field.DataFormatString && field.DataFormatString.length > 0 ? String.localeFormat(field.DataFormatString, v) : v.toString();
            this._renderCreateNewBegin(sb, field);
            sb.append(String.format('<table cellpadding="0" cellspacing="0" class="DataViewLookup"><tr><td><a href="#" onclick="$find(\'{0}\').showLookup({1});return false" id="{0}_Item{1}_ShowLookupLink" title="{3}">{2}</a><a href="#" class="Clear" onclick="$find(\'{0}\').clearLookupValue({1});return false" id="{0}_Item{1}_ClearLookupLink" title="{5}">&nbsp;</a></td></tr></table><input type="hidden" id="{0}_Item{1}" value="{4}"/><input type="hidden" id="{0}_Text{1}" value="{6}"/>', 
                this.get_id(), field.Index, this.htmlEncode(field, s), String.format(Web.DataViewResources.Lookup.SelectToolTip, field.Label), this.get_lookupValue(), String.format(Web.DataViewResources.Lookup.ClearToolTip, field.Label), Web.DataView.htmlAttributeEncode(s)));
            this._renderCreateNewEnd(sb, field);
            this._container.innerHTML = sb.toString();
            if (this.get_lookupValue() == '') $get(this.get_id() + '_Item0_ClearLookupLink').style.display = 'none';
        }
        else {
            sb.append('<table class="DataView" cellpadding="0" cellspacing="0">');
            if (this.get_view().Type == 'Form')
                this._renderFormView(sb);
            else 
                this._renderGridView(sb);
            sb.append('</table>');
            this._container.innerHTML = sb.toString();
            this._attachBehaviors();
            if (this._isInserting) {
                $find(this.get_id() + 'ModalPopup').show();
                if (this._container.offsetHeight > this.get_element().offsetHeight) {
                    if (Sys.Browser.agent == Sys.Browser.InternetExplorer) this._container.style.width = (this._container.offsetWidth - 20) + 'px';
                }
                else {
                    this.get_element().style.height = this._container.offsetHeight + 'px';
                    $find(this.get_id() + 'ModalPopup').show();
                }
                $get('Buttons', this.get_element().parentNode).style.visibility = 'visible';
            }
            if (this.get_isEditing()) this._focus();
        }
    },
    
    _renderFormView: function(sb) {
        this._renderViewDescription(sb);
        if (Web.DataViewResources.Form.ShowActionBar) this._renderActionBar(sb);
        var row = this.get_isInserting() ? [] : this.get_selectedRow();
        this._tabIndex = 1;
        if (this.get_fields().length > 10 && row)
            this._renderActionButtons(sb, 'Top');
        if (!row) this._renderNoRecordsWhenNeeded(sb);
        else {
            var t = $get(this.get_controller() + '_' + this.get_viewId());
            if (t) {
                sb.append('<tr class="CategoryRow"><td valign="top" class="Fields" colspan="2">');
                var s = t.innerHTML;
                var iterator = /([\s\S]*?)\{([\w\d]+)\}/g;
                var lastIndex = 0;
                var match = iterator.exec(s);
                while (match) {
                    lastIndex = match.index + match[0].length;
                    sb.append(match[1]);
                    for (var j = 0; j < this._allFields.length; j++) {
                        var field = this._allFields[j];
                        if (field.Name == match[2]) {
                            this._renderItem(sb, field, row, true);
                            break;
                        }
                    }
                    match = iterator.exec(s);
                }
                if (lastIndex < s.length) sb.append(s.substring(lastIndex));
                sb.append('</td></tr>');
            }
            else
                for (var i = 0; i < this.get_categories().length; i++) {
                    var category = this.get_categories()[i];
                    sb.append(String.format('<tr class="CategoryRow"><td valign="top" class="Category"><table class="Category" cellpadding="0" cellspacing="0"><tr><td class="HeaderText">{0}</td></tr><tr><td class="Description">{1}</td></tr></table></td><td valign="top" class="Fields">', category.HeaderText, category.Description));
                    for (j = 0; j < this.get_fields().length; j++) {
                        field = this.get_fields()[j];
                        if (!field.Hidden && field.CategoryIndex == category.Index)
                            this._renderItem(sb, field, row, true);
                    }
                    sb.append('</td></tr>');
                }
        }
        if (row) this._renderActionButtons(sb, 'Bottom');
    },
    
    _renderItem: function(sb, field, row, isSelected) {
        var isForm = this.get_view().Type == 'Form';
        var v = row[field.Index];
        if (v != null) v = v.toString();
        var checkBox = null;
        if (this.get_isEditing() && field.ItemsStyle == 'CheckBox' && field.Items.length == 2)
            checkBox = String.format('<input type="checkbox" id="{0}_Item{1}"{2} tabindex="{3}" value="{4}" onclick="this.value=this.checked"/>', this.get_id(), field.Index, field.Items[1][0] && v == 'true' ? ' checked' : '', this._tabIndex++, v);
        if (isForm) {
            sb.append(String.format('<div class="Item" id="{0}_ItemContainer{1}"><div class="Error" id="{0}_Item{1}_Error" style="display:none"></div>', this.get_id(), field.Index));
            var headerText = this._allFields[field.AliasIndex].HeaderText;
            if (headerText.length > 0)
                sb.append(String.format('<div class="Header">{3}<label for="{0}_Item{1}">{2}{4}</label></div>', this.get_id(), field.Index, headerText, checkBox, this.get_isEditing() && !field.AllowNulls && Web.DataViewResources.Form.RequiredFieldMarker ? Web.DataViewResources.Form.RequiredFieldMarker : ''));
            if (checkBox == null)
                sb.append('<div class="Value">');
        }
        if (this.get_isEditing() && isSelected && !field.ReadOnly) {
            if (!isForm && checkBox) sb.append(checkBox);
            if (checkBox == null) 
                if (field.Items.length > 0) {
                    if (field.ItemsStyle == 'RadioButtonList') {
                        sb.append('<table cellpadding="0" cellspacing="0" class="RadioButtonList">');
                        var columns = field.Columns == 0 ? 1 : field.Columns;
                        var rows = Math.floor(field.Items.length / columns) + (field.Items.length % columns  > 0 ? 1 : 0);
                        for (var r = 0; r < rows; r++) {
                            sb.append('<tr>');
                            for (var c = 0; c < columns; c++) {
                                var itemIndex = c * rows + r; //r * columns + c;
                                if (itemIndex < field.Items.length) {                                
                                    var item = field.Items[itemIndex];
                                    var itemValue = item[0] == null ? '' : item[0].toString();
                                    if (v == null) v = '';
                                    sb.append(String.format(
                                        '<td class="Button"><input type="radio" id="{0}_Item{1}_{2}" name="{0}_Item{1}" value="{3}"{4} tabindex="{6}"/></td><td class="Option"><label for="{0}_Item{1}_{2}">{5}<label></td>', 
                                        this.get_id(), field.Index, itemIndex, itemValue, itemValue == v ? " checked" : "", this.htmlEncode(field, item[1]), this._tabIndex++));
                                }
                                else
                                    sb.append('<td class="Button">&nbsp;</td><td class="Option"></td>');
                            }
                            sb.append('</tr>');
                        }
                        sb.append('</table>');
                    }
                    else {
                        sb.append(String.format('<select id="{0}_Item{1}" size="{2}" tabindex="{3}">', this.get_id(), field.Index, field.ItemsStyle == 'ListBox' ? (field.Rows == 0 ? 5 : field.Rows) : '1', this._tabIndex++));
                        if (v == null) v = '';
                        v = v.toString();
                        for (var i = 0; i < field.Items.length; i++) {
                            item = field.Items[i];
                            itemValue = item[0];
                            if (itemValue == null) itemValue = '';
                            itemValue = itemValue.toString();
                            sb.append(String.format('<option value="{0}"{1}>{2}</option>', itemValue, itemValue == v ? ' selected' : '', this.htmlEncode(field, item[1])));
                        }
                        sb.append('</select>');
                    }
                }
                else if (field.ItemsDataController && field.ItemsDataController.length > 0) {
                    v = row[field.AliasIndex];
                    if (v == null) v = Web.DataViewResources.Lookup.SelectLink;
                    var s = field.DataFormatString && field.DataFormatString.length > 0 ? String.localeFormat(field.DataFormatString, v) : v.toString();
                    this._renderCreateNewBegin(sb, field);
                    sb.append(String.format('<table cellpadding="0" cellspacing="0" class="Lookup"><tr><td><a href="#" onclick="$find(\'{0}\').showLookup({1});return false" id="{0}_Item{1}_ShowLookupLink" title="{3}" tabindex="{5}">{2}</a><a href="#" class="Clear" onclick="$find(\'{0}\').clearLookupValue({1});return false" id="{0}_Item{1}_ClearLookupLink" title="{7}" tabindex="{6}" style="display:{8}">&nbsp;</a></td></tr></table><input type="hidden" id="{0}_Item{1}" value="{4}"/>', 
                        this.get_id(), field.Index, this.htmlEncode(field, s), String.format(Web.DataViewResources.Lookup.SelectToolTip, field.Label), row[field.Index], this._tabIndex++, this._tabIndex++, String.format(Web.DataViewResources.Lookup.ClearToolTip, field.Label), row[field.Index] != null ? 'display' : 'none'));
                    this._renderCreateNewEnd(sb, field);
                }
                else if (field.Rows > 1) {
                    this._renderLiquidFrameHeader(sb);
                    sb.append(String.format('<textarea id="{0}_Item{1}" tabindex="{2}"', this.get_id(), field.Index, this._tabIndex++));
                    if (!isForm) 
                        sb.append(' style="width:95%"');
                    else
                        sb.append(String.format(' cols="{0}"', field.Columns > 0 ? field.Columns : 50));
                    sb.append(String.format(' rows="{0}"', field.Rows));
                    sb.append('>');
                    sb.append(this.htmlEncode(field, v));
                    sb.append('</textarea>');
                    this._renderLiquidFrameFooter(sb);
                }
                else {
                    this._renderLiquidFrameHeader(sb);
                    sb.append(String.format('<input type="text" id="{0}_Item{1}" tabindex="{2}"', this.get_id(), field.Index, this._tabIndex++));
                    if (this.get_view().Type == 'Grid') 
                        sb.append(' style="width:100%"');
                    else
                        sb.append(String.format(' size="{0}"', field.Columns > 0 ? field.Columns : 50));
                    v = row[field.Index];
                    if (v == null) 
                        s = '';
                    else
                        s = field.DataFormatString && field.DataFormatString.length > 0 ? String.localeFormat(field.DataFormatString, v) : v.toString();
                    sb.append(String.format(' value="{0}"', Web.DataView.htmlAttributeEncode(s)));
                    sb.append('/>');
                    if (field.Type == 'DateTime' && isForm && Web.DataViewResources.Form.ShowCalendarButton)
                        sb.append(String.format('<a id="{0}_Item{1}_Button" href="#" onclick="return false" class="Calendar" tabindex="{2}">&nbsp;</a>', this.get_id(), field.Index, this._tabIndex++));
                    this._renderLiquidFrameFooter(sb);
                }
        }
        else  {
            v = this.htmlEncode(field, row[field.AliasIndex]);
            if (field.Items.length == 0) {
                if (field.Type == 'String' && v != null && v.length > Web.DataViewResources.Data.MaxReadOnlyStringLen)
                    v = v.substring(0, Web.DataViewResources.Data.MaxReadOnlyStringLen) + '...';
                s = v == null || field.Type == "String" && v.trim().length == 0 ? (isForm ? Web.DataViewResources.Data.NullValueInForms : Web.DataViewResources.Data.NullValue) : (field.DataFormatString && field.DataFormatString.length > 0 ? String.localeFormat(field.DataFormatString, v) : v.toString());
            }
            else {
                item = this._findItemByValue(field,  v);
                s = item[1];
            }
            sb.append(s);
        }
        if (isForm) {
            if (checkBox == null)
                sb.append('</div>');
            if (field.FooterText && field.FooterText.length > 0)
                sb.append(String.format('<div class="Footer">{0}</div>', field.FooterText));
            sb.append('</div>');
        }
    },
    
    _renderLiquidFrameHeader: function(sb) {
        if (this.get_view().Type=='Grid') sb.append('<table class="Liquid" cellpadding="0" cellspacing="0"><tr><td class="Liquid">');
    },
    
    _renderLiquidFrameFooter: function(sb) {
        if (this.get_view().Type=='Grid') sb.append('</td></tr></table>');
    },
    
    _renderActionButtons: function(sb, location) {
        if (this._isInserting) return;
        var actions = this.get_actions('Form');
        sb.append(String.format('<tr class="ActionButtonsRow {0}ButtonsRow"><td colspan="{1}" class="ActionButtons">', location, this._get_colSpan()));
        sb.append(String.format('<table style="width:100%" cellpadding="0" cellspacing="0" class="ActionButtons"><tr><td id="{0}_Wait" align="left">{1}&nbsp;</td><td align="right">&nbsp;', location == 'Bottom' ? this.get_id() : '', this.get_isEditing() && Web.DataViewResources.Form.RequiredFieldMarker ? Web.DataViewResources.Form.RequiredFiledMarkerFootnote : ''));
        for (var i = 0; i < actions.length; i++) {
            var action = actions[i];
            if (this._isActionAvailable(action))
                sb.append(String.format('<button onclick="$find(\'{0}\').executeAction(\'Form\', {1},-1);return false;" tabindex="{3}">{2}</button>', this.get_id(), i, action.HeaderText, this._tabIndex++));
        }
        sb.append('</tr></tr></table></td></tr>');
    },
    
    _isActionAvailable: function(action, rowIndex) {
        var lastCommand = action.WhenLastCommandName ? action.WhenLastCommandName : '';
        var available = lastCommand.length == 0 || lastCommand == this.get_lastCommandName();
        if (available && this.get_isEditing()) {
            var isSelected = this._rowIsSelected(rowIndex == null ? this._selectedRowIndex : rowIndex);
            if (isSelected)
                return lastCommand == 'New' || lastCommand == 'Edit';
            else if (!isSelected && rowIndex == null && lastCommand == 'New')
                return true;
            else
                return lastCommand.length == 0 && rowIndex != null;
        }
        return available;
    },
    
    _rowIsSelected: function(rowIndex) {
        var row = this._rows[rowIndex];
        if (row && this._keyFields.length == this._selectedKey.length) {
            for (var j = 0; j < this._keyFields.length; j++) {
                field = this._keyFields[j];
                var v1 = this._selectedKey[j];
                var v2 = row[field.Index];
                if (field.Type == 'DateTime') {
                    if (!(v1 || v2)) return false;
                    v1 = v1.toString();
                    v2 = v2.toString();
                }
                if (v1 != v2) return false;
            }
            return true;
        }
        else
            return false;
    },
    
    _renderGridView: function(sb) {
        this._renderViewDescription(sb);
        this._renderActionBar(sb);
        this._renderInfoBar(sb);
        sb.append('<tr class="HeaderRow">');
        for (var i = 0; i < this.get_fields().length; i++) {
            var field = this.get_fields()[i];
            sb.append(String.format('<th><div id="{0}_Header{1}" style="padding:3px;cursor:pointer;{2}">', this.get_id(), i, Web.DataView.isIE6 ? 'display:inline-block;' : ''));
            this._renderFieldHeaderText(sb, field)
            sb.append('</div></th>');
        }
        sb.append('</tr>');
        var isEditing = this.get_isEditing();
        for (i = 0; i < this.get_rows().length; i++) {
            var row = this.get_rows()[i];
            var isSelectedRow = this._rowIsSelected(i);
            sb.append(String.format('<tr id="{0}_Row{1}" class="{2}Row{3}" onmouseover="Sys.UI.DomElement.addCssClass(this,\'Highlight\');" onmouseout="Sys.UI.DomElement.removeCssClass(this,\'Highlight\');">', this.get_id(), i, i % 2 == 0 ? '' : 'Alternating', isSelectedRow ? ' Selected' : ''));
            for (j = 0; j < this.get_fields().length; j++) {
                field = this.get_fields()[j];
                if (j == 0 && this.get_lookupField() == null || isSelectedRow) sb.append('<td class="Cell">'); else sb.append(String.format('<td class="Cell" style="cursor:default;" onclick="$find(&quot;{0}&quot;).executeRowCommand({1},&quot;Select&quot;);return false;">', this.get_id(), i));
                if (isSelectedRow && isEditing && !field.ReadOnly) sb.append(String.format('<div class="Error" id="{0}_Item{1}_Error" style="display:none"></div>', this.get_id(), field.Index));
                if (j == 0) {
                    sb.append(String.format('<div id="{0}_RowSelector{1}" style="padding:2px;cursor:pointer;{2}">', this.get_id(), i, Web.DataView.isIE6 ? 'display:inline-block;' : ''));
                    if (!(isSelectedRow && isEditing)) sb.append(String.format('<a href="#" onclick="$find(\'{0}\').executeAction(\'Grid\',-1,{1});return false">', this.get_id(), i));
                }
                this._renderItem(sb, field, row, isSelectedRow);                 
                if (j == 0 && !isEditing) {
                    if (!(isSelectedRow && isEditing)) sb.append('</a>');
                    sb.append('</div>');
                }
                sb.append('</td>');
            }
            sb.append('</tr>');
        }
        this._renderNoRecordsWhenNeeded(sb);
        this._renderViewPager(sb);
    },
    
    _renderNoRecordsWhenNeeded: function(sb) {
        if (this._totalRowCount == 0)
            sb.append(String.format('<tr class="Row NoRecords"><td colspan="{0}" class="Cell">{1}</td></tr>', this._get_colSpan(), Web.DataViewResources.Data.NoRecords));
    },
    
    _viewSelectorOnShown: function(e, args) {
        e._dropPopupPopupBehavior.set_y(Sys.Browser.agent === Sys.Browser.Safari ? 5 : 3);
    },
    
    _attachBehaviors: function() {
        this._detachBehaviors();
        this._attachActionBarBehaviors();
        if (this.get_view().Type == 'Grid') {
            this._attachRowContextBehaviors();
            this._attachHeaderDropDownBehaviors();
        }
        this._attachFieldBehaviors();
    },
    
    _attachActionBarBehaviors: function() {
        var offsetX = -4;
        var offsetY = 4;
        if (Sys.Browser.agent === Sys.Browser.Opera) {
            offsetX = 0;
            offsetY = 0;
        }
        else if (Sys.Browser.agent === Sys.Browser.Firefox && Sys.Browser.version >= 3) {
            offsetX = 0;
            offsetY = 1;
        }
        else if (Sys.Browser.agent !== Sys.Browser.InternetExplorer) {
            offsetX = 0;
            offsetY = 22;
        }
        var groups = this.get_actionGroups('ActionBar');
        for (var i = 0; i < groups.length; i++) {
            var group = groups[i];
            var target = $get(this.get_id() + '_ActionBarGroup' + i.toString());
            if (target) {
                var panel = group._panel = document.createElement('div');
                panel.id = this.get_id() + '_ActionBarGroupPanel' + i.toString()
                Sys.UI.DomElement.setVisible(panel, false);
                this.get_element().appendChild(panel);
                panel.className = 'ContextMenuPanel ActionBarContextMenuPanel';
                var sb = new Sys.StringBuilder();
                if (Web.DataView.isIE6) sb.append('<table cellpadding="0" cellspacing="0"><tr><td style="padding:0px">');
                for (var j = 0; j < group.Actions.length; j++) {
                    var action = group.Actions[j];
                    if (this._isActionAvailable(action))
                        if (action.CommandName == null || action.CommandName.length == 0)
                            sb.append('<div class="ContextMenuBreak"></div>');
                        else 
                            sb.append(String.format('<a href="#" onclick="$find(\'{0}\').executeAction(\'ActionBar\',{1},null,{2});return false" class="ContextMenuItem {4}"><div class="Title">{3}</div><div class="Description">{5}</div></a>',
                                this.get_id(), j, i, action.HeaderText, action.CssClass && action.CssClass.length > 0 ? action.CssClass : action.CommandName + "LargeIcon", action.Description));
                }
                if (Web.DataView.isIE6) sb.append('</td></tr></table>');
                panel.innerHTML = sb.toString();
                var popup = group._popupBehavior = $create(AjaxControlToolkit.PopupControlBehavior, {id: this.get_id() + "_ActionBarGroupPopup" + i.toString(), PopupControlID: panel.id, Position: AjaxControlToolkit.PopupControlPopupPosition.Bottom, OffsetY: offsetY, OffsetX: offsetX}, null, null, target);
                popup.hidePopup();
                popup._popupBehavior.add_showing(this._actionBarGroupOnShowingHandler);
            }
        }
        var selector = $get(this.get_id() + '_ViewSelector');
        if (selector) {        
            selector.innerHTML = String.format('<table style="width:100%;" cellpadding="0" cellspacing="0"><tr><td nowrap style="width:100%;padding:1px 16px 1px 4px" onmouseover="Sys.UI.DomElement.addCssClass(this,\'Highlight\');" onmouseout="Sys.UI.DomElement.removeCssClass(this,\'Highlight\');"><span tabIndex=0>{0}</span></td ><td class="ajax__dropdown_arrow_image" style="padding:0px 14px 0px 0px">&nbsp;</td></table>', this.get_view().Label);
            panel = this._viewSelectorPanel = document.createElement('div');
            Sys.UI.DomElement.setVisible(panel, false);
            this.get_element().appendChild(panel);
            panel.className = 'ContextMenuPanel';
            sb = new Sys.StringBuilder();
            for (i = 0; i < this.get_views().length; i++) {
                var view = this.get_views()[i];
                if (view.Type != 'Form' || view.Id == this.get_viewId())
                    sb.append(String.format('<a href="#" onclick="$find(\'{0}\').executeCommand({{commandName:\'Select\',commandArgument:\'{1}\'}});return false" class="ContextMenuItem {2}">{3}</a>',        
                        this.get_id(), view.Id, view.Id == this.get_viewId() ? 'Checked' : '', view.Label));
            }
            panel.innerHTML = sb.toString();
            var dropDown = this._viewSelectorDropDownBehavior = $create(AjaxControlToolkit.DropDownBehavior, {dropDownControl: panel, id: this.get_id() + '_ViewSelectorDropDown'}, null, null, selector);
            dropDown.set_highlightBorderColor('#FFBC47');
            dropDown.set_dropArrowBackgroundColor('');
            dropDown.add_shown(this._viewSelectorOnShownHandler);
        }
    },
    
    _attachRowContextBehaviors: function() {
        this._rowSelectors = [];
        var actions = this.get_actions('Grid');
        if (actions && actions.length > 0 && this.get_lookupField() == null)
            for (i = 0; i < this._rows.length; i++) {
                if (!this._rowIsSelected(i) || (!this.get_isEditing() || Web.DataViewResources.Grid.InPlaceEditContextMenuEnabled)) {
                    sb = new Sys.StringBuilder();
                    if (Web.DataView.isIE6) sb.append('<table cellpadding="0" cellspacing="0"><tr><td style="padding:0px">'); 
                    for (var j = 0; j < actions.length; j++) {
                        var action = actions[j];
                        if (this._isActionAvailable(action, i))
                            if (action.CommandName == null || action.CommandName.length == 0)
                                sb.append('<div class="ContextMenuBreak"></div>');
                            else 
                                sb.append(String.format('<a href="#" onclick="$find(\'{0}\').executeAction(\'Grid\', {1},{2});return false" class="ContextMenuItem {4}">{3}</a>',
                                    this.get_id(), j, i, action.HeaderText, action.CssClass && action.CssClass.length > 0 ? action.CssClass : action.CommandName + 'Icon'));
                    }        
                    panel = this._rowSelectorPanel = document.createElement('div');
                    Sys.UI.DomElement.setVisible(panel, false);
                    this.get_element().appendChild(panel);
                    panel.className = 'ContextMenuPanel';
                    if (Web.DataView.isIE6) sb.append('</td></tr></table>');
                    panel.innerHTML = sb.toString();
                    dropDown = $create(AjaxControlToolkit.DropDownBehavior, {dropDownControl: panel, id: this.get_id() + '_RowDropDown' + i.toString()}, null, null, $get(this.get_id() + '_RowSelector' + i.toString()));
                    dropDown.set_highlightBackgroundColor('#FFFFFF');
                    Array.add(this._rowSelectors, {_panel: panel, _dropDownBehavior: dropDown});
                }
            }
    },
    
    _attachHeaderDropDownBehaviors: function() {
        for (i = 0; i < this.get_fields().length; i++) {
            var field = this.get_fields()[i];
            var headerDiv = $get(this.get_id() + '_Header' + i.toString());
            if (field.AllowSorting || field.AllowQBE) {
                if (!field._dropDownPanel) {
                    panel = field._dropDownPanel = document.createElement('div');
                    Sys.UI.DomElement.setVisible(panel, false);
                    panel.className = 'ContextMenuPanel';
                    panel.id = this.get_id() + '_DropDownPanel' + i.toString();
                    this.get_element().appendChild(panel);
                }
                dropDown = field._headerDropDownBehavior = $create(AjaxControlToolkit.DropDownBehavior, {dropDownControl: field._dropDownPanel, id: this.get_id() + '_HeaderDropDown' + i.toString()}, null, null, headerDiv);
                dropDown.set_highlightBorderColor('#DDE1E5');
                dropDown.set_highlightBackgroundColor('#DDE1E5');
                dropDown.set_dropArrowBackgroundColor('#FFE18F');
                dropDown.add_showing(this._headerDropDownOnShowingHandler);
            }
            else
                headerDiv.style.cursor = '';
        }
    },
    
    _attachFieldBehaviors: function() {
        if (this.get_isEditing()) 
            for (var i = 0; i < this.get_fields().length; i++) {
                var field = this.get_fields()[i];
                if (field.Type == 'DateTime') {
                    var element = $get(this.get_id() + '_Item' + field.Index);
                    if (element) {
                        field._calendarBehavior = $create(AjaxControlToolkit.CalendarBehavior, {id: this.get_id() + '_Calendar' + field.Index}, null, null, element);
                        field._calendarBehavior.set_format(field.DataFormatString.match(/\{0:([\s\S]*?)\}/)[1]);
                        var button = $get(element.id + '_Button');
                        if (button) field._calendarBehavior.set_button(button);
                    }
                }
            }
    },
    
    _detachBehaviors: function() {
        // detach view selector
        if (this._viewSelectorDropDownBehavior) {
            this._viewSelectorDropDownBehavior.remove_showing(this._viewSelectorOnShownHandler);
            this._viewSelectorDropDownBehavior.dispose();
            this._viewSelectorDropDownBehavior = null;
        }
        if (this._viewSelectorPanel) {
            this.get_element().removeChild(this._viewSelectorPanel);
            this._viewSelectorPanel = null;
        }
        // detach action bar popups
        var groups = this.get_actionGroups('ActionBar', true);
        for (var i = 0; i < groups.length; i++) {
            var group = groups[i];
            if (group._popupBehavior) {
                group._popupBehavior._popupBehavior.remove_showing(this._actionBarGroupOnShowingHandler);
                group._popupBehavior.dispose();
                group._popupBehavior = null;
                this.get_element().removeChild(group._panel);
                group._panel = null;
            }
        }
        // detach row selectors
        if (this._rowSelectors) {
            for (i = 0; i < this._rowSelectors.length; i++) {
                this._rowSelectors[i]._dropDownBehavior.get_element().style.backgroundColor = '';
                this._rowSelectors[i]._dropDownBehavior.dispose();
                this._rowSelectors[i]._dropDownBehavior = null;
                this.get_element().removeChild(this._rowSelectors[i]._panel);
                this._rowSelectors[i]._panel = null;
            }
            this._rowSelectors = null;
        }
        // detach row header drop downs and field behaviors
        if (this.get_fields() != null)
            for (i = 0; i < this.get_fields().length; i++) {
                var field = this.get_fields()[i];
                if (field._headerDropDownBehavior != null) {
                 
                    field._headerDropDownBehavior.remove_showing(this._headerDropDownOnShowingHandler);
                    field._headerDropDownBehavior.dispose();
                    field._headerDropDownBehavior = null;
                }
                if (field._lookupDataControllerBehavior != null) {
                    field._lookupDataControllerBehavior.dispose();
                    field._lookupDataControllerBehavior = null;
                }
                if (field._lookupModalBehavior != null) {
                    if (Web.DataView.isIE6) field._lookupModalBehavior._windowHandlersAttached = true;
                    field._lookupModalBehavior.dispose();
                    field._lookupModalBehavior = null;
                    this.get_element().removeChild(field._lookupModalPanel);
                    field._lookupModalPanel = null;
                }
                if (field._dropDownPanel != null) {
                    this.get_element().removeChild(field._dropDownPanel);
                    field._dropDownPanel = null;
                }
                if (field._calendarBehavior != null) {
                    field._calendarBehavior.dispose();
                    field._calendarBehavior = null;
                }
            }
    },
    
    _renderFieldHeaderText: function(sb, field) {
        field = this._allFields[field.AliasIndex];
        if (field.AllowSorting) {
            sb.append(String.format('<a href="#" onclick="$find(\'{0}\').sort(\'{1}\');return false" title="{3}">{2}</a>', 
                this.get_id(), field.Name, field.HeaderText, String.format(Web.DataViewResources.HeaderFilter.SortBy, field.HeaderText)));
            if (this.get_sortExpression() != null && this.get_sortExpression().startsWith(field.Name + " "))
                sb.append(this.get_sortExpression().endsWith(' asc') ? '<span class="SortUp">&nbsp;</span>' : '<span class="SortDown">&nbsp;</span>');
            if (this.filterOf(field) != null)
                sb.append('<span class="Filter">&nbsp;</span>');
        }
        else
            sb.append(field.HeaderText);
    },
    
    _renderActionBar: function(sb) {
        if (!this.get_showActionBar()) return;
        sb.append(String.format('<tr class="ActionRow"><td colspan="{0}"  class="ActionBar">', this._get_colSpan()));
        sb.append('<table style="width:100%" cellpadding="0" cellspacing="0"><tr><td style="width:100%">');
        var groups = this.get_actionGroups('ActionBar');
        if (groups.length == 0 || this.get_lookupField()) sb.append("&nbsp;");
        else {
            sb.append('<table cellpadding="0" cellspacing="0" class="Groups"><tr>');
            for (var i = 0; i < groups.length; i++) {
                if (i > 0)
                    sb.append('<td class="Divider"><div></div></td>');
                var group = groups[i];
                sb.append(String.format('<td class="Group"><a href="#" id="{0}_ActionBarGroup{1}" onclick="return false"><div>{2}<span>&nbsp;</span></div></a></td>', this.get_id(), i, group.HeaderText));
            }
            sb.append('</tr></table>');
        }
        sb.append('</td><td align="right">');
        sb.append(String.format('<table class="ViewSelector" cellpadding="0" cellspacing="0"><tr><td class="Label">{1}:</td><td class="Selector"><div id="{0}_ViewSelector" class="Name">Name</div></td></tr></table>', this.get_id(), Web.DataViewResources.ActionBar.View));
        sb.append('</td></tr></table>');
        sb.append('</td></tr>');
    },
    
    _renderViewDescription: function(sb) {
        if (this.get_view().HeaderText != null || this.get_lookupField()) {
            sb.append(String.format('<tr class="HeaderTextRow"><td colspan="{0}" class="HeaderText">', this._get_colSpan()));        
            if (this.get_lookupField() != null)
                sb.append('<table style="width:100%" cellpadding="0" cellspacing="0"><tr><td style="padding:0px">');
            sb.append(this.get_view().HeaderText);
            if (this.get_lookupField() != null)
                sb.append(String.format('</td><td align="right" style="padding:0px"><a href="#" class="Close" onclick="$find(\'{0}\').hideLookup();return false">{1}</a></td></tr></table>', this.get_id(), Web.DataViewResources.ModalPopup.Close));
            sb.append('</td></tr>');
        }
    },
    
    _renderInfoBar: function(sb) {
        if (this.get_filter().length > 0 && !this.filterIsExternal()) {
            sb.append(String.format('<tr class="InfoRow"><td colspan="{0}" id="{2}_InfoBar">', this._get_colSpan()));
            if (this.get_view().Type != "Form") this._renderFilterDetails(sb);
            sb.append('</td></tr>');
        }
    },
    
    _renderFilterDetails: function(sb) {
        sb.append(String.format('<span class="Information">&nbsp;</span>{0}', Web.DataViewResources.InfoBar.FilterApplied)); 
        for (var i = 0; i < this.get_filter().length; i++) {
            var filter = this.get_filter()[i].match(/(\w+):([\s\S]*)/);
            var field = this.findField(filter[1]);
            if (!field || this._fieldIsInExternalFilter(field)) continue;
            var aliasField = this._allFields[field.AliasIndex];
            sb.append(String.format(Web.DataViewResources.InfoBar.ValueIs, aliasField.HeaderText));
            var re = /(\*|\>={0,1}|\<={0,1}|=)([\s\S]*?)(\0|$)/g;
            var first = true;
            var fieldOperator = filter[2].match(">|<") ? Web.DataViewResources.InfoBar.And : Web.DataViewResources.InfoBar.Or;
            while ((info = re.exec(filter[2])) != null) {
                if (first) 
                    first = false;
                else
                    sb.append(fieldOperator);
                switch (info[1]) {
                    case '=':
                        sb.append(info[2] == 'null' ? Web.DataViewResources.InfoBar.Empty : Web.DataViewResources.InfoBar.EqualTo);
                        break;
                    case '<':
                        sb.append(Web.DataViewResources.InfoBar.LessThan);
                        break;
                    case '<=':
                        sb.append(Web.DataViewResources.InfoBar.LessThanOrEqualTo);
                        break;
                    case '>':
                        sb.append(Web.DataViewResources.InfoBar.GreaterThan);
                        break;
                    case '>=':
                        sb.append(Web.DataViewResources.InfoBar.GreaterThanOrEqual);
                        break;
                    case '*':
                        sb.append(info[2].startsWith('%') ? Web.DataViewResources.InfoBar.Like : Web.DataViewResources.InfoBar.StartsWith);
                        break;
                }
                var item = this._findItemByValue(field, info[2]);
                var v = item == null ? info[2] : item[1];
                if (info[2] != 'null') sb.append(String.format('<b>{0}</b>', Web.DataView.htmlEncode(v)));
            }
            sb.append('.');
        }
    },
    
    _renderFieldHeaderOptions: function(field, values) {
        field._adjustmentNeeded = true;
        var ascending = Web.DataViewResources.HeaderFilter.GenericSortAscending;
        var descending = Web.DataViewResources.HeaderFilter.GenericSortDescending;
        switch (field.Type) {  
            case 'String':
                ascending = Web.DataViewResources.HeaderFilter.StringSortAscending;
                descending = Web.DataViewResources.HeaderFilter.StringSortDescending;
                break;
            case 'DateTime':
                ascending = Web.DataViewResources.HeaderFilter.DateSortAscending;
                descending = Web.DataViewResources.HeaderFilter.DateSortDescending;
                break;
        }
        var sb = new Sys.StringBuilder();
        if (Web.DataView.isIE6) sb.append('<table cellpadding="0" cellspacing="0"><tr><td>');
        if (field.AllowSorting) 
            sb.append(String.format(
                '<a href="#" onclick="$find(\'{0}\').sort(\'{1} asc\');return false" class="ContextMenuItem SortAscending">{2}</a><a href="#" onclick="$find(\'{0}\').sort(\'{1} desc\');return false" class="ContextMenuItem SortDescending">{3}</a>',  
                this.get_id(), field.Name, ascending, descending));
        if (!values)
            values = field._listOfValues;
        if (field.AllowQBE)
            if (values) {
                var aliasField = this._allFields[field.AliasIndex];
                var fieldFilter = this.filterOf(field);
                fieldFilter = fieldFilter && fieldFilter.startsWith('=') ? fieldFilter.substr(1) : (fieldFilter ? '\0' : null);
                if (field.AllowSorting) sb.append('<div class="ContextMenuBreak"></div>');
                sb.append(String.format('<div id="Options"><a href="#" id="{0}_CustomFilterOption{1}" onclick="{3}if(!this.disabled)$find(\'{0}\').applyFilterByIndex({1},-1);return false" class="ContextMenuItem FilterOff{2} {2}" {3}>{4}&nbsp;</a><a href="#" onclick="$find(\'{0}\').showCustomFilter({1});return false" class="ContextMenuItem {6}">{5}</a>',
                    this.get_id(), field.AliasIndex, fieldFilter ? '' : 'Disabled', fieldFilter ? '' : 'return false;', String.format(Web.DataViewResources.HeaderFilter.ClearFilter, aliasField.HeaderText), Web.DataViewResources.HeaderFilter.CustomFilterOption, fieldFilter && fieldFilter.indexOf('\0') >= 0 ? 'Checked' : 'CustomFilter'));
                if (values.length > 0) sb.append('<div class="ContextMenuBreak"></div>');
                for (var i = 0; i < values.length; i++) {
                    var isSelected = false;
                    var v = values[i];
                    var text = v;
                    if (v == null)
                        text = Web.DataViewResources.HeaderFilter.EmptyValue;
                    else if (field.Items.length > 0) {
                        var item = this._findItemByValue(field, v);
                        text = item[1];
                    }
                    else {
                        if (field.Type == 'String' && v.length == 0)
                            text = Web.DataViewResources.HeaderFilter.BlankValue;
                        else if (field.DataFormatString != null && field.DataFormatString.length > 0)
                            text = String.localeFormat(field.DataFormatString, v);
                    }
                    v = v == null ? 'null' : this.convertFieldValueToString(field, v);
                    isSelected = v == fieldFilter;
                    if (text.length > Web.DataViewResources.HeaderFilter.MaxSampleTextLen) text = text.substring(0, Web.DataViewResources.HeaderFilter.MaxSampleTextLen) + '...';
                    sb.append(String.format('<a href="#" onclick="$find(\'{0}\').applyFilterByIndex({1},{2});return false" class="ContextMenuItem {4}">{3}</a>',
                        this.get_id(), field.AliasIndex, i, aliasField.Type == "String" && v != "null" ? Web.DataView.htmlEncode(text) : text, isSelected ? 'Checked' : ''));
                }
                sb.append('</div>');
            }
            else
                sb.append(String.format('<div class="Wait">{0}</div>', Web.DataViewResources.HeaderFilter.Loading));
        if (Web.DataView.isIE6) sb.append('</td></tr></table>');
        field._dropDownPanel.innerHTML = sb.toString();
    },
    
    _findItemByValue: function(field, value) {
        if (field.Items.length == 0) return null;
        value = value == null ? '' : value.toString();
        for (var i = 0; i < field.Items.length; i++) {
            var item = field.Items[i];
            var itemValue = item[0] == null ? "" : item[0].toString();
            if (itemValue == value)
                return item;
        }
        return [value, value];
    },
    
    _adjustFieldHeaderOptions: function(field) {
        var panel = field._dropDownPanel;
        if (field._listOfValues && field._adjustmentNeeded && field.AllowQBE) {
            var oldDisplay = panel.style.display
            panel.style.display = 'block';
            panel.style.width = '115px';
            field._adjustmentNeeded = false;
            var optionsDiv = $get('Options', panel);
            var needHeightAdjustment = optionsDiv.offsetHeight > 250
            var scrollBarWidth = needHeightAdjustment ? 20 : 0;
            optionsDiv.style.overflow = 'auto';
            var actualWidth = optionsDiv.scrollWidth;
            optionsDiv.style.overflow = '';
            if (panel.offsetWidth < actualWidth) {
                optionsDiv.style.width = (actualWidth + scrollBarWidth) + 'px';
                panel.style.width = (actualWidth + scrollBarWidth) + 'px';
            }
            var headerBounds = $common.getBounds(field._headerDropDownBehavior.get_element());
            var panelBounds = $common.getBounds(panel);
            var p = {x: headerBounds.x + headerBounds.width - panelBounds.width, y: panel.offsetTop};
            var b = $common.getBounds(this.get_element());
            if (p.x < 0) p.x = 0;
            Sys.UI.DomElement.setLocation(panel, p.x, panel.offsetTop);
            if (needHeightAdjustment) {
                var clientBounds = $common.getClientBounds();
                var optionsHeight = 250;
                var scrollTop = (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
                var optionsBounds = $common.getBounds(optionsDiv);
                if (optionsBounds.y + optionsHeight - scrollTop > clientBounds.height - 2)
                    optionsHeight = clientBounds.height - (optionsBounds.y - scrollTop) - 2;
                if (optionsHeight < 50) optionsHeight = 50;
                optionsDiv.style.height = optionsHeight + 'px';
                optionsDiv.style.overflow = 'auto';
            }
            panel.style.display = oldDisplay;
        }
    },
    
    _renderViewPager: function (sb) {
        sb.append(String.format('<tr class="FooterRow"><td colspan="{0}" class="Footer"><table cellpadding="0" cellspacing="0" style="width:100%"><tr><td align="left" class="Pager">', this._get_colSpan()));
        if (this.get_pageCount() > 1) {
            var buttonIndex = this._firstPageButtonIndex;
            var buttonCount = Web.DataViewResources.Pager.PageButtonCount;
            if (this.get_pageIndex() > 0)
                sb.append(String.format('<a href="#" onclick="$find(\'{1}\').goToPage({0});return false" class="PaddedLink">{2}</a>', this.get_pageIndex() - 1, this.get_id(), Web.DataViewResources.Pager.Previous));
            else
                sb.append(String.format('<span class="Disabled">{0}</span>', Web.DataViewResources.Pager.Previous));
            sb.append(String.format(' | {0}: ', Web.DataViewResources.Pager.Page));
            if (buttonIndex > 0)
                sb.append(String.format('<a href="#" onclick="$find(\'{1}\').goToPage({0});return false" class="PaddedLink">...</a>', buttonIndex - 1, this.get_id()));
            while (buttonCount > 0 && buttonIndex < this.get_pageCount()) {
                if (buttonIndex == this.get_pageIndex())
                    sb.append(String.format('<span class="Selected">{0}</span>', buttonIndex + 1));
                else
                    sb.append(String.format('<a href="#" onclick="$find(\'{1}\').goToPage({0});return false" class="PaddedLink">{2}</a>', buttonIndex, this.get_id(), buttonIndex + 1));
                buttonIndex++;
                buttonCount--;
            }
            if (buttonIndex <= this.get_pageCount() - 1)
                sb.append(String.format('<a href="#" onclick="$find(\'{1}\').goToPage({0});return false" class="PaddedLink">...</a>', this._firstPageButtonIndex + Web.DataViewResources.Pager.PageButtonCount, this.get_id()));
            sb.append(' | ');
            if (this.get_pageIndex() < this.get_pageCount() - 1)
                sb.append(String.format('<a href="#" onclick="$find(\'{1}\').goToPage({0});return false" class="PaddedLink">{2}</a>', this.get_pageIndex() + 1, this.get_id(), Web.DataViewResources.Pager.Next));
            else    
                sb.append(String.format('<span class="Disabled">{0}</span>', Web.DataViewResources.Pager.Next));
        }
        sb.append('</td><td align="right" class="Pager">&nbsp;');
        var pageSizes = Web.DataViewResources.Pager.PageSizes;
        if (this._totalRowCount > this.get_pageSize()) {
            sb.append(Web.DataViewResources.Pager.ItemsPerPage);
            for (i = 0; i < pageSizes.length; i++) {
                if (i > 0) sb.append(', ');
                if (this.get_pageSize() == pageSizes[i]) 
                    sb.append(String.format('<b>{0}</b>', this.get_pageSize()));
                else 
                    sb.append(String.format('<a href="#" onclick="$find(\'{0}\').set_pageSize({1});return false">{1}</a>', this.get_id(), pageSizes[i]));
            }
            sb.append(' | ');
        }
        if (this._totalRowCount > 0) {
            var lastVisibleItemIndex = (this.get_pageIndex() + 1) * this.get_pageSize();
            if (lastVisibleItemIndex > this._totalRowCount) lastVisibleItemIndex = this._totalRowCount;
            sb.append(String.format(Web.DataViewResources.Pager.ShowingItems, this.get_pageIndex() * this.get_pageSize() + 1, lastVisibleItemIndex, this._totalRowCount));
            sb.append(' | ');
        }
        sb.append(String.format('</td><td align="center" class="Pager" id="{0}_Wait" style="width:45px">', this.get_id()));
        sb.append(String.format('<a href="#" onclick="$find(\'{0}\').goToPage(-1);return false" class="PaddedLink">{1}</a>', this.get_id(), Web.DataViewResources.Pager.Refresh));
        sb.append('</td></tr></table>');
        sb.append('</td></tr>');
    },
    
    _loadPage: function() {
        this._delayedLoading = false;
        if (this.get_mode() != Web.DataViewMode.View) {
            this._allFields = [{Index: 0, Label: '', DataFormatString: '', AliasIndex: 0, ItemsDataController: this.get_controller(), ItemsNewDataView: this.get_newViewId(), _dataView: this}];
            this._fields = this._allFields;
            this._render();
        }
        else {
            this._busy(true);
            this._detachBehaviors();
            this._showWait();
            this._invoke('GetPage', {controller: this.get_controller(), view: this.get_viewId(), request: {PageIndex: this.get_pageIndex(), PageSize: this.get_pageSize(), SortExpression: this.get_sortExpression(), Filter: this.get_filter(), ContextKey: this.get_id(), Cookie: this.get_cookie(), FilterIsExternal: this._externalFilter.length > 0, RequiresMetaData: this._isInserting}}, 
                Function.createDelegate(this, this._onGetPageComplete));
        }
    },
    
    _invoke: function(methodName, params, onSuccess, userContext) {
        if (this.get_servicePath().startsWith('http')) {
            var m = this.get_servicePath().match(/(.+?)\w+\/\w+\.\w+(\?|$)/)
            var scriptParamId = String.format('__{0}_{1}_ScriptParam', this.get_id(), methodName);
            var scriptParam = $get(scriptParamId);
            var p = scriptParam ? scriptParam.value : Sys.Serialization.JavaScriptSerializer.serialize(params);
            if (scriptParam) scriptParam.value = '';
            var paramLength = p.length;
            while (p) {
                var src = String.format('{0}ScriptHost.ashx?sender={1}&method={2}&ctx={3}&args={4}&cookie={5}', m && m[1].startsWith('http') ? m[1]: '', this.get_id(), methodName, userContext, encodeURI(p), this.get_cookie());
                if (src.length <= 2048) {
                    if (scriptParam && scriptParam.value.length == 0) {
                        scriptParam.parentElement.removeChild(scriptParam);
                        scriptParam = null;
                    }
                    break;
                };
                if (!scriptParam) {
                    scriptParam = document.createElement('input');
                    scriptParam.setAttribute('type', 'hidden');
                    scriptParam.setAttribute('id', scriptParamId);
                    document.body.appendChild(scriptParam);
                }
                paramLength = Math.round(paramLength / 3 * 2);
                p = p + scriptParam.value; // reconstruct the serialized parameter
                scriptParam.value = p.substr(paramLength, p.length - paramLength);
                p = p.substr(0, paramLength)
            }
            var head = document.getElementsByTagName('head')[0];
            var script = document.createElement('script');
            script.setAttribute('id', String.format('__{0}_{1}_ScriptCallBack', this.get_id(), methodName));
            script.setAttribute('type', 'text/javascript');
            script.setAttribute('language', 'javascript');
            script.setAttribute('src', src + (scriptParam ? '&c=1' : ''));
            head.appendChild(script);
        }
        else 
            Sys.Net.WebServiceProxy.invoke(this.get_servicePath(), methodName, false, params, onSuccess, Function.createDelegate(this, this._onMethodFailed), userContext);
    },
    
    _onGetPageComplete: function(result, context) {
        this._busy(false);
        if (this._pageIndex < 0) {
            if (this._pageIndex == -1) {
                this._allFields = result.Fields;
                this._fields = [];
                this._keyFields = [];
                for (i = 0; i < result.Fields.length; i++) result.Fields[i].Index = i;
                for (i = 0; i < result.Fields.length; i++) {
                    field = result.Fields[i];
                    field.AliasIndex = field.AliasName && field.AliasName.length > 0 ? this.findField(field.AliasName).Index : i;
                    if (this._fieldIsInExternalFilter(field)) 
                        field.Hidden = true;
                }
                for (var i = 0; i < result.Fields.length; i++) {
                    var field = result.Fields[i];
                    field._dataView = this;
                    if (!field.Hidden) Array.add(this._fields, field);
                    if (field.IsPrimaryKey) Array.add(this._keyFields, field);
                    if (!field.HeaderText || field.HeaderText.length == 0) field.HeaderText = field.Label;
                    if (!field.HeaderText || field.HeaderText.length == 0) field.HeaderText = field.Name;
                    if (field.DataFormatString  && field.DataFormatString && field.DataFormatString.indexOf('{') == -1)
                        field.DataFormatString = '{0:' + field.DataFormatString + '}';
                    if (field.Type == 'DateTime' && !field.DataFormatString) field.DataFormatString = '{0:d}';
                    if (field.Type == 'Boolean' && field.Items.length == 0) {
                        field.Items = field.AllowNulls ? Web.DataViewResources.Data.BooleanOptionalDefaultItems : Web.DataViewResources.Data.BooleanDefaultItems ;
                        if (!field.ItemsStyle) field.ItemsStyle = Web.DataViewResources.Data.BooleanDefaultStyle;
                    }
                    if (field.Items && field.Items.length > 0 && field.AllowNulls && field.Items[0][0] != null)
                        Array.insert(field.Items, 0, [null, Web.DataViewResources.Data.NullValueInForms]);
                }
                this._views = result.Views;
                this._actionGroups = result.ActionGroups ? (result.ActionGroups.length == 0 ? Web.DataViewResources.Actions.DefaultGroups : result.ActionGroups) : [];
                for (i = 0; i < this._actionGroups.length; i++)
                    for (j = 0; j < this._actionGroups[i].Actions.length; j++) {
                        var action = this._actionGroups[i].Actions[j];
                        if (!action.HeaderText || action.HeaderText.length == 0)
                            action.HeaderText = action.CommandName;
                    }
                this._categories = result.Categories;
            }
            this._totalRowCount = result.TotalRowCount;
            this._filter = result.Filter;
            this._sortExpression = result.SortExpression;
            this._pageIndex = result.PageIndex;
            this._firstPageButtonIndex = Math.floor(result.PageIndex / Web.DataViewResources.Pager.PageButtonCount) * Web.DataViewResources.Pager.PageButtonCount;//result.PageIndex;
            this._pageSize = result.PageSize;
            this._pageCount = Math.floor(result.TotalRowCount / result.PageSize);
            if (result.TotalRowCount % result.PageSize != 0)
                this._pageCount++;
        }
        this._rows = result.Rows;
        if (this.get_view().Type == 'Form' && this._selectedRowIndex == null && this._totalRowCount > 0) {
            this._selectedRowIndex = 0;
            this._selectKeyByRowIndex(0);
        }
        this._render();
        this._adjustLookupSize();
    },
    
    _adjustLookupSize: function() {
        if (this.get_lookupField() && Web.DataView.isIE6) this.get_lookupField()._lookupModalBehavior._layout();;
        if (this.get_lookupField() && this.get_pageSize() > 3) {
            var scrollTop = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
            var clientBounds = $common.getClientBounds()
            var b = Sys.UI.DomElement.getBounds(this.get_element());
            if (b.height + b.y > clientBounds.height + scrollTop) this.set_pageSize(Math.ceil(this.get_pageSize() * 0.66));
        }
    },
    
    _onMethodFailed: function(err, response, context) {
        this._busy(false);
        alert(String.format('Timed out: {0}\rException: {1}\rMessage: {2}\rStack:\r{3}', err.get_timedOut(), err.get_exceptionType(), err.get_message(), err.get_stackTrace()));
    },
    
    _loadListOfValues: function(fieldName, distinctFieldName) {
        this._busy(true);
        this._invoke('GetListOfValues', {controller: this.get_controller(), view: this.get_viewId(), request: {FieldName:  distinctFieldName, Filter: this.get_filter().length == 1 && this.get_filter()[0].match(/(\w+):/)[1] == distinctFieldName ? null : this.get_filter()}},
            Function.createDelegate(this, this._onGetListOfValuesComplete), fieldName);
    },
    
    _onGetListOfValuesComplete: function(result, context) {
        this._busy(false);
        var field = this.findField(context);
        field._listOfValues = result;
        if (result[result.length - 1] == null) {
            Array.insert(result, 0, result[result.length - 1]);
            Array.removeAt(result, result.length - 1);
        }
        this._renderFieldHeaderOptions(field, result);
        this._adjustFieldHeaderOptions(field);
     },
     
     _execute: function(args) {
        this._busy(true);
        this._showWait();
        this._lastArgs = args;
        this._invoke('Execute', {controller: this.get_controller(), view: this.get_viewId(), args: args}, Function.createDelegate(this, this._onExecuteComplete));
     },
     
     _onExecuteComplete: function(result, context) {
        this._busy(false);
        this._hideWait();
        var ev = {'result': result, 'context': context, 'handled': false}
        this.raiseExecuted(ev);
        if (ev.handled) return;
        var existingRow = !this._lastArgs.CommandName.match(/Insert/i);
        if (existingRow) 
            for (var i = 0; i < result.Values.length; i++) {
                var v = result.Values[i];
                var field = this.findFind(v.Name);
                if (field) this.get_selectedRow()[field.Index] = v.NewValue;
            }
        else {
            this._selectedKey = [];
            this._selectedKeyFilter = [];
            if (result.Values.length == 0) result.Values = this._lastArgs.Values;
            for (i=0; i < this._keyFields.length; i++) {
                field = this._keyFields[i];
                v = null;
                for (var j = 0; j < result.Values.length; j++)
                    if (result.Values[j].Name == field.Name) {
                        v = result.Values[j];
                        break;
                    }
                Array.add(this._selectedKey, v ? v.NewValue : null);
                Array.add(this._selectedKeyFilter, field.Name + ':=' + this.convertFieldValueToString(field, v ? v.NewValue : null));
            }
            this.raiseSelected(Sys.EventArgs.Empty);
        }
        if (result.Errors.length == 0)
            if (result.ClientScript) {
                result.ClientScript = result.ClientScript.replace('~/', this.get_baseUrl());
                eval(result.ClientScript);
            }
            else if (result.NavigateUrl) {
                result.NavigateUrl = result.NavigateUrl.replace('~/', this.get_baseUrl());
                this.navigate(result.NavigateUrl, existingRow ? this._lastArgs.Values : result.Values);
            }
            else {
                this.set_lastCommandName(null);
                this.goToView(this._lastViewId);
            }
        else {
            var sb = new Sys.StringBuilder();
            for (i = 0; i < result.Errors.length; i++)
                sb.append(Web.DataView.formatMessage('Attention', result.Errors[i]));
            Web.DataView.showMessage(sb.toString());
        }
     },
     
     _busy: function(isBusy) {
        this._isBusy = isBusy;
        this._enableButtons(!isBusy);
     },
     
     _enableButtons: function(enable) {
        var buttons = document.getElementsByTagName('button');
        for (var i = 0; i < buttons.length; i++) {
            var button = buttons[i];
            if (button)
                if (!enable) {
                    button.WasDisabled = true;
                    button.disabled = true;
                }
                else if (button.WasDisabled) {
                    button.WasDisabled = false;
                    button.disabled = false;
                }
        }
     },
     
    _headerDropDownOnShowing: function (e, args) {
        var m = e.get_id().match(/_HeaderDropDown(\d+)/);
        var field = this.get_fields()[Number.parseInvariant(m[1])];
        this._renderFieldHeaderOptions(field);
        if (!field._listOfValues && field.AllowQBE)
            this._loadListOfValues(field.Name, this._allFields[field.AliasIndex].Name);
        else
            this._adjustFieldHeaderOptions(field);
    },
    
    _actionBarGroupOnShowing: function(e, args) {
        this._hidePopups();
    },
    
    _hidePopups: function() {
        var components = Sys.Application.getComponents();
        for (var i = 0; i < components.length; i++) {
            var c = components[i];
            if (AjaxControlToolkit.DropDownBehavior.isInstanceOfType(c)) {
                c.hide();
                c.unhover();
            }
            if (AjaxControlToolkit.PopupControlBehavior.isInstanceOfType(c)) 
                c.hidePopup();
       }
    },
    
    _bodyKeydown: function(e) {
        if (this._customFilterField) {
            if (e.keyCode == Sys.UI.Key.enter) this.applyCustomFilter();
            else if (e.keyCode == Sys.UI.Key.esc) this.closeCustomFilter();
        }
        else if (this.get_lookupField())
            if (e.keyCode == Sys.UI.Key.esc) this.hideLookup();
    },
    
    _filterSourceSelected: function(e) {
        for (var i = 0; i < this._externalFilter.length; i++) this._externalFilter[i].Value = null;
        if (Web.DataView.isInstanceOfType(e))
            this._populateExternalViewFilter(e);
        else if (this._externalFilter.length > 0)
            this._externalFilter[0].Value = e.target.value;
        this.applyExternalFilter();
        this.set_pageIndex(-1);
        //this._loadPage();
        this.loadPage();
        Array.clear(this._selectedKey);
        this.raiseSelected(Sys.EventArgs.Empty);
    },
    
    _createExternalFilter: function() {
        this._externalFilter = [];
        var iterator = /(\w+)(,|$)/g;
        var match = null;
        if (this.get_filterFields()) 
            while (match = iterator.exec(this.get_filterFields()))
                Array.add(this._externalFilter, {Name: match[1], Value: null});
    },
    
    _populateExternalViewFilter: function(view) {
        if (!(view._selectedKey && view._selectedKey.length == view._keyFields.length)) return;
        for (var i = 0; i < this._externalFilter.length; i++) {
            var filterItem = this._externalFilter[i];
            var found = false;
            for (var j = 0; j < view._keyFields.length; j++) {
                var field = view._keyFields[j];
                if (filterItem.Name == field.Name) {
                    filterItem.Value = view._selectedKey[j];
                    found = true;
                    break;
                }
            }
            if (!found && view._selectedKey.length >= i)
                filterItem.Value = view._selectedKey[i];
        }
    }
}

Web.DataView.registerClass('Web.DataView', Sys.UI.Behavior);

Web.DataView.hideMessage = function() {Web.DataView.showMessage()}

Web.DataView.formatMessage = function(type, message) {return String.format('<table cellpadding="0" cellspacing="0" style="width:100%"><tr><td class="{0}" valign="top">&nbsp;</td><td class="Message">{1}</td></tr></table>', type, message)}
     
Web.DataView.showMessage = function(message) {
    if (!message && !Web.DataView.MessageBar) return;
    var bodyTag = document.getElementsByTagName('body')[0];
    if (!Web.DataView.MessageBar) {
        var panel = document.createElement('div');
        panel.id = 'DataView_MessageBar';
        bodyTag.appendChild(panel);
        Sys.UI.DomElement.setVisible(panel, false);
        Sys.UI.DomElement.addCssClass(panel, 'MessageBar');
        Web.DataView.MessageBar = $create(AjaxControlToolkit.AlwaysVisibleControlBehavior, {VerticalOffset: AjaxControlToolkit.VerticalSide.Top}, null, null, panel);
        var b = Sys.UI.DomElement.getBounds(bodyTag);
        Web.DataView.OriginalBodyTopOffset = b.y;
    }
    panel = $get('DataView_MessageBar');
    panel.innerHTML = message ? message : '';
    Sys.UI.DomElement.setVisible(panel, message != null);
    var bound = Sys.UI.DomElement.getBounds(panel);
    bodyTag.style.marginTop = (message ? Web.DataView.OriginalBodyTopOffset + bound.height : Web.DataView.OriginalBodyTopOffset) + 'px'; 
}

Web.DataView._delayedLoadingViews = [];

Web.DataView._performDelayedLoading = function() {
    var i = 0;
    while (i < Web.DataView._delayedLoadingViews.length) {
        var v = Web.DataView._delayedLoadingViews[i];
        if (v.get_isDisplayed()) {
            Array.remove(Web.DataView._delayedLoadingViews, v);
            v._loadPage();
        }
        else i++;
    }
}

Web.DataView.find = function(id) {
    var id = '_' + id;
    var list = Sys.Application.getComponents();
    for (var i = 0; i < list.length; i++) {
        var c = list[i];
        if (Web.DataView.isInstanceOfType(c) && c.get_id().endsWith(id)) return c;
    }
    return null;
}

Sys.Application.add_load(function() { 
    if (Web.DataView._delayedLoadingViews.length > 0) 
        Web.DataView._delayedLoadingTimer = window.setInterval('Web.DataView._performDelayedLoading()', 1000);
});

Web.DataViewMode = { View: 'View', Lookup: 'Lookup' };

if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.
This is a Organisation

1 members

Comments and Discussions