Example #1
0
define("bui/extensions/search", ["jquery", "bui/common", "bui/form", "bui/overlay", "bui/list", "bui/data"], function(require, exports, module) {
  /**
   * @fileOverview
   * @ignore
   */
  var $ = require('jquery'),
    BUI = require("bui/common"),
    Form = require("bui/form");

  function Search(config) {
    Search.superclass.constructor.call(this, config);
  }
  BUI.extend(Search, BUI.Base);
  Search.ATTRS = {
    tpl: {
      value: '<p><input type="text" name="key"/> <button class="button button-small">确定</button></p>'
    }
  }
  BUI.augment(Search, {
    createDom: function(control) {
      var _self = this,
        el = $('<div></div>').append(_self.get('tpl')),
        group = new Form.Group({
          srcNode: el
        }).render();
      _self.set('el', el);
      _self.set('group', group);
    },
    renderUI: function(control) {
      var el = control.get('el');
      el.before(this.get('el'));
    },
    bindUI: function(control) {
      var _self = this,
        el = _self.get('el'),
        store = control.get('store'),
        group = _self.get('group');
      el.find('.button').on('click', function(ev) {
        store.load(group.getRecord());
      })
    }
  });
  module.exports = Search;
});
Example #2
0
File: swf.js Project: 858888/bui
define("bui/swf/swf", ["jquery", "bui/common", "bui/swf/ua/ua"], function(require, exports, module) {
  /**
   * @ignore
   * insert swf into document in an easy way
   * @author yiminghe@gmail.com, oicuicu@gmail.com
   */
  var $ = require("jquery"),
    BUI = require("bui/common"),
    FlashUA = require("bui/swf/ua/ua"),
    UA = BUI.UA,
    JSON = BUI.JSON,
    TYPE = 'application/x-shockwave-flash',
    CID = 'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000',
    FLASHVARS = 'flashvars',
    EMPTY = '',
    SPACE = ' ',
    EQUAL = '=',
    DOUBLE_QUOTE = '"',
    LT = '<',
    GT = '>',
    doc = document,
    fpv = FlashUA.fpv,
    fpvGEQ = FlashUA.fpvGEQ,
    fpvGTE = FlashUA.fpvGTE,
    OBJECT_TAG = 'object',
    EMBED_TAG = 'embed',
    encode = encodeURIComponent,
    // flash player 的参数范围
    PARAMS = {
      // swf 传入的第三方数据。支持复杂的 Object / XML 数据 / Json 字符串
      // flashvars: EMPTY,
      wmode: EMPTY,
      allowscriptaccess: EMPTY,
      allownetworking: EMPTY,
      allowfullscreen: EMPTY,
      // 显示 控制 删除
      play: 'false',
      loop: EMPTY,
      menu: EMPTY,
      quality: EMPTY,
      scale: EMPTY,
      salign: EMPTY,
      bgcolor: EMPTY,
      devicefont: EMPTY,
      hasPriority: EMPTY,
      //	其他控制参数
      base: EMPTY,
      swliveconnect: EMPTY,
      seamlesstabbing: EMPTY
    };
  var SWF = function(config) {
      SWF.superclass.constructor.call(this, config);
      this.initializer();
    }
    /**
     * insert a new swf into container
     * @class KISSY.SWF
     * @extends KISSY.Base
     */
  BUI.extend(SWF, BUI.Base, {
    initializer: function() {
      var self = this;
      var expressInstall = self.get('expressInstall'),
        swf,
        html,
        id,
        htmlMode = self.get('htmlMode'),
        flashVars,
        params = self.get('params'),
        attrs = self.get('attrs'),
        doc = self.get('document'),
        placeHolder = $('<span>'),
        elBefore = self.get('elBefore'),
        installedSrc = self.get('src'),
        version = self.get('version');
      id = attrs.id = attrs.id || BUI.guid('bui-swf-');
      // 2. flash 插件没有安装
      if (!fpv()) {
        self.set('status', SWF.Status.NOT_INSTALLED);
        return;
      }
      // 3. 已安装,但当前客户端版本低于指定版本时
      if (version && !fpvGTE(version)) {
        self.set('status', SWF.Status.TOO_LOW);
        // 有 expressInstall 时,将 src 替换为快速安装
        if (expressInstall) {
          installedSrc = expressInstall;
          // from swfobject
          if (!('width' in attrs) || (!/%$/.test(attrs.width) && parseInt(attrs.width, 10) < 310)) {
            attrs.width = "310";
          }
          if (!('height' in attrs) || (!/%$/.test(attrs.height) && parseInt(attrs.height, 10) < 137)) {
            attrs.height = "137";
          }
          flashVars = params.flashVars = params.flashVars || {};
          // location.toString() crash ie6
          BUI.mix(flashVars, {
            MMredirectURL: location.href,
            MMplayerType: UA.ie ? "ActiveX" : "PlugIn",
            MMdoctitle: doc.title.slice(0, 47) + " - Flash Player Installation"
          });
        }
      }
      if (htmlMode == 'full') {
        html = _stringSWFFull(installedSrc, attrs, params)
      } else {
        html = _stringSWFDefault(installedSrc, attrs, params)
      }
      // ie 再取  target.innerHTML 属性大写,很多多与属性,等
      self.set('html', html);
      if (elBefore) {
        placeHolder.insertBefore(elBefore);
      } else {
        placeHolder.appendTo(self.get('render'));
      }
      if ('outerHTML' in placeHolder[0]) {
        placeHolder[0].outerHTML = html;
      } else {
        placeHolder.replaceWith($(html));
      }
      swf = doc.getElementById(id);
      self.set('swfObject', swf);
      if (htmlMode == 'full') {
        if (UA.ie) {
          self.set('swfObject', swf);
        } else {
          self.set('swfObject', swf.parentNode);
        }
      }
      // bug fix: 重新获取对象,否则还是老对象.
      // 如 入口为 div 如果不重新获取则仍然是 div	longzang | 2010/8/9
      self.set('el', swf);
      if (!self.get('status')) {
        self.set('status', SWF.Status.SUCCESS);
      }
    },
    /**
     * Calls a specific function exposed by the SWF 's ExternalInterface.
     * @param func {String} the name of the function to call
     * @param args {Array} the set of arguments to pass to the function.
     */
    callSWF: function(func, args) {
      var swf = this.get('el'),
        ret,
        params;
      args = args || [];
      try {
        if (swf[func]) {
          ret = swf[func].apply(swf, args);
        }
      } catch (e) {
        // some version flash function is odd in ie: property or method not supported by object
        params = "";
        if (args.length !== 0) {
          params = "'" + args.join("', '") + "'";
        }
        //avoid eval for compression
        ret = (new Function('swf', 'return swf.' + func + '(' + params + ');'))(swf);
      }
      return ret;
    },
    /**
     * remove its container and swf element from dom
     */
    destroy: function() {
      var self = this;
      // self.detach();
      var swfObject = self.get('swfObject');
      /* Cross-browser SWF removal
         - Especially needed to safely and completely remove a SWF in Internet Explorer
         */
      if (UA.ie) {
        swfObject.style.display = 'none';
        // from swfobject
        (function() {
          if (swfObject.readyState == 4) {
            removeObjectInIE(swfObject);
          } else {
            setTimeout(arguments.callee, 10);
          }
        })();
      } else {
        swfObject.parentNode.removeChild(swfObject);
      }
    }
  }, {
    ATTRS: {
      /**
       * express install swf url.
       * Defaults to: swfobject 's express install
       * @cfg {String} expressInstall
       */
      /**
       * @ignore
       */
      expressInstall: {
        //value: S.config('base') + 'swf/assets/expressInstall.swf'
      },
      /**
       * new swf 's url
       * @cfg {String} src
       */
      /**
       * @ignore
       */
      src: {},
      /**
       * minimum flash version required. eg: "10.1.250"
       * Defaults to "9".
       * @cfg {String} version
       */
      /**
       * @ignore
       */
      version: {
        value: "9"
      },
      /**
       * params for swf element
       *  - params.flashVars
       * @cfg {Object} params
       */
      /**
       * @ignore
       */
      params: {
        value: {},
        shared: false
      },
      /**
       * attrs for swf element
       * @cfg {Object} attrs
       */
      /**
       * @ignore
       */
      attrs: {
        value: {},
        shared: false
      },
      /**
       * container where flash will be appended.
       * Defaults to: body
       * @cfg {HTMLElement} render
       */
      /**
       * @ignore
       */
      render: {
        setter: function(v) {
          if (typeof v == 'string') {
            v = $(v)[0];
          }
          return v;
        },
        valueFn: function() {
          return document.body;
        }
      },
      /**
       * element where flash will be inserted before.
       * @cfg {HTMLElement} elBefore
       */
      /**
       * @ignore
       */
      elBefore: {
        setter: function(v) {
          if (typeof v == 'string') {
            v = $(v)[0];
          }
          return v;
        }
      },
      /**
       * html document current swf belongs.
       * Defaults to: current document
       * @cfg {HTMLElement} document
       */
      /**
       * @ignore
       */
      document: {
        value: doc
      },
      /**
       * status of current swf
       * @property status
       * @type {KISSY.SWF.Status}
       * @readonly
       */
      /**
       * @ignore
       */
      status: {},
      /**
       * swf element
       * @readonly
       * @type {HTMLElement}
       * @property el
       */
      /**
       * @ignore
       */
      el: {},
      /**
       * @ignore
       * @private
       */
      swfObject: {},
      /**
       * swf element 's outerHTML
       * @property html
       * @type {String}
       * @readonly
       */
      /**
       * @ignore
       */
      html: {},
      /**
       *  full or default(depends on browser object)
       *  @cfg {KISSY.SWF.HtmlMode} htmlMode
       */
      /**
       * @ignore
       */
      htmlMode: {
        value: 'default'
      }
    },
    /**
     * get src from existing oo/oe/o/e swf element
     * @param {HTMLElement} swf
     * @returns {String}
     * @static
     */
    getSrc: function(swf) {
      //swf = $(swf)[0];
      var srcElement = getSrcElements(swf)[0],
        src,
        nodeName = srcElement && srcElement.nodeName.toLowerCase();
      if (nodeName == 'embed') {
        return $(srcElement).attr('src');
      } else if (nodeName == 'object') {
        return $(srcElement).attr('data');
      } else if (nodeName == 'param') {
        return $(srcElement).attr('value');
      }
      return null;
    },
    /**
     * swf status
     * @enum {String} KISSY.SWF.Status
     */
    Status: {
      /**
       * flash version is too low
       */
      TOO_LOW: 'flash version is too low',
      /**
       * flash is not installed
       */
      NOT_INSTALLED: 'flash is not installed',
      /**
       * success
       */
      SUCCESS: 'success'
    },
    /**
     * swf htmlMode
     * @enum {String} KISSY.SWF.HtmlMode
     */
    HtmlMode: {
      /**
       * generate object structure depending on browser
       */
      DEFAULT: 'default',
      /**
       * generate object/object structure
       */
      FULL: 'full'
    },
    fpv: fpv,
    fpvGEQ: fpvGEQ,
    fpvGTE: fpvGTE
  });

  function removeObjectInIE(obj) {
    for (var i in obj) {
      if (typeof obj[i] == "function") {
        obj[i] = null;
      }
    }
    obj.parentNode.removeChild(obj);
  }

  function getSrcElements(swf) {
    var url = "",
      params, i, param,
      elements = [],
      nodeName = swf.nodeName.toLowerCase();
    if (nodeName == "object") {
      url = $(swf).attr("data");
      if (url) {
        elements.push(swf);
      }
      params = swf.childNodes;
      for (i = 0; i < params.length; i++) {
        param = params[i];
        if (param.nodeType == 1) {
          if (($(param).attr("name") || "").toLowerCase() == "movie") {
            elements.push(param);
          } else if (param.nodeName.toLowerCase() == "embed") {
            elements.push(param);
          } else if (param.nodeName.toLowerCase() == "object") {
            elements.push(param);
          }
        }
      }
    } else if (nodeName == "embed") {
      elements.push(swf);
    }
    return elements;
  }
  // setSrc ie 不重新渲染
  function collectionParams(params) {
    var par = EMPTY;
    BUI.each(params, function(v, k) {
      k = k.toLowerCase();
      if (k in PARAMS) {
        par += stringParam(k, v);
      }
      // 特殊参数
      else if (k == FLASHVARS) {
        par += stringParam(k, toFlashVars(v));
      }
    });
    return par;
  }

  function _stringSWFDefault(src, attrs, params) {
    return _stringSWF(src, attrs, params, UA.ie) + LT + '/' + OBJECT_TAG + GT;
  }

  function _stringSWF(src, attrs, params, ie) {
    var res,
      attr = EMPTY,
      par = EMPTY;
    if (ie == undefined) {
      ie = UA.ie;
    }
    if (ie) {
      // 普通属性
      BUI.each(attrs, function(v, k) {
        attr += stringAttr(k, v);
      });
      attr += stringAttr('classid', CID);
      par += stringParam('movie', src);
      par += collectionParams(params);
      res = LT + OBJECT_TAG + attr + GT + par;
    } else {
      // 源
      attr += stringAttr('src', src);
      BUI.each(attrs, function(v, k) {
        attr += stringAttr(k, v);
      });
      // 源
      attr += stringAttr('data', src);
      // 特殊属性
      attr += stringAttr('type', TYPE);
      // 参数属性
      for (k in params) {
        if (k in PARAMS) par += stringAttr(k, params[k]);
      }
      // 特殊参数
      if (params[FLASHVARS]) par += stringAttr(FLASHVARS, toFlashVars(params[FLASHVARS]));
      res = LT + EMBED_TAG + attr + par + '/' + GT;
    }
    return res
  }

  function _stringEmbed(src, attrs, params, ie) {
    var res,
      attr = EMPTY,
      par = EMPTY;
    return res;
  }
  // full oo 结构
  function _stringSWFFull(src, attrs, params) {
    var outside, inside;
    if (UA.ie) {
      outside = _stringSWF(src, attrs, params, 1);
      delete attrs.id;
      delete attrs.style;
      inside = _stringSWF(src, attrs, params, 0);
    } else {
      inside = _stringSWF(src, attrs, params, 0);
      delete attrs.id;
      delete attrs.style;
      outside = _stringSWF(src, attrs, params, 1);
    }
    return outside + inside + LT + '/' + OBJECT_TAG + GT + LT + '/' + OBJECT_TAG + GT;
  }
  /*
 将普通对象转换为 flashvars
 eg: {a: 1, b: { x: 2, z: 's=1&c=2' }} => a=1&b=encode({"x":2,"z":"s%3D1%26c%3D2"})
 */
  function toFlashVars(obj) {
    var arr = [],
      ret;
    BUI.each(obj, function(data, prop) {
      if (typeof data != 'string') {
        data = JSON.stringify(data);
      }
      if (data) {
        arr.push(prop + '=' + encode(data));
      }
    });
    ret = arr.join('&');
    return ret;
  }

  function stringParam(key, value) {
    return '<param name="' + key + '" value="' + value + '"></param>';
  }

  function stringAttr(key, value) {
    return SPACE + key + EQUAL + DOUBLE_QUOTE + value + DOUBLE_QUOTE;
  }
  return SWF;
  /**
   * NOTES:
   * 20130903 从kissy1.3.1移植成BUI的模块(索丘修改)
   */
});
Example #3
0
define('bui/data/treestore',['bui/common','bui/data/node','bui/data/abstractstore','bui/data/proxy'],function (require) {

  var BUI = require('bui/common'),
    Node = require('bui/data/node'),
    Proxy = require('bui/data/proxy'),
    AbstractStore = require('bui/data/abstractstore');

  //构建树结构
  function processData(data,pidField){

    BUI.each(data,function(obj){
      if(!obj.children){
        var id = obj.id,
          children = BUI.Array.filter(data,function(item){
          return item[pidField] == id;
        });

        if(children.length){
          obj.children = children;
          obj.leaf = false;
        }else{
          obj.leaf = true;
        }
      }
    });
  }

  /**
   * @class BUI.Data.TreeStore
   * 树形数据缓冲类
   * <p>
   * <img src="../assets/img/class-data.jpg"/>
   * </p>
   * <pre><code>
   *   //加载静态数据
   *   var store = new TreeStore({
   *     root : {
   *       text : '根节点',
   *       id : 'root'
   *     },
   *     data : [{id : '1',text : 1},{id : '2',text : 2}] //会加载成root的children
   *   });
   *   //异步加载数据,自动加载数据时,会调用store.load({id : 'root'}); //root为根节点的id
   *   var store = new TreeStore({
   *     root : {
   *       text : '根节点',
   *       id : 'root'
   *     },
   *     url : 'data/nodes.php',
   *     autoLoad : true  //设置自动加载,初始化后自动加载数据
   *   });
   *
   *   //加载指定节点
   *   var node = store.findNode('1');
   *   store.loadNode(node);
   *   //或者
   *   store.load({id : '1'});//可以配置自定义参数,返回值附加到指定id的节点上
   * </code></pre>
   * @extends BUI.Data.AbstractStore
   */
  function TreeStore(config){
    TreeStore.superclass.constructor.call(this,config);
  }

  TreeStore.ATTRS = {
    /**
     * 根节点
     * <pre><code>
     *  var store = new TreeStore({
     *    root : {text : '根节点',id : 'rootId',children : [{id : '1',text : '1'}]}
     *  });
     * </code></pre>
     * @cfg {Object} root
     */
    /**
     * 根节点,初始化后不要更改对象,可以更改属性值
     * <pre><code>
     *  var root = store.get('root');
     *  root.text = '修改的文本';
     *  store.update(root);
     * </code></pre>
     * @type {Object}
     * @readOnly
     */
    root : {

    },
    /**
     * 数据映射,用于设置的数据跟@see {BUI.Data.Node} 不一致时,进行匹配。
     * 如果此属性为null,那么假设设置的对象是Node对象
     * <pre><code>
     *   //例如原始数据为 {name : '123',value : '文本123',isLeaf: false,nodes : []}
     *   var store = new TreeStore({
     *     map : {
     *       'name' : 'id',
     *       'value' : 'text',
     *       'isLeaf' : 'leaf' ,
     *       'nodes' : 'children'
     *     }
     *   });
     *   //映射后,记录会变成  {id : '123',text : '文本123',leaf: false,children : []};
     *   //此时原始记录会作为对象的 record属性
     *   var node = store.findNode('123'),
     *     record = node.record;
     * </code></pre> 
     * **Notes:**
     * 使用数据映射的记录仅做于展示数据,不作为可更改的数据,add,update不会更改数据的原始数据
     * @cfg {Object} map
     */
    map : {

    },
    /**
     * 标示父元素id的字段名称
     * @type {String}
     */
    pidField : {
      
    },
    /**
     * 返回数据标示数据的字段<br/>
     * 异步加载数据时,返回数据可以使数组或者对象
     * - 如果返回的是对象,可以附加其他信息,那么取对象对应的字段 {nodes : [],hasError:false}
     * - 如何获取附加信息参看 @see {BUI.Data.AbstractStore-event-beforeprocessload}
     * <pre><code>
     *  //返回数据为数组 [{},{}],会直接附加到加载的节点后面
     *  
     *  var node = store.loadNode('123');
     *  store.loadNode(node);
     *  
     * </code></pre>
     * @cfg {Object} [dataProperty = 'nodes']
     */
    dataProperty : {
      value : 'nodes'
    },

    /**
     * 本地数据源
     * @type {Array}
     */
    data : {
      setter : function(data){
        var _self = this,
          proxy = _self.get('proxy'),
          pidField = _self.get('pidField');
        
        if(proxy.set){
          proxy.set('data',data);
          if(pidField){
            processData(data,pidField);
          }
        }else{
          proxy.data = data;
        }
        //设置本地数据时,把autoLoad置为true
        _self.set('autoLoad',true);
      }
    },
    events : {
      value : [
        /**  
        * 当添加数据时触发该事件
        * @event  
        * <pre><code>
        *  store.on('add',function(ev){
        *    list.addItem(e.node,index);
        *  });
        * </code></pre>
        * @param {jQuery.Event} e  事件对象
        * @param {Object} e.node 添加的节点
        * @param {Number} index 添加的位置
        */
        'add',
        /**  
        * 当更新数据指定字段时触发该事件 
        * @event  
        * @param {jQuery.Event} e  事件对象
        * @param {Object} e.node 更新的节点
        */
        'update',
        /**  
        * 当删除数据时触发该事件
        * @event  
        * @param {jQuery.Event} e  事件对象
        * @param {Object} e.node 删除的节点
        * @param {Number} index 删除节点的索引
        */
        'remove',
        /**  
        * 节点加载完毕触发该事件
        * <pre><code>
        *   //异步加载节点,此时节点已经附加到加载节点的后面
        *   store.on('load',function(ev){
        *     var params = ev.params,
        *       id = params.id,
        *       node = store.findNode(id),
        *       children = node.children;  //节点的id
        *     //TO DO
        *   });
        * </code></pre>
        * 
        * @event  
        * @param {jQuery.Event} e  事件对象
        * @param {Object} e.node 加载的节点
        * @param {Object} e.params 加载节点时的参数
        */
        'load'
      ]
    }
  }

  BUI.extend(TreeStore,AbstractStore);

  BUI.augment(TreeStore,{
    /**
     * @protected
     * @override
     * 初始化前
     */
    beforeInit:function(){
      this.initRoot();
    },
    //初始化数据,如果默认加载数据,则加载数据
    _initData : function(){
      var _self = this,
        autoLoad = _self.get('autoLoad'),
        pidField = _self.get('pidField'),
        proxy = _self.get('proxy'),
        data = _self.get('data'),
        root = _self.get('root');

      //添加默认的匹配父元素的字段
      if(!proxy.get('url') && pidField){
        proxy.get('matchFields').push(pidField);
      }

      if(pidField && data && data.length){
        processData(data,pidField);
      }
      if(autoLoad && !root.children){
        _self.loadNode(root);
      }
    },
    /**
     * @protected
     * 初始化根节点
     */
    initRoot : function(){
      var _self = this,
        map = _self.get('map'),
        root = _self.get('root');
      if(!root){
        root = {};
      }
      if(!root.isNode){
        root = new Node(root,map);
        //root.children= [];
      }
      root.path = [root.id];
      root.level = 0;
      if(root.children){
        _self.setChildren(root,root.children);
      }
      _self.set('root',root);
    },
    /**
     * 添加节点,触发{@link BUI.Data.TreeStore#event-add} 事件
     * <pre><code>
     *  //添加到根节点下
     *  store.add({id : '1',text : '1'});
     *  //添加到指定节点
     *  var node = store.findNode('1'),
     *    subNode = store.add({id : '11',text : '11'},node);
     *  //插入到节点的指定位置
     *  var node = store.findNode('1'),
     *    subNode = store.add({id : '12',text : '12'},node,0);
     * </code></pre>
     * @param {BUI.Data.Node|Object} node 节点或者数据对象
     * @param {BUI.Data.Node} [parent] 父节点,如果未指定则为根节点
     * @param {Number} [index] 添加节点的位置
     * @return {BUI.Data.Node} 添加完成的节点
     */
    add : function(node,parent,index){
      var _self = this;

      node = _self._add(node,parent,index);
      _self.fire('add',{node : node,record : node,index : index});
      return node;
    },
    //
    _add : function(node,parent,index){
      parent = parent || this.get('root');  //如果未指定父元素,添加到跟节点
      var _self = this,
        map = _self.get('map'),
        nodes = parent.children,
        nodeChildren;

      if(!node.isNode){
        node = new Node(node,map);
      }

      nodeChildren = node.children || []

      if(nodeChildren.length == 0 && node.leaf == null){
        node.leaf = true;
      }
      if(parent){
        parent.leaf = false;
      }
      
      node.parent = parent;
      node.level = parent.level + 1;
      node.path = parent.path.concat(node.id);
      index = index == null ? parent.children.length : index;
      BUI.Array.addAt(nodes,node,index);

      _self.setChildren(node,nodeChildren);
      return node;
    },
    /**
     * 移除节点,触发{@link BUI.Data.TreeStore#event-remove} 事件
     * 
     * <pre><code>
     *  var node = store.findNode('1'); //根据节点id 获取节点
     *  store.remove(node);
     * </code></pre>
     * 
     * @param {BUI.Data.Node} node 节点或者数据对象
     * @return {BUI.Data.Node} 删除的节点
     */
    remove : function(node){
      var parent = node.parent || _self.get('root'),
        index = BUI.Array.indexOf(node,parent.children) ;

      BUI.Array.remove(parent.children,node);
      if(parent.children.length === 0){
        parent.leaf = true;
      }
      this.fire('remove',{node : node ,record : node , index : index});
      node.parent = null;
      return node;
    },
    /**
    * 设置记录的值 ,触发 update 事件
    * <pre><code>
    *  store.setValue(obj,'value','new value');
    * </code></pre>
    * @param {Object} obj 修改的记录
    * @param {String} field 修改的字段名
    * @param {Object} value 修改的值
    */
    setValue : function(node,field,value){
      var 
        _self = this;
        node[field] = value;

      _self.fire('update',{node:node,record : node,field:field,value:value});
    },
    /**
     * 更新节点
     * <pre><code>
     *  var node = store.findNode('1'); //根据节点id 获取节点
     *  node.text = 'modify text'; //修改文本
     *  store.update(node);        //此时会触发update事件,绑定了store的控件会更新对应的DOM
     * </code></pre>
     * @return {BUI.Data.Node} 更新节点
     */
    update : function(node){
      this.fire('update',{node : node,record : node});
    },
    /**
     * 返回缓存的数据,根节点的直接子节点集合
     * <pre><code>
     *   //获取根节点的所有子节点
     *   var data = store.getResult();
     *   //获取根节点
     *   var root = store.get('root');
     * </code></pre>
     * @return {Array} 根节点下面的数据
     */
    getResult : function(){
      return this.get('root').children;
    },
    /**
     * 设置缓存的数据,设置为根节点的数据
    *   <pre><code>
    *     var data = [
    *       {id : '1',text : '文本1'},
    *       {id : '2',text : '文本2',children:[
    *         {id : '21',text : '文本21'}
    *       ]},
    *       {id : '3',text : '文本3'}
    *     ];
    *     store.setResult(data); //会对数据进行格式化,添加leaf等字段:
    *                            //[{id : '1',text : '文本1',leaf : true},{id : '2',text : '文本2',leaf : false,children:[...]}....]
    *   </code></pre>
     * @param {Array} data 缓存的数据
     */
    setResult : function(data){
      var _self = this,
        proxy = _self.get('proxy'),
        root = _self.get('root');
      if(proxy instanceof Proxy.Memery){
        _self.set('data',data);
        _self.load({id : root.id});
      }else{
        _self.setChildren(root,data);
      }
    },
    /**
     * 设置子节点
     * @protected
     * @param {BUI.Data.Node} node  节点
     * @param {Array} children 子节点
     */
    setChildren : function(node,children){
      var _self = this;
      node.children = [];
      if(!children.length){
        return;
      }
      BUI.each(children,function(item){
        _self._add(item,node);
      });
    },
    /**
     * 查找节点
     * <pre><code>
     *  var node = store.findNode('1');//从根节点开始查找节点
     *  
     *  var subNode = store.findNode('123',node); //从指定节点开始查找
     * </code></pre>
     * @param  {String} id 节点Id
     * @param  {BUI.Data.Node} [parent] 父节点
     * @param {Boolean} [deep = true] 是否递归查找
     * @return {BUI.Data.Node} 节点
     */
    findNode : function(id,parent,deep){
      return this.findNodeBy(function(node){
        return node.id === id;
      },parent,deep);
    },
    /**
     * 根据匹配函数查找节点
     * @param  {Function} fn  匹配函数
     * @param  {BUI.Data.Node} [parent] 父节点
     * @param {Boolean} [deep = true] 是否递归查找
     * @return {BUI.Data.Node} 节点
     */
    findNodeBy : function(fn,parent,deep){
      var _self = this;
      deep = deep == null ? true : deep;
      if(!parent){
        var root = _self.get('root');
        if(fn(root)){
          return root;
        }
        return _self.findNodeBy(fn,root);
      }
      var children = parent.children,
        rst = null;
      BUI.each(children,function(item){
        if(fn(item)){
          rst = item;
        }else if(deep){
          rst = _self.findNodeBy(fn,item);
        }
        if(rst){
          return false;
        }
      });
      return rst;
    },
    /**
     * 查找节点,根据匹配函数查找
     * <pre><code>
     *  var nodes = store.findNodesBy(function(node){
     *   if(node.status == '0'){
     *     return true;
     *   }
     *   return false;
     *  });
     * </code></pre>
     * @param  {Function} func 匹配函数
     * @param  {BUI.Data.Node} [parent] 父元素,如果不存在,则从根节点查找
     * @return {Array} 节点数组
     */
    findNodesBy : function(func,parent){
      var _self = this,
        root,
        rst = [];

      if(!parent){
        parent = _self.get('root');
      }

      BUI.each(parent.children,function(item){
        if(func(item)){
          rst.push(item);
        }
        rst = rst.concat(_self.findNodesBy(func,item));
      });

      return rst;
    },
    /**
     * 根据path查找节点
     * @return {BUI.Data.Node} 节点
     * @ignore
     */
    findNodeByPath : function(path){
      if(!path){
        return null;
      }
      var _self = this,
        root = _self.get('root'),
        pathArr = path.split(','),
        node,
        i,
        tempId = pathArr[0];
      if(!tempId){
        return null;
      }
      if(root.id == tempId){
        node = root;
      }else{
        node = _self.findNode(tempId,root,false);
      }
      if(!node){
        return;
      }
      for(i = 1 ; i < pathArr.length ; i = i + 1){
        var tempId = pathArr[i];
        node = _self.findNode(tempId,node,false);
        if(!node){
          break;
        }
      }
      return node;
    },
    /**
     * 是否包含指定节点,如果未指定父节点,从根节点开始搜索
     * <pre><code>
     *  store.contains(node); //是否存在节点
     *
     *  store.contains(subNode,node); //节点是否存在指定子节点
     * </code></pre>
     * @param  {BUI.Data.Node} node 节点
     * @param  {BUI.Data.Node} parent 父节点
     * @return {Boolean} 是否包含指定节点
     */
    contains : function(node,parent){
      var _self = this,
        findNode = _self.findNode(node.id,parent);
      return !!findNode;
    },
    /**
     * 加载完数据
     * @protected
     * @override
     */
    afterProcessLoad : function(data,params){
      var _self = this,
        pidField = _self.get('pidField'),
        id = params.id || params[pidField],
        dataProperty = _self.get('dataProperty'),
        node = _self.findNode(id) || _self.get('root');//如果找不到父元素,则放置在跟节点

      if(BUI.isArray(data)){
        _self.setChildren(node,data);
      }else{
        _self.setChildren(node,data[dataProperty]);
      }
      node.loaded = true; //标识已经加载过
      _self.fire('load',{node : node,params : params});
    },
    /**
     * 是否包含数据
     * @return {Boolean} 
     */
    hasData : function(){
      //return true;
      return this.get('root').children && this.get('root').children.length !== 0;
    },
    /**
     * 是否已经加载过,叶子节点或者存在字节点的节点
     * @param   {BUI.Data.Node} node 节点
     * @return {Boolean}  是否加载过
     */
    isLoaded : function(node){
      var root = this.get('root');
      if(node == root && !root.children){
        return false;
      }
      if(!this.get('url') && !this.get('pidField')){ //如果不从远程加载数据,默认已经加载
        return true;
      }
      
      return node.loaded || node.leaf || !!(node.children && node.children.length);
    },
    /**
     * 加载节点的子节点
     * @param  {BUI.Data.Node} node 节点
     * @param {Boolean} forceLoad 是否强迫重新加载节点,如果设置成true,不判断是否加载过
     */
    loadNode : function(node,forceLoad){
      var _self = this,
        pidField = _self.get('pidField'),
        params;
      //如果已经加载过,或者节点是叶子节点
      if(!forceLoad && _self.isLoaded(node)){
        return ;
      }
      params = {id : node.id};
      if(pidField){
        params[pidField] = node.id;
      }
      _self.load(params);  
    },
    /**
     * 重新加载节点
     * @param  {BUI.Data.Node} node node节点
     */
    reloadNode : function(node){
      var _self = this;
      node = node || _self.get('root');
      node.loaded = false;
      //node.children = [];
      _self.loadNode(node,true);
    },
    /**
     * 加载节点,根据path
     * @param  {String} path 加载路径
     * @ignore
     */
    loadPath : function(path){
      var _self = this,
        arr = path.split(','),
        id = arr[0];
      if(_self.findNodeByPath(path)){ //加载过
        return;
      }
      _self.load({id : id,path : path});
    }
  });

  return TreeStore;

});
Example #4
0
define('common/search',['bui/common','bui/grid','bui/form','bui/data','bui/overlay'],function (require) {
  var BUI = require('bui/common'),
    Grid = require('bui/grid'),
    Data = require('bui/data'),
    Overlay = require('bui/overlay'),
    Form = require('bui/form');

  /**
   * @class Search
   * 鎼灭储椤电被
   */
  function Search(config){

    Search.superclass.constructor.call(this, config);
    this._init();
  }

  Search.ATTRS = {
    /**
     * 鏄惁镊姩镆ヨ锛屾墦寮€椤甸溃镞舵湭镣瑰向镆ヨ鎸夐挳镞舵槸鍚﹁嚜锷ㄦ煡璇?
     * @type {Boolean}
     */
    autoSearch :{
      value : true
    },
    /**
     * grid 瀹瑰櫒镄?id
     * @type {String}
     */
    gridId : {
      value : 'grid'
    },
    /**
     * 琛ㄥ崟镄勫鍣ㄧ殑id
     * @type {String}
     */
    formId : {
      value : 'searchForm'
    },
    /**
     * 镆ヨ鎸夐挳镄刬d
     * @type {Object}
     */
    btnId : {
      value : 'btnSearch'
    },
    /**
     * 琛ㄥ崟镄勯厤缃」
     * @type {Object}
     */
    formCfg : {
      value : {}
    },
    /**
     * grid 琛ㄦ牸镄勯厤缃」
     * @type {Object}
     */
    gridCfg : {

    },
    /**
     * 琛ㄥ崟瀵硅薄
     * @type {Object}
     */
    form : {

    },
    /**
     * 琛ㄦ牸瀵硅薄
     * @type {Object}
     */
    grid : {

    },
    /**
     * 鏁版嵁缂揿啿绫?
     * @type {Object}
     */
    store : {

    }
  }

  BUI.extend(Search,BUI.Base);

  BUI.augment(Search,{
    _init : function(){
      var _self = this;

      _self._initForm();
      _self._initStoreEvent();
      _self._initGrid();
      _self._initEvent();
      _self._initData();
    },
    //鍒濆鍖栦簨浠?
    _initEvent : function(){
      this._initDomEvent();
      this._initFormEvent();
      this._initGridEvent();
    },
    _initDomEvent : function(){
      var _self = this,
        btnId = _self.get('btnId'),
        store = _self.get('store'),
        form = _self.get('form');
      $('#'+btnId).on('click',function(ev){
        ev.preventDefault();
        form.valid();
        if(form.isValid()){
          _self.load(true);
        }
      });
    },
    //鍒濆鍖杅orm
    _initForm : function(){
      var _self = this,
        form = _self.get('form');
      if(!form){
        var formCfg = BUI.merge(_self.get('formCfg'),{
          srcNode : '#' + _self.get('formId')
        });
        form = new Form.HForm(formCfg);
        form.render();
        _self.set('form',form);
      }
    },
    _initFormEvent : function(){

    },
    //鍒濆鍖栬〃镙?
    _initGrid : function(){
      var _self = this,
        grid = _self.get('grid');
      if(!grid){
        var gridCfg = _self.get('gridCfg'),
          store = _self.get('store');
        gridCfg.store = store;
        gridCfg.render = '#' +_self.get('gridId'),
        grid = new Grid.Grid(gridCfg);
        grid.render();
        _self.set('grid',grid);
      }
    },
    _initGridEvent : function(){

    },
    _initData : function(){
      var _self = this,
        autoSearch = _self.get('autoSearch');
      if(autoSearch){
        _self.load(true);
      }
    },
    //鍒濆鍖栨暟鎹姞杞戒簨浠?
    _initStoreEvent : function(){
      var _self = this,
        store = _self.get('store');
      //澶勭悊寮傚父
      store.on('exception',function(ev){
        BUI.Message.Alert(ev.error);
      });
    },
    /**
     * 锷犺浇鏁版嵁
     * @param {Boolean} reset 鏄惁閲岖疆琛ㄦ牸镆ヨ镄勯〉鏁?
     */
    load : function(reset){
      var _self =this,
        form = _self.get('form'),
        store = _self.get('store'),
        param = form.serializeToObject();
      if(reset){
        param.start=0;
        param.pageIndex = 0;
      }
      store.load(param);
    }
  });

  Search.createStore = function(url,cfg){

    cfg = BUI.merge({
      autoLoad : false,
      url : url,
      pageSize : 30
    },cfg);
    return new Data.Store(cfg);
  };

  Search.createGridCfg = function(columns,cfg){
    cfg = BUI.merge({
      columns : columns,
      loadMask : true,
      bbar:{
        pagingBar:true
      }
    },cfg);
    
    return cfg;
  };

  Search.createLink = function(cfg){
    var temp = '<span class="page-action grid-command" data-id="{id}" data-href="{href}" title="{title}">{text}</span>';
    return BUI.substitute(temp,cfg);
  }
  return Search;
});
Example #5
0
File: data.js Project: haodw/bui
define('bui/data/abstractstore',['bui/common','bui/data/proxy'],function (require) {
  var BUI = require('bui/common'),
    Proxy = require('bui/data/proxy');

  /**
   * @class BUI.Data.AbstractStore
   * 数据缓冲抽象类
   * @extends BUI.Base
   */
  function AbstractStore(config){
    AbstractStore.superclass.constructor.call(this,config);
    this._init();
  }

  AbstractStore.ATTRS = {
    /**
    * 创建对象时是否自动加载
    * @cfg {Boolean} [autoLoad=false]
    */
    /**
    * 创建对象时是否自动加载
    * @type {Boolean}
    * @default false
    */
    autoLoad: {
      value :false 
    },
    /**
     * 上次查询的参数
     * @type {Object}
     * @readOnly
     */
    lastParams : {
      value : {}
    },
    /**
     * 初始化时查询的参数,在初始化时有效
     * @cfg {Object} params
     */
    params : {

    },
    /**
     * 数据代理对象
     * @type {Object|BUI.Data.Proxy}
     * @protected
     */
    proxy : {
      value : {
        
      }
    },
    /**
     * 请求数据的地址,通过ajax加载数据,
     * 此参数设置则加载远程数据
     * 否则把 {BUI.Data.Store#cfg-data}作为本地缓存数据加载
     * @cfg {String} url
     */
    /**
     * @ignore
     */
    url : {

    },
    events : {
      value : [
        /**  
        * 数据接受改变,所有增加、删除、修改的数据记录清空
        * @name BUI.Data.Store#acceptchanges
        * @event  
        */
        'acceptchanges',
        /**  
        * 当数据加载完成后
        * @name BUI.Data.Store#load  
        * @event  
        * @param {jQuery.Event} e  事件对象,包含加载数据时的参数
        */
        'load',

        /**  
        * 当数据加载前
        * @name BUI.Data.Store#beforeload
        * @event  
        */
        'beforeload',

        /**  
        * 发生在,beforeload和load中间,数据已经获取完成,但是还未触发load事件,用于获取返回的原始数据
        * @name BUI.Data.Store#beforeProcessLoad
        * @event  
        * @param {jQuery.Event} e  事件对象
        * @param {Object} e.data 从服务器端返回的数据
        */
        'beforeProcessLoad',
        
        /**  
        * 当添加数据时触发该事件
        * @event  
        * @param {jQuery.Event} e  事件对象
        * @param {Object} e.record 添加的数据
        */
        'add',

        /**
        * 加载数据发生异常时触发
        * @event
        * @name BUI.Data.Store#exception
        * @param {jQuery.Event} e 事件对象
        * @param {String|Object} e.error 加载数据时返回的错误信息或者加载数据失败,浏览器返回的信息(httpResponse 对象 的textStatus)
        * @param {String} e.responseText 网络或者浏览器加载数据发生错误是返回的httpResponse 对象的responseText
        */
        'exception',

        /**  
        * 当删除数据是触发该事件
        * @event  
        * @param {jQuery.Event} e  事件对象
        * @param {Object} e.data 删除的数据
        */
        'remove',
        
        /**  
        * 当更新数据指定字段时触发该事件 
        * @event  
        * @param {jQuery.Event} e  事件对象
        * @param {Object} e.record 更新的数据
        * @param {Object} e.field 更新的字段
        * @param {Object} e.value 更新的值
        */
        'update',

        /**  
        * 前端发生排序时触发
        * @name BUI.Data.Store#localsort
        * @event  
        * @param {jQuery.Event} e  事件对象
        * @param {Object} e.field 排序的字段
        * @param {Object} e.direction 排序的方向 'ASC','DESC'
        */
        'localsort'
      ]
    },
    /**
     * 本地数据源,使用本地数据源时会使用{@link BUI.Data.Proxy.Memery}
     * @cfg {Array} data
     */
    /**
     * 本地数据源
     * @type {Array}
     */
    data : {
      setter : function(data){
        var _self = this,
          proxy = _self.get('proxy');
        if(proxy.set){
          proxy.set('data',data);
        }else{
          proxy.data = data;
        }
        //设置本地数据时,把autoLoad置为true
        _self.set('autoLoad',true);
      }
    }
  };

  BUI.extend(AbstractStore,BUI.Base);

  BUI.augment(AbstractStore,{
    /**
     * 是否是数据缓冲对象,用于判断对象
     * @type {Boolean}
     */
    isStore : true,
    /**
     * @private
     * 初始化
     */
    _init : function(){
      var _self = this;

      _self.beforeInit();
      //初始化结果集
      _self._initParams();
      _self._initProxy();
      _self._initData();
    },
    /**
     * @protected
     * 初始化之前
     */
    beforeInit : function(){

    },
    //初始化数据,如果默认加载数据,则加载数据
    _initData : function(){
      var _self = this,
        autoLoad = _self.get('autoLoad');

      if(autoLoad){
        _self.load();
      }
    },
    //初始化查询参数
    _initParams : function(){
      var _self = this,
        lastParams = _self.get('lastParams'),
        params = _self.get('params');

      //初始化 参数
      BUI.mix(lastParams,params);
    },
    /**
     * @protected
     * 初始化数据代理类
     */
    _initProxy : function(){
      var _self = this,
        url = _self.get('url'),
        proxy = _self.get('proxy');

      if(!(proxy instanceof Proxy)){

        if(url){
          proxy.url = url;
        }

        //异步请求的代理类
        if(proxy.type === 'ajax' || proxy.url){
          proxy = new Proxy.Ajax(proxy);
        }else{
          proxy = new Proxy.Memery(proxy);
        }

        _self.set('proxy',proxy);
      }
    },
    /**
     * 加载数据
     * @param  {Object} params 参数键值对
     */
    load : function(params){
      var _self = this,
        proxy = _self.get('proxy'),
        lastParams = _self.get('lastParams');

      BUI.mix(true,lastParams,_self.getAppendParams(),params);

      _self.fire('beforeload',{params:lastParams});

      //防止异步请求未结束,又发送新请求回调参数错误
      params = BUI.cloneObject(lastParams);
      proxy.read(lastParams,function(data){
        _self.onLoad(data,params);
      },_self);
    },
    /**
     * 加载完数据
     * @template
     */
    onLoad : function(data,params){
      var _self = this;

      var processResult = _self.processLoad(data,params);
      //如果处理成功,返回错误时,不进行后面的处理
      if(processResult){
        _self.afterProcessLoad(data,params);
      }
    },
    /**
     * @private
     * 加载完数据处理数据
     */
    processLoad : function(data,params){
      var _self = this,
        hasErrorField = _self.get('hasErrorProperty');
      //获取的原始数据
      _self.fire('beforeProcessLoad',data);

      if(data[hasErrorField] || data.exception){
        _self.onException(data);
        return false;
      }
      return true;
    },
    /**
     * @protected
     * @template
     * 处理数据后
     */
    afterProcessLoad : function(data,params){

    },
    /**
     * @protected
     * 处理错误函数
     * @param  {*} data 出错对象
     */
    onException : function(data){
      var _self = this,
        errorProperty = _self.get('errorProperty'),
        obj = {};
      //网络异常、转码错误之类,发生在json获取或转变时
      if(data.exception){
        obj.type = 'exception';
        obj[errorProperty] = data.exception;
      }else{//用户定义的错误
        obj.type = 'error';
        obj[errorProperty] = data[errorProperty];
      }
      _self.fire('exception',obj);

    },
    /**
     * 是否包含数据
     * @return {Boolean} 
     */
    hasData : function(){

    },
    /**
     * 获取附加的参数
     * @template
     * @protected
     * @return {Object} 附加的参数
     */
    getAppendParams : function(){
      return {};
    }
  });

  return AbstractStore;
});/**
Example #6
0
File: data.js Project: haodw/bui
define('bui/data/store',['bui/data/proxy','bui/data/abstractstore','bui/data/sortable'],function(require) {
  
  var Proxy = require('bui/data/proxy'),
    AbstractStore = require('bui/data/abstractstore'),
    Sortable = require('bui/data/sortable');

  //移除数据
  function removeAt(index,array){
    if(index < 0){
      return;
    }
    var records = array,
      record = records[index];
    records.splice(index,1);
    return record;
  }

  function removeFrom(record,array){
    var index = BUI.Array.indexOf(record,array);   
    if(index >= 0){
      removeAt(index,array);
    }
  }

  function contains(record,array){
    return BUI.Array.indexOf(record,array) !== -1;
  }
  /**
   * 用于加载数据,缓冲数据的类
   * <p>
   * <img src="../assets/img/class-data.jpg"/>
   * </p>
   * @class BUI.Data.Store
   * @extends BUI.Data.AbstractStore
   * @mixins BUI.Data.Sortable
   */
  var store = function(config){
    store.superclass.constructor.call(this,config);
    //this._init();
  };

  store.ATTRS = 
  /**
   * @lends BUI.Data.Store#
   * @ignore
   */
  {
    /**
     * 当前页码
     * @cfg {Number} [currentPage=0]
     */
    /**
     * 当前页码
     * @type {Number}
     * @default 0
     */
    currentPage:{
      value : 0
    },
    
    /**
     * 删除掉的纪录
     * @readOnly
     * @type {Array}
     */
    deletedRecords : {
      value:[]
    },
    /**
     * 错误字段,包含在返回信息中表示错误信息的字段
     * @cfg {String} [errorProperty='error']
     */
    /**
     * 错误字段
     * @type {String}
     * @default 'error'
     */
    errorProperty : {
      value : 'error'
    },
    /**
     * 是否存在错误,加载数据时如果返回错误,此字段表示有错误发生
     * @cfg {String} [hasErrorProperty='hasError']
     */
    /**
     * 是否存在错误
     * @type {String}
     * @default 'hasError'
     */
    hasErrorProperty : {
      value : 'hasError'
    },

    /**
     * 对比2个对象是否相当,在去重、更新、删除,查找数据时使用此函数
     * @default  
     * function(obj1,obj2){
     *   return obj1 == obj2;
     * }
     * @type {Object}
     * @example
     * function(obj1 ,obj2){
     *   //如果id相等,就认为2个数据相等,可以在添加对象时去重
     *   //更新对象时,仅提供改变的字段
     *   return obj1.id == obj2.id;
     * }
     * 
     */
    matchFunction : {
      value : function(obj1,obj2){
        return obj1 == obj2;
      }
    },
    /**
     * 更改的纪录集合
     * @type {Array}
     * @readOnly
     */
    modifiedRecords : {
      value:[]
    },
    /**
     * 新添加的纪录集合,只读
     * @type {Array}
     * @readOnly
     */
    newRecords : {
      value : []
    },
    /**
     * 是否远程排序,由于当前Store存储的不一定是数据源的全集,所以此配置项需要重新读取数据
     * 在分页状态下,进行远程排序,会进行全集数据的排序,并返回首页的数据
     * remoteSort为 false的情况下,仅对当前页的数据进行排序
     * @cfg {Boolean} [remoteSort=false]
     */
    /**
     * 是否远程排序,由于当前Store存储的不一定是数据源的全集,所以此配置项需要重新读取数据
     * 在分页状态下,进行远程排序,会进行全集数据的排序,并返回首页的数据
     * remoteSort为 false的情况下,仅对当前页的数据进行排序
     * @type {Boolean}
     * @default false
     */
    remoteSort : {
      value : false
    },
    /**
     * 缓存的数据,包含以下几个字段
     * <ol>
     * <li>rows: 数据集合</li>
     * <li>results: 总的数据条数</li>
     * </ol>
     * @type {Object}
     * @protected
     * @readOnly
     */
    resultMap : {
      value : {}
    },
    /**
    * 加载数据时,返回数据的根目录
    * @cfg {String} [root='rows']
    *   '{"rows":[{"name":"abc"},{"name":"bcd"}],"results":100}'
    */
    /**
    * 加载数据时,返回数据的根目录
    * @field
    * @type {String}
    * @default  "rows"
    *   '{"rows":[{"name":"abc"},{"name":"bcd"}],"results":100}'
    */
    root: { value : 'rows'}, 

    /**
     * 当前Store缓存的数据条数
     * @type {Number}
     * @readOnly
     */
    rowCount :{
      value : 0
    },
    /**
    * 加载数据时,返回记录的总数的字段,用于分页
    * @cfg {String} [totalProperty='results']
    *
    *   '{"rows":[{"name":"abc"},{"name":"bcd"}],"results":100}'
    */
    /**
    * 加载数据时,返回记录的总数的字段,用于分页
    * @field
    * @type {String}
    * @default  "results"
    *
    *   '{"rows":[{"name":"abc"},{"name":"bcd"}],"results":100}'
    */
    totalProperty: {value :'results'}, 

    /**
     * 加载数据的起始位置
     * @type {Object}
     */
    start:{
      value : 0
    },
    /**
     * 每页多少条记录,默认为null,此时不分页,当指定了此值时分页
     * @cfg {Number} pageSize
     */
    /**
     * 每页多少条记录,默认为null,此时不分页,当指定了此值时分页
     * @type {Number}
     */
    pageSize : {

    }
  };
  BUI.extend(store,AbstractStore);

  BUI.mixin(store,[Sortable]);

  BUI.augment(store,
  /**
   * @lends BUI.Data.Store.prototype
   * @ignore
   */
  {
    /**
    * 添加记录,默认添加在后面
    * @param {Array|Object} data 添加的数据,可以是数组,可以是单条记录
    * @param {Boolean} [noRepeat = false] 是否去重,可以为空,默认: false 
    * @param {Function} [match] 匹配函数,可以为空,
    * @default 配置项中 matchFunction 属性传入的函数,默认是:<br>
    *  function(obj1,obj2){
    *    return obj1 == obj2;
    *  }
    * 
    */
    add :function(data,noRepeat,match){
      var _self = this,
        count = _self.getCount();
      _self.addAt(data,count,noRepeat,match)
    },
    /**
    * 添加记录,指定索引值
    * @param {Array|Object} data 添加的数据,可以是数组,可以是单条记录
    * @param {Number} index 开始添加数据的位置
    * @param {Boolean} [noRepeat = false] 是否去重,可以为空,默认: false 
    * @param {Function} [match] 匹配函数,可以为空,
     */
    addAt : function(data,index,noRepeat,match){
      var _self = this;

      match = match || _self._getDefaultMatch();
      if(!BUI.isArray(data)){
        data = [data];
      }

      $.each(data,function(pos,element){
        if(!noRepeat || !_self.contains(element,match)){
          _self._addRecord(element,pos + index);

          _self.get('newRecords').push(element);

          removeFrom(element,_self.get('deletedRecords'));
          removeFrom(element,_self.get('modifiedRecords'));
        }
      });
    },
    /**
    * 验证是否存在指定记录
    * @param {Object} record 指定的记录
    * @param {Function} [match = function(obj1,obj2){return obj1 == obj2}] 默认为比较2个对象是否相同
    * @return {Boolean}
    */
    contains :function(record,match){
      return this.findIndexBy(record,match)!==-1;
    },
    /**
    * 查找记录,仅返回第一条
    * @param {String} field 字段名
    * @param {String} value 字段值
    * @return {Object|null}
    */
    find : function(field,value){
      var _self = this,
        result = null,
        records = _self.getResult();
      $.each(records,function(index,record){
        if(record[field] === value){
          result = record;
          return false;
        }
      });
      return result;
    },
    /**
    * 查找记录,返回所有符合查询条件的记录
    * @param {String} field 字段名
    * @param {String} value 字段值
    * @return {Array}
    */
    findAll : function(field,value){
      var _self = this,
        result = [],
        records = _self.getResult();
      $.each(records,function(index,record){
        if(record[field] === value){
          result.push(record);
        }
      });
      return result;
    },
    /**
    * 根据索引查找记录
    * @param {Number} index 索引
    * @return {Object} 查找的记录
    */
    findByIndex : function(index){
      return this.getResult()[index];
    },
    /**
    * 查找数据所在的索引位置,若不存在返回-1
    * @param {Object} target 指定的记录
    * @param {Function} [match = matchFunction] @see {BUI.Data.Store#matchFunction}默认为比较2个对象是否相同
    * @return {Number}
    */
    findIndexBy :function(target,match){
      var _self = this,
        position = -1,
        records = _self.getResult();
      match = match || _self._getDefaultMatch();
      if(target === null || target === undefined){
        return -1;
      }
      $.each(records,function(index,record){
        if(match(target,record)){
          position = index;
          return false;
        }
      });
      return position;
    },
    /**
    * 获取下一条记录
    * @param {Object} record 当前记录
    * @return {Object} 下一条记录
    */
    findNextRecord : function(record){
      var _self = this,
        index = _self.findIndexBy(record);
      if(index >= 0){
        return _self.findByIndex(index + 1);
      }
      return;
    },
    /**
     * 获取缓存的记录数
     * @return {Number} 记录数
     */
    getCount : function(){
      return this.getResult().length;
    },
    /**
     * 获取数据源的数据总数,分页时,当前仅缓存当前页数据
     * @return {Number} 记录的总数
     */
    getTotalCount : function(){
      var _self = this,
        resultMap = _self.get('resultMap'),
        total = _self.get('totalProperty');
      return resultMap[total] || 0;
    },
    /**
     * 获取当前缓存的纪录
     * @return {Array} 纪录集合
     */
    getResult : function(){
      var _self = this,
        resultMap = _self.get('resultMap'),
        root = _self.get('root');
      return resultMap[root];
    },
    /**
     * 是否包含数据
     * @return {Boolean} 
     */
    hasData : function(){
      return this.getCount() !== 0;
    },
    /**
     * 设置数据源
     */
    setResult : function(data){
      var _self = this,
        proxy = _self.get('proxy');
      if(proxy instanceof Proxy.Memery){
        _self.set('data',data);
        _self.load({start:0});
      }else{
        _self._setResult(data);
      }
    },

    /**
    * 删除记录触发 remove 事件.
    * @param {Array|Object} data 添加的数据,可以是数组,可以是单条记录
    * @param {Function} [match = function(obj1,obj2){return obj1 == obj2}] 匹配函数,可以为空
    */
    remove :function(data,match){
      var _self =this,
        delData=[];
      match = match || _self._getDefaultMatch();
      if(!BUI.isArray(data)){
        data = [data];
      }
      $.each(data,function(index,element){
        var index = _self.findIndexBy(element,match),
            record = removeAt(index,_self.getResult());
        //添加到已删除队列中,如果是新添加的数据,不计入删除的数据集合中
        if(!contains(record,_self.get('newRecords')) && !contains(record,_self.get('deletedRecords'))){
          _self.get('deletedRecords').push(record);
        }
        removeFrom(record,_self.get('newRecords'));
        removeFrom(record,_self.get('modifiedRecords'));
        _self.fire('remove',{record:record});
      }); 
    },
    /**
     * 排序
     * @param  {String} field     排序字段
     * @param  {String} direction 排序方向
     */
    sort : function(field,direction){
      var _self = this,
        remoteSort = _self.get('remoteSort');

      if(!remoteSort){
        _self._localSort(field,direction);
      }else{
        _self.set('sortField',field);
        _self.set('sortDirection',direction);
        _self.load(_self.get('sortInfo'));
      }
    },
    /**
     * 计算指定字段的和
     * @param  {String} field 字段名
     * @param  {Array} [data] 计算的集合,默认为Store中的数据集合
     * @return {Number} 汇总和
     */
    sum : function(field,data){
      var  _self = this,
        records = data || _self.getResult(),
        sum = 0;
      BUI.each(records,function(record){
        var val = record[field];
        if(!isNaN(val)){
          sum += parseFloat(val);
        }
      });
      return sum;
    },
    /**
    * 设置记录的值 ,触发 update 事件
    * @param {Object} obj 修改的记录
    * @param {String} field 修改的字段名
    * @param {Object} value 修改的值
    */
    setValue : function(obj,field,value){
      var record = obj,
        _self = this;

      record[field]=value;
      if(!contains(record,_self.get('newRecords')) && !contains(record,_self.get('modifiedRecords'))){
          _self.get('modifiedRecords').push(record);
      }
      _self.fire('update',{record:record,field:field,value:value});
    },
    /**
    * 更新记录 ,触发 update事件
    * @param {Object} obj 修改的记录
    * @param {Boolean} [isMatch = false] 是否需要进行匹配,检测指定的记录是否在集合中
    */
    update : function(obj,isMatch){
      var record = obj,
        _self = this,
        match = null,
        index = null;
      if(isMatch){
        match = _self._getDefaultMatch();
        index = _self.findIndexBy(obj,match);
        if(index >=0){
          record = _self.getResult()[index];
        }
      }
      record = BUI.mix(record,obj);
      if(!contains(record,_self.get('newRecords')) && !contains(record,_self.get('modifiedRecords'))){
          _self.get('modifiedRecords').push(record);
      }
      _self.fire('update',{record:record});
    },
    //添加纪录
    _addRecord :function(record,index){
      var records = this.getResult();
      if(index == undefined){
        index = records.length;
      }
      records.splice(index,0,record);
      this.fire('add',{record:record,index:index});
    },
    //清除改变的数据记录
    _clearChanges : function(){
      var _self = this;
      _self.get('newRecords').splice(0);
      _self.get('modifiedRecords').splice(0);
      _self.get('deletedRecords').splice(0);
    },
    //获取默认的匹配函数
    _getDefaultMatch :function(){

      return this.get('matchFunction');
    },

    //获取分页相关的信息
    _getPageParams : function(){
      var _self = this,
        sortInfo = _self.get('sortInfo'),
        params = {
          start : _self.get('start'),
          limit : _self.get('pageSize'),
          pageIndex : _self.get('pageIndex') //一般而言,pageIndex = start/limit
        };

      if(_self.get('remoteSort')){
        BUI.mix(params,sortInfo);
      }

      return params;
    },
     /**
     * 获取附加的参数,分页信息,排序信息
     * @override
     * @protected
     * @return {Object} 附加的参数
     */
    getAppendParams : function(){
      return this._getPageParams();
    },
    /**
     * @protected
     * 初始化之前
     */
    beforeInit : function(){
      //初始化结果集
      this._setResult([]);
    },
    //本地排序
    _localSort : function(field,direction){
      var _self = this;

      _self._sortData(field,direction);

      _self.fire('localsort');
    },
    _sortData : function(field,direction,data){
      var _self = this;
      data = data || _self.getResult();

      _self.sortData(field,direction,data);
    },
    //处理数据
    afterProcessLoad : function(data,params){
      var _self = this,
        root = _self.get('root'),
        start = params.start,
        limit = params.limit,
        totalProperty = _self.get('totalProperty');

      if(BUI.isArray(data)){
        _self._setResult(data);
      }else{
        _self._setResult(data[root],data[totalProperty]);
      }

      _self.set('start',start);

      if(limit){
        _self.set('pageIndex',start/limit);
      }

      //如果本地排序,则排序
      if(!_self.get('remoteSort')){
        _self._sortData();
      }

      _self.fire('load',{ params : params });
    },
    //设置结果集
    _setResult : function(rows,totalCount){
      var _self = this,
        resultMap = _self.get('resultMap');

      totalCount = totalCount || rows.length;
      resultMap[_self.get('root')] = rows;
      resultMap[_self.get('totalProperty')] = totalCount;

      //清理之前发生的改变
      _self._clearChanges();
    }
  });

  return store;
});
Example #7
0
File: border.js Project: 2zyun/bui
define('bui/layout/borderitem',['bui/common','bui/layout/baseitem'],function (require) {
	var BUI = require('bui/common'),
		Base = require('bui/layout/baseitem'),
		CLS_COLLAPSED = 'x-collapsed',
		REGINS = {
			NORTH : 'north',
			EAST : 'east',
			SOUTH : 'south',
			WEST : 'west',
			CENTER : 'center'
		};
		

	/**
	 * 边框布局选项
	 * @class BUI.Layout.Item.Border
	 * @extends BUI.Layout.Item
	 */
	var Border = function(config){
		Border.superclass.constructor.call(this,config);
	};

	Border.ATTRS = {

		/**
		 * 位置
		 *<ol>
     * <li>fit: 'none', 内部控件不跟随布局项的宽高自适应</li>
     * <li>fit: 'width',内部控件跟随布局项的宽度进行自适应</li>
     * <li>fit: 'height',内部控件跟随布局项的高度进行自适应</li>
     * <li>fit: 'both',内部控件跟随布局项的宽度、高度都进行自适应</li>
     *</ol>
		 * @cfg {String} region
		 */
		region : {

		},
		/**
		 * 标题的模板
		 * <pre><code>
		 * 	children : [{
					layout : {
						title : 'north',
						region : 'north',
						height : 50,
						titleTpl : '&lt;div class="x-border-title x-border-title-{region}">{title}&lt;/div>'
					},
					width : 100,
					height :15,
					elCls : 'red',
					xclass : 'grid',
					content : "无自适应"
				}]
		 * </code></pre>
		 * @cfg {Object} titleTpl
		 */
		titleTpl : {
			value : '<div class="x-border-title x-border-title-{region}">{title}</div>'
		},
		/**
		 * 收缩展开的dom的模板
		 * <pre><code>
		 * 	children : [{
					layout : {
						title : 'north',
						region : 'north',
						height : 50,
						collapsable : true,//只有callapsable:true,collapseTpl才会生效
						collapseTpl : '&lt;s class="x-collapsed-btn x-collapsed-{region}">&lt;/s>'
					},
					width : 100,
					height :15,
					elCls : 'red',
					xclass : 'grid',
					content : "无自适应"
				}]
		 * </code></pre>
		 * @cfg {Object} collapseTpl
		 */
		collapseTpl : {
			value : '<s class="x-collapsed-btn x-collapsed-{region}"></s>'
		},
		/**
		 * 是否可以折叠
		 *  <pre><code>
		 * 	children : [{
					layout : {
						title : 'north',
						region : 'north',
						height : 50,
						collapsable : true
					},
					width : 100,
					height :15,
					elCls : 'red',
					xclass : 'grid',
					content : "无自适应"
				}]
		 * </code></pre>
		 * @cfg {Boolean} collapsable
		 */
		collapsable : {
			value : false
		},
		/**
		 * 是否默认折叠
		 * @cfg {Boolean} collapsed
		 */
		/**
		 * 是否折叠
		 * @type {Boolean}
		 */
		collapsed : {
			value : false
		},
		/**
		 * 收缩后剩余的宽度或者高度,如果存在title,则以title的高度为准
		 * @cfg {Number} leftRange
		 */
		leftRange : {
			value : 28
		},
		/**
		 * 附加模板
		 * @type {Object}
		 */
		tplProperties : {
			value : [
				{name : 'title',value : 'titleTpl',prev : true},
				{name : 'collapsable',value : 'collapseTpl',prev : true}
			]
		},
		statusProperties : {
			value : ['collapsed']
		}
	};

	Border.REGINS = REGINS;

	BUI.extend(Border,Base);

	BUI.augment(Border,{
		/**
		 * 根据属性附加一些元素
		 * @protected
		 */
		syncElements : function(el,attrs){
			Border.superclass.syncElements.call(this,el,attrs);
			var _self = this,
				el = _self.get('el'),
				property = _self.getCollapseProperty();
			if(_self.get('collapsed') && _self.get(property) == el[property]()){
				_self.collapse(0);
			}
		},
		/**
		 * 展开
		 * <pre>
		 * <code>
		 * var item = layout.getItemsByRegion('west')[0];
		 * item && item.expand()
		 * </code>
		 * </pre>
		 */
		expand : function(range,duration,callback){
			var _self = this,
				property = _self.getCollapseProperty(),
				el = _self.get('el'),
				toRange = _self.get(property),
				css = {};
			css[property] = toRange;

			el.animate(css,duration,function(){
				_self.set('collapsed',false);
				el.removeClass(CLS_COLLAPSED);
				callback && callback();
			});
		},
		//获取折叠的属性,width,length
		getCollapseProperty : function(){
			var _self = this,
				region = _self.get('region');
			if(region == REGINS.SOUTH || region == REGINS.NORTH){
				return 'height';
			}
			return 'width';
		},
		//获取剩余的宽度或者高度
		_getLeftRange : function(){
			var _self = this,
				el = _self.get('el'),
				left = _self.get('leftRange');
			return left;
		},
		/**
		 * @protected
		 * @ignore
		 */
		getCollapsedRange : function(){
			var _self = this,
				property = _self.getCollapseProperty(),
				el = _self.get('el'),
				val = _self.get(property);
			if(BUI.isString(val)){
				var dynacAttrs = _self._getDynacAttrs();
				if(val.indexOf('{') != -1){
					val = BUI.substitute(val,dynacAttrs);
					val = BUI.JSON.looseParse(val);
				}
				else if(val.indexOf('%') != -1){
					val = parseInt(val,10) * 0.01 * dynacAttrs[property];
				}else{
					val = parseInt(val,10);
				}
			}
			return val - _self._getLeftRange(property);
		},
		/**
		 * 折叠
		 * <pre>
		 * <code>
		 * var item = layout.getItemsByRegion('west')[0];
		 * item && layout.collapseItem(item);
		 * </code></pre>
		 */
		collapse : function(duration,callback){
			var _self = this,
				property = _self.getCollapseProperty(),
				el = _self.get('el'),
				left = _self._getLeftRange(property),
				css = {};
			css[property] = left;
			el.animate(css,duration,function(){
				_self.set('collapsed',true);
				el.addClass(CLS_COLLAPSED);
			  if(callback){
			  	callback();
			  }
			});
		}
	});



	return Border;
});
Example #8
0
File: tips.js Project: alexmiao/bui
define('bui/form/tips',function (require) {

  var BUI = require('bui/common'),
    prefix = BUI.prefix,
    Overlay = require('bui/overlay').Overlay,
    FIELD_TIP = 'data-tip',
    CLS_TIP_CONTAINER = prefix + 'form-tip-container';

  /**
   * 表单提示信息类
   * xclass:'form-tip'
   * @class BUI.Form.TipItem
   * @extends BUI.Overlay.Overlay
   */
  var tipItem = Overlay.extend(
  /**
   * @lends BUI.Form.TipItem.prototype
   * @ignore
   */
  {
    initializer : function(){
      var _self = this,
        render = _self.get('render');
      if(!render){
        var parent = $(_self.get('trigger')).parent();
        _self.set('render',parent);
      }
    },
    renderUI : function(){
      var _self = this;

      _self.resetVisible();
      
    },
    /**
     * 重置是否显示
     */
    resetVisible : function(){
      var _self = this,
        triggerEl = $(_self.get('trigger'));

      if(triggerEl.val()){//如果默认有文本则不显示,否则显示
        _self.set('visible',false);
      }else{
        _self.set('align',{
          node:$(_self.get('trigger')),
          points: ['cl','cl']
        });
        _self.set('visible',true);
      }
    },
    bindUI : function(){
      var _self = this,
        triggerEl = $(_self.get('trigger'));

      _self.get('el').on('click',function(){
        _self.hide();
        triggerEl.focus();
      });
      triggerEl.on('click focus',function(){
        _self.hide();
      });

      triggerEl.on('blur',function(){
        _self.resetVisible();
      });
    }
  },{
    ATTRS : 
    /**
     * @lends BUI.Form.TipItem#
     * @ignore
     */
    {
      /**
       * 提示的输入框 
       * @cfg {String|HTMLElement|jQuery} trigger
       */
      /**
       * 提示的输入框
       * @type {String|HTMLElement|jQuery}
       */
      trigger:{

      },
      /**
       * 提示文本
       * @cfg {String} text
       */
      /**
       * 提示文本
       * @type {String}
       */
      text : {

      },
      /**
       * 提示文本上显示的icon样式
       * @cfg {String} iconCls
       *     iconCls : icon-ok
       */
      /**
       * 提示文本上显示的icon样式
       * @type {String}
       *     iconCls : icon-ok
       */
      iconCls:{

      },
      /**
       * 默认的模版
       * @type {String}
       * @default '<span class="{iconCls}"></span><span class="tip-text">{text}</span>'
       */
      tpl:{
        value:'<span class="{iconCls}"></span><span class="tip-text">{text}</span>'
      }
    }
  },{
    xclass : 'form-tip'
  });

  /**
   * 表单提示信息的管理类
   * @class BUI.Form.Tips
   * @extends BUI.Base
   */
  var Tips = function(config){
    if (this.constructor !== Tips){
      return new Tips(config);
    }

    Tips.superclass.constructor.call(this,config);
    this._init();
  };

  Tips.ATTRS = 
  /**
   * @lends BUI.Form.Tips
   * @ignore
   */
  {

    /**
     * 表单的选择器
     * @cfg {String|HTMLElement|jQuery} form
     */
    /**
     * 表单的选择器
     * @type {String|HTMLElement|jQuery}
     */
    form : {

    },
    /**
     * 表单提示项对象 {@link BUI.Form.TipItem}
     * @readOnly
     * @type {Array} 
     */
    items : {
      value:[]
    }
  };

  BUI.extend(Tips,BUI.Base);

  BUI.augment(Tips,{
    _init : function(){
      var _self = this,
        form = $(_self.get('form'));
      if(form.length){
        BUI.each($.makeArray(form[0].elements),function(elem){
          var tipConfig = $(elem).attr(FIELD_TIP);
          if(tipConfig){
            _self._initFormElement(elem,$.parseJSON(tipConfig));
          }
        });
        form.addClass(CLS_TIP_CONTAINER);
      }
    },
    _initFormElement : function(element,config){
      if(config){
        config.trigger = element;
        //config.render = this.get('form');
      }
      var _self = this,
        items = _self.get('items'),
        item = new tipItem(config);
      items.push(item);
    },
    /**
     * 获取提示项
     * @param {String} name 字段的名称
     * @return {BUI.Form.TipItem} 提示项
     */
    getItem : function(name){
      var _self = this,
        items = _self.get('items'),
        result = null;
      BUI.each(items,function(item){

        if($(item.get('trigger')).attr('name') === name){
          result = item;
          return false;
        }

      });

      return result;
    },
    /**
     * 重置所有提示的可视状态
     */
    resetVisible : function(){
      var _self = this,
        items = _self.get('items');

      BUI.each(items,function(item){
        item.resetVisible();
      });
    },
    /**
     * 生成 表单提示
     */
    render:function(){
       var _self = this,
        items = _self.get('items');
      BUI.each(items,function(item){
        item.render();
      });
    },
    /**
     * 删除所有提示
     */
    destroy:function(){
      var _self = this,
        items = _self.get(items);

      BUI.each(items,function(item){
        item.destroy();
      });
    }
  });
  
  Tips.Item = tipItem;
  return Tips;

});
Example #9
0
define('bui/grid/plugins/rowgroup',['bui/common'],function(require){

  var BUI = require('bui/common'),
    DATA_GROUP = 'data-group',
    PREFIX = BUI.prefix,
    CLS_GROUP = PREFIX + 'grid-row-group',
    CLS_TRIGGER = PREFIX + 'grid-cascade',
    CLS_EXPAND = PREFIX + 'grid-cascade-expand';

  //新的分组
  function newGroup (value,text) {
    return {items : [],value : value,text : text};
  }

  /**
   * 表头列分组功能,仅处理数据展示,排序,不处理这个过程中的增删改,添加删除列
   * @class BUI.Grid.Plugins.RowGroup
   * @extends BUI.Base
   */
  var Group = function (cfg) {
    Group.superclass.constructor.call(this,cfg);
  };

  Group.ATTRS = {
   
    groups : {
      shared : false,
      value : []
    },
    /**
     * 渲染分组内容,函数原型 function(text,group){}
     *
     *  - text 是分组字段格式化后的文本
     *  - group 是当前分组,包括,text(文本),value(值),items(分组包含的项)
     * @type {Function}
     */
    renderer : {

    }
  };

  BUI.extend(Group,BUI.Base);

  BUI.augment(Group,{

    renderUI : function (grid) {
      var _self = this,
        tbodyEl = grid.get('el').find('tbody');
      _self.set('grid',grid);
      _self.set('tbodyEl',tbodyEl);

    },
    bindUI : function (grid) {
      var _self = this,
         groups = [];

      //显示完成记录时
      grid.on('aftershow',function () {
        var items = grid.getItems(),
          column = _self._getSortColumn();
        _self._clear();
        if(column){
          grid.get('view').getAllElements().hide();
          var field = column.get('dataIndex');
          BUI.each(items,function (item,index) {
            var last = groups[groups.length - 1],
              renderer = column.get('renderer'),
              value = item[field],
              text;
            if(!last || value != last.value){
              text = renderer ? renderer(value,item) : value;
              var current = newGroup(value,text);
              current.begin = index;
              groups.push(current);
              last && _self._createGroup(last);
              last = current;
            }
            
            last.items.push(item);
            
            
          });
          var last = groups[groups.length - 1];
          last && _self._createGroup(last);
          _self.set('groups',groups);
        }
        
      });

      //清除所有记录时
      grid.on('clear',function () {
        _self._clear();
      });

      _self.get('tbodyEl').delegate('.' + CLS_TRIGGER,'click',function (ev) {
        var sender = $(ev.currentTarget),
          group = _self._getGroupData(sender);
        if(sender.hasClass(CLS_EXPAND)){
          _self._collapse(group);
          sender.removeClass(CLS_EXPAND);
        }else{
          _self._expand(group);
          sender.addClass(CLS_EXPAND);
        }

      });
    },
    //获取排序的字段对应的列
    _getSortColumn: function(){
      var _self = this,
        grid = _self.get('grid'),
        store = grid.get('store'),
        field = store.get('sortField');

      return grid.findColumnByField(field);
    },
    //获取分组的数据
    _getGroupData : function (el) {
      var _self = this,
        groupEl = el.closest('.' + CLS_GROUP);
      return groupEl.data(DATA_GROUP);
    },
    _createGroup : function (group) {
      var _self = this,
        grid = _self.get('grid'),
        item = group.items[0],
        firstEl = grid.findElement(item),
        count = grid.get('columns').length,
        renderer = _self.get('renderer'),
        text = renderer ? renderer(group.text,group) : group.text,
        tpl = '<tr class="'+CLS_GROUP+'"><td colspan="' + count + '"><div class="bui-grid-cell-inner"><span class="bui-grid-cell-text"><span class="bui-grid-cascade"><i class="bui-grid-cascade-icon"></i></span> ' + text + '</span></div></td></tr>',
        node = $(tpl).insertBefore(firstEl);
      node.data(DATA_GROUP,group);
    },
    _getGroupedElements : function(group){
      var _self = this,
        grid = _self.get('grid'),
        elements = grid.get('view').getAllElements(),
        begin = group.begin,
        end = group.items.length + begin,
        rst = [];
      for(var i = begin; i < end; i++){
        rst.push(elements[i]);
      }
      return $(rst);
    },
    _expand : function (group) {
      var _self = this,
        subEls = _self._getGroupedElements(group);
      subEls.show();
    },
    _collapse : function (group) {
       var _self = this,
        subEls = _self._getGroupedElements(group);
      subEls.hide();
    },
    _clear : function () {
      var _self = this,
        groups = _self.get('groups'),
        tbodyEl = _self.get('tbodyEl');

      BUI.Array.empty(groups);
      tbodyEl.find('.' + CLS_GROUP).remove();

    }
  });

  return Group;

});
Example #10
0
File: flow.js Project: 2zyun/bui
define('bui/layout/flow',['bui/common','bui/layout/abstract','bui/layout/baseitem'],function (require) {
	var BUI = require('bui/common'),
		Abstract = require('bui/layout/abstract'),
		Item = require('bui/layout/baseitem');
	
	/**
	 * @class BUI.Layout.Flow
	 * 流布局控件
	 * @extends BUI.Layout.Abstract
	 * <pre>
	 * 	<code>
	 * 		var layout = new Flow(),
					control = new BUI.Component.Controller({
					width:600,
					height:500,
					render : '#J_Layout',
					elCls : 'layout-test',
					children : [{
						layout : {
							width : 100,
							height:100
						},
						xclass : 'controller',
						content : "一"
					},{
						xclass : 'controller',
						layout : {
							width:200,
							height:50
						},
						content : '二'
					},{
						xclass : 'controller',
						layout : {
							width:50,
							height:100
						},
						content : "三"
					},{
						xclass : 'controller',
						layout : {
							width:200,
							height : 200
						},
						content : "四"
					}],
					plugins : [layout]
				});

				control.render();
	 * 	</code>
	 * </pre>
	 */
	var Flow = function(config){
		Flow.superclass.constructor.call(this,config)
	};

	Flow.ATTRS = {
		itemConstructor : {
			value : Item
		},
		itemTpl : {
			value : '<div class="x-layout-item-flow pull-left"></div>'
		}
	};

	BUI.extend(Flow,Abstract);

	return Flow;
});
Example #11
0
define('bui/layout/abstract',['bui/common','bui/layout/baseitem'],function(require){

	var BUI = require('bui/common'),
		Item = require('bui/layout/baseitem');

	/**
	 * @class BUI.Layout.Abstract
	 * 控件布局插件的抽象类
	 * @extends BUI.Base
	 */
	var Abstract = function(config){
		Abstract.superclass.constructor.call(this,config);
	};

	BUI.extend(Abstract,BUI.Base);

	Abstract.ATTRS = {

		/**
		 * 子项对应的构造函数
		 * @type {Function}
		 */
		itemConstructor : {
			value : Item
		},
		/**
		 * 使用此插件的控件
		 * @type {BUI.Component.Controller}
		 */
		control : {

		},
		/**
		 * 控件的的那些事件会引起重新布局
		 * @type {Array}
		 */
		layoutEvents : {
			value : ['afterWidthChange','afterHeightChange']
		},
		/**
		 * 内部选项
		 * @type {String}
		 */
		items : {

		},
		/**
		 * 布局容器上添加的样式
		 * @type {String}
		 */
		elCls : {

		},
		/**
		 * 布局子项的默认得配置项
		 * @type {Object}
		 */
		defaultCfg : {
			value : {}
		},
		/**
		 * 放置控件的容器css
		 * @type {string}
		 */
		wraperCls : {

		},
		/**
		 * 放置布局的容器
		 * @type {jQuery}
		 */
		container : {

		},
		/**
		 * 布局相关的模板,将所有的子控件放置其中
		 * @type {String}
		 */
		tpl : {

		},
		/**
		 * 每一个布局子项的模板
		 * @type {String}
		 */
		itemTpl : {
			value : '<div></div>'
		}
	}

	BUI.augment(Abstract,{

		initializer : function(control){
			var _self = this;
			_self.set('control',control);
		},
		renderUI : function(){
			this._initWraper();
			this.initItems();
		},
		//绑定宽度,高度发生改变的情形
		bindUI : function(){
			var _self = this,
				control = _self.get('control'),
				layoutEvents = _self.get('layoutEvents').join(' ');

			control.on('afterAddChild',function(ev){
				var child = ev.child;
				_self.addItem(child);
				
			});

			control.on('afterRemoveChild',function(ev){
				_self.removeItem(ev.child);
			});
			
			control.on(layoutEvents,function(){
				_self.resetLayout();
			});

			
			_self.appendEvent(control);
		},
		/**
		 * @protected
		 * 附加事件
		 * @param  {Object} control 使用layout的控件
		 */
		appendEvent : function(control){

		},
		//初始化容器
	  _initWraper : function(){
	  	var _self = this,
	  		control = _self.get('control'),
	  		controlEl = control.get('view').get('contentEl'),
	  		node,
	  		elCls = _self.get('elCls'),
	  		tpl = _self.get('tpl');
	  	if(tpl){
	  		node = $(tpl).appendTo(controlEl);
	  	}else{
	  		node = controlEl;
	  	}
	  	if(elCls){
	  		node.addClass(elCls);
	  	}
	  	_self.set('container',node);
	  	_self.afterWraper();
		},
		/**
		 * @protected
		 * 容器初始化完毕开始渲染布局子项
		 */
		afterWraper : function(){

		},
		/**
		 * 通过DOM查找子项
		 * @param  {jQuery} element DOM元素
		 * @return {BUI.Layout.Item} 布局选项
		 */
		getItemByElement : function(element){
			return this.getItemBy(function(item){
				return $.contains(item.get('el')[0],element[0]);
			});
		},
		/**
		 * @protected
		 * 获取布局选项的容器
		 */
		getItemContainer : function(itemAttrs){
			return this.get('container');
		},
		/**
		 * @private
		 * 初始化子项
		 */
		initItems : function(){
			var _self = this,
				control = _self.get('control'),
				items = [],
				controlChildren = control.get('children');

			_self.set('items',items);

			for (var i = 0; i < controlChildren.length; i++) {
				_self.addItem(controlChildren[i]);
			};
			_self.afterInitItems();
			
		},
		/**
		 * 布局选项初始化完毕
		 * @protected
		 */
		afterInitItems : function(){

		},
		/**
		 * 获取下一项选项,如果当前项是最后一条记录,则返回第一条记录
		 * @param  {BUI.Layout.Item} item 选项
		 * @return {BUI.Layout.Item}  下一个选项
		 */
		getNextItem : function(item){
			var _self = this,
				index = _self.getItemIndex(item),
				count = _self.getCount(),
				next = (index + 1) % count;
			return _self.getItemAt(next);
		},
		/**
		 * @protected
		 * 返回子项的配置信息
		 * @param {Object}  controlChild 包装的控件
		 * @return {Object} 配置信息
		 */
		getItemCfg : function(controlChild){
			var _self = this,
				defaultCfg = _self.get('defaultCfg'),
				cfg = BUI.mix({},defaultCfg,{
					control : controlChild,
					tpl : _self.get('itemTpl'),
					layout : _self,
					wraperCls : _self.get('wraperCls'),
					container : _self.getItemContainer(cfg)
				},controlChild.get('layout'));

			return cfg;
		},
		/**
		 * @protected 
		 * 初始化子项
		 */
		initItem : function(controlChild){
			var _self = this,
				c = _self.get('itemConstructor'),
				cfg = _self.getItemCfg(controlChild);

			return new c(cfg);
		},
		/**
		 * 添加布局项
		 * @protected
		 * @param {Object} controlChild 控件
		 */
		addItem : function(control){
			var _self = this,
				items = _self.getItems(),
				item = _self.initItem(control);
			items.push(item);
			return item;
		},
		/**
		 * 移除布局项
		 * @protected
		 * @param  {Object} controlChild 使用布局的控件的子控件
		 */
		removeItem : function(control){
			var _self = this,
			  items = _self.getItems(),
				item = _self.getItem(control);
			if(item){
				item.destroy();
				BUI.Array.remove(items,item);
			}
		},
		/**
		 * 通过匹配函数获取布局选项
		 * @param  {Function} fn 匹配函数
		 * @return {BUI.Layout.Item} 布局选项
		 */
		getItemBy : function(fn){
			var _self = this,
				items = _self.getItems(),
				rst = null;

			BUI.each(items,function(item){
				if(fn(item)){
					rst = item;
					return false;
				}
			});
			return rst;
		},
		/**
		 * 通过匹配函数获取布局选项集合
		 * @param  {Function} fn 匹配函数
		 * @return {Array} 布局选项集合
		 */
		getItemsBy : function(fn){
			var _self = this,
				items = _self.getItems(),
				rst = [];

			BUI.each(items,function(item){
				if(fn(item)){
					rst.push(item);
				}
			});
			return rst;
		},
		/**
		 * 获取布局选项
		 * @param {Object} controlChild 子控件
		 * @return {BUI.Layout.Item} 布局选项
		 */
		getItem : function(control){
			return this.getItemBy(function(item){
				return item.get('control') == control;
			});
		},
		/**
		 * 返回子项的数目
		 * @return {Number} 数目
		 */
		getCount : function(){
			return this.getItems().length;
		},
		/**
		 * 根据索引返回选项
		 * @return {BUI.Layout.Item}} 返回选项
		 */
		getItemAt : function(index){
			return this.getItems()[index];
		},
		/**
		 * 获取索引
		 * @param  {BUI.Layout.Item} item 选项
		 * @return {Number} 索引
		 */
		getItemIndex : function(item){
			var items = this.getItems();
			return BUI.Array.indexOf(item,items);
		},
		/**
		 * 获取内部子项,不等同于children,因为可能有
		 * @return {Array} 返回布局的子项
		 */
		getItems : function(){
			return this.get('items');
		},
		/**
		 * @protected
		 * 重置布局,子类覆盖此类
		 */
		resetLayout : function(){
			var _self = this,
			 	items = _self.getItems();

			BUI.each(items,function(item){
				item.syncItem();
			});
		},
		/**
		 * 清除所有的布局
		 * @protected
		 */
		clearLayout : function(){
			var _self = this,
				items = _self.getItems();
			BUI.each(items,function(item){
				item.destroy();
			});
		},
		/**
		 * 重新布局
		 */
		reset: function(){
			this.resetLayout();
		},
		/**
		 * 析构函数
		 */
		destroy : function(){
			var _self = this;
			_self.clearLayout();
			_self.off();
			_self.clearAttrVals();
		}
	});

	return Abstract;
});
Example #12
0
 */define("bui/editor",function(require){var e=require("bui/common"),t=require("bui/form"),n=e.namespace("Editor");return e.mix(n,{Editor:require("bui/editor/editor"),RecordEditor:require("bui/editor/record"),DialogEditor:require("bui/editor/dialog")}),n}),define("bui/editor/mixin",function(require){function e(e){var t=e,n=t.get("controlCfgField"),r=t.get(n),i=t.addChild(r);t.setInternal(n,i)}var t=function(){e(this)};return t.ATTRS={acceptEvent:{value:"autohide"},preventHide:{value:!0},changeSourceEvent:{value:"show triggerchange"},ignoreInputFields:{value:!1},innerValueField:{},emptyValue:{},controlCfgField:{},autoUpdate:{value:!0},events:{value:{accept:!1,cancel:!1}}},t.prototype={__bindUI:function(){var e=this,t=e.get("acceptEvent"),n=e.get("changeSourceEvent");t&&e.on(t,function(){if(e.accept())return;if(e.get("preventHide"))return!1;e.cancel()}),n&&e.on(n,function(){e.setValue(e.getSourceValue()),e.get("visible")&&e.focus()})},getInnerControl:function(){var e=this,t=e.get("children");return t[0]},setValue:function(e){var t=this,n=t.getInnerControl();t.set("editValue",e),t.clearControlValue(),n.set(t.get("innerValueField"),e),e||t.valid()},getValue:function(){var e=this,t=e.getInnerControl();return t.get(e.get("innerValueField"))},isValid:function(){var e=this,t=e.getInnerControl();return t.isValid?t.isValid():!0},valid:function(){var e=this,t=e.getInnerControl();t.valid&&t.valid()},getErrors:function(){var e=this,t=e.getInnerControl();return t.getErrors?t.getErrors():[]},isChange:function(){var e=this,t=e.get("editValue"),n=e.getValue();return t!==n},clearValue:function(){this.clearControlValue(),this.clearErrors()},clearControlValue:function(){var e=this,t=e.getInnerControl();t.set(e.get("innerValueField"),e.get("emptyValue"))},clearErrors:function(){var e=this,t=e.getInnerControl();t.clearErrors()},getSourceValue:function(){},updateSource:function(){},handleNavEsc:function(){this.cancel()},handleNavEnter:function(e){var t=e.target;t.tagName==="BUTTON"&&$(t).trigger("click"),this.accept()},focus:function(){var e=this,t=e.getInnerControl();t.focus&&t.focus()},accept:function(){var e=this,t;e.valid();if(!e.isValid())return!1;t=e.getValue(),e.get("autoUpdate")&&e.updateSource(t);if(e.fire("beforeaccept",{value:t})==0)return;return e.fire("accept",{value:t,editValue:e.get("editValue")}),e.hide(),!0},cancel:function(){this.fire("cancel"),this.clearValue(),this.hide()}},t}),define("bui/editor/editor",function(require){var e=require("bui/common"),t=require("bui/overlay").Overlay;CLS_TIPS="x-editor-tips",Mixin=require("bui/editor/mixin");var n=t.extend([Mixin],{bindUI:function(){var e=this,t=e.getInnerControl();e.on("validchange",function(t){!e.isValid()&&e.get("visible")?e._showError(e.getErrors()):e._hideError()}),e.on("hide",function(){e._hideError()}),e.on("show",function(){e.isValid()||e._showError(e.getErrors())})},_initOverlay:function(){var e=this,n=new t({children:[{xclass:"simple-list",itemTpl:'<li><span class="x-icon x-icon-mini x-icon-error" title="{error}">!</span>&nbsp;<span>{error}</span></li>'}],elCls:CLS_TIPS,autoRender:!0});return e.set("overlay",n),n},_getErrorList:function(){var e=this,t=e.get("overlay");return t&&t.get("children")[0]},_showError:function(t){var n=this,r=n.get("overlay")||n._initOverlay(),i=n._getErrorList(),s=n.get("errorAlign"),o=e.Array.map(t,function(e){return{error:e}});i.set("items",o),s.node=n.get("el"),r.set("align",s),r.show()},_hideError:function(){var e=this,t=e.get("overlay");t&&t.hide()},getSourceValue:function(){var e=this,t=e.get("curTrigger");return t.text()},updateSource:function(e){var t=this,n=t.get("curTrigger");n&&n.length&&n.text(e)},_uiSetWidth:function(e){var t=this;if(e!=null){var n=t.getInnerControl();n.set&&n.set("width",e)}}},{ATTRS:{innerValueField:{value:"value"},emptyValue:{value:""},autoHide:{value:!0},controlCfgField:{value:"field"},defaultChildCfg:{value:{tpl:"",forceFit:!0,errorTpl:""}},defaultChildClass:{value:"form-field"},align:{value:{points:["tl","tl"]}},errorAlign:{value:{points:["bl","tl"],offset:[0,10]}},overlay:{},field:{value:{}}}},{xclass:"editor"});return n}),define("bui/editor/record",function(require){var e=require("bui/common"),t=require("bui/editor/editor"),n=t.extend({getSourceValue:function(){return this.get("record")},updateSource:function(t){var n=this,r=n.get("record");e.mix(r,t)},_uiSetRecord:function(e){this.setValue(e)}},{ATTRS:{innerValueField:{value:"record"},acceptEvent:{value:""},emptyValue:{value:{}},autoHide:{value:!1},record:{value:{}},controlCfgField:{value:"form"},form:{value:{}},errorAlign:{value:{points:["tr","tl"],offset:[10,0]}},defaultChildCfg:{valueFn:function(){var e=this;return{xclass:"form",errorTpl:"",showError:!0,showChildError:!0,defaultChildCfg:{elCls:"bui-inline-block",tpl:"",forceFit:!0},buttons:[{btnCls:"button button-primary",text:"\u786e\u5b9a",handler:function(){e.accept()}},{btnCls:"button",text:"\u53d6\u6d88",handler:function(){e.cancel()}}]}}}}},{xclass:"record-editor"});return n}),define("bui/editor/dialog",function(require){var e=require("bui/overlay").Dialog,t=require("bui/editor/mixin"),n=e.extend([t],{getSourceValue:function(){return this.get("record")},updateSource:function(e){var t=this,n=t.get("record");BUI.mix(n,e)},_uiSetRecord:function(e){this.setValue(e)}},{ATTRS:{innerValueField:{value:"record"},acceptEvent:{value:""},record:{value:{}},emptyValue:{value:{}},controlCfgField:{value:"form"},changeSourceEvent:{value:""},defaultChildCfg:{value:{xclass:"form-horizontal"}},success:{value:function(){this.accept()}},form:{value:{}}}},{xclass:"dialog-editor"});return n});
Example #13
0
File: shape.js Project: cnJun/bui
define('bui/graphic/shape',['bui/common','bui/graphic/base','bui/graphic/canvasitem','bui/graphic/raphael','bui/graphic/util'],function(require){

  var BUI = require('bui/common'),
    Base = require('bui/graphic/base'),
    Item = require('bui/graphic/canvasitem'),
    Util = require('bui/graphic/util'),
    Raphael = require('bui/graphic/raphael');

  /**
   * @class BUI.Graphic.Shape
   * 图形的基类
   * @extends BUI.Graphic.Base
   */
  var Shape = function(cfg){
    Shape.superclass.constructor.call(this,cfg);
  };

  Shape.ATTRS = {
    attrs : {}
  }

  BUI.extend(Shape,Base);

  //获取画布内元素的一些共性方法
  BUI.mixin(Shape,[Item]);

  BUI.augment(Shape,{
    /**
     * 是否图形
     * @type {Boolean}
     */
    isShape : true,
    
    //渲染shape
    renderUI : function(){

      var _self = this,
        el = _self.get('el'),
        node,
        cfg,
        attrs;
      if(!el){
        cfg = _self.cfg;
        attrs = _self.parseElCfg(cfg.attrs);
        el = _self.createElement(attrs);
        _self.set('el',el);
      }
      node = el.node;
      node.shape = this;
      _self.set('node',node);
    },
    /**
     * @private
     */
    createElement : function(attrs){
      var _self = this,
        parent = _self.get('parent'),
        set = parent.get('el').add([attrs]),
        element;
      element = set[0];
      return element;
    },
    /**
     * @protected
     * 格式化初始化配置项
     */
    parseElCfg : function(attrs){
      attrs.type = this.get('type');
      return attrs;
    },
    /**
     * 获取图形的整体长度
     * @return {Number} 长度
     */
    getTotalLength : function(){
      return this.get('el').getTotalLength();
    },
    /**
     * 旋转
     * @param  {Number} a 旋转的角度
     * @param  {Number} x 旋转的中心点 x
     * @param  {Number} y 旋转的中心点 y
     */
    rotate : function(a, x, y){
      var _self = this;
      if(_self.isGroup){
        if(x == null && y == null){
          var tpoint = _self._getTranslatePoint();
          x = tpoint.x;
          y = tpoint.y;
        }
      }
      this.get('el').rotate(a,x,y);
    },
    /**
     * 放大
     * @param  {Number} sx x轴方向的倍数 
     * @param  {Number} sy y轴方向的倍数
     * @param  {Number} cx x轴方向扩展的中心
     * @param  {Number} cy y轴方向扩展的中心
     */
    scale : function(sx, sy, cx,cy){
      var _self = this,
        el = _self.get('el');
      
      el.scale(sx, sy, cx,cy);
    },
    /**
     * 直接使用transform方法 <br>
     *  "t100,100r30,100,100s2,2,100,100r45s1.5"
     *   - 
     * @param  {String} tstr 几何转换的字符串
     */
    transform : function(tstr){
      var _self = this,
        el = _self.get('el');
      el.transform(tstr);
    },
    getBBox : function(){
      return this.get('el').getBBox();
    },
    /**
     * 获取路径
     * @return {Array} 路径的数组
     */
    getPath : function(){
      var _self = this,
        el = _self.get('el'),
        path = el.getPath();
      if(BUI.isString(path)){
        path = Util.parsePathString(path);
      }
      return path;
    },
    /**
     * 获取路径字符串
     * @return {String} 路径的字符串
     */
    getPathString : function(){
      var _self = this,
        path = _self.getPath();
      return Util.parsePathArray(path);
    },
    /**
     * 获取使用平移后的path
     * @return {Array} 路径的数组
     */
    getTransformPath : function(){
      var _self = this,
        path = _self.getPath(),
        matrix = _self.get('el').matrix;
      return Util.transformPath(path,matrix.toTransformString());
    },
    //获取到移动的位置
    _getTranslatePoint : function(){
      var _self = this,
        tPath = _self.getTransformPath(),
        rst = {x : 0,y : 0};
      BUI.each(tPath,function(item){
        if(item[0] == 'M'){
          rst.x = item[1];
          rst.y = item[2];
        }
      });
      return rst;
    },
    //获取转换的信息,返回一个数组,处理非数组的场景
    __getTransform : function(value){
      if(BUI.isString(value)){
        value = value.replace(/([t,s,r])/,';$1 ').split(';');
        var temp = [];
        BUI.each(value,function(str){
          if(str){
            var sub = str.split(' ');
            sub = $.map(sub,function(subStr){
              if(BUI.isNumeric(subStr)){
                return parseFloat(subStr);
              }
              return subStr;
            });
            temp.push(sub);
          }
        });
        value = temp;
      }
      return value;
    }
  });

  /**
   * 圆
   * @class BUI.Graphic.Shape.Circle
   * @extends BUI.Graphic.Shape
   */
  var Circle = function(cfg){
    Circle.superclass.constructor.call(this,cfg);
  };

  Circle.ATTRS = {
    /**
     * 圆心的x坐标
     * @type {Number}
     */
    cx : {},
    /**
     * 圆心的y坐标
     * @type {Number}
     */
    cy : {},
    /**
     * 圆的半径
     * @type {Number}
     */
    r : {}
  };

  BUI.extend(Circle,Shape);

  Shape.Circle = Circle;

  /**
   * 矩形
   * @class BUI.Graphic.Shape.Rect
   * @extends BUI.Graphic.Shape
   */
  var Rect = function(cfg){
    Rect.superclass.constructor.call(this,cfg);
  };

  Rect.ATTRS = {
    /**
     * 矩形的左定点x坐标
     * @type {Number}
     */
    x : {},
    /**
     * 矩形的左定点y坐标
     * @type {Number}
     */
    y : {},
    /**
     * 矩形的宽度
     * @type {Number}
     */
    width : {},
    /**
     * 矩形的高度
     * @type {Number}
     */
    height : {},
    /**
     * 圆角
     * @type {Number}
     */
    r: {
      value : 0
    }
  };

  BUI.extend(Rect,Shape);
  Shape.Rect = Rect;

  /**
   * 矩形
   * @class BUI.Graphic.Shape.Ellipse
   * @extends BUI.Graphic.Shape
   */
  var Ellipse = function(cfg){
    Ellipse.superclass.constructor.call(this,cfg);
  };

  Ellipse.ATTRS = {
    /**
     * 矩形的左定点x坐标
     * @type {Number}
     */
    cx : {},
    /**
     * 矩形的左定点y坐标
     * @type {Number}
     */
    cy : {},
    /**
     * 矩形的宽度
     * @type {Number}
     */
    rx : {},
    /**
     * 矩形的高度
     * @type {Number}
     */
    ry : {}
  };

  BUI.extend(Ellipse,Shape);
  Shape.Ellipse = Ellipse;

  /**
   * 路径
   * @class BUI.Graphic.Shape.Path
   * @extends BUI.Graphic.Shape
   */
  var Path = function(cfg){
    Path.superclass.constructor.call(this,cfg);
  };

  Path.ATTRS = {
    /**
     * 路径
     * @type {String}
     */
    path : {}
  };


  BUI.extend(Path,Shape);

  Shape.Path = Path;

  /**
   * 直线
   * @class BUI.Graphic.Shape.Line
   * @extends BUI.Graphic.Shape.Path
   */
  var Line = function(cfg){
    Line.superclass.constructor.call(this,cfg);
  };

  Line.ATTRS = {
    /**
     * 起始x坐标
     * @type {Number}
     */
    x1 : {},
    /**
     * 起始y坐标
     * @type {Number}
     */
    y1 : {},
    /**
     * 终止x坐标
     * @type {Number}
     */
    x2 : {},
    /**
     * 终止y坐标
     * @type {Number}
     */
    y2 : {}
  };

  BUI.extend(Line,Path);

  BUI.augment(Line,{
    /**
     * @protected
     * 格式化初始化配置项
     */
    parseElCfg : function(attrs){
      attrs.type = 'path'; //将线转换成path
      attrs.path = BUI.substitute('M {x1},{y1}L{x2},{y2}',attrs);
      return attrs;
    },
    //获取线的坐标点
    _getLinePoint : function(pointIndex,coordIndex){
      var path = this.getPath();
      return path[pointIndex][coordIndex];
    },
    //设置线的坐标点
    _setLinePoint : function(pointIndex,coordIndex,value){
      var _self = this,
        path = this.getPath();
      path[pointIndex][coordIndex] = value;
      _self.attr('path',path);
    },
    //设置坐标x1
    __setX1 : function(value){
      this._setLinePoint(0,1,value);
    },
    __getX1 : function(){
      return this._getLinePoint(0,1);
    },
    //设置坐标x2
    __setX2 : function(value){
      this._setLinePoint(1,1,value);
    },
    __getX2 : function(){
      return this._getLinePoint(1,1);
    },
    //设置坐标y1
    __setY1 : function(value){
      this._setLinePoint(0,2,value);
    },
    __getY1 : function(){
      return this._getLinePoint(0,2);
    },
    //设置坐标y2
    __setY2 : function(value){
      this._setLinePoint(1,2,value);
    },
    __getY2 : function(){
      return this._getLinePoint(1,2);
    }
  });

  Shape.Line = Line;


  function points2path(points,z){
    if(BUI.isArray(points)){
      points = points.join(' ');
    }
    return 'M' + points + z;
  }

  /**
   * 折线,polyLine
   * @class BUI.Graphic.Shape.PolyLine
   * @extends BUI.Graphic.Shape.Path
   */
  var PolyLine = function(cfg){
    PolyLine.superclass.constructor.call(this,cfg);
  };

  PolyLine.ATTRS = {
    /**
     * 定点集合,可以是字符串、或者数组
     *
     *  - 字符串: '0,0 25,25 31,50'
     *  - 数组 : ['0,0','25,25','31,50']
     *  
     * @type {Array|String}
     */
    points : {}
  };

  BUI.extend(PolyLine,Path);

  BUI.augment(PolyLine,{
    //设置顶点
    __setPoints : function(value){
      var _self = this,
        el = _self.get('el'),
        path = points2path(value,'');
      _self.attr('path',path);
    },
    /**
     * @protected
     * 格式化初始化配置项
     */
    parseElCfg : function(attrs){
      attrs.type = 'path'; //将线转换成path
      attrs.path = points2path(attrs.points,'');
      return attrs;
    }

  });

  Shape.PolyLine = PolyLine;

  /**
   * 多边形
   * @class BUI.Graphic.Shape.Polygon
   * @extends BUI.Graphic.Shape.Path
   */
  var Polygon = function(cfg){
    PolyLine.superclass.constructor.call(this,cfg);
  };

  Polygon.ATTRS = {
    /**
     * 定点集合,可以是字符串、或者数组
     *
     *  - 字符串: '0,0 25,25 31,50'
     *  - 数组 : ['0,0','25,25','31,50']
     *  
     * @type {Array|String}
     */
    points : {}
  };

  BUI.extend(Polygon,Path);

  BUI.augment(Polygon,{
    //设置顶点
    __setPoints : function(value){
      var _self = this,
        el = _self.get('el'),
        path = points2path(value,'z');
      _self.attr('path',path);
    },
    /**
     * @protected
     * 格式化初始化配置项
     */
    parseElCfg : function(attrs){
      attrs.type = 'path'; //将线转换成path
      attrs.path = points2path(attrs.points,'z');
      return attrs;
    }

  });

  Shape.Polygon = Polygon;

  /**
   * 文本
   * @class BUI.Graphic.Shape.Text
   * @extends BUI.Graphic.Shape
   */
  var Text = function(cfg){
    Text.superclass.constructor.call(this,cfg);
  };

  Text.ATTRS = {
    /**
     * x轴坐标
     * @type {Number}
     */
    x : {},
    /**
     * y轴坐标
     * @type {Number}
     */
    y : {},
    /**
     * 显示的文本
     * @type {String}
     */
    text : {},
    /**
     * 字体相关的属性,也可以单独设置其中的属性: font-family,font-weight....
     * @type {String}
     */
    'font' : {},
    /**
     * 文本的对齐方式:默认对齐方式: 'middle'
     * @type {String}
     */
    'text-anchor' : {}
  };

  BUI.extend(Text,Shape);

  Shape.Text = Text;

  /**
   * @class BUI.Graphic.Shape.Label
   * 文本标签,继承自文本,但是提供了rotate属性
   * @extends BUI.Graphic.Shape.Text
   */
  var Label = function(cfg){
    Label.superclass.constructor.call(this,cfg);
  };

  BUI.extend(Label,Text);

  Label.ATTRS = {
    /**
     * 旋转角度
     * @type {Number}
     */
    rotate : {}
  };

  BUI.augment(Label,{
    /**
     * @protected
     * 格式化初始化配置项
     */
    parseElCfg : function(attrs){
      attrs.type = 'text';
      if(attrs.rotate){
        attrs.transform = BUI.substitute('r{rotate} {x} {y}',attrs);
      }
      
      return attrs;
    }
  });

  Shape.Label = Label;

  /**
   * @class BUI.Graphic.Shape.Marker
   * 用于标示节点的图形
   * @extends BUI.Graphic.Shape
   */
  var Marker = function(cfg){
    Marker.superclass.constructor.call(this,cfg);
  };

  Marker.ATTRS = {
    /**
     * 类型 "circle", "square", "diamond", "triangle" and "triangle-down";如果是 "url(xxx)"则是图片;custom则需要指定路径
     * @type {String}
     */
    symbol :{
      value : 'custom'
    },
    /**
     * 半径
     * @type {Number}
     */
    radius : {
      value : 5
    },
    /**
     * 如果类型为"custom"时指定路径
     * @type {Object}
     */
    path : {

    },
    /**
     * 起始x轴位置
     * @type {Number}
     */
    x : {

    },
    /**
     * 起始y轴位置
     * @type {Number}
     */
    y : {

    }
  };

  Marker.Symbols = {
    //圆
    circle : function(x,y,r){
      return [['M',x,y - r],['a',r,r,0,1,1,0,2*r],['a',r,r,0,1,1,0,-2*r],['z']];
    },
    //正方形
    square : function(x,y,r){
      return [['M',x-r,y-r],['L',x + r,y-r],['L',x + r,y + r],['L',x - r,y + r],['z']];
    },
    //菱形
    diamond : function(x,y,r){
      return [['M',x - r,y],['L',x,y - r],['L',x + r, y],['L',x,y + r],['z']];
    },
    //三角形
    triangle : function(x,y,r){
      var diffX = r / 0.866,
        diffY =  r;
      return [['M',x,y-r],['L',x + diffX,y + diffY],['L',x - diffX, y + diffY],['z']];
    },
    //倒三角形
    'triangle-down' : function(x,y,r){
      var diffX = r / 0.866,
        diffY =  r;
      return [['M',x,y + r],['L',x + diffX, y - diffY],['L',x - diffX,y - diffY],['z']];
    }
  };



  BUI.extend(Marker,Shape);

  BUI.augment(Marker,{
    //设置半径
    __setRadius : function(v){
      var _self = this,
        attrs = _self.get('attrs');

      _self._setSize(attrs.x,attrs.y,v);

    },
    __getRadius : function(){
      return this.get('attrs').radius;
    },
    //设置x
    __setX : function(x){
      var _self = this,
        attrs = _self.get('attrs');

      _self._setSize(x,attrs.y,attrs.radius);

    },
    __getX : function(){
      return this.get('attrs').x;
    },
    //设置y
    __setY : function(y){
      var _self = this,
        attrs = _self.get('attrs');

      _self._setSize(attrs.x,y,attrs.radius);

    },
    __getY : function(){
      return this.get('attrs').y;
    },
    __getSymbol : function(){
      return this.get('attrs').symbol;
    },
    //设置大小,位置
    _setSize : function(x,y,radius){
      var _self = this,
        attrs = _self.get('attrs'),
        el = _self.get('el');
      if(el.type !== 'image'){
        var cfg = {
          x : x,
          y : y,
          radius : radius
        };
        BUI.mix(attrs,cfg);
        var path = _self._getPath(attrs);
        el.attr('path',path);
      }else{
        BUI.mix(attrs,{
          width : radius * 2,
          height : radius * 2,
          x : x - (radius - attrs.radius),
          y : y - (radius - attrs.radius),
          radius : radius
        });
        el.attr(attrs);
      }
    },
    animate : function(params,ms,easing,callback){
      var _self = this;

      if(_self.get('el').type == 'image'){
        var radius = params.radius || _self.attr('radius');
        params.x = params.x - radius;
        params.y = params.y - radius;
        _self.get('el').animate(params,ms,easing,callback);
      }else{
        var attrs = _self.get('attrs'),
          path;
          BUI.mix(attrs,{
            x : params.x,
            y : params.y
          });
          
          path = _self._getPath(attrs);

        _self.get('el').animate({path : path},ms,easing,callback);
      }

    },

    /**
     * @protected
     * 格式化初始化配置项
     */
    parseElCfg : function(attrs){
      var _self = this,
        symbol = attrs.symbol,
        radius = attrs.radius || 5;
      if(symbol && symbol.indexOf('url') != -1){ //图片
          attrs.type = 'image';
          attrs.src = symbol.replace(/url\((.*)\)/,'$1');
          attrs.width = attrs.radius * 2;
          attrs.height = attrs.radius * 2;
          attrs.x -= radius,
          attrs.y -= radius;
      }else{
        attrs.type = 'path';
        attrs.path = _self._getPath(attrs);
      }
      return attrs;
    },
    //获取path
    _getPath : function(attrs){
      if(!attrs.symbol && attrs.path){
        return  BUI.substitute(attrs.path,attrs);
      }
      var method = Marker.Symbols[attrs.symbol];
      if(method){
        return method(attrs.x,attrs.y,attrs.radius)
      }else{
        throw 'not support this type ' + attrs.symbol;
      }
    }

  });

  Shape.Marker = Marker;



  /**
   * @class BUI.Graphic.Shape.Image
   * 图片
   * @extends BUI.Graphic.Shape
   */
  var Image = function(cfg){
    Image.superclass.constructor.call(this,cfg);
  };

  Image.ATTRS = {
    /**
     * 路径
     * @type {String}
     */
    src : {}, 
    /**
     * x轴位置
     * @type {Number}
     */
    x : {}, 
    /**
     * y轴位置
     * @type {Number}
     */
    y : {}, 
    /**
     * 宽度
     * @type {Number}
     */
    width : {}, 
    /**
     * 高度
     * @type {Number}
     */
    height : {}
  }

  BUI.extend(Image,Shape);

  Shape.Image = Image;

  
  return Shape;
});
Example #14
0
define('bui/chart/circleaxis',['bui/common','bui/graphic','bui/chart/abstractaxis'],function (require) {
  
  var BUI = require('bui/common'),
    Util = require('bui/graphic').Util,
    Abstract = require('bui/chart/abstractaxis');

  var RAD = Math.PI / 180;

  //获取圆上的点
  function getPoint(self,r,angle){
    var center = self.getCenter(),
      rst = {};
      rst.x = center.x + r * Math.sin(angle * RAD);
      rst.y = center.y - r * Math.cos(angle * RAD);
    return rst;
  }


  /**
   * @class BUI.Chart.Axis.Circle
   * 圆形的坐标
   * @extends BUI.Chart.Axis.Abstract
   */
  var Circle = function(cfg){
    Circle.superclass.constructor.call(this,cfg);
  };

  BUI.extend(Circle,Abstract);


  Circle.ATTRS = {

    type : {
      value : 'circle'
    },
    /**
     * 起始角度,0-360度
     * @type {Number}
     */
    startAngle : {
      value : 0
    },
    /**
     * 结束的角度
     * @type {Number}
     */
    endAngle : {
      value : 360
    },
    /**
     * 与绘图区域的边距
     * @type {Number}
     */
    margin : {
      value : 20
    },
    /**
     * 半径长度,一般根据绘图区域自动计算
     * @type {Number}
     */
    radius : {

    },
    /**
     * 指定角度值,将圆分成几部分,一定是能够将圆平分的角度值
     * @type {Number}
     */
    tickInterval : {

    },
    grid : {
      value :{
        line : {
          'stroke-width' : 1,
          'stroke' : '#C0D0E0'
        }
      } 
    }
  };

  BUI.augment(Circle,{

    beforeRenderUI : function(){
      var _self = this;
      Circle.superclass.beforeRenderUI.call(_self);
      
      var tickInterval = _self.get('tickInterval'),
        ticks = _self.get('ticks'),
        startAngle = _self.get('startAngle'),
        endAngle = _self.get('endAngle'),
        count;

      if(tickInterval && !ticks){
        ticks = [];
        count = (endAngle - startAngle)/tickInterval
        for (var i = 0; i < count; i++) {
          ticks.push(startAngle + tickInterval * i);
        };
        _self.set('ticks',ticks);

      }
    },
    /**
     * 获取中心点
     * @return {Number} 中心点
     */
    getCenter : function(){
      var _self = this,
        plotRange = _self.get('plotRange');
      return plotRange.cc;
    },
    /**
     * 获取半径
     * @return {Number} 半径
     */
    getRadius : function(){
      var _self = this,
        radius = _self.get('radius'),
        plotRange = _self.get('plotRange');
      if(!radius){
        //半径等于宽高比较小的1/2,以及20像素的边框
        radius = Math.min(plotRange.getWidth(),plotRange.getHeight())/2 - _self.get('margin');
        _self.set('radius',radius);
      }
      return radius;
    },
    /**
     * 获取坐标点间的平均角度
     * @return {Number} 角度值
     */
    getTickAvgAngle : function(){
      var _self = this,
        ticks = _self.get('ticks'),
        startAngle = _self.get('startAngle'),
        endAngle = _self.get('endAngle');
      return (endAngle - startAngle) / ticks.length;
    },
    /**
     * @protected
     * 获取坐标轴的path
     * @return {String|Array} path
     */
    getLinePath : function(){
      var _self = this,
        center = _self.getCenter(),
        x = center.x,
        y = center.y,
        rx =  _self.getRadius(),
        ry = rx;

      return [["M", x, y], ["m", 0, -ry], ["a", rx, ry, 0, 1, 1, 0, 2 * ry], ["a", rx, ry, 0, 1, 1, 0, -2 * ry], ["z"]];
    },
    //获取坐标轴上的节点位置
    getOffsetPoint : function(index){
      var _self = this,
        angle = _self.getOffsetByIndex(index),
        radius = _self.getRadius();
      return _self.getCirclePoint(angle,radius);
    },
    /**
     * 根据半径和角度获取对应的点
     * @param  {Number} angle 角度
     * @param  {Number} r 半径,可以为空,默认为圆的半径
     * @return {Object} 坐标点
     */
    getCirclePoint : function(angle,r){
      if(r == null){
        r = this.getRadius();
      }
      
      return getPoint(this,r,angle);
    },
    /**
     * 获取点到圆心的距离
     * @param  {Number} x x坐标
     * @param  {Number} y y坐标
     * @return {Number} 距离
     */
    getDistance : function(x,y){
      var _self = this,
        center = _self.getCenter();
      return Math.sqrt(Math.pow(x - center.x,2) + Math.pow(y - center.y,2));
    },
    /**
     * 获取点对应的角度,0 - 360
     * @param  {Number} x x坐标
     * @param  {Number} y y坐标
     * @return {Number} 获取点的角度
     */
    getCircleAngle : function(x,y){
      var _self = this,
        center = _self.getCenter(),
        r = _self.getDistance(x,y),
        angle = (Math.asin(Math.abs(x - center.x) / r) / Math.PI) * 180;

      if(x >= center.x && y <= center.y){//第一象限
        return angle;
      }


      if(x >= center.x && y >= center.y){ //第四象限
        return 180 - angle;
      }

      if(x <= center.x && y >= center.y){//第三象限
        return angle + 180;
      } 

      return 360 - angle; //第四象限
    },
    /**
     * 圆的坐标轴来说,根据索引获取对应的角度
     * @param  {Number} index 顺序 
     * @return {Number} 节点坐标点(单一坐标)x轴的坐标点或者y轴的坐标点
     */
    getOffsetByIndex : function(index){
      var _self = this,
        ticks = _self.get('ticks'),
        length = ticks.length,
        startAngle = _self.get('startAngle'),
        endAngle = _self.get('endAngle');
      return startAngle + ((endAngle - startAngle) / length) * index;
    },
    /**
     * 圆形坐标轴上,存在坐标点的值,例如,存在 0,45,90 ... 360,那么 80将返回90
     * @param  {Number} offset 
     * @return {Number} 点在坐标轴上角度
     */
    getValue : function(offset){
      return this.getSnapValue(offset);
    },
     /**
     * 获取逼近坐标点的值
     * @param  {Number} offset 画布上的点在坐标轴上的对应值
     * @return {Number} 坐标轴上的值
     */
    getSnapValue : function(offset,tolerance){
      
      //tolerance = tolerance || this.getTickAvgAngle() / 2;
      var _self = this,
            pointCache = _self.get('pointCache');
        return Util.snapFloor(pointCache,offset);
    },
    /**
     * 获取栅格项的配置信息,一般是起始点信息
     * @protected
     */
    getGridItemCfg : function(point){
      var _self = this,
        center = _self.getCenter();
      return{
        x1 : center.x,
        y1 : center.y,
        x2 : point.x,
        y2 : point.y
      };
    },
    //重置点的位置
    addLabel : function(text,point,angle){

      var _self = this,
        margin = _self.get('margin'),
        radius = _self.getRadius();

      point = _self.getCirclePoint(angle,radius + margin);

      Circle.superclass.addLabel.call(_self,text,point);
    },
    /**
     * @protected
     * 获取标示坐标点的线的终点
     */
    getTickEnd : function(start,angle){
      var _self = this,
        radius = _self.getRadius(),
        tickLine = _self.get('tickLine'),
        length = tickLine.value,
        point = _self.getCirclePoint(angle,radius + length);
      return {
        x2 : point.x,
        y2 : point.y
      };
    }

  });

  return Circle;
});
Example #15
0
File: form.js Project: dxq613/bui-1
if(r.valid(),r.isValid()){if(0==r.onBeforeSubmit())return;i===t.NORMAL?r.get("el")[0].submit():i===t.AJAX&&r.ajaxSubmit(e)}else r.focusError()},ajaxSubmit:function(t){var r,i=this,n=i.get("method"),a=i.get("action"),o=i.get("callback"),l=i.get("submitMask"),u=i.serializeToObject(),s=e.merge(!0,{url:a,type:n,dataType:"json",data:u},t);t&&t.success&&(r=t.success),s.success=function(e){l&&l.hide&&l.hide(),r&&r(e),o&&o.call(i,e)},l&&l.show&&l.show(),$.ajax(s)},_initSubmitMask:function(){var r=this,i=r.get("submitType"),n=r.get("submitMask");i===t.AJAX&&n&&e.use("bui/mask",function(t){var i=$.isPlainObject(n)?n:{};n=new t.LoadMask(e.mix({el:r.get("el")},i)),r.set("submitMask",n)})},serializeToObject:function(){return e.FormHelper.serializeToObject(this.get("el")[0])},toObject:function(){return this.serializeToObject()},onBeforeSubmit:function(){return this.fire("beforesubmit")},reset:function(){var e=this,t=e.get("initRecord");e.setRecord(t)},resetTips:function(){var t=this,r=t.getFields();e.each(r,function(e){e.resetTip()})},destructor:function(){var e=this,t=e.get("buttonBar"),r=e.get("submitMask");t&&t.destroy&&t.destroy(),r&&r.destroy&&r.destroy()},_uiSetInitRecord:function(e){this.setRecord(e)}},{ATTRS:{action:{view:!0,value:""},allowTextSelection:{value:!0},events:{value:{beforesubmit:!1}},method:{view:!0,value:"get"},defaultLoaderCfg:{value:{autoLoad:!0,property:"record",dataType:"json"}},submitMask:{value:{msg:"\u6b63\u5728\u63d0\u4ea4\u3002\u3002\u3002"}},submitType:{value:"normal"},focusError:{value:!0},callback:{},decorateCfgFields:{value:{method:!0,action:!0}},defaultChildClass:{value:"form-field"},elTagName:{value:"form"},buttons:{},buttonBar:{shared:!1,value:{}},childContainer:{value:".x-form-fields"},initRecord:{},showError:{value:!1},xview:{value:i},tpl:{value:'<div class="x-form-fields"></div>'}}},{xclass:"form"});return n.View=i,n}),define("bui/form/horizontal",["bui/common","bui/form/form"],function(require){var e=(require("bui/common"),require("bui/form/form")),t=e.extend({getDefaultButtonBarCfg:function(){var e=this,t=e.get("buttons");return{autoRender:!0,elCls:"actions-bar toolbar row",tpl:'<div class="form-actions span21 offset3"></div>',childContainer:".form-actions",render:e.get("el"),items:t,defaultChildClass:"bar-item-button"}}},{ATTRS:{defaultChildClass:{value:"form-row"},errorTpl:{value:'<span class="valid-text"><span class="estate error"><span class="x-icon x-icon-mini x-icon-error">!</span><em>{error}</em></span></span>'},elCls:{value:"form-horizontal"}},PARSER:{}},{xclass:"form-horizontal"});return t}),define("bui/form/row",["bui/common","bui/form/fieldcontainer"],function(require){var e=(require("bui/common"),require("bui/form/fieldcontainer")),t=e.extend({},{ATTRS:{elCls:{value:"row"},defaultChildCfg:{value:{tpl:' <label class="control-label">{label}</label>                <div class="controls">                </div>',childContainer:".controls",showOneError:!0,controlContainer:".controls",elCls:"control-group span8",errorTpl:'<span class="valid-text"><span class="estate error"><span class="x-icon x-icon-mini x-icon-error">!</span><em>{error}</em></span></span>'}},defaultChildClass:{value:"form-field-text"}}},{xclass:"form-row"});return t}),define("bui/form/rule",["bui/common"],function(require){function e(e,t,n,a,o){i.isArray(n)&&i.isString(n[1])&&(n[1]&&(a=n[1]),n=n[0]);var l=e,u=l.get("validator"),s=r(e,n,a);return t=null==t?"":t,u.call(l,t,n,s,o)}function t(e){if(null==e)return{};if($.isPlainObject(e))return e;var t=e,r={};if(i.isArray(e)){for(var n=0;n<t.length;n++)r[n]=t[n];return r}return{0:e}}function r(e,r,n){var a=t(r);return n=n||e.get("msg"),i.substitute(n,a)}var i=require("bui/common"),n=function(e){n.superclass.constructor.call(this,e)};return i.extend(n,i.Base),n.ATTRS={name:{},msg:{},validator:{value:function(){}}},i.augment(n,{valid:function(t,r,i,n){var a=this;return e(a,t,r,i,n)}}),n}),define("bui/form/rules",["bui/form/rule"],function(require){function e(e){return parseFloat(e)}function t(e){return BUI.Date.parse(e)}function r(e,t,r){var i=e&&e.equals!==!1;return i?t>=r:t>r}function i(e){return""==e||null==e}function n(e,t,n,a){for(var o=a.getFields(),l=!0,u=1;u<o.length;u++){var s,c,d=o[u],f=o[u-1];if(d&&f&&(s=d.get("value"),c=f.get("value"),!i(s)&&!i(c)&&!r(t,s,c))){l=!1;break}}return l?null:n}function a(e){var t=e.getFieldAt(0);return t?t.get("name"):""}function o(e,t){if(BUI.isArray(t)||(t=[t]),!e||!t.length)return!1;var r=e?BUI.isArray(e)?e.length:1:0;if(1==t.length){var i=t[0];if(!i)return!0;if(i>r)return!1}else{var n=t[0],a=t[1];if(n>r||r>a)return!1}return!0}{var l=require("bui/form/rule"),u={},s={add:function(e){var t;return $.isPlainObject(e)?(t=e.name,u[t]=new l(e)):e.get&&(t=e.get("name"),u[t]=e),u[t]},remove:function(e){delete u[e]},get:function(e){return u[e]},valid:function(e,t,r,i,n){var a=s.get(e);return a?a.valid(t,r,i,n):null},isValid:function(e,t,r,i){return null==s.valid(e,t,r,i)}};s.add({name:"required",msg:"\u4e0d\u80fd\u4e3a\u7a7a\uff01",validator:function(e,t,r){return t!==!1&&/^\s*$/.test(e)?r:void 0}}),s.add({name:"equalTo",msg:"\u4e24\u6b21\u8f93\u5165\u4e0d\u4e00\u81f4\uff01",validator:function(e,t,r){var i=$(t);return i.length&&(t=i.val()),e===t?void 0:r}}),s.add({name:"min",msg:"\u8f93\u5165\u503c\u4e0d\u80fd\u5c0f\u4e8e{0}\uff01",validator:function(t,r,i){return BUI.isString(t)&&(t=t.replace(/\,/g,"")),""!==t&&e(t)<e(r)?i:void 0}}),s.add({name:"max",msg:"\u8f93\u5165\u503c\u4e0d\u80fd\u5927\u4e8e{0}\uff01",validator:function(t,r,i){return BUI.isString(t)&&(t=t.replace(/\,/g,"")),""!==t&&e(t)>e(r)?i:void 0}}),s.add({name:"length",msg:"\u8f93\u5165\u503c\u957f\u5ea6\u4e3a{0}\uff01",validator:function(e,t,r){return null!=e&&(e=$.trim(e.toString()),t!=e.length)?r:void 0}}),s.add({name:"minlength",msg:"\u8f93\u5165\u503c\u957f\u5ea6\u4e0d\u5c0f\u4e8e{0}\uff01",validator:function(e,t,r){if(null!=e){e=$.trim(e.toString());var i=e.length;if(t>i)return r}}}),s.add({name:"maxlength",msg:"\u8f93\u5165\u503c\u957f\u5ea6\u4e0d\u5927\u4e8e{0}\uff01",validator:function(e,t,r){if(e){e=$.trim(e.toString());var i=e.length;if(i>t)return r}}}),s.add({name:"regexp",msg:"\u8f93\u5165\u503c\u4e0d\u7b26\u5408{0}\uff01",validator:function(e,t,r){return t?t.test(e)?void 0:r:void 0}}),s.add({name:"email",msg:"\u4e0d\u662f\u6709\u6548\u7684\u90ae\u7bb1\u5730\u5740\uff01",validator:function(e,t,r){return e=$.trim(e),e?/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(e)?void 0:r:void 0}}),s.add({name:"date",msg:"\u4e0d\u662f\u6709\u6548\u7684\u65e5\u671f\uff01",validator:function(e,t,r){return BUI.isNumber(e)||BUI.isDate(e)?void 0:(e=$.trim(e),e?BUI.Date.isDateString(e)?void 0:r:void 0)}}),s.add({name:"minDate",msg:"\u8f93\u5165\u65e5\u671f\u4e0d\u80fd\u5c0f\u4e8e{0}\uff01",validator:function(e,r,i){if(e){var n=t(e);if(n&&n<t(r))return i}}}),s.add({name:"maxDate",msg:"\u8f93\u5165\u65e5\u671f\u4e0d\u80fd\u5927\u4e8e{0}\uff01",validator:function(e,r,i){if(e){var n=t(e);if(n&&n>t(r))return i}}}),s.add({name:"mobile",msg:"\u4e0d\u662f\u6709\u6548\u7684\u624b\u673a\u53f7\u7801\uff01",validator:function(e,t,r){return e=$.trim(e),e?/^\d{11}$/.test(e)?void 0:r:void 0}}),s.add({name:"number",msg:"\u4e0d\u662f\u6709\u6548\u7684\u6570\u5b57\uff01",validator:function(e,t,r){return BUI.isNumber(e)?void 0:(e=e.replace(/\,/g,""),isNaN(e)?r:void 0)}}),s.add({name:"dateRange",msg:"\u7ed3\u675f\u65e5\u671f\u4e0d\u80fd\u5c0f\u4e8e\u8d77\u59cb\u65e5\u671f\uff01",validator:n}),s.add({name:"numberRange",msg:"\u7ed3\u675f\u6570\u5b57\u4e0d\u80fd\u5c0f\u4e8e\u5f00\u59cb\u6570\u5b57\uff01",validator:n}),s.add({name:"checkRange",msg:"\u5fc5\u987b\u9009\u4e2d{0}\u9879\uff01",validator:function(e,t,r,i){var n,l=a(i),u=t;return l&&u&&(n=e[l],!o(n,u))?r:null}})}return s}),define("bui/form/remote",["bui/common"],function(require){var e=require("bui/common"),t=function(){};t.ATTRS={isLoading:{},loadingEl:{}},t.prototype={getLoadingContainer:function(){},_setLoading:function(){var e=this,t=e.get("loadingEl"),r=e.get("loadingTpl");r&&!t&&(t=$(r).appendTo(e.getLoadingContainer()),e.setInternal("loadingEl",t))},_clearLoading:function(){var e=this,t=e.get("loadingEl");t&&(t.remove(),e.setInternal("loadingEl",null))},_uiSetIsLoading:function(e){var t=this;e?t._setLoading():t._clearLoading()}};var r=function(){};return r.ATTRS={defaultRemote:{value:{method:"GET",cache:!0,callback:function(e){return e}}},remoteDaly:{value:500},cacheMap:{value:{}},loadingTpl:{view:!0,value:'<img src="http://img02.taobaocdn.com/tps/i2/T1NU8nXCVcXXaHNz_X-16-16.gif" alt="loading"/>'},isLoading:{view:!0,value:!1},remote:{setter:function(t){return e.isString(t)&&(t={url:t}),t}},remoteHandler:{},events:{value:{remotecomplete:!1,remotestart:!1}}},r.prototype={__bindUI:function(){var e=this;e.on("valid",function(){if(e.get("remote")&&e.isValid()&&!e.get("pauseValid")){var t=e.getControlValue(),r=e.getRemoteParams();e._startRemote(r,t)}}),e.on("error",function(){e.get("remote")&&e._cancelRemote()})},_startRemote:function(e,t){function r(){i._remoteValid(e,n,t),i.set("isLoading",!0)}var i=this,n=i.get("remoteHandler"),a=i.get("cacheMap"),o=i.get("remoteDaly");return n&&i._cancelRemote(n),null!=a[t]?void i._validResult(i._getCallback(),a[t]):(n=setTimeout(r,o),void i.setInternal("remoteHandler",n))},_validResult:function(e,t){var r=this,i=e(t);r.onRemoteComplete(i,t)},onRemoteComplete:function(e,t,r){var i=this;r==i.get("remoteHandler")&&(i.fire("remotecomplete",{error:e,data:t}),i.set("isLoading",!1),i.setInternal("remoteHandler",null))},_getOptions:function(t){var r=this,i=r.get("remote"),n=r.get("defaultRemote"),a=e.merge(n,i,{data:t});return a},_getCallback:function(){return this._getOptions().callback},_remoteValid:function(e,t,r){var i=this,n=i.get("cacheMap"),a=i._getOptions(e);a.success=function(e){var o=a.callback,l=o(e);n[r]=e,i.onRemoteComplete(l,e,t)},a.error=function(e,r,n){i.onRemoteComplete(n,null,t)},i.fire("remotestart",{data:e}),$.ajax(a)},getRemoteParams:function(){},clearCache:function(){this.set("cacheMap",{})},_cancelRemote:function(e){var t=this;e=e||t.get("remoteHandler"),e&&(clearTimeout(e),t.setInternal("remoteHandler",null)),t.set("isLoading",!1)}},r.View=t,r});
Example #16
0
define('bui/grid/plugins/columnresize',function (require) {
  

  var BUI = require('bui/common'),
    NUM_DIS = 15,
    NUM_MIN = 30,
    STYLE_CURSOR = 'col-resize';

  var Resize = function(cfg){
    Resize.superclass.constructor.call(this,cfg);
  };

  Resize.ATTRS = {
    /**
     * @private
     * 是否正在拖拽
     * @type {Boolean}
     */
    resizing : {
      value : false
    },
    //拖拽属性
    draging : {

    }
  };

  BUI.extend(Resize,BUI.Base);

  BUI.augment(Resize,{

    renderUI : function(grid){
      this.set('grid',grid);
    },

    bindUI : function(grid){
      var _self = this,
        header = grid.get('header'),
        curCol,
        preCol,
        direction;

      header.get('el').delegate('.bui-grid-hd','mouseenter',function(ev){
        var resizing = _self.get('resizing');
        if(!resizing){
          var sender = ev.currentTarget;
          curCol = _self._getColumn(sender);
          preCol = _self._getPreCol(curCol);
        }
      }).delegate('.bui-grid-hd','mouseleave',function(ev){
        var resizing = _self.get('resizing');
        if(!resizing && curCol){
          curCol.get('el').css('cursor','');
          curCol = null; 
        }
      }).delegate('.bui-grid-hd','mousemove',function(ev){
        var resizing = _self.get('resizing');

        if(!resizing && curCol){
          var el = curCol.get('el'),
            pageX = ev.pageX,
            offset = el.offset(),
            left = offset.left,
            width = el.width();
            
          if(pageX - left < NUM_DIS && preCol){
            el.css('cursor',STYLE_CURSOR);
            direction = -1;
          }else if((left + width) - pageX < NUM_DIS){
            direction = 1;
            el.css('cursor',STYLE_CURSOR);
          }else{
            curCol.get('el').css('cursor','');
          }
        }

        if(resizing){
          ev.preventDefault();
          var draging = _self.get('draging'),
            start = draging.start,
            pageX = ev.pageX,
            dif = pageX - start,
            width = direction > 0 ? curCol.get('width') : preCol.get('width'),
            toWidth = width + dif;
          if(toWidth > NUM_MIN && toWidth < grid.get('el').width()){
            draging.end = pageX;
            _self.moveDrag(pageX);
          }
        }

      }).delegate('.bui-grid-hd','mousedown',function(ev){
        var resizing = _self.get('resizing');
        if(!resizing && curCol && curCol.get('el').css('cursor') == STYLE_CURSOR){
          ev.preventDefault();
          _self.showDrag(ev.pageX);
          bindDraging();
        }
      });

      function callback(ev){
        var draging = _self.get('draging')
        if(curCol && draging){
          var col = direction > 0 ? curCol : preCol,
            width = col.get('width'),
            dif = draging.end - draging.start;

          _self.hideDrag();
          if(grid.get('forceFit')){
            var originWidth = col.get('originWidth'),
              factor = width / originWidth,
              toWidth = (width + dif) / factor;
           // console.log(originWidth + ' ,'+width);
            col.set('originWidth',toWidth);
            col.set('width',toWidth);
            //

          }else{
            col.set('width',width + dif);
          }
          
        }    
        $(document).off('mouseup',callback);
      }

      function bindDraging(){
        $(document).on('mouseup',callback);
      }

    },
    //显示拖拽
    showDrag : function(pageX){
      var _self = this,
        grid = _self.get('grid'),
        header = grid.get('header'),
        bodyEl = grid.get('el').find('.bui-grid-body'),
        height = header.get('el').height() + bodyEl.height(),
        offset = header.get('el').offset(),
        dragEl = _self.get('dragEl');

      if(!dragEl){
        var  tpl = '<div class="bui-drag-line"></div>';
        dragEl = $(tpl).appendTo('body');
        _self.set('dragEl',dragEl);
      }

      dragEl.css({
        top: offset.top,
        left: pageX,
        height : height
      });

      _self.set('resizing',true);

      _self.set('draging',{
        start : pageX,
        end : pageX
      });
      dragEl.show();
    },
    //关闭拖拽
    hideDrag : function(){
      var _self = this,
        dragEl = _self.get('dragEl');
      dragEl && dragEl.hide();
      _self.set('draging',null);
      _self.set('resizing',false);
    },
    //移动drag
    moveDrag : function(pageX){
      var _self = this,
        dragEl = _self.get('dragEl');
      dragEl && dragEl.css('left',pageX);
    },
    //获取点击的列
    _getColumn : function(element){
      var _self = this,
        columns = _self.get('grid').get('columns'),
        rst = null;
      BUI.each(columns,function(column){
        if(column.containsElement(element)){
          rst = column;
          return false;
        }
      });

      return rst;
    },
    //获取前一个列
    _getPreCol : function(col){
      var _self = this,
        columns = _self.get('grid').get('columns'),
        rst = null;
      BUI.each(columns,function(column,index){
        if(column == col){
          return false;
        }else if(column.get('visible')){
          rst = column;
        }
        
      });

      return rst;
    }
  });

  return Resize;
});
Example #17
0
File: markers.js Project: imhu/bui
define('bui/chart/markers',['bui/chart/plotitem','bui/graphic','bui/chart/activedgroup'],function (require) {

	var BUI = require('bui/common'),
		Util = require('bui/graphic').Util,
		Group = require('bui/chart/activedgroup'),
		PlotItem = require('bui/chart/plotitem');

		
	
	/**
	 * @class BUI.Chart.Markers
	 * 显示点的标记集合
	 * @extends BUI.Chart.PlotItem
	 */
	var Markers = function(cfg){
		Markers.superclass.constructor.call(this,cfg);
	};


	BUI.extend(Markers,PlotItem);

	BUI.mixin(Markers,[Group]);

	Markers.ATTRS = {
		elCls : {
			value : 'x-chart-markers'
		},
		zIndex : {
			value : 3
		},
		/**
		 * 标记的配置项
		 * @type {Object}
		 */
		marker : {

		},
		/**
		 * 标记处于active状态时的配置项
		 * @type {Object}
		 */
		actived : {

		},
		/**
		 * 是否只有一个marker
		 * @type {Boolean}
		 */
		single : {
			value : false
		},
		/**
		 * @private
		 */
		xCache : {
			value : [],
			shared : false
		}

	};

	BUI.augment(Markers,{

		//渲染控件
		renderUI : function(){
			var _self = this;
			Markers.superclass.renderUI.call(_self);
			_self._drawMarkers();
		},
		/**
		 * @protected
		 * 是否激活
		 * @param {BUI.Chart.Actived} item 可以被激活的元素
		 * @return {BUI.Chart.Actived[]} 可以被激活的元素集合
		 */
		isItemActived : function(item){
			return item.get('actived');
		},
		/**
		 * @protected
		 * 设置激活状态
		 * @param {BUI.Chart.Actived} item 可以被激活的元素
		 * @param {Boolean} actived 是否激活
		 */
		setItemActived : function(item,actived){
			var _self = this,
				marker = _self.get('marker'),
				activedCfg = _self.get('actived'),
				single = _self.get('single');
			if(actived){
				item.attr(activedCfg);
				item.set('actived',true);
				if(single && !item.get('visible')){
					item.show();
				}
			}else{
				item.attr(marker);
				item.set('actived',false);
				if(single){
					item.hide();
				}
			}
		},
		/**
		 * 标记改变
		 * @param {Array} items 标记集合
		 */
		change : function(items){
			var _self = this,
				children = _self.get('children'),
				xCache = [];
			

			_self.set('items',items);

			BUI.each(items,function(item,index){
				var marker = children[index];
				if(marker){
					if(Util.svg){
						marker.animate({
							x : item.x,
							y : item.y
						},400);
					}else{
						marker.attr(item);
					}
					
				}
				xCache.push(item.x);
			});

			_self.set('xCache',xCache); //清空缓存

		},
		_drawMarkers : function(){
			var _self = this,
				single = _self.get('single'),
				items = _self.get('items');

			if(single){
				items = [{x : 0 ,y : 0,visible:false}];
			}
			BUI.each(items,function(item){
				_self._addMarker(item)
			});
		},
		/**
		 * 添加marker
		 * @param {Object} item marker的配置信息
		 */
		addMarker : function(item){
			return this._addMarker(item);
		},
		//添加marker
		_addMarker : function(item){
			var _self = this,
				xCache = _self.get('xCache'),
				marker = _self.get('marker'),
				cfg = BUI.merge(marker,item);

			xCache.push(parseInt(item.x));
			return _self.addShape('marker',cfg);
				
		},
		/**
		 * 获取逼近的marker
		 * @return {BUI.Graphic.Shape} marker
		 */
		getSnapMarker : function(point,tolerance){
			var _self = this,
				xCache = _self.get('xCache'),
				single = _self.get('single'),
				offset = BUI.isObject(point) ? point.x : point;

			if(single){
				//var marker = _self.getChildAt(0);
				return _self.getChildAt(0);
			}

			var	snap = Util.snapTo(xCache,offset,tolerance),
				index = BUI.Array.indexOf(snap,xCache);
			return _self.getChildAt(index);
		}
	});

	return Markers;
});
Example #18
0
File: legend.js Project: 2zyun/bui
define('bui/chart/legend',['bui/common','bui/chart/plotitem','bui/chart/legenditem'],function (require) {

  var BUI = require('bui/common'),
    PlotItem = require('bui/chart/plotitem'),
    Item = require('bui/chart/legenditem'),
    LINE_HEIGHT = 15,
    PADDING = 5;

  function min(x,y){
    return x > y ? y : x;
  }
  function max(x,y){
    return x > y ? x : y;
  }

  /**
   * @class BUI.Chart.Legend
   * 图例
   * @extends BUI.Chart.PlotItem
   * @mixins BUI.Chart.ActivedGroup
   */
  var Legend = function(cfg){
    Legend.superclass.constructor.call(this,cfg);
  };

  Legend.ATTRS = {
    zIndex : {
      value : 8
    },
    elCls : {
      value : 'x-chart-legend'
    },
    /**
     * 子项的配置项
     * @type {Array}
     */
    items : {

    },
    /**
     * 布局方式: horizontal,vertical
     * @type {String}
     */
    layout : {
      value : 'horizontal'
    },
    /**
     * 对齐位置的偏移量x
     * @type {Number}
     */
    dx : {
      value : 0
    },
    /**
     * 对齐位置的偏移量y
     * @type {Number}
     */
    dy : {
      value : 0
    },
    /**
     * 对齐方式,top,left,right,bottom
     * @type {String}
     */
    align : {
      value : 'bottom'
    },
    /**
     * 边框的配置项,一般是一个正方形
     * @type {Object}
     */
    back : {
      value : {
        stroke : '#909090',
        fill : '#fff'
      }
    }

  }

  BUI.extend(Legend,PlotItem);

  BUI.augment(Legend,{

    renderUI : function(){
      var _self = this
      Legend.superclass.renderUI.call(_self);
      _self._renderItems();
      _self._renderBorder();    
    },
    bindUI : function(){
      Legend.superclass.bindUI.call(_self);
      var _self = this;
      _self.on('mousemove',function(ev){
        ev.stopPropagation();
      });
    },
    _renderItems : function(){
      var _self = this,
        items = _self.get('items'),
        itemsGroup = _self.addGroup();

      _self.set('itemsGroup',itemsGroup);

      BUI.each(items,function(item,index){
        _self._addItem(item,index);
      });
    },
    /**
     * 添加图例
     * @param {Object} item 图例项的配置信息
     */
    addItem : function(item){
      var _self = this,
        items = _self.get('items');

      _self._addItem(item,items.length);
      _self.resetBorder();
      _self.resetPosition();
    },
    //添加图例
    _addItem : function(item,index){
      var _self = this,
        itemsGroup = _self.get('itemsGroup'),
        x = _self._getNextX(),
        y = _self._getNextY(),
        cfg = BUI.mix({x : x,y : y},item);

      cfg.legend = _self;
      itemsGroup.addGroup(Item,cfg);
    },

    //生成边框
    _renderBorder : function(){
      var _self = this,
        border = _self.get('back'),
        width,
        height,
        cfg,
        shape;

      if(border){
        width = _self._getTotalWidth();
        height = _self._getTotalHeight();

        cfg = BUI.mix({
          r: 5,
          width : width,
          height : height
        },border);

        shape = _self.addShape('rect',cfg);
        shape.toBack();
        _self.set('borderShape',shape);
      }
    },
    //重置边框
    resetBorder : function(){
      var _self = this,
        borderShape = _self.get('borderShape');
      if(borderShape){
        borderShape.attr({
          width : _self._getTotalWidth(),
          height : _self._getTotalHeight()
        });
      }
    },
    //定位
    resetPosition : function(){
      var _self = this,
        align = _self.get('align'),
        plotRange = _self.get('plotRange'),
        top = plotRange.tl,
        end = plotRange.br,
        dx = _self.get('dx'),
        dy = _self.get('dy'),
        width = _self._getTotalWidth(),
        x,y;
      switch(align){
        case 'top' :
          x = top.x;
          y = top.y;
          break;
        case 'left':
          x = top.x - width;
          y = (top.y + end.y)/2;
          break;
        case 'right':
          x = end.x;
          y = (top.y + end.y)/2;
          break;
        case 'bottom':
          x = (top.x + end.x) /2 - width/2;
          y = end.y;
        default : 
          break;
      }

     _self.move(x+dx,y+dy);

    },
    //获取总的个数
    _getCount : function(){

      return this.get('itemsGroup').get('children').length;
    },
    //获取下一个图例项的x坐标
    _getNextX : function(){
      var _self = this,
        layout = _self.get('layout'),
        
        nextX = PADDING;
      if(layout == 'horizontal'){
        var children = _self.get('itemsGroup').get('children');
        BUI.each(children,function(item){
          if(item.isGroup){
            nextX += (item.getWidth() + PADDING);
          }
        });
      }
      return nextX;
    },
    //获取下一个图例项的y坐标
    _getNextY : function(){
      var _self = this,
        layout = _self.get('layout');
      if(layout == 'horizontal'){
        return PADDING;
      }else{
        return LINE_HEIGHT * _self._getCount() + PADDING ;
      }
    },
    //获取总的宽度
    _getTotalWidth : function(){
      var _self = this;
      if(_self.get('layout') == 'horizontal'){
        return this._getNextX();
      }else{
        var children = _self.get('itemsGroup').get('children'),
          max = PADDING;
        BUI.each(children,function(item){
          var width = item.getWidth();
          if(item.isGroup && width > max){
            max = width;
          }
        });
        return max + PADDING * 2;
      }
      
    },
    //获取整体的高度
    _getTotalHeight : function(){
      var _self = this,
        nextY = _self._getNextY();

      if(_self.get('layout') == 'horizontal'){
        return LINE_HEIGHT + PADDING * 2;
      }
      return nextY + PADDING;
    }
  });

  return Legend;
});
Example #19
0
File: base.js Project: dericgit/bui
define('bui/layout/baseitem',['bui/common'],function (require) {

	var BUI = require('bui/common');

	function parseValue(attrs,value){
		if(!BUI.isString(value)){ //只转换字符串
			return value;
		}
		if(value.indexOf('{') != -1){ //如果有可替换的值,进行计算
			value = BUI.substitute(value,attrs);
			value = BUI.JSON.looseParse(value); //转成对应的值
		}
		return value;
	}

	/**
	 * @class BUI.Layout.Item
	 * 布局插件的子项,用于操作位置、宽度等
	 * @extends BUI.Base
	 */
	var Item = function(config){
		Item.superclass.constructor.call(this,config);
		this.init();
	};

	Item.ATTRS = {

		/**
		 * 自适应内部控件,自适应的类型:
		 *   - none : 内部控件不自适应(默认)
		 *   - width : 内部控件自适应宽度,当layout重新布局时宽度自适应
		 *   - height : 内部控件自适应高度,当layout重新布局时高度自适应
		 *   - both : 内部控件自适应宽高,当layout重新布局时宽度、高度自适应
		 * @type {String}
		 */
		fit : {
			value : 'none'
		},
		/**
		 * 所属的layout
		 * @type {BUI.Layout.Abstract}
		 */
		layout : {

		},
		/**
		 * @private
		 * 封装的控件
		 * @type {Object}
		 */
		control : {

		},
		/**
		 * 封装控件的容器的样式,默认为空
		 * @type {string}
		 */
		wraperCls : {

		},
		/**
		 * 容器
		 * @type {jQuery}
		 */
		container : {

		},
		/**
		 * 如果srcNode指定,那么不会使用container属性,也不会生成DOM
		 * @type {jQuery}
		 */
		srcNode : {

		},
		/**
		 * @protected
		 * 同步的css属性
		 * @type {Array}
		 */
		cssProperties : {
			value : ['width','height']
		},
		/**
		 * @protected
		 * 同步的attributes
		 * @type {Array}
		 */
		attrProperties : {

		},
		/**
		 * 状态相关的字段
		 * @type {Array}
		 */
		statusProperties : {

		},
		/**
		 * 附加模板
		 * @type {Object}
		 */
		tplProperties : {

		},
		/**
		 * 当前项的DOM
		 * @type {jQuery}
		 */
		el : {

		},
		/**
		 * 应用的样式
		 * @type {Object}
		 */
		elCls : {

		},
		/**
		 * 模板
		 * @type {String}
		 */
		tpl : {

		}
	};

	BUI.extend(Item,BUI.Base);

	BUI.augment(Item,{

		/**
		 * 初始化
		 */
		init : function(){
			var _self = this,
				el = _self._wrapControl();
			_self.set('el',el);
			_self.syncItem();
		},
		/**
		 * 获取选项的DOM节点
		 * @return {jQuery} 操作节点
		 */
		getElement : function(){
			return this.get('el');
		},
		//封装控件
		_wrapControl : function(){
	
			var _self = this,
				control = _self.get('control'),
				controlEl = control.get('el'),
				elCls = _self.get('elCls'),
				container = _self._getContainer(controlEl),
				tpl = BUI.substitute(_self.get('tpl'),_self.getLayoutAttrs()) ,
				node = $(tpl).appendTo(container),
				bodyEl;
			if(elCls){
				node.addClass(elCls);
			}
			bodyEl = _self.getControlContainer(node);
			controlEl.appendTo(bodyEl);
			_self.set('bodyEl',bodyEl);

			return node;
		},
		/**
		 * 获取内部控件的容器
		 * @return {jQuery} 容器
		 */
		getControlContainer : function(el){
			var _self = this,
				wraperCls = _self.get('wraperCls');
			if(wraperCls){
				return el.find('.' + wraperCls);
			}
			return el;
		},
		/**
		 * 同步属性到子项,同步css和attr
		 */
		syncItem : function(attrs){
			attrs = attrs || this.getLayoutAttrs();
			var _self = this,
				el = _self.get('el'),
				css = _self._getSyncCss(attrs),
				attr = _self._getSyncAttr(attrs);
			
			el.css(css);
			el.attr(attr);
			_self.syncStatus(el,attrs); //同步状态
			_self.syncElements(el,attrs); //同步DOM元素
			_self.syncFit(); //同步内部控件的宽高
		},
		/**
		 * 根据属性附加一些元素
		 * @protected
		 */
		syncElements : function(el,attrs){
			var _self = this,
				tplProperties = _self.get('tplProperties');

			if(tplProperties){
				BUI.each(tplProperties,function(item){
					_self.synTpl(el,item,attrs);
				});
			}
		},
		/**
		 * @protected
		 * 同步选项
		 */
		synTpl : function(el,item,attrs){
			var _self = this,
				name = item.name,
				elName = '_'+name + 'El', //title 使用_titleEl作为临时变量存储对应的DOM 
				tpl,
				m, //使用的附加方法
				tplEl = _self.get(elName);
			if(attrs[name]){
				if(!tplEl){
					tpl = _self.get(item.value);
					tpl = BUI.substitute(tpl,attrs);
					m = item.prev ? 'prependTo' : 'appendTo';
					tplEl = $(tpl)[m](el);
					_self.set(elName,tplEl);
				}
			}else if(tplEl){
				tplEl.remove();
			}
		},
		/**
		 * @protected
		 * 同步状态
		 */
    syncStatus : function(el,attrs){
    	el = el || this.get('el');
    	attrs = attrs || this.getLayoutAttrs();
    	var _self = this,
    		statusProperties = _self.get('statusProperties');
    	if(statusProperties){
    		BUI.each(statusProperties,function(status){
    			var value = _self.get(status);
    			if(value != null){
    				var m = value ? 'addClass' : 'removeClass',
    					cls = 'x-' + status;
    				el[m](cls);
    			}
    		});
    	}
		},
		/**
		 * 同步自适应
		 */
		syncFit : function(){
			var _self = this,
				control = _self.get('control'),
				fit = _self.get('fit');
			if(fit === 'none'){
				return;
			}
			if(fit === 'width'){
				_self._syncControlWidth(control);
				return;
			}
			if(fit === 'height'){
				_self._syncControlHeight(control);
				return;
			}
			if(fit === 'both'){
				_self._syncControlWidth(control);
				_self._syncControlHeight(control);
			}
		},
		//同步控件的宽度
		_syncControlWidth : function(control){
			var _self = this,
				width = _self.get('el').width(),
				appendWidth = control.getAppendWidth();
			control.set('width',width - appendWidth);

		},
		//同步控件的高度
		_syncControlHeight : function(control){
			var _self = this,
				height = _self._getFitHeight(),
				appendHeight = control.getAppendHeight();
			control.set('height',height - appendHeight);
		},
		_getFitHeight : function(){
			var _self = this,
				el = _self.get('el'),
				bodyEl = _self.get('bodyEl'),
				siblings,
				outerHeight = el.height(),
				height = outerHeight;
			if(bodyEl[0] == el[0]){ //如果控件的容器等于外层容器
				return outerHeight;
			}
			siblings = bodyEl.siblings(); //获取外层容器减去兄弟元素的高度
			BUI.each(siblings,function(elem){
				var node = $(elem);
				if(node.css('position') !== 'absolute'){
					height -= node.outerHeight();
				}
			});
			return height;
		},
		/**
		 * @protected
		 * 获取布局相关的属性
		 * @return {Object} 获取布局相关的属性
		 */
		getLayoutAttrs : function(){
			return this.getAttrVals();
		},
		//获取需要同步的css属性
		_getSyncCss : function(attrs){
			var _self = this,
				properties = _self.get('cssProperties'),
				dynacAttrs = _self._getDynacAttrs(),
				css = {};

			BUI.each(properties,function(p){
				css[p] = parseValue(dynacAttrs,attrs[p]);
			});
			return css;
		},
		//获取动态的值,进行计算
		_getDynacAttrs : function(){
			var _self = this,
				container = _self.get('container');
			return {
				width : container.width(),
				height : container.height()
			};
		},
		//获取需要
		_getSyncAttr : function(attrs){
			var _self = this,
				properties = _self.get('attrProperties'),
				attr = {};

			BUI.each(properties,function(p){
				attr[p] = attrs[p];
			});
			return attr;
		},
		//获取容器
		_getContainer : function(controlEl){
			var _self = this,
				container = _self.get('container');
			if(container){
				return container;
			}
			return controlEl.parent();
		},	
		/**
		 * 释放
		 */
		destroy : function(){
			var _self = this;
			_self.get('el').remove();
			_self.off();
			_self.clearAttrVals();
		}
	});

	return Item;
});
Example #20
0
File: time.js Project: 2zyun/bui
define('bui/chart/timeaxis',['bui/common','bui/chart/numberaxis'],function (require) {

  var BUI = require('bui/common'),
    NAixs = require('bui/chart/numberaxis');

  function parseTime(d){
    if(d instanceof Date){
      return d.getTime();
    }
    if(BUI.isNumber(d)){
      return d;
    }
    var date = d;
    if(BUI.isString(d)){
      date = d.replace('-','\/');
      date = new Date(date).getTime();
    }
    return date;
  }

  /**
   * @class BUI.Chart.Axis.Time
   * 时间坐标轴
   */
  var Time = function(cfg){
    Time.superclass.constructor.call(this,cfg)
  };

  Time.ATTRS = {

    /**
     * 开始日期时间
     * @type {Date}
     */
    startDate : {

    },
    dateFormat : {

    },
    /**
     * 结束日期时间
     * @type {Date}
     */
    endDate : {

    }
  };

  BUI.extend(Time,NAixs);

  BUI.augment(Time,{
    //渲染控件前
    beforeRenderUI : function(){
      var _self = this;
      
      
      var startTime = parseTime(_self.get('startDate')),
        endTime = parseTime(_self.get('endDate'));
      if(startTime && !_self.get('min')){
        _self.set('min',startTime);
      }
      if(endTime && !_self.get('max')){
        _self.set('max',endTime);
      }

      Time.superclass.beforeRenderUI.call(_self);

    }
  });

  return Time;
});
Example #21
0
define('bui/form/rule',['bui/common'],function (require) {

  var BUI = require('bui/common');
  /**
   * @class BUI.Form.Rule
   * 验证规则
   * @extends BUI.Base
   */
  var Rule = function (config){
    Rule.superclass.constructor.call(this,config);
  }

  BUI.extend(Rule,BUI.Base);

  Rule.ATTRS = {
    /**
     * 规则名称
     * @type {String}
     */
    name : {

    },
    /**
     * 验证失败信息
     * @type {String}
     */
    msg : {

    },
    /**
     * 验证函数
     * @type {Function}
     */
    validator : {
      value : function(value,baseValue,formatedMsg,control){

      }
    }
  }

  //是否通过验证
  function valid(self,value,baseValue,msg,control){
    var _self = self,
      validator = _self.get('validator'),
      formatedMsg = formatError(self,baseValue,msg),
      valid = true;
    value = value == null ? '' : value;
    return validator.call(_self,value,baseValue,formatedMsg,control);
  }

  function parseParams(values){

    if(values == null){
      return {};
    }

    if($.isPlainObject(values)){
      return values;
    }

    var ars = values,
        rst = {};
    if(BUI.isArray(values)){

      for(var i = 0; i < ars.length; i++){
        rst[i] = ars[i];
      }
      return rst;
    }

    return {'0' : values};
  }

  function formatError(self,values,msg){
    var ars = parseParams(values); 
    msg = msg || self.get('msg');
    return BUI.substitute(msg,ars);
  }

  BUI.augment(Rule,{

    /**
     * 是否通过验证,该函数可以接收多个参数
     * @param  {*}  [value] 验证的值
     * @param  {*} [baseValue] 跟传入值相比较的值
     * @param {String} [msg] 验证失败后的错误信息,显示的错误中可以显示 baseValue中的信息
     * @param {BUI.Form.Field|BUI.Form.Group} [control] 发生验证的控件
     * @return {String}   通过验证返回 null ,未通过验证返回错误信息
     * 
     *         var msg = '输入数据必须在{0}和{1}之间!',
     *           rangeRule = new Rule({
     *             name : 'range',
     *             msg : msg,
     *             validator :function(value,range,msg){
     *               var min = range[0], //此处我们把range定义为数组,也可以定义为{min:0,max:200},那么在传入校验时跟此处一致即可
     *                 max = range[1];   //在错误信息中,使用用 '输入数据必须在{min}和{max}之间!',验证函数中的字符串已经进行格式化
     *               if(value < min || value > max){
     *                 return false;
     *               }
     *               return true;
     *             }
     *           });
     *         var range = [0,200],
     *           val = 100,
     *           error = rangeRule.valid(val,range);//msg可以在此处重新传入
     *         
     */
    valid : function(value,baseValue,msg,control){
      var _self = this;
      return valid(_self,value,baseValue,msg,control);
    }
  });

  return Rule;


});
Example #22
0
define('common/main',['bui/common','bui/tree','bui/tab'],function (require) {
  var win = window,
    BUI = require('bui/common'),
    Tree = require('bui/tree'),
    Tab = require('bui/tab');

  function setTopManager(mainPageObj){
    window.topManager = mainPageObj;
  }

  function addSearch(href,search){
    if(href.indexOf('?') !== -1){
      return href + '&' + search;
    }else{
      return href + '?' + search;
    }
  }

   //更改地址栏连接
  function setNavPosition(pageId){
    pageId = pageId||'';

    var str = '#' + pageId;

    location.hash = str;
  }

  function getNavPositionSetting(){
    var pos = location.hash,
      pageId ='',
      splitIndex = pos.lastIndexOf('/'),
      search = null;
    if(!pos){
      return null;
    }
    pageId = pos.replace('#','');
    if(splitIndex >= 0){
      pageId = pos.substring(splitIndex + 1);
    }
    search = getParam(pageId);
    if(search){
      pageId = pageId.replace('?'+search,'');
    }

    return {pageId : pageId,search : search};
  }

  function getParam(pageId){
    var index = pageId.indexOf('?');
    if(index >= 0){
      return pageId.substring(index + 1);
    }
    return null;
  }


  /**
   * @class Main
   * 主页控制逻辑类
   */
  var Main = function(config){
    Main.superclass.constructor.call(this,config);
    setTopManager(this);
  };

  Main.ATTRS = {
    header : {
      valueFn : function(){
        return $('#header');
      }
    },
    content : {
      valueFn : function(){
        return $('#content');
      }
    },
    footer : {
      valueFn : function(){
        return $('#footer');
      }
    },
    /**
     * 首页id
     * @type {String}
     */
    homePage : {

    },
    /**
     * 页面的后缀
     * @type {String}
     */
    urlSuffix : {
      value : 'html'
    },
    /**
     * 菜单配置
     * @type {Array}
     */
    menus : {

    },
    /**
     * 目录树
     * @type {Object}
     */
    tree : {

    },
    /**
     * 切换标签
     * @type {Object}
     */
    tab : {

    }
  };

  BUI.extend(Main,BUI.Base);

  BUI.augment(Main,{
    /**
     * 打开页面
     * @param  {Object} info 页面信息
     * @param {String} info.id 页面id
     * @param {String} info.title 信息的title
     * @param {String} info.href 页面地址
     * @param {Boolean} info.isClose 打开新页面后,是否关闭当前页面
     * @param {Boolean} info.closeable 页面是否可以关闭
     * @param {Boolean} info.reload 页面如果已经打开,是否刷新页面
     * @param {String} info.search 打开页面需要的参数 ?a=1&b=2
     */
    openPage : function(pageInfo){

      pageInfo.title = pageInfo.title || '新的标签页';
      var _self = this,
        reload = pageInfo.reload,
        tab = _self.get('tab'),
        tree = _self.get('tree'),
        treeItem = tree.findNode(pageInfo.id),
        curTabPage = tab.getActivedItem();/*,
        sourceId = curTabPage ? curTabPage.get('id') : null;*/
      if(treeItem){
        _self._setPageSelected(pageInfo.id,reload,pageInfo.search);
      }else{
        tab.addTab(pageInfo,reload);
      }
      
      if( pageInfo.isClose){
        curTabPage.close();
      }
      
    },
    /**
     * 关闭页面
     * @param  {String} id 页面id,可以为空,默认为当前页面
     */
    closePage:function(id){
      this.operatePage(id,'close');
    },
    //刷新
    /**
     * 刷新页面
     * @param  {String} id 页面id,可以为空,默认为当前页面
     */
    reloadPage : function(id){
      this.operatePage(id,'reload');
    },
    /**
     * 更改标题
     * @param  {String} title 页面标题
     * @param  {String} id 页面id,可以为空,默认为当前页面
     */
    setPageTitle : function(title,id){
      this.operatePage(id,'setTitle',[title]);
    },
    /**
     * 操作页面
     * @param  {String} id  页面id
     * @param  {String} action 操作名称
     * @param  {Array} args 操作参数,可以为空
     */
    operatePage : function(id,action,args){
      args = args || [];
      var _self = this,
        tab = _self.get('tab'),
        item = id ? tab.getItemById(id) : tab.getActivedItem();

      if(item && item[action]){
        item[action].apply(item,args);
      }
    },
    //初始化
    init : function(){
      this._initDom();
      this._initEvent();
    },
    //初始化DOM
    _initDom : function(){
      this.autoFitHeight();
      this._initTree();
      this._initTab();
      this._initHomePage();
      this._initNavPos();
    },
    //初始化tree
    _initTree : function(){
      var _self = this,
        menus = _self.get('menus'),
        tree = new Tree.TreeList({
          render: '#J_Tree',
          accordion : true,
          expandAnimate : true,
          expandEvent : 'itemclick', //单击展开节点
          collapseEvent : 'itemclick',
          nodes : menus
        });
      tree.render();
      _self.set('tree',tree);
    },
    //初始化标签
    _initTab : function(){
      var _self = this,
        tab = new Tab.NavTab({
          render : '#J_Tab'
        });
      tab.render();
      _self.set('tab',tab);
    },
    _initHomePage : function(){
      var _self = this,
        homePage = _self.get('homePage');
      if(homePage){
        _self._setPageSelected(homePage);
      }
    },
    //初始化导航位置
    _initNavPos : function(){
      var _self = this,
        info = getNavPositionSetting();
      if(info){
        _self._setPageSelected(info.pageId,true,info.search);
      }
    },
    //初始化事件
    _initEvent : function(){
      this._initResizeEvent();
      this._initNavEvent();
    },
    //初始化tree和tab的事件
    _initNavEvent : function(){
      var _self = this,
        tree = _self.get('tree'),
        tab = _self.get('tab');

      tree.on('itemclick',function(ev){
        var node = ev.item;

        if(node.leaf){
          _self._openPage(node,true);
        }
      });

      //选中的菜单发生改变后,更新链接上的页面编号
      tree.on('itemselected',function(ev){   
        var item = ev.item; 
        if(item){
          setNavPosition(item.id);
        }    
      });

      tab.on('activeChange',function(ev){
        var item = ev.item,
          node;
        if(item){
          node = tree.findNode(item.get('id'));
          tree.expandNode(node);
          tree.setSelected(node);
        }else{
          tree.clearSelection();
        }
      });

    },
    //初始化窗口变化事件
    _initResizeEvent : function(){
      var _self = this;
      $(win).on('resize',function(){
        _self.autoFitHeight();
      });
    },
    /**
     * 自动调整content高度
     */
    autoFitHeight : function(){
      var _self = this,
        headerEl = _self.get('header'),
        footerEl = _self.get('footer'),
        contentEl = _self.get('content'),
        winHeight = BUI.viewportHeight();
      contentEl.height(winHeight - footerEl.height() - headerEl.height());
    },
    //获取节点代表的页面地址
    _getNodeHref : function (node){
      var _self = this,
        path = node.path.join('/');
      if(path.indexOf('/') == 0){
        path = path.substring(1);
      }
      return path +'.' + _self.get('urlSuffix');
    },
    //设置节点选中
    _setPageSelected : function(pageId,isReload,search){
      var _self = this,
        tree = _self.get('tree'),
        tab = _self.get('tab'),
        node = tree.findNode(pageId),
        href = '',
        suffixIndex = -1;
      if(node){
        tree.expandNode(node);
        tree.setSelected(node);
        _self._openPage(node,isReload,search);

      }else if(pageId){

        var subDir = pageId.replace('-','/');

        if((suffixIndex = pageId.indexOf('.')) === -1){
          subDir += _self.get('urlSuffix');
        }
        href = search ? (subDir + '?' + search) : subDir;
        tab.addTab({id:pageId,title:'',href:href},!!isReload);
      }
    },
    _openPage : function(node,isReload,search){
      var _self = this,
        tab = _self.get('tab'),
        tree = _self.get('tree'),
        href = node.href || _self._getNodeHref(node);
      if(node.leaf){
        href = search ? (addSearch(href,search)) : href;
        tab.addTab({id: node.id, title: node.text,closeable : node.closeable, href: href},!!isReload);
      }else{
        tree.expandNode(node);
      }
      
    }

  });
  return Main;
});
Example #23
0
File: data.js Project: haodw/bui
define('bui/data/proxy',['bui/data/sortable'],function(require) {

  var Sortable = require('bui/data/sortable');

  /**
   * 数据代理对象,加载数据,
   * 一般不直接使用,在store里面决定使用什么类型的数据代理对象
   * @class BUI.Data.Proxy
   * @extends BUI.Base
   * @abstract 
   */
  var proxy = function(config){
    proxy.superclass.constructor.call(this,config);
  };

  proxy.ATTRS = {
    
  };

  BUI.extend(proxy,BUI.Base);

  BUI.augment(proxy,
  /**
   * @lends BUI.Data.Proxy.prototype
   * @ignore
   */
  {
    /**
     * @protected
     * @private
     */
    _read : function(params,callback){

    },
    /**
     * 读数据
     * @param  {Object} params 键值对形式的参数
     * @param {Function} callback 回调函数,函数原型 function(data){}
     * @param {Object} scope 回调函数的上下文
     */
    read : function(params,callback,scope){
      var _self = this;
      scope = scope || _self;

      _self._read(params,function(data){
        callback.call(scope,data);
      });
    },
    /**
     * 更新数据
     * @protected
     */
    update : function(params,callback,scope){

    }
  });

  /**
   * 异步加载数据的代理
   * @class BUI.Data.Proxy.Ajax
   * @extends BUI.Data.Proxy
   */
  var ajaxProxy = function(config){
    ajaxProxy.superclass.constructor.call(this,config);
  };

  ajaxProxy.ATTRS = BUI.mix(true,proxy.ATTRS,
  /**
   * @lends BUI.Data.Proxy.Ajax#
   * @ignore
   */
  {
    /**
     * 限制条数
     * @cfg {String} [limitParam='limit'] 
     */
    /**
     * 限制条数
     * @type {String}
     * @default 'limit'
     */
    limitParam : {
      value : 'limit'
    },
    /**
     * 起始纪录代表的字段
     * @cfg {String} [startParam='start']
     */
    /**
     * 起始纪录代表的字段
     * @type {String}
     */
    startParam : {
      value : 'start'
    },
    /**
     * 页码的字段名
     * @cfg {String} [pageIndexParam='pageIndex']
     */
    /**
     * 页码的字段名
     * @type {String}
     * @default 'pageIndex'
     */
    pageIndexParam : {
      value : 'pageIndex'
    },
    /**
    * 加载数据时,返回的格式,目前只支持"json、jsonp"格式<br>
    * @cfg {String} [dataType='json']
    */
   /**
    * 加载数据时,返回的格式,目前只支持"json、jsonp"格式<br>
    * @type {String}
    * @default "json"
    */
    dataType: {
      value : 'json'
    },
    /**
     * 获取数据的方式,'GET'或者'POST',默认为'GET'
     * @cfg {String} [method='GET']
     */
    /**
     * 获取数据的方式,'GET'或者'POST',默认为'GET'
     * @type {String}
     * @default 'GET'
     */
    method : {
      value : 'GET'
    },
    /**
     * 是否不读取缓存数据
     * @cfg {Boolean} [noCache=true]
     */
    /**
     * 是否不读取缓存数据
     * @type {Boolean}
     */
    noCache : {
      value : true
    },
    /**
     * 是否使用Cache
     * @type {Boolean}
     */
    cache : {
      value : false
    },
    /**
     * 加载数据的链接
     * @cfg {String} url
     * @required
     */
    /**
     * 加载数据的链接
     * @type {String}
     * @required
     */
    url :{

    }

  });
  BUI.extend(ajaxProxy,proxy);

  BUI.augment(ajaxProxy,{
    _processParams : function(params){
      var _self = this,
        arr = ['start','limit','pageIndex'];

      $.each(arr,function(field){
        var fieldParam = _self.get(field+'Param');
        if(fieldParam !== field){
          params[fieldParam] = params[field];
          delete params[field];
        }
      });
    },
    /**
     * @protected
     * @private
     */
    _read : function(params,callback){
      var _self = this;

      params = BUI.cloneObject(params);
      _self._processParams(params);

      $.ajax({
        url: _self.get('url'),
        type : _self.get('method'),
        dataType: _self.get('dataType'),
        data : params,
        cache : _self.get('cache'),
        success: function(data) {
          callback(data);
        },
        error : function(jqXHR, textStatus, errorThrown){
          var result = {
            exception : {
              status : textStatus,
              errorThrown: errorThrown,
              jqXHR : jqXHR
            }
          };
          callback(result);
        }
      });
    }
  });

  /**
   * 读取缓存的代理
   * @class BUI.Data.Proxy.Memery
   * @extends BUI.Data.Proxy
   * @mixins BUI.Data.Sortable
   */
  var memeryProxy = function(config){
    memeryProxy.superclass.constructor.call(this,config);
  };

  BUI.extend(memeryProxy,proxy);

  BUI.mixin(memeryProxy,[Sortable]);

  BUI.augment(memeryProxy,{
    /**
     * @protected
     * @ignore
     */
    _read : function(params,callback){
      var _self = this,
        pageable = params.pageable,
        start = params.start,
        sortField = params.sortField,
        sortDirection = params.sortDirection,
        limit = params.limit,
        data = _self.get('data'),
        rows = []; 

      _self.sortData(sortField,sortDirection); 

      if(limit){//分页时
        rows = data.slice(start,start + limit);
        callback({rows:rows,results:data.length});
      }else{//不分页时
        rows = data.slice(start);
        callback(rows);
      }
      
    }

  });

  proxy.Ajax = ajaxProxy;
  proxy.Memery = memeryProxy;

  return proxy;


});
Example #24
0
File: base.js Project: cnJun/bui
define('bui/uploader/type/base',['bui/common'], function(require) {

  var BUI = require('bui/common');
  /**
   * @class BUI.Uploader.UploadType
   *  上传方式类的基类,定义通用的事件和方法,一般不直接监听此类的事件
   * @extends BUI.Base
   */
  function UploadType(config) {
    var _self = this;
    //调用父类构造函数
    UploadType.superclass.constructor.call(_self, config);
  }

  UploadType.ATTRS = {
    /**
     * 当前处理的文件
     * @type {Object}
     */
    file: {
    },
    /**
     * 服务器端路径
     * @type String
     * @default ""
     */
    url: {
    },
    /**
     * 传送给服务器端的参数集合(会被转成hidden元素post到服务器端)
     * @type Object
     * @default {}
     */
    data: {
    },
    fileDataName: {
      value: 'Filedata'
    },
    events: {
      value: {
        /**
         * 开始上传后触发
         * @event
         * @param {Object} e 事件对象
         */
        start: false,
        /**
         * 停止上传后触发
         * @event
         * @param {Object} e 事件对象
         */
        cancel: false,
        /**
         * 上传成功后触发
         * @event
         * @param {Object} e 事件对象
         */
        success: false,
        /**
         * 上传失败后触发
         * @event
         * @param {Object} e 事件对象
         */
        error: false
      }
    }
  }

  
  //继承于Base,属性getter和setter委托于Base处理
  BUI.extend(UploadType, BUI.Base, {
    /**
     * 上传文件
     * @param {Object} File 数据对像
     * @description
     * 因为每种上传类型需要的数据都不一样,
     * Ajax需要File对像,
     * Iframe需要input[type=file]对像
     * 所以为了保持接口的一致性,这里的File对像不是浏览器原生的File对像,而是包含File和input的对像
     * 类似{name: 'test.jpg', size: 1024, textSize: '1K', input: {}, file: File}
     */
    upload: function(File) {
    },
    /** 
     * 停止上传
     */
    cancel: function(){
    },
    /**
     * 处理服务器端返回的结果集
     * @private
     */
    _processResponse: function(responseText){
      var _self = this,
        file = _self.get('file'),
        result;
      //格式化成json数据
      if(BUI.isString(responseText)){
        try{
          result = BUI.JSON.parse(responseText);
          // result = _self._fromUnicode(result);
        }catch(e){
          result = responseText;
        }
      }else if(BUI.isObject(responseText)){
        result = _self._fromUnicode(responseText);
      }
      BUI.log('服务器端输出:' + BUI.JSON.stringify(result));
      return result;
    },
    /**
     * 将unicode的中文转换成正常显示的文字,(为了修复flash的中文乱码问题)
     * @private
     */
    _fromUnicode:function(data){
        if(!BUI.isObject(data)) return data;
        _each(data);
        function _each(data){
            BUI.each(data,function(v,k){
                if(BUI.isObject(data[k])){
                    _each(data[k]);
                }else{
                    data[k] = BUI.isString(v) && BUI.fromUnicode(v) || v;
                }
            });
        }
        return data;
    },
    reset: function(){
    }
  });

  return UploadType;
});
Example #25
0
File: data.js Project: haodw/bui
define('bui/data/treestore',['bui/common','bui/data/node','bui/data/abstractstore'],function (require) {

  var BUI = require('bui/common'),
    Node = require('bui/data/node'),
    AbstractStore = require('bui/data/abstractstore');

  /**
   * @class BUI.Data.TreeStore
   * 树形数据缓冲类
   * <p>
   * <img src="../assets/img/class-data.jpg"/>
   * </p>
   * @extends BUI.Data.AbstractStore
   */
  function TreeStore(config){
    TreeStore.superclass.constructor.call(this,config);
  }

  TreeStore.ATTRS = {
    /**
     * 根节点
     * @type {Object}
     */
    root : {

    },
    /**
     * 数据映射,用于设置的数据跟@see {BUI.Data.Node} 不一致时,进行匹配。
     * 如果此属性为null,那么假设设置的对象是Node对象
     * @type {Object}
     */
    map : {

    },
    /**
     * 返回数据标示数据的字段
     * @type {Object}
     */
    dataProperty : {
      value : 'nodes'
    }
  }

  BUI.extend(TreeStore,AbstractStore);

  BUI.augment(TreeStore,{
    /**
     * @protected
     * @override
     * 初始化前
     */
    beforeInit:function(){
      this.initRoot();
    },
    //初始化数据,如果默认加载数据,则加载数据
    _initData : function(){
      var _self = this,
        autoLoad = _self.get('autoLoad'),
        root = _self.get('root');

      if(autoLoad){
        params = root.id ? {id : root.id}: {};
        _self.load(params);
      }
    },
    /**
     * @protected
     * 初始化根节点
     */
    initRoot : function(){
      var _self = this,
        map = _self.get('map'),
        root = _self.get('root');
      if(!root){
        root = {};
      }
      if(!root.isNode){
        root = new Node(root,map);
      }
      root.path = [root.id];
      root.level = 0;
      if(root.children){
        _self.setChildren(root,root.children);
      }
      _self.set('root',root);
    },
    /**
     * 添加节点
     * @param {BUI.Data.Node|Object} node 节点或者数据对象
     * @param {BUI.Data.Node} parent 父节点
     * @param {Number} index 添加节点的位置
     */
    add : function(node,parent,index){
      var _self = this,
        map = _self.get('map'),
        nodes = parent.children,
        nodeChildren = node.children || [];
      if(!node.isNode){
        node = new Node(node,map);
      }
      node.parent = parent;
      node.level = parent.level + 1;
      node.path = parent.path.concat(node.id);
      parent.leaf = false;
      index = index == null ? parent.children.length : index;
      BUI.Array.addAt(nodes,node,index);

      _self.setChildren(node,nodeChildren);
      _self.fire('add',{node : node,index : index});
      return node;
    },
    /**
     * 移除节点
     * @param {BUI.Data.Node} node 节点或者数据对象
     */
    remove : function(node){
      var parent = node.parent;
      BUI.Array.remove(parent.children,node);
      this.fire('remove',{node : node});
    },
    /**
     * 设置子节点
     * @param {BUI.Data.Node} node  节点
     * @param {Array} children 子节点
     */
    setChildren : function(node,children){
      var _self = this;
      node.children = [];
      if(!children.length){
        return;
      }
      BUI.each(children,function(item){
        _self.add(item,node);
      });
    },
    /**
     * 查找节点
     * @param  {String} id 节点Id
     * @param  {BUI.Data.Node} parent 父节点
     * @return {BUI.Data.Node} 节点
     */
    findNode : function(id,parent){
      var _self = this;

      if(!parent){
        var root = _self.get('root');
        if(root.id === id){
          return root;
        }
        return _self.findNode(id,root);
      }
      var children = parent.children,
        rst = null;
      BUI.each(children,function(item){
        if(item.id === id){
          rst = item;
        }else{
          rst = _self.findNode(id,item);
        }
        if(rst){
          return false;
        }
      });
      return rst;
    },
    /**
     * 是否包含指定节点,如果未指定父节点,从根节点开始搜索
     * @param  {BUI.Data.Node} node 节点
     * @param  {BUI.Data.Node} parent 父节点
     * @return {Boolean} 是否包含指定节点
     */
    contains : function(node,parent){
      var _self = this,
        findNode = _self.findNode(node.id,parent);
      return !!findNode;
    },
    /**
     * 加载完数据
     * @template
     */
    afterProcessLoad : function(data,params){
      var _self = this,
        id = params.id,
        dataProperty = _self.get('dataProperty'),
        node = _self.findNode(id) || _self.get('root');//如果找不到父元素,则放置在
      if(BUI.isArray(data)){
        _self.setChildren(node,data);
      }else{
        _self.setChildren(node,data[dataProperty]);
      }
      _self.fire('load',{node : node,params : params});
    },
    /**
     * 是否包含数据
     * @return {Boolean} 
     */
    hasData : function(){
      return this.get('root').children && this.get('root').children.length !== 0;
    },
    /**
     * 是否已经加载过,叶子节点或者存在字节点的节点
     * @param   {BUI.Data.Node} node 节点
     * @return {Boolean}  是否加载过
     */
    isLoaded : function(node){
      return node.leaf || node.children.length;
    },
    /**
     * 加载节点的子节点
     * @param  {BUI.Data.Node} node 节点
     */
    loadNode : function(node){
      var _self = this;
      //如果已经加载过,或者节点是叶子节点
      if(_self.isLoaded(node)){
        return ;
      }
      _self.load({id:node.id});
    }
  });

  return TreeStore;

});/**
Example #26
0
define('bui/chart/series/itemgroup',['bui/chart/baseseries'],function (require) {
  
  var BUI = require('bui/common'),
    Base = require('bui/chart/baseseries'),
    Util = require('bui/graphic').Util;

  /**
   * @class BUI.Chart.Series.ItemGroup
   * 包含数据序列子项的数据序列类,作为一个扩展可以用于柱状图、饼图
   */
  var Group = function(){

  };

  Group.ATTRS = {
    /**
     * 子项的配置信息
     * @type {Object}
     */
    item : {

    },
    /**
     * 存放子项的容器
     * @type {BUI.Graphic.Group}
     */
    group : {

    },
    /**
     * 是否允许选中
     * @type {Boolean}
     */
    allowPointSelect : {
      value : false
    },
    /**
     * 是否允许取消选中,选中状态下,继续点击则会取消选中
     * @type {Boolean}
     */
    cancelSelect : {
      value : true
    }
  }

  BUI.extend(Group,Base);

  BUI.augment(Group,{
    addItem : function(point,index){
      var _self = this,
        group = _self.get('group'),
        cfg;
      if(index == null){
        index = _self.getItems().length;
      }
      if(!group){
        group = _self.addGroup();
        _self.set('group',group);
      }

      cfg = _self.getItemCfg(point,index);
      if(_self.get('animate')){
        cfg.path = _self.pointToFactorPath(point,0);
      }else{
        cfg.path = _self.pointToPath(point);
      }

      var shape = group.addShape('path',cfg);
      shape.isSeriesItem = true;
      shape.set('point',point);
      return shape;
    },
     //绑定点击事件
    bindItemClick : function(){
      var _self = this,
        cancelSelect = _self.get('cancelSelect');
      
      _self.on('click',function(ev){
        var target = ev.target,
          shape = target.shape,
          selected;
        if(shape && shape.isSeriesItem){
          if(_self.get('allowPointSelect')){
            selected = shape.get('selected');
            if(cancelSelect && selected){
              _self.clearSelected(shape)
            }else{
              _self.setSelected(shape);
            }
          }
          _self.fireUpGroup('click',shape);
        }
      });
    },
    /**
     * 设置选中
     * @param {Object} item 选项
     */
    setSelected : function(item){
      var _self = this;
      if(!_self.isSelected(item)){
        _self.clearSelected();
        _self.setItemSelected(item,true);
        _self.onSelected(item);
      }
    },
    /**
     * @protected
     * points 发生改变时
     */
    changePoints : function(points){
      var _self = this,
        items = _self.getItems(),
        animate = _self.get('animate');

      points = points || _self.getPoints();

      //修改现有的path
      BUI.each(items,function(item,index){
        var point = points[index],
          prePoint,
          path;
        if(point){
          prePoint = item.get('point');
          item.set('point',point);
          item.set('prePoint',prePoint);

          if(!animate){
            path = _self.pointToPath(point);
            item.attr('path',path);
          }else{
            _self.animateItem(item,prePoint);
          }
          
        }
      });

      var count = points.length,
        length = items.length;

      //大于现有的点
      for (var i = length; i < count; i++) {
        var shape = _self.addItem(points[i],i);

        animate && _self.animateItem(shape,items[length - 1].get('prePoint'));
      }

      //小于现有的点
      for(var i = length - 1; i >= count; i--){
        var item = items[i];
        item.remove();
      }

    },
    
    /**
     * @protected
     * 触发选中事件
     */
    onSelected : function(item){
      this.fireUpGroup('selected',item);
    },
    /**
     * @protected
     * 触发移除选中
     */
    onUnSelected : function(item){
      this.fireUpGroup('unselected',item);
    },
    /**
     * 清除选中
     * @param  {Object} item 选项
     */
    clearSelected : function(item){
      var _self = this;
      item = item || _self.getSelected();
      if(item){
        _self.setItemSelected(item,false);
        _self.onUnSelected(item);
      }
    },
    /**
     * @protected
     * 设置选中
     * @param {Object} item  
     * @param {Boolean} selected 选中状态
     */
    setItemSelected : function(item,selected){

    },
    /**
     * 是否选中
     * @param  {Object}  item 是否选中
     * @return {Boolean}  是否选中
     */
    isSelected : function(item){
      return item && item.get('selected');
    },
    /**
     * 获取选中的项
     * @return {Object} 选中的项
     */
    getSelected : function(){
      var _self = this,
        items = _self.getItems(),
        rst;
      BUI.each(items,function(item){
        if(_self.isSelected(item)){
          rst = item;
          return false;
        }
      });
      return rst;
    },
    /**
     * @protected
     * 获取子项的配置信息
     * @param  {Object} item 信息
     */
    getItemCfg : function(point,index){
      var _self = this,
        item = _self.get('item'),
        cfg = point.obj,
        rst = {};

      BUI.mix(rst,item);
      if(cfg && cfg.attrs){
        BUI.mix(rst,cfg.attrs);
      }
      return rst;
    },
    /**
     * 数据序列的子项
     * @return {Array} 子项集合
     */
    getItems : function(){
      var group = this.get('group');

      return group ? group.get('children') : [];
    },
    /**
     * 生成动画
     * @protected
     */
    animateItems : function(callback){
      var _self = this,
        items = _self.getItems();

      Util.animStep(_self.get('duration'),function(factor){

        BUI.each(items,function(item){
          var point = item.get('point'),
            path = _self.pointToFactorPath(point,factor);
          item.attr('path',path);
        });
      },callback);
    },
    /**
     * 执行单个点的动画
     * @protected
     */
    animateItem : function(item,prePoint){
      var _self = this,
        point = item.get('point'),
        path = _self.pointToPath(point);

      item.animate({
        path : path
      },_self.get('changeDuration'));
    },
    /**
     * 删除子项
     * @param  {Object} item 子项
     */
    removeItem : function(item){
      var _self = this;
      _self.removeLabel(item);
      item.remove();
    },
    /**
     * @protected
     * 移除对应的label
     */
    removeLabel : function(item){
      var label = item.get('label');
      label && label.remove();
    },
    /**
     * @protected
     * 动画过程中根据比例获取path
     * @param  {Object} point  子项的节点信息
     * @param  {Number} factor 比例
     * @return {Array}  path
     */
    pointToFactorPath : function(point,factor){

    },
    /**
     * @protected
     * 获取path
     * @param  {Object} point  子项的节点信息
     * @return {Array}  path
     */
    pointToPath : function(point){
      return this.pointToFactorPath(point,1);
    }
  });


  return Group;
});
Example #27
0
File: number.js Project: 2zyun/bui
define('bui/chart/numberaxis',['bui/chart/baseaxis','bui/common','bui/graphic'],function (require) {
	
	var BUI = require('bui/common'),
		Axis = require('bui/chart/baseaxis'),
		Util = require('bui/graphic').Util,
    abbrs = ['k','m','g','t'],
		NAN = NaN;

  //取小于当前值的
	var floor = Util.snapFloor,
	  ceiling = Util.snapCeiling;

	/**
	 * @class BUI.Chart.Axis.Number
	 * 数字坐标轴
	 * @extends BUI.Chart.Axis
	 */
	function NumberAxis(cfg){
		NumberAxis.superclass.constructor.call(this,cfg);
	}

	BUI.extend(NumberAxis,Axis);

	NumberAxis.ATTRS = {

		/**
		 * 坐标开始的最小值
		 * @type {Number}
		 */
		min : {

		},
		/**
		 * 坐标结束的最大值
		 * @type {Number}
		 */
		max : {

		},
		/**
		 * 坐标轴上节点的最小距离
		 * @type {Number}
		 */
		tickInterval : {

		},
		/**
     * 类型
     * @type {String}
     */
		type : {
			value : 'number'
		},
    /**
     * 格式化坐标轴上的节点
     * @type {Function}
     */
    formatter : {
      value : function(value){
        if(value == null || isNaN(value)){
          return '';
        }
        if(value < 1e3){
          return value;
        }
        var interval = this.get('tickInterval');
        if(interval % 1e3 !== 0){
          return value;
        }

        var base = 1e3;
        
        for(var i = 1 ; i <= abbrs.length;i++){

          if(value >= base && value < base * 1e3){
            return (value/base) + abbrs[i - 1];
          }
          base = base * 1e3;
        }

        return value/1e12 + 't';
      }
    }

	};

	BUI.augment(NumberAxis,{
		//渲染控件前
		beforeRenderUI : function(){
			var _self = this;
			NumberAxis.superclass.beforeRenderUI.call(_self);
			
			//如果未指定坐标轴上的点,则自动计算
			if(!_self.get('ticks')){
				var	ticks = _self._getTicks(_self.get('max'),_self.get('min'),_self.get('tickInterval'));

				_self.set('ticks',ticks);
			}
		},
    _getTicks : function(max,min,tickInterval){
      var ticks = [],
        count = (max - min)/tickInterval,
        cur;

        ticks.push(min);
        for(var i = 1 ; i <= count ;i++){
          cur = tickInterval * i + min;
          ticks.push(cur);
        }
        // if(cur != max){
        //   ticks.push(max);
        // }
        return ticks;
    },
   
    /**
     * @protected
     * 修改信息
     */
    changeInfo : function(info){
        var _self = this;

        if(info.interval){
          info.tickInterval = info.interval;
        }

        if(info.ticks){
          _self.set('ticks',info.ticks);
        }else{
          var ticks = _self._getTicks(info.max,info.min,info.tickInterval);
          _self.set('ticks',ticks);
        }
        
        info.tickInterval && _self.set('tickInterval',info.tickInterval);
    },
		/**
     * 将指定的节点转换成对应的坐标点
     * @param  {*} value 数据值或者分类 
     * @return {Number} 节点坐标点(单一坐标)x轴的坐标点或者y轴的坐标点
     */
    getOffset : function(value){
      value = parseFloat(value);
    	var _self = this,
    		offset = _self.getRelativeOffset(value);

    	return _self._appendEndOffset(offset) + _self._getStartCoord();
    },
    /**
     * 根据画板上的点获取坐标轴上的值,用于将cavas上的点的坐标转换成坐标轴上的坐标
     * @param  {Number} offset 
     * @return {Number} 点在坐标轴上的值,如果不在坐标轴上,值为NaN
     */
    getValue : function(offset){
        var _self = this,
            startCoord = _self._getStartCoord(),
            endCoord = _self._getEndCoord(),
            pointCache,
            floorVal,
            floorIndex,
            ceilingVal,
            tickInterval,
            ticks;

        if(offset < startCoord || offset > endCoord){
            return NaN;
        }
        pointCache = _self.get('pointCache');
        floorVal = floor(pointCache,offset); 
        floorIndex = BUI.Array.indexOf(floorVal,pointCache);
        ticks = _self.get('ticks');
        tickInterval = _self.get('tickInterval');
        avg = _self._getAvgLength(ticks.length);

        if(floorVal == offset){
        	return ticks[floorIndex];
        }

        if(tickInterval){
        	return ticks[floorIndex] + ((offset - floorVal) / avg) * tickInterval;
        }
        

        ceilingVal = ceiling(pointCache,offset);
        
        return ticks[floorIndex] + ((offset - floorVal) / avg) * (ticks[floorIndex + 1] - ticks[floorIndex]);;
        
    },
    _getAvgLength : function(count){
    	var _self = this,
    		length = _self._getLength();
    	return (length / (count - 1));
    },
		 /**
     * @protected
     * 获取相对位置
     * @param  {*} value 数据值或者分类 
     * @return {Number}  相对于坐标轴开始位置的偏移量
     */
    getRelativeOffset : function(value){
      var _self = this,
          ticks = _self.get('ticks'),
          index = BUI.Array.indexOf(value,ticks),
          tickInterval = _self.get('tickInterval'),
          floorVal,
          ceilingVal,
          avg = _self._getAvgLength(ticks.length),
          offset;

      //如果在指定的坐标点中,直接返回坐标点的位置
      if(index !== -1){
      	return avg * index;
      }
      //获取小于当前值的最后一个坐标点
      floorVal = floor(ticks,value);
      if(isNaN(floorVal)){
      	return NAN;
      }
      index = BUI.Array.indexOf(floorVal,ticks);
     	offset = avg * index;
      if(tickInterval){
      	offset = offset + ((value - floorVal)/tickInterval) * avg;
      }else{
      	ceilingVal = ceiling(ticks,value);
      	offset = offset + ((value - floorVal)/(ceilingVal - floorVal)) * avg;
      }
      
      return offset;
    }
	});

	return NumberAxis;
});
Example #28
0
File: form.js Project: dxq613/bui-1
!function(){var e="bui/form/";define("bui/form",["bui/common",e+"fieldcontainer",e+"form",e+"row",e+"fieldgroup",e+"horizontal",e+"rules",e+"field",e+"fieldgroup"],function(t){var r=t("bui/common"),i=r.namespace("Form"),n=t(e+"tips");return r.mix(i,{Tips:n,TipItem:n.Item,FieldContainer:t(e+"fieldcontainer"),Form:t(e+"form"),Row:t(e+"row"),Group:t(e+"fieldgroup"),HForm:t(e+"horizontal"),Rules:t(e+"rules"),Field:t(e+"field"),FieldGroup:t(e+"fieldgroup")}),i})}(),define("bui/form/tips",["bui/common","bui/overlay"],function(require){var e=require("bui/common"),t=e.prefix,r=require("bui/overlay").Overlay,i="data-tip",n=t+"form-tip-container",a=r.extend({initializer:function(){var e=this,t=e.get("render");if(!t){var r=$(e.get("trigger")).parent();e.set("render",r)}},renderUI:function(){var e=this;e.resetVisible()},resetVisible:function(){var e=this,t=$(e.get("trigger"));t.val()?e.set("visible",!1):(e.set("align",{node:$(e.get("trigger")),points:["cl","cl"]}),e.set("visible",!0))},bindUI:function(){var e=this,t=$(e.get("trigger"));e.get("el").on("click",function(){e.hide(),t.focus()}),t.on("click focus",function(){e.hide()}),t.on("blur",function(){e.resetVisible()})}},{ATTRS:{trigger:{},text:{},iconCls:{},tpl:{value:'<span class="{iconCls}"></span><span class="tip-text">{text}</span>'}}},{xclass:"form-tip"}),o=function(e){return this.constructor!==o?new o(e):(o.superclass.constructor.call(this,e),void this._init())};return o.ATTRS={form:{},items:{valueFn:function(){return[]}}},e.extend(o,e.Base),e.augment(o,{_init:function(){var t=this,r=$(t.get("form"));r.length&&(e.each($.makeArray(r[0].elements),function(e){var r=$(e).attr(i);r&&t._initFormElement(e,$.parseJSON(r))}),r.addClass(n))},_initFormElement:function(e,t){t&&(t.trigger=e);var r=this,i=r.get("items"),n=new a(t);i.push(n)},getItem:function(t){var r=this,i=r.get("items"),n=null;return e.each(i,function(e){return $(e.get("trigger")).attr("name")===t?(n=e,!1):void 0}),n},resetVisible:function(){var t=this,r=t.get("items");e.each(r,function(e){e.resetVisible()})},render:function(){var t=this,r=t.get("items");e.each(r,function(e){e.render()})},destroy:function(){var t=this,r=t.get(r);e.each(r,function(e){e.destroy()})}}),o.Item=a,o}),define("bui/form/basefield",["bui/common","bui/form/tips","bui/form/valid","bui/form/remote"],function(require){var e=require("bui/common"),t=e.Component,r=require("bui/form/tips").Item,i=require("bui/form/valid"),n=require("bui/form/remote"),a=e.prefix+"form-field-error",o="bui-form-tip-container",l=t.View.extend([n.View,i.View],{renderUI:function(){var e=this,t=e.get("control");if(t)e.set("controlContainer",t.parent());else{var r=e.get("controlTpl"),i=e.getControlContainer();if(r){var t=$(r).appendTo(i);e.set("control",t)}}},clearErrors:function(){var e=this,t=e.get("msgEl");t&&(t.remove(),e.set("msgEl",null)),e.get("el").removeClass(a)},showError:function(t,r){var i=this,n=i.get("control"),o=e.substitute(r,{error:t}),l=$(o);l.appendTo(n.parent()),i.set("msgEl",l),i.get("el").addClass(a)},getControlContainer:function(){var t=this,r=t.get("el"),i=t.get("controlContainer");return i&&e.isString(i)&&(i=r.find(i)),i&&i.length?i:r},getLoadingContainer:function(){return this.getControlContainer()},_uiSetName:function(e){var t=this;t.get("control").attr("name",e)}},{ATTRS:{error:{},controlContainer:{},msgEl:{},control:{}}}),u=t.Controller.extend([n,i],{isField:!0,initializer:function(){var e=this;e.on("afterRenderUI",function(){var t=e.get("tip");if(t){var i=e.getTipTigger();i&&i.parent().addClass(o),t.trigger=i,t.autoRender=!0,t=new r(t),e.set("tip",t)}})},bindUI:function(){var e=this,t=e.get("validEvent"),r=e.get("changeEvent"),i=e.get("firstValidEvent"),n=e.getInnerControl();n.is("select")&&(t="change"),n.on(t,function(){var t=e.getControlValue(n);e.validControl(t)}),i&&n.on(i,function(){if(!e.get("hasValid")){var t=e.getControlValue(n);e.validControl(t)}}),e.on(r,function(){e.onValid()}),e.on("remotecomplete",function(t){e._setError(t.error)})},onValid:function(){var e=this,t=e.getControlValue();t=e.parseValue(t),e.isCurrentValue(t)||(e.setInternal("value",t),e.onChange())},onChange:function(){this.fire("change")},isCurrentValue:function(e){return e==this.get("value")},_clearError:function(){this.set("error",null),this.get("view").clearErrors()},_setError:function(e){this.set("error",e),this.showErrors()},getControlValue:function(e){var t=this;return e=e||t.getInnerControl(),e.val()},getControlContainer:function(){return this.get("view").getControlContainer()},getRemoteParams:function(){var e=this,t={};return t[e.get("name")]=e.getControlValue(),t},setControlValue:function(e){var t=this,r=t.getInnerControl();r.val(e)},parseValue:function(e){return e},valid:function(){var e=this;e.validControl()},validControl:function(e){var t,r=this;return e=e||r.getControlValue(),preError=r.get("error"),t=r.getValidError(e),r.setInternal("hasValid",!0),t?(r._setError(t),r.fire("error",{msg:t,value:e}),preError!==t&&r.fire("validchange",{valid:!1})):(r._clearError(),r.fire("valid"),preError&&r.fire("validchange",{valid:!0})),!t},focus:function(){this.getInnerControl().focus()},change:function(){var e=this.getInnerControl();e.change()},blur:function(){this.getInnerControl().blur()},isValid:function(){var e=this;return e.get("hasValid")||e.validControl(),!e.get("error")},getError:function(){return this.get("error")},getErrors:function(){var e=this.getError();return e?[e]:[]},clearErrors:function(e){var t=this;t._clearError(),e&&t.getControlValue()!=t.get("value")&&t.setControlValue(t.get("value"))},getInnerControl:function(){return this.get("view").get("control")},getTipTigger:function(){return this.getInnerControl()},destructor:function(){var e=this,t=e.get("tip");t&&t.destroy&&t.destroy()},setInnerWidth:function(t){var r=this,i=r.getInnerControl(),n=i.siblings(),a=i.outerWidth()-i.width();e.each(n,function(e){a+=$(e).outerWidth()}),i.width(t-a)},_resetTip:function(){var e=this,t=e.get("tip");t&&t.resetVisible()},resetTip:function(){this._resetTip()},_uiSetValue:function(e){var t=this;t.setControlValue(e),t.get("rendered")&&(t.validControl(),t.onChange()),t._resetTip()},_uiSetDisabled:function(t){var r=this,i=r.getInnerControl(),n=r.get("children");i.attr("disabled",t),r.get("rendered")&&(t&&r.clearErrors(),t||r.valid()),e.each(n,function(e){e.set("disabled",t)})},_uiSetWidth:function(e){var t=this;null!=e&&t.get("forceFit")&&t.setInnerWidth(e)}},{ATTRS:{hasValid:{value:!1},forceFit:{value:!1},tip:{},changeEvent:{value:"valid"},firstValidEvent:{value:"blur"},validEvent:{value:"keyup change"},name:{view:!0},showError:{view:!0,value:!0},value:{view:!0},label:{},controlContainer:{view:!0},control:{view:!0},controlTpl:{view:!0,value:'<input type="text"/>'},events:{value:{error:!1,valid:!1,change:!0,validchange:!0}},tpl:{value:"<label>{label}</label>"},xview:{value:l}},PARSER:{control:function(e){var t=e.find("input,select,textarea");return t.length?t:e},disabled:function(e){return!!e.attr("disabled")},value:function(e){var t=this,r="select,input,textarea",i=t.get("value");return i||(e.is(r)?(i=e.val(),!i&&e.is("select")&&(i=e.attr("value"))):i=e.find(r).val()),i},name:function(e){var t=this,r="select,input,textarea",i=t.get("name");return i||(i=e.is(r)?e.attr("name"):e.find(r).attr("name")),i}}},{xclass:"form-field"});return u.View=l,u}),define("bui/form/textfield",["bui/form/basefield"],function(require){var e=require("bui/form/basefield"),t=e.extend({},{xclass:"form-field-text"});return t}),define("bui/form/textareafield",["bui/form/basefield"],function(require){var e=require("bui/form/basefield"),t=e.extend({_uiSetRows:function(e){var t=this,r=t.getInnerControl();e&&r.attr("rows",e)},_uiSetCols:function(e){var t=this,r=t.getInnerControl();e&&r.attr("cols",e)}},{ATTRS:{controlTpl:{value:"<textarea></textarea>"},rows:{},cols:{},decorateCfgFields:{value:{rows:!0,cols:!0}}}},{xclass:"form-field-textarea"});return t}),define("bui/form/numberfield",["bui/form/basefield"],function(require){var e=require("bui/form/basefield"),t=e.extend({parseValue:function(e){if(""==e||null==e)return null;if(BUI.isNumber(e))return e;var t=this,r=t.get("allowDecimals");return e=e.replace(/\,/g,""),r?parseFloat(parseFloat(e).toFixed(t.get("decimalPrecision"))):parseInt(e,10)},_uiSetMax:function(e){this.addRule("max",e)},_uiSetMin:function(e){this.addRule("min",e)}},{ATTRS:{max:{},min:{},decorateCfgFields:{value:{min:!0,max:!0}},validEvent:{value:"keyup change"},defaultRules:{value:{number:!0}},allowDecimals:{value:!0},decimalPrecision:{value:2},step:{value:1}}},{xclass:"form-field-number"});return t}),define("bui/form/hiddenfield",["bui/form/basefield"],function(require){var e=require("bui/form/basefield"),t=e.extend({},{ATTRS:{controlTpl:{value:'<input type="hidden"/>'},tpl:{value:""}}},{xclass:"form-field-hidden"});return t}),define("bui/form/readonlyfield",["bui/form/basefield"],function(require){var e=require("bui/form/basefield"),t=e.extend({},{ATTRS:{controlTpl:{value:'<input type="text" readonly="readonly"/>'}}},{xclass:"form-field-readonly"});return t}),define("bui/form/selectfield",["bui/common","bui/form/basefield"],function(require){function e(e,i,n){e.children().remove();var a=n.get("emptyText");a&&n.get("showBlank")&&t("",a,e),r.each(i,function(r){t(r.value,r.text,e)})}function t(e,t,r){var i=new Option(t,e),n=r[0].options;n[n.length]=i}var r=require("bui/common"),i=require("bui/form/basefield"),n=i.extend({renderUI:function(){var e=this,t=e.getInnerControl(),r=e.get("select");e.get("srcNode")&&t.is("select")||$.isPlainObject(r)&&e._initSelect(r)},_initSelect:function(e){{var t=this;t.get("items")}r.use("bui/select",function(r){e.render=t.getControlContainer(),e.valueField=t.getInnerControl(),e.autoRender=!0,e=new r.Select(e),t.set("select",e),t.set("isCreate",!0),t.get("children").push(e),e.on("change",function(){var r=e.getSelectedValue();t.set("value",r)})})},setItems:function(t){var i=this,n=i.get("select");if($.isPlainObject(t)){var a=[];r.each(t,function(e,t){a.push({value:t,text:e})}),t=a}var o=i.getInnerControl();o.is("select")&&(e(o,t,i),i.setControlValue(i.get("value")),i.getControlValue()||i.setInternal("value","")),n&&(n.set?n.set("items",t):n.items=t)},setControlValue:function(e){var t=this,r=t.get("select"),i=t.getInnerControl();i.val(e),r&&r.set&&r.getSelectedValue()!==e&&r.setSelectedValue(e)},getSelectedText:function(){var e=this,t=e.get("select"),r=e.getInnerControl();if(r.is("select")){var i=r[0],n=i.options[i.selectedIndex];return n?n.text:""}return t.getSelectedText()},getTipTigger:function(){var e=this,t=e.get("select");return t&&t.rendered?t.get("el").find("input"):e.get("el")},_uiSetItems:function(e){e&&this.setItems(e)},setInnerWidth:function(e){var t=this,r=t.getInnerControl(),i=t.get("select"),n=r.outerWidth()-r.width();r.width(e-n),i&&i.set&&i.set("width",e)}},{ATTRS:{items:{},controlTpl:{value:'<input type="hidden"/>'},showBlank:{value:!0},emptyText:{value:"\u8bf7\u9009\u62e9"},select:{shared:!1,value:{}}},PARSER:{emptyText:function(e){if(!this.get("showBlank"))return"";var t=e.find("option"),r=this.get("emptyText");return t.length&&(r=$(t[0]).text()),r}}},{xclass:"form-field-select"});return n}),define("bui/form/datefield",["bui/common","bui/form/basefield","bui/calendar"],function(require){var e=require("bui/common"),t=require("bui/form/basefield"),r=e.Date,i=t.extend({renderUI:function(){var e=this,t=e.get("datePicker");$.isPlainObject(t)&&e.initDatePicker(t),(t.get&&t.get("showTime")||t.showTime)&&e.getInnerControl().addClass("calendar-time")},initDatePicker:function(t){var r=this;e.use("bui/calendar",function(e){t.trigger=r.getInnerControl(),t.autoRender=!0,t=new e.DatePicker(t),r.set("datePicker",t),r.set("isCreatePicker",!0),r.get("children").push(t)})},setControlValue:function(t){var i=this,n=i.getInnerControl();e.isDate(t)&&(t=r.format(t,i._getFormatMask())),n.val(t)},_getFormatMask:function(){var e=this,t=e.get("datePicker");return t.showTime||t.get&&t.get("showTime")?"yyyy-mm-dd HH:MM:ss":"yyyy-mm-dd"},parseValue:function(t){return e.isNumber(t)?new Date(t):r.parse(t)},isCurrentValue:function(e){return r.isEquals(e,this.get("value"))},_uiSetMax:function(e){this.addRule("max",e);var t=this,r=t.get("datePicker");r&&(r.set?r.set("maxDate",e):r.maxDate=e)},_uiSetMin:function(e){this.addRule("min",e);var t=this,r=t.get("datePicker");r&&(r.set?r.set("minDate",e):r.minDate=e)}},{ATTRS:{controlTpl:{value:'<input type="text" class="calendar"/>'},defaultRules:{value:{date:!0}},max:{},min:{},value:{setter:function(t){return e.isNumber(t)?new Date(t):t}},datePicker:{shared:!1,value:{}},isCreatePicker:{value:!0}},PARSER:{datePicker:function(t){var r=this,i=r.get("datePicker")||{};return t.hasClass("calendar-time")&&e.mix(i,{showTime:!0}),i}}},{xclass:"form-field-date"});return i}),define("bui/form/checkfield",["bui/form/basefield"],function(require){var e=require("bui/form/basefield"),t=e.extend({onValid:function(){var e=this,t=e._getControlChecked();e.setInternal("checked",t),e.fire("change"),e.fire(t?"checked":"unchecked")},_setControlChecked:function(e){var t=this,r=t.getInnerControl();r.attr("checked",!!e)},_getControlChecked:function(){var e=this,t=e.getInnerControl();return!!t.attr("checked")},_uiSetValue:function(e){this.setControlValue(e)},_uiSetWidth:function(){},_uiSetChecked:function(e){var t=this;t._setControlChecked(e),t.get("rendered")&&t.onValid()}},{ATTRS:{validEvent:{value:"click"},checked:{value:!1},events:{value:{checked:!1,unchecked:!1}}},PARSER:{checked:function(e){return!!e.attr("checked")}}},{xclass:"form-check-field"});return t}),define("bui/form/checkboxfield",["bui/form/checkfield"],function(e){var t=e("bui/form/checkfield"),r=t.extend({},{ATTRS:{controlTpl:{view:!0,value:'<input type="checkbox"/>'},controlContainer:{value:".checkbox"},tpl:{value:'<label><span class="checkbox"></span>{label}</label>'}}},{xclass:"form-field-checkbox"});return r}),define("bui/form/radiofield",["bui/form/checkfield"],function(e){var t=e("bui/form/checkfield"),r=t.extend({bindUI:function(){var e=this,t=e.get("parent"),r=e.get("name");t&&e.getInnerControl().on("click",function(){var i=t.getFields(r);BUI.each(i,function(t){t!=e&&t.set("checked",!1)})})}},{ATTRS:{controlTpl:{view:!0,value:'<input type="radio"/>'},controlContainer:{value:".radio"},tpl:{value:'<label><span class="radio"></span>{label}</label>'}}},{xclass:"form-field-radio"});return r}),define("bui/form/plainfield",["bui/form/basefield"],function(require){var e=require("bui/form/basefield"),t=e.View.extend({_uiSetValue:function(e){var t,r=this,i=r.get("textEl"),n=r.getControlContainer(),a=r.get("renderer"),o=a?a(e):e,l=r.get("width"),u=0;i&&i.remove(),o=o||"&nbsp;",t=BUI.substitute(r.get("textTpl"),{text:o}),i=$(t).appendTo(n),u=i.outerWidth()-i.width(),i.width(l-u),r.set("textEl",i)}},{ATTRS:{textEl:{},value:{}}},{xclass:"form-field-plain-view"}),r=e.extend({},{ATTRS:{controlTpl:{value:'<input type="hidden"/>'},textTpl:{view:!0,value:'<span class="x-form-text">{text}</span>'},renderer:{view:!0,value:function(e){return e}},tpl:{value:""},xview:{value:t}}},{xclass:"form-field-plain"});return r}),define("bui/form/listfield",["bui/common","bui/form/basefield","bui/list"],function(require){function e(e){var r=e;return $.isPlainObject(e)&&(r=[],t.each(e,function(e,t){r.push({text:e,value:t})})),r}var t=require("bui/common"),r=require("bui/list"),i=require("bui/form/basefield"),r=i.extend({initializer:function(){var e=this;e._initList()},_getList:function(){var e=this,t=e.get("children");return t[0]},bindUI:function(){var e=this,t=e._getList();t&&t.on("selectedchange",function(){var r=e._getListValue(t);e.set("value",r)})},_getListValue:function(e){var t=this;return e=e||t._getList(),e.getSelectionValues().join(",")},setControlValue:function(e){var t=this,r=t.getInnerControl(),i=t._getList();r.val(e),t._getListValue(i)!==e&&i.getCount()&&(i.get("multipleSelect")&&i.clearSelection(),i.setSelectionByField(e.split(",")))},syncUI:function(){this.set("list",this._getList())},_initList:function(){var e=this,r=e.get("defaultListCfg"),i=e.get("children"),n=e.get("list")||{};i[0]||($.isPlainObject(n)&&t.mix(n,r),i.push(n))},setItems:function(t){var r=this,i=r.get("value"),n=r._getList();n.set("items",e(t)),n.setSelectionByField(i.split(","))},_uiSetItems:function(e){e&&this.setItems(e)}},{ATTRS:{controlTpl:{value:'<input type="hidden"/>'},defaultListCfg:{value:{xclass:"simple-list"}},items:{setter:function(e){if($.isPlainObject(e)){var r=[];t.each(e,function(e,t){r.push({value:t,text:e})}),e=r}return e}},list:{}},PARSER:{list:function(e){var t=e.find(".bui-simple-list");return t.length?{srcNode:t}:void 0}}},{xclass:"form-field-list"});return r}),define("bui/form/uploaderfield",["bui/common","bui/form/basefield","bui/form/rules"],function(require){var e=require("bui/common"),t=e.JSON,r=require("bui/form/basefield"),i=require("bui/form/rules"),n=r.extend({renderUI:function(){var e=this,t=e.getInnerControl();e.get("srcNode")&&"file"===t.get(0).type||(e._initControlValue(),e._initUpload())},_initUpload:function(){var t=this,r=(t.get("children"),t.get("uploader")||{});e.use("bui/uploader",function(e){r.render=t.getControlContainer(),r.autoRender=!0,r=new e.Uploader(r),t.set("uploader",r),t.set("isCreate",!0),t.get("children").push(r),t._initQueue(r.get("queue")),r.on("success",function(){var e=t._getUploaderResult();t.setControlValue(e)}),r.get("queue").on("itemremoved",function(){var e=t._getUploaderResult();t.setControlValue(e)})})},_getUploaderResult:function(){var t=this,r=t.get("uploader"),i=r.get("queue"),n=i.getItems(),a=[];return e.each(n,function(e){e.result&&a.push(e.result)}),a},setControlValue:function(e){var r=this,i=r.getInnerControl();i.val(t.stringify(e))},_initControlValue:function(){var t,r=this,i=r.getControlValue();i&&(t=e.JSON.parse(i),r.set("value",t))},_initQueue:function(t){var r=this,i=r.get("value"),n=[];e.each(i,function(t){var r=e.cloneObject(t);r.success=!0,r.result=t,n.push(r)}),t&&t.setItems(n)}},{ATTRS:{controlTpl:{value:'<input type="hidden"/>'},uploader:{setter:function(e){var t=this.get("disabled");return e&&e.isController&&e.set("disabled",t),e}},disabled:{setter:function(e){var t=this,r=t.get("uploader");r&&r.isController&&r.set("disabled",e)}},value:{shared:!1,value:[]},defaultRules:function(){}}},{xclass:"form-field-uploader"});return i.add({name:"uploader",msg:"\u4e0a\u4f20\u6587\u4ef6\u9009\u62e9\u6709\u8bef\uff01",validator:function(e,t,r,i){var n=i.get("uploader");return n&&!n.isValid()?r:void 0}}),n}),define("bui/form/checklistfield",["bui/common","bui/form/listfield"],function(require){"use strict";var e=(require("bui/common"),require("bui/form/listfield")),t=e.extend({},{ATTRS:{defaultListCfg:{value:{itemTpl:'<li><span class="x-checkbox"></span>{text}</li>',multipleSelect:!0,allowTextSelection:!1}}}},{xclass:"form-field-checklist"});return t}),define("bui/form/radiolistfield",["bui/common","bui/form/listfield"],function(require){"use strict";var e=(require("bui/common"),require("bui/form/listfield")),t=e.extend({},{ATTRS:{defaultListCfg:{value:{itemTpl:'<li><span class="x-radio"></span>{text}</li>',allowTextSelection:!1}}}},{xclass:"form-field-radiolist"});return t}),function(){var e="bui/form/";define(e+"field",["bui/common",e+"textfield",e+"datefield",e+"selectfield",e+"hiddenfield",e+"numberfield",e+"checkfield",e+"radiofield",e+"checkboxfield",e+"plainfield",e+"listfield",e+"uploaderfield",e+"checklistfield",e+"radiolistfield",e+"textareafield"],function(require){var t=require("bui/common"),r=require(e+"basefield");return t.mix(r,{Text:require(e+"textfield"),Date:require(e+"datefield"),Select:require(e+"selectfield"),Hidden:require(e+"hiddenfield"),Number:require(e+"numberfield"),Check:require(e+"checkfield"),Radio:require(e+"radiofield"),Checkbox:require(e+"checkboxfield"),Plain:require(e+"plainfield"),List:require(e+"listfield"),TextArea:require(e+"textareafield"),Uploader:require(e+"uploaderfield"),CheckList:require(e+"checklistfield"),RadioList:require(e+"radiolistfield")}),r})}(),define("bui/form/valid",["bui/common","bui/form/rules"],function(require){var e=require("bui/common"),t=require("bui/form/rules"),r=function(){};r.prototype={getErrorsContainer:function(){var t=this,r=t.get("errorContainer");return r?e.isString(r)?t.get("el").find(r):r:t.getContentElement()},showErrors:function(t){var r=this,i=r.getErrorsContainer(),n=r.get("errorTpl");return r.clearErrors(),r.get("showError")?r.get("showOneError")?void(t&&t.length&&r.showError(t[0],n,i)):void e.each(t,function(e){e&&r.showError(e,n,i)}):void 0},showError:function(){},clearErrors:function(){}};var i=function(){};return i.ATTRS={defaultRules:{value:{}},defaultMessages:{value:{}},rules:{shared:!1,value:{}},messages:{shared:!1,value:{}},validator:{},errorContainer:{view:!0},errorTpl:{view:!0,value:'<span class="x-field-error"><span class="x-icon x-icon-mini x-icon-error">!</span><label class="x-field-error-text">{error}</label></span>'},showError:{view:!0,value:!0},showOneError:{},error:{},pauseValid:{value:!1}},i.prototype={__bindUI:function(){var e=this;e.on("afterDisabledChange",function(t){var r=t.newVal;r?e.clearErrors(!1,!1):e.valid()})},isValid:function(){},valid:function(){},validControl:function(){},validRules:function(e,r){if(!e)return null;if(this.get("pauseValid"))return null;var i=this,n=i._getValidMessages(),a=null;for(var o in e)if(e.hasOwnProperty(o)){var l=e[o];if(a=t.valid(o,r,l,n[o],i))break}return a},_getValidMessages:function(){var t=this,r=t.get("defaultMessages"),i=t.get("messages");return e.merge(r,i)},getValidError:function(e){var t=this,r=t.get("validator"),i=null;return i=t.validRules(t.get("defaultRules"),e)||t.validRules(t.get("rules"),e),i||this.get("pauseValid")||(t.parseValue&&(e=t.parseValue(e)),i=r?r.call(this,e):""),i},getErrors:function(){},showErrors:function(e){var t=this,e=e||t.getErrors();t.get("view").showErrors(e)},clearErrors:function(t,r){r=null==r?!0:r;var i=this,n=i.get("children");r&&e.each(n,function(e){e.clearErrors&&(e.field?e.clearErrors(t):e.clearErrors(t,r))}),i.set("error",null),i.get("view").clearErrors()},addRule:function(e,t,r){var i=this,n=i.get("rules"),a=i.get("messages");n[e]=t,r&&(a[e]=r)},addRules:function(t,r){var i=this;e.each(t,function(e,t){var n=r?r[t]:null;i.addRule(t,e,n)})},removeRule:function(e){var t=this,r=t.get("rules");delete r[e]},clearRules:function(){var e=this;e.set("rules",{})}},i.View=r,i}),define("bui/form/groupvalid",["bui/form/valid"],function(require){function e(){}function t(){}var r="x-form-error",i=require("bui/form/valid");return BUI.augment(e,i.View,{showError:function(e,t,i){var n=BUI.substitute(t,{error:e}),a=$(n);a.appendTo(i),a.addClass(r)},clearErrors:function(){var e=this,t=e.getErrorsContainer();t.children("."+r).remove()}}),t.ATTRS=ATTRS=BUI.merge(!0,i.ATTRS,{events:{value:{validchange:!0,change:!0}}}),BUI.augment(t,i,{__bindUI:function(){var e=this,t="validchange change";e.on(t,function(t){var r=t.target;if(r!=this&&e.get("showError")){var i=r.isValid();e._hasAllChildrenValid()&&(i=i&&e.isChildrenValid(),i&&(e.validControl(e.getRecord()),i=e.isSelfValid())),i?e.clearErrors():e.showErrors()}})},isValid:function(){if(this.get("disabled"))return!0;var e=this,t=e.isChildrenValid();return t&&e.isSelfValid()},valid:function(){var e=this,t=e.get("children");e.get("disabled")||BUI.each(t,function(e){e.get("disabled")||e.valid()})},_hasAllChildrenValid:function(){var e=this,t=e.get("children"),r=!0;return BUI.each(t,function(e){return e.get("disabled")||e.get("hasValid")!==!1?void 0:(r=!1,!1)}),r},isChildrenValid:function(){var e=this,t=e.get("children"),r=!0;return BUI.each(t,function(e){return e.get("disabled")||e.isValid()?void 0:(r=!1,!1)}),r},isSelfValid:function(){return!this.get("error")},validControl:function(e){var t=this,r=t.getValidError(e);t.set("error",r)},getErrors:function(){var e=this,t=e.get("children"),r=e.get("showChildError"),i=null,n=[];return r&&BUI.each(t,function(e){e.getErrors&&(n=n.concat(e.getErrors()))}),e._hasAllChildrenValid()&&e.isChildrenValid()&&(i=e.get("error"),i&&n.push(i)),n},_uiSetErrorTpl:function(e){var t=this,r=t.get("children");BUI.each(r,function(t){t.get("userConfig").errorTpl||t.set("errorTpl",e)})}}),t.View=e,t}),define("bui/form/fieldcontainer",["bui/common","bui/form/field","bui/form/groupvalid"],function(require){function e(e){return e.is(s)}function t(i,n){if(i!=n){if(e(i))return[i];var a=i.attr("class");if(a&&(-1!==a.indexOf(u)||-1!==a.indexOf(l)))return[i]}var o=[],s=i.children();return r.each(s,function(e){o=o.concat(t($(e),n))}),o}var r=require("bui/common"),i=require("bui/form/field"),n=require("bui/form/groupvalid"),a=r.prefix,o="form-field",l=a+o,u=a+"form-group",s="input,select,textarea",c=r.Component.View.extend([n.View]),d=r.Component.Controller.extend([n],{syncUI:function(){var e=this,t=e.getFields(),i=e.get("validators");r.each(t,function(e){var t=e.get("name");i[t]&&e.set("validator",i[t])}),r.each(i,function(t,r){if(0==r.indexOf("#")){var i=r.replace("#",""),n=e.getChild(i,!0);n&&n.set("validator",t)}})},getDecorateElments:function(){var e=this,r=e.get("el"),i=t(r,r);return i},findXClassByNode:function(t,i){return"checkbox"===t.attr("type")?o+"-checkbox":"radio"===t.attr("type")?o+"-radio":"number"===t.attr("type")?o+"-number":t.hasClass("calendar")?o+"-date":"SELECT"==t[0].tagName?o+"-select":e(t)?o:r.Component.Controller.prototype.findXClassByNode.call(this,t,i)},getRecord:function(){var e=this,t={},i=e.getFields();return r.each(i,function(i){var n=i.get("name"),a=e._getFieldValue(i);if(t[n]){if(r.isArray(t[n])&&null!=a)t[n].push(a);else if(null!=a){var o=[t[n]];o.push(a),t[n]=o}}else t[n]=a}),t},getFields:function(e){var t=this,n=[],a=t.get("children");return r.each(a,function(t){t instanceof i?e&&t.get("name")!=e||n.push(t):t.getFields&&(n=n.concat(t.getFields(e)))}),n},getField:function(e){var t=this,i=t.getFields(),n=null;return r.each(i,function(t){return t.get("name")===e?(n=t,!1):void 0}),n},getFieldAt:function(e){return this.getFields()[e]},setFieldValue:function(e,t){var i=this,n=i.getFields(e);r.each(n,function(e){i._setFieldValue(e,t)})},_setFieldValue:function(e,t){if(!e.get("disabled"))if(e instanceof i.Check){var n=e.get("value");t&&(n===t||r.isArray(t)&&r.Array.contains(n,t))?e.set("checked",!0):e.set("checked",!1)}else null==t&&(t=""),e.clearErrors(!0),e.set("value",t)},getFieldValue:function(e){var t=this,i=t.getFields(e),n=[];return r.each(i,function(e){var r=t._getFieldValue(e);r&&n.push(r)}),0===n.length?null:1===n.length?n[0]:n},_getFieldValue:function(e){return e instanceof i.Check&&!e.get("checked")?null:e.get("value")},clearFields:function(){this.clearErrors(!0),this.setRecord({})},setRecord:function(e){var t=this,i=t.getFields();r.each(i,function(r){var i=r.get("name");t._setFieldValue(r,e[i])})},updateRecord:function(e){var t=this,i=t.getFields();r.each(i,function(r){var i=r.get("name");e.hasOwnProperty(i)&&t._setFieldValue(r,e[i])})},focus:function(){var e=this,t=e.getFields(),r=t[0];r&&r.focus()},_uiSetDisabled:function(e){var t=this,i=t.get("children");r.each(i,function(t){t.set("disabled",e)})}},{ATTRS:{record:{setter:function(e){this.setRecord(e)},getter:function(){return this.getRecord()}},validators:{value:{}},defaultLoaderCfg:{value:{property:"children",dataType:"json"}},disabled:{sync:!1},isDecorateChild:{value:!0},xview:{value:c}}},{xclass:"form-field-container"});return d.View=c,d}),define("bui/form/group/base",["bui/common","bui/form/fieldcontainer"],function(require){var e=(require("bui/common"),require("bui/form/fieldcontainer")),t=e.extend({},{ATTRS:{label:{view:!0},defaultChildClass:{value:"form-field"}}},{xclass:"form-group"});return t}),define("bui/form/group/range",["bui/form/group/base"],function(require){function e(e,t,r){var i=e.get("allowEqual");return i?t>=r:t>r}var t=require("bui/form/group/base"),r=t.extend({},{ATTRS:{rangeText:{value:"\u5f00\u59cb\u4e0d\u80fd\u5927\u4e8e\u7ed3\u675f\uff01"},allowEqual:{value:!0},validator:{value:function(){for(var t=this,r=t.getFields(),i=!0,n=1;n<r.length;n++){var a,o,l=r[n],u=r[n-1];if(l&&u&&(a=l.get("value"),o=u.get("value"),!e(t,a,o))){i=!1;break}}return i?null:t.get("rangeText")}}}},{xclass:"form-group-range"});return r}),define("bui/form/group/check",["bui/form/group/base"],function(require){function e(e){var t=e.getFieldAt(0);return t?t.get("name"):""}var t=require("bui/form/group/base"),r=t.extend({bindUI:function(){var t=this;t.on("change",function(){var r=e(t),i=t.get("range"),n=t.getRecord(),a=n[r],o=i[1];a&&a.length>=o?t._setFieldsEnable(r,!1):t._setFieldsEnable(r,!0)})},_setFieldsEnable:function(e,t){var r=this,i=r.getFields(e);BUI.each(i,function(e){t?e.enable():e.get("checked")||e.disable()})},_uiSetRange:function(e){this.addRule("checkRange",e)}},{ATTRS:{range:{setter:function(e){return(BUI.isString(e)||BUI.isNumber(e))&&(e=[parseInt(e,10)]),e}}}},{xclass:"form-group-check"});return r}),define("bui/form/group/select",["bui/form/group/base","bui/data"],function(require){function e(e){var t=[];return BUI.each(e,function(e){t.push({text:e.text,value:e.id})}),t}var t=require("bui/form/group/base"),r=require("bui/data"),i=BUI.Component.UIBase.Bindable,n=t.extend([i],{initializer:function(){var e=this,t=e.get("url"),i=e.get("store")||e._getStore();i.isStore||(i.autoLoad=!0,t&&(i.url=t),i=new r.TreeStore(i)),e.set("store",i)},bindUI:function(){var e=this;e.on("change",function(t){var r=t.target;if(r!=e){var i=r,n=i.get("value"),a=e._getFieldIndex(i)+1;e._valueChange(n,a)}})},onLoad:function(e){var t=this,r=e?e.node:t.get("store").get("root");t._setFieldItems(r.level,r.children)},_getStore:function(){var e=this,t=e.get("type");return t&&a[t]?a[t]:{}},_valueChange:function(e,t){var r=this,i=r.get("store");if(e){var n=i.findNode(e);if(!n)return;i.isLoaded(n)?r._setFieldItems(t,n.children):i.loadNode(n)}else r._setFieldItems(t,[])},_setFieldItems:function(t,r){var i=this,n=i.getFieldAt(t),a=e(r);n&&(n.setItems(a),i._valueChange(n.get("value"),t+1))},_getFieldIndex:function(e){var t=this,r=t.getFields();return BUI.Array.indexOf(e,r)}},{ATTRS:{type:{},store:{}}},{xclass:"form-group-select"}),a={};return n.addType=function(e,t){a[e]=t},n.addType("city",{proxy:{url:"http://lp.taobao.com/go/rgn/citydistrictdata.php",dataType:"jsonp"},map:{isleaf:"leaf",value:"text"}}),n}),define("bui/form/fieldgroup",["bui/common","bui/form/group/base","bui/form/group/range","bui/form/group/check","bui/form/group/select"],function(require){var e=require("bui/common"),t=require("bui/form/group/base");return e.mix(t,{Range:require("bui/form/group/range"),Check:require("bui/form/group/check"),Select:require("bui/form/group/select")}),t}),define("bui/form/form",["bui/common","bui/form/fieldcontainer"],function(require){var e=require("bui/common"),t={NORMAL:"normal",AJAX:"ajax",IFRAME:"iframe"},r=require("bui/form/fieldcontainer"),i=(e.Component,r.View.extend({_uiSetMethod:function(e){this.get("el").attr("method",e)},_uiSetAction:function(e){this.get("el").attr("action",e)}},{ATTRS:{method:{},action:{}}},{xclass:"form-view"})),n=r.extend({renderUI:function(){var t,r=this,i=r.get("buttonBar");$.isPlainObject(i)&&r.get("buttons")&&(t=e.merge(r.getDefaultButtonBarCfg(),i),r._initButtonBar(t)),r._initSubmitMask()},_initButtonBar:function(t){var r=this;e.use("bui/toolbar",function(e){buttonBar=new e.Bar(t),r.set("buttonBar",buttonBar)})},bindUI:function(){var e=this,r=e.get("el");r.on("submit",function(r){return e.valid(),e.isValid()&&e.onBeforeSubmit()!==!1?void(e.isValid()&&e.get("submitType")===t.AJAX&&(r.preventDefault(),e.ajaxSubmit())):(r.preventDefault(),void e.focusError())})},getDefaultButtonBarCfg:function(){var e=this,t=e.get("buttons");return{autoRender:!0,elCls:"toolbar",render:e.get("el"),items:t,defaultChildClass:"bar-item-button"}},focusError:function(){var t=this,r=t.getFields();e.each(r,function(t){if(t.get("visible")&&!t.get("disabled")&&!t.isValid()){try{t.focus()}catch(r){e.log(r)}return!1}})},submit:function(e){var r=this,i=r.get("submitType");
Example #29
0
File: base.js Project: cnJun/bui
define('bui/chart/baseaxis',['bui/common','bui/graphic','bui/chart/abstractaxis'],function(require) {

    var BUI = require('bui/common'),
        Abstract = require('bui/chart/abstractaxis'),
        Util = require('bui/graphic').Util,
        CLS_AXIS = 'x-chart-axis';

    //是否在2个数之间
    function isBetween(x,x1,x2){
        if(x1 > x2){
            var temp = x2;
            x2 = x1;
            x1 = temp;
        }
        return x >= x1 && x <= x2;
    }

    /**
     * @class BUI.Chart.Axis
     * 坐标轴
     * @extends BUI.Chart.Axis.Abstract
     */
    function Axis(cfg){
        Axis.superclass.constructor.call(this,cfg);
    }

    Axis.ATTRS = {
        zIndex : {
            value : 4
        },
        /**
         * 距离初始位置的x轴偏移量,仅对于左侧、右侧的纵向坐标有效
         * @type {Number}
         */
        x : {

        },
        /**
         * 距离初始位置的y轴偏移量,仅对顶部、底部的横向坐标轴有效
         * @type {Number}
         */
        y : {

        },
        /**
         * 起始点
         * @type {Object}
         */
        start : {

        },
        /**
         * 终点
         * @type {Object}
         */
        end : {

        },
        /**
         * 起点终点的偏移量
         * @type {Number}
         */
        tickOffset : {
            value : 0
        },
        /**
         * 附加的样式
         * @type {String}
         */
        elCls : {
            value : CLS_AXIS
        },
        /**
         * 位置,此属性决定是横坐标还是纵坐标
         *
         * - top : 顶部的横向坐标轴
         * - bottrom : 底部的横向坐标轴
         * - left :左侧纵向坐标轴
         * - right : 右侧纵向坐标轴
         * @type {String}
         */
        position : {
            value : 'bottom'
        },
        /**
         * 坐标轴线的配置信息,如果设置成null,则不显示轴线
         * @type {Object}
         */
        line : {
            value : {
                'stroke-width' : 1,
                'stroke' : '#C0D0E0'
            }
        },
        /**
         * 标注坐标线的配置
         * @type {Object}
         */
        tickLine : {
            value : {
                'stroke-width' : 1,
                'stroke' : '#C0D0E0',
                value : 5
            }
        }
       

    };

    BUI.extend(Axis,Abstract);


    BUI.augment(Axis,{

        //渲染控件前
        beforeRenderUI : function(){
            var _self = this,
                plotRange;
            Axis.superclass.beforeRenderUI.call(_self);
            plotRange = _self.get('plotRange');

            if(plotRange){
                var start = plotRange.start,
                    position = _self.get('position'),
                    end = {};
                if(_self.isVertical()){
                    if(position == 'left'){
                        end.y = plotRange.end.y;
                        end.x = start.x; 
                    }else{
                        start = {};
                        end = plotRange.end;
                        start.x = plotRange.end.x;
                        start.y = plotRange.start.y;
                    }
                    
                }else{
                    
                    end.x = plotRange.end.x;
                    end.y = start.y;
                }
                _self.set('start',start);
                _self.set('end',end);
            }

            _self.set('indexCache',{});
            _self.set('pointCache',[]);

        },
         /**
         * 改变坐标轴
         */
        change : function(info){
            var _self = this;
            if(_self.isChange(info.ticks)){
                _self._clearTicksInfo();
                _self.changeInfo(info);
                _self._processTicks(null,true);
                _self._changeTicks();
                _self._changeGrid();
                _self.resetLabels();
            }
        },
        /**
         * 坐标轴是否将要发生改变
         * @param  {Array}  ticks 新的坐标点
         * @return {Boolean}  是否发生改变
         */
        isChange : function(ticks){
          var _self = this,
              preTicks = _self.get('ticks');

          return  !BUI.Array.equals(ticks,preTicks);
        },
        /**
         * @protected
         * 更改信息
         */
        changeInfo : function(info){
            var _self = this;

            _self.set('ticks',info.ticks);
        },
        _clearTicksInfo : function(){
            var _self = this,
                grid = _self.get('grid'),
                labels = _self.get('labels');

            _self.set('pointCache',[]);
            _self.set('indexCache',[]);
            _self.set('tickItems',[]);

            if(grid){
                grid.items = [];
            }

            if(labels){
                labels.items = [];
            }

        },
        
        /**
         * 绘制坐标轴
         */
        paint : function(){
            var _self = this;
            _self._drawLines();
            _self._renderTicks();
            _self._renderGrid(); 
        },
        /**
         * 是否是纵坐标
         */
        isVertical : function(){
            var _self = this,
                isVertical = _self.get('isVertical'),
                position;
            if(isVertical != null){
                return isVertical;
            }
            position = _self.get('position');
            if(position == 'bottom' || position == 'top'){
                isVertical = false;
            }else{
                isVertical = true;
            }
            
            _self.set('isVertical',isVertical);
            return isVertical;
        },
        /**
         * 将指定的节点转换成对应的坐标点
         * @param  {*} value 数据值或者分类 
         * @return {Number} 节点坐标点(单一坐标)x轴的坐标点或者y轴的坐标点
         */
        getOffset : function(value){
            var _self = this,
                ticks = _self.get('ticks'),
                index = BUI.Array.indexOf(value,ticks);

            return _self.getOffsetByIndex(index);
        },
        /**
         * 起点的坐标位置,也就是cavas上的点的位置
         * @return {Number} 坐标点的位置
         */
        getStartOffset : function(){
            return this._getStartCoord();
        },
        /**
         * 终点的坐标位置,也就是cavas上的点的位置
         * @return {Number} 坐标点的位置
         */
        getEndOffset : function(){
            return this._getEndCoord();
        },
        /**
         * 根据画板上的点获取坐标轴上的值,用于将cavas上的点的坐标转换成坐标轴上的坐标
         * @param  {Number} offset 
         * @return {Number} 点在坐标轴上的值
         */
        getValue : function(offset){
            var _self = this,
                startCoord = _self._getStartCoord(),
                endCoord = _self._getEndCoord();

            if(offset < startCoord || offset > endCoord){
                return NaN;
            }

            return _self.parseOffsetValue(offset);
        },
        /**
         * 获取坐标轴上起点代表的值
         * @return {*} 起点代表的值
         */
        getStartValue : function(){
            var _self = this,
                ticks = _self.get('ticks');
            return ticks[0];
        },
        /**
         * 获取坐标轴终点代表的值
         * @return {*} 终点代表的值
         */
        getEndValue : function(){
            var _self = this,
                ticks = _self.get('ticks');
            return ticks[ticks.length - 1];
        },

        
        getSnapIndex : function(offset){
            var _self = this,
                pointCache = _self.get('pointCache'),
                snap = Util.snapTo(pointCache,offset);;
            return BUI.Array.indexOf(snap,pointCache);
        },
        _appendEndOffset : function(offset){
            var _self = this,
                tickOffset = _self.get('tickOffset'),
                directfactor;
            if(tickOffset){
                directfactor = _self._getDirectFactor();
                if(offset == 0){
                    offset = offset + tickOffset * directfactor;
                }else if(offset > 0){
                
                    offset = offset + tickOffset;
                }else{
                    offset = offset - tickOffset;
                }
            }
            return offset;
        },
        /**
         * 将指定的节点转换成对应的坐标点
         * @param  {Number} index 顺序 
         * @return {Number} 节点坐标点(单一坐标)x轴的坐标点或者y轴的坐标点
         */
        getOffsetByIndex : function(index){
            var _self = this,
                length = _self._getLength(),
                ticks = _self.get('ticks'),
                count = ticks.length,
                offset = (length / (count - 1)) * index;

            return _self._appendEndOffset(offset) + _self._getStartCoord();
        },
        //获取坐标轴上的节点位置
        getOffsetPoint : function(index,current){

            var _self = this,
                ortho = _self._getOrthoCoord(),
                indexCache = _self.get('indexCache'); //根据索引获取值的缓存,防止重复计算

            if(!current){
                if(indexCache[index] !== undefined){
                    current = indexCache[index];
                }else{
                    current = _self.getOffsetByIndex(index);
                    indexCache[index] = current;
                }
                
            }
            
            if(_self.isVertical()){
                return {
                    x : ortho,
                    y : current
                };
            }

            return {
                x : current,
                y : ortho
            };

        },
        /**
         * @protected
         * 获取显示坐标点的位置
         */
        getTickOffsetPoint : function(index){
            return this.getOffsetPoint(index);
        },
       
        //获取坐标轴开始的点
        _getStartCoord : function(){
            var _self = this,
                start = _self.get('start');
            if(_self.isVertical()){
                return start.y;
            }else{
                return start.x;
            }
        },
        //获取平行于坐标轴的点
        _getOrthoCoord : function(){
            var _self = this,
                start = _self.get('start');
            if(_self.isVertical()){
                return start.x;
            }else{
                return start.y;
            }
        },
        //获取坐标轴结束的点
        _getEndCoord : function(){
            var _self = this,
                end = _self.get('end');
            if(_self.isVertical()){
                return end.y;
            }else{
                return end.x;
            }
        },
        //获取中间点的位置
        _getMiddleCoord : function(){
            var _self = this,
                start = _self._getStartCoord(),
                length = _self._getLength();
            return start + _self._appendEndOffset(length/2);
        },
        /**
         * 获取坐标轴的长度
         * @return {Number} 坐标轴长度
         */
        getLength : function(){
            return Math.abs(this._getLength());
        },
        /**
         * 获取坐标点之间的长度
         * @return {Number} 坐标点之间的宽度
         */
        getTickAvgLength : function(){
            var _self = this,
                ticks = _self.get('ticks');
            return _self.getLength()/(ticks.length - 1);
        },
        //获取坐标轴内部的长度,不计算偏移量
        _getLength : function(){
            var _self = this,
                start = _self.get('start'),
                offset = _self.get('tickOffset'),
                end = _self.get('end'),
                length;
            if(_self.isVertical()){
                length = end.y - start.y;
            }else{
                length = end.x - start.x;
            }
            if(length > 0){
                length = length - offset * 2;
            }else{
                length = length + offset * 2;
            }
            return length;
        },
        /**
         * @protected
         * 获取坐标轴的path
         * @return {String|Array} path
         */
        getLinePath : function(){
            var _self = this,
                start = _self.get('start'),
                end = _self.get('end'),
                path = [];

            path.push(['M',start.x,start.y]);
            path.push(['L',end.x,end.y]);
            return path;
        },
        getTickEnd : function(start){
            var _self = this,
                lineAttrs = _self.get('tickLine'),
                factor = _self._getAlignFactor(),
                value = lineAttrs.value,
                rst = {};

            if(_self.isVertical()){
                rst.x2 = start.x1 + value * factor;
                rst.y2 = start.y1;
            }else {
                rst.x2 = start.x1;
                rst.y2 = start.y1 + value * factor;
            }
            return rst;
        },
        _changeTicks : function(){
            var _self = this,
                tickShape = _self.get('tickShape'),
                tickItems = _self.get('tickItems'),
                path = '';
            if(!tickShape){
                return;
            }
            BUI.each(tickItems,function(item){
                var subPath = BUI.substitute('M{x1} {y1}L{x2} {y2}',item);
                path += subPath;
            });
            Util.animPath(tickShape,path,2);
        },

        //获取方向的系数,坐标轴方向跟浏览器的方向是否一致
        _getDirectFactor : function(){
            var _self = this,
                directfactor = _self.get('directfactor'),
                position,
                start,
                end;
            if(directfactor){
                return directfactor;
            }
            directfactor = 1;
            position = _self.get('position');
            start = _self.get('start');
            end = _self.get('end');
            //判断方向是否与坐标系方向一致
            if(position == 'bottom' || position == 'top'){
                if(start.x > end.x){
                    directfactor = -1;
                }
            }else{
                if(start.y > end.y){
                    directfactor = -1;
                }
            }

            _self.set('directfactor',directfactor);
            return directfactor;
        },
        //获取文本、坐标点线方向的因子
        _getAlignFactor : function(){
            var _self = this,
                factor = _self.get('factor'),
                position;
            if(factor){
                return factor;
            }
            position = _self.get('position');

            if(position == 'bottom' || position == 'right'){
                factor = 1;
            }else{
                factor = -1;
            }
            _self.set('factor',factor);
            return factor;
        },
        //渲染标题
        _renderTitle : function(){
            var _self = this,
                title = _self.get('title'),
                middle = _self._getMiddleCoord(),
                offsetPoint = _self.getOffsetPoint(null,middle),
                cfg = BUI.mix({},title);
            if(title.text){


                cfg.x = offsetPoint.x + (title.x || 0);
                cfg.y = offsetPoint.y + (title.y || 0);
                _self.addShape({
                    type : 'label',
                    elCls : CLS_AXIS + '-title',
                    attrs : cfg
                });
            }

        },
        /**
         * 获取栅格项的配置信息,一般是起始点信息
         * @protected
         */
        getGridItemCfg : function(offsetPoint){
            var _self = this,
                item = {},
                plotRange = _self.get('plotRange');

            item.x1 = offsetPoint.x;
            item.y1 = offsetPoint.y;
            if(_self.isVertical()){
                item.y2 = item.y1;
                item.x2 = plotRange.end.x;
            }else{
                item.x2 = item.x1;
                item.y2 = plotRange.end.y;
            }

            return item;

        },

        _changeGrid : function(){
            var _self = this,
                grid = _self.get('grid'),
                gridGroup;
            if(!grid){
                return;
            }
            gridGroup = _self.get('gridGroup');

            gridGroup && gridGroup.change(grid.items);
        },
        //移除控件前移除对应的grid和labels
        remove : function(){
            
            var _self = this,
                gridGroup = _self.get('gridGroup'),
                labelsGroup = _self.get('labelsGroup');
            gridGroup && gridGroup.remove();
            _self.removeLabels();
            Axis.superclass.remove.call(this);
        }
    });

    return Axis;
});
Example #30
0
  ,'bui/chart/activedgroup','bui/chart/series','bui/chart/tooltip','bui/chart/axis'],function (require) {

  var BUI = require('bui/common'),
    ActivedGroup = require('bui/chart/activedgroup'),
    PlotItem = require('bui/chart/plotitem'),
    Legend = require('bui/chart/legend'),
    Tooltip = require('bui/chart/tooltip'),
    Axis = require('bui/chart/axis'),
    Series = require('bui/chart/series'),
    maxPixel = 120, //坐标轴上的最大间距
    minPixel = 80; //坐标轴上最小间距

  function min(x,y){
    return x > y ? y : x;
  }
  function max(x,y){
    return x > y ? x : y;
  }

  /**
   * @class BUI.Chart.SeriesGroup
   * 数据序列的容器
   * @protected
   */
  function Group(cfg){
    Group.superclass.constructor.call(this,cfg);
  }

  Group.ATTRS = {
    elCls : {
      value : 'x-chart-series-group'
    },
    zIndex : {
      value : 5
    },
    plotRange : {

    },
    /**
     * 存在多个序列时,线的颜色,marker的颜色
     * @type {Object}
     */
    colors : {
      value : ['#2f7ed8','#0d233a','#8bbc21','#910000','#1aadce','#492970','#f28f43','#77a1e5','#c42525','#a6c96a']
    },
    /**
     * 如果使用marker,那么不同图形序列的形状
     * @type {Array}
     */
    symbols : {
      value : ['circle','diamond','square','triangle','triangle-down']
    },
    /**
     * 序列图的统一配置项,不同的序列图有不同的配置项例如:
     *
     *  - lineCfg : 折线图的配置项
     *  - columnCfg : 柱状图的配置项
     * @type {Object}
     */
    seriesOptions : {
      value : {}
    },
    /**
     * 数据图形序列的配置项
     * @type {Array}
     */
    series : {

    },
    /**
     * 图例
     * @type {Object}
     */
    legend : {

    },
    /**
     * x 坐标轴
     * @type {BUI.Chart.Axis}
     */
    xAxis : {

    },
    /**
     * y 坐标轴
     * @type {Array|BUI.Chart.Axis}
     */
    yAxis : {

    },
    /**
     * 提示信息的配置项
     * @type {Object}
     */
    tooltip : {

    },
    /**
     * @private
     * 缓存的层叠数据
     * @type {Array}
     */
    stackedData : {

    },
    /**
     * 可以设置数据序列共同的数据源
     * @type {Array}
     */
    data : {

    },
    /**
     * 活动子项的名称,用于组成 itemactived,itemunactived的事件
     * @protected
     * @type {String}
     */
    itemName : {
      value : 'series'
    }

  };

  BUI.extend(Group,PlotItem);

  BUI.mixin(Group,[ActivedGroup]);

  BUI.augment(Group,{


    //渲染控件
    renderUI : function(){
      var _self = this;
      Group.superclass.renderUI.call(_self);
      //_self._renderTracer();
      _self._renderLegend();

      _self._renderSeries();
      _self._renderAxis();
      _self._addSeriesAxis();

      _self._paintAxis(_self.get('xAxis'),'xAxis');
      _self._paintAxis(_self.get('yAxis'),'yAxis');
      _self._paintSeries();

      _self._renderTooltip();
    },
    //绑定事件
    bindUI : function(){
      var _self = this;
      Group.superclass.bindUI.call(_self);
      _self.bindCanvasEvent();
    },
    //绑定鼠标在画板上移动事件
    bindCanvasEvent : function(){
      var _self = this,
        triggerEvent = _self.get('tipGroup').get('triggerEvent'),
        canvas = _self.get('canvas');

      if (triggerEvent == 'click') {
        function __documentClick(ev){
          if(!$.contains(canvas.get('node'), ev.target)&&canvas.get('node') != ev.target){
            _self.onTriggerOut(ev);
            $(document).off('click', __documentClick);
          }
        }
        canvas.on('click',function(ev){
          _self.onCanvasMove(ev);
          setTimeout(function(){
            $(document).off('click', __documentClick).on('click', __documentClick);
          })
        });

      } else {
        canvas.on('mousemove',BUI.wrapBehavior(_self,'onCanvasMove'));
        canvas.on('mouseout',BUI.wrapBehavior(_self,'onMouseOut'));
      }
    },
    //处理鼠标在画板上移动
    onCanvasMove : function(ev){
      var _self = this,
        canvas = _self.get('canvas'),
        tipGroup = _self.get('tipGroup'),
        point,
        tipInfo;

      if(!tipGroup){
        return;
      }

      point = canvas.getPoint(ev.pageX,ev.pageY);
      if(_self._isInAxis(point)){
        _self._processTracking(point,tipGroup);
      }else{
        _self.onMouseOut();
      }
    },
    // 处理隐藏tip事件
    onTriggerOut : function(ev){
      var _self = this,
        tipGroup = _self.get('tipGroup');
      _self.clearActivedItem();
      //标志从显示到隐藏
      if(tipGroup.get('visible')){
        if(tipGroup.get('shared')){
          BUI.each(_self.getVisibleSeries(),function(series){
            var markers = series.get('markersGroup');
            markers && markers.clearActivedItem();
          });
        }
        _self._hideTip();
      }
    },

    onMouseOut : function(ev){
      var _self = this;
      if(ev && ev.target != _self.get('canvas').get('none')){
        return;
      }
      _self.onTriggerOut(ev);

    },
    /**
     * 获取所有的数据序列
     * @return {Array} [description]
     */
    getSeries : function(){
      return this.get('children');
    },
    //处理鼠标跟随事件
    _processTracking : function(point,tipGroup){
      var _self = this,
        sArray = [],
        //prePoint = _self.get('prePoint'),
        tipInfo;


      if(!tipGroup.get('shared')){
        var activedItem = _self.getActived();
        activedItem && sArray.push(activedItem);
      }else{
        sArray = _self.getSeries();
      }

      BUI.each(sArray,function(series){
        if(series && series.get('stickyTracking') && series.get('visible')){
          series.onStickyTracking({point : point});
        }
      });
      if(sArray.length){
        tipInfo = _self._getTipInfo(sArray,point);
        if(tipInfo.items.length){
          _self._showTooltip(tipInfo.title,tipInfo.point,tipInfo.items);
        }

      }
    },
    //获取显示tooltip的内容
    _getTipInfo : function(sArray,point){
      var rst = {
        items : [],
        point : {}
      };
      var count = 0,
        renderer = this.get('tipGroup').get('pointRenderer');
      BUI.each(sArray,function(series,index){
        var info = series.getTrackingInfo(point),
            item = {},
            title;

        if(info){
          if(series.get('visible')){
            count = count + 1;
            item.name = series.get('name');
            item.value = renderer ? renderer(info,series) : series.getTipItem(info);
            item.color = info.color || series.get('color');
            rst.items.push(item);
            var markersGroup = series.get('markersGroup');
            if(markersGroup && markersGroup.get('single')){
              var marker = markersGroup.getChildAt(0);
              marker && marker.attr({
                x :info.x,
                y : info.y
              });
            }
          }
          if(series.get('xAxis')){
            title = series.get('xAxis').formatPoint(info.xValue);
          }else{
            title = info.xValue;
          }
          if(count == 1){
            rst.title =  title;
            if(info.x){
              rst.point.x = info.x;
              if(sArray.length == 1){
                rst.point.y = info.y;
              }else{
                rst.point.y = point.y;
              }
            }else{
              rst.point.x = point.x;
              rst.point.y = point.y;
            }

          }
        }
      });

      return rst;
    },
    //显示tooltip
    _showTooltip : function(title,point,items){
      var _self = this,
        tooltip = _self.get('tipGroup'),
        prePoint = _self.get('prePoint');
      if(!prePoint || prePoint.x != point.x || prePoint.y != point.y){
        tooltip.setTitle(title);
        tooltip.setItems(items);
        tooltip.setPosition(point.x,point.y);
        if(!tooltip.get('visible')){
          tooltip.show();
        }
        _self.set('prePoint',point);
      }
    },
    //隐藏tip
    _hideTip : function(){
      var _self = this,
        tipGroup = _self.get('tipGroup');
      if(tipGroup && tipGroup.get('visible')){
        tipGroup.hide();
        _self.set('prePoint',null);
      }
    },
    //是否在坐标系内
    _isInAxis : function(point){
      var _self = this,
        plotRange = _self.get('plotRange');

      return plotRange.isInRange(point);
    },
    //渲染所有的序列
    _renderSeries : function(){
      var _self = this,
        series = _self.get('series');

      BUI.each(series,function(item,index){
        _self.addSeries(item,index);
      });
    },
    //渲染legend
    _renderLegend : function(){
      var _self = this,
        legend = _self.get('legend'),
        legendGroup;

      if(legend){
        legend.items = legend.items || [];
        legend.plotRange = _self.get('plotRange');
        legendGroup = _self.get('parent').addGroup(Legend,legend);
        _self.set('legendGroup',legendGroup);
      }
    },
    //渲染tooltip
    _renderTooltip : function(){
      var _self = this,
        tooltip = _self.get('tooltip'),
        tipGroup;
      if(tooltip){
        tooltip.plotRange = _self.get('plotRange');
        tipGroup = _self.get('parent').addGroup(Tooltip,tooltip);
        _self.set('tipGroup',tipGroup);
      }
    },
    _renderAxis : function(){
      var _self = this,
        xAxis = _self.get('xAxis'),
        yAxis = _self.get('yAxis');
      if(xAxis && !xAxis.isGroup){
        xAxis = _self._createAxis(xAxis);
        _self.set('xAxis',xAxis);
      }

      if(BUI.isArray(yAxis) && !yAxis[0].isGroup){ //如果y轴是一个数组
        var temp = [];
        BUI.each(yAxis,function(item){
          temp.push(_self._createAxis(item));
          _self.set('yAxis',temp);
        });
      }else if(yAxis && !yAxis.isGroup){
        if(xAxis && xAxis.get('type') == 'circle'){
          yAxis.type = 'radius';
          yAxis.circle = xAxis;
        }
        yAxis = _self._createAxis(yAxis);
        _self.set('yAxis',yAxis);
      }


    },
    //创建坐标轴
    _createAxis : function(axis){
      var _self = this,
        type = axis.type,
        C,
        name;
      if(axis.categories){
        type = 'category';
      }else if(!axis.ticks && type != 'circle'){
        axis.autoTicks = true; //标记是自动计算的坐标轴
      }
      if(type == 'category' && !axis.categories){
        axis.autoTicks = true; //标记是自动计算的坐标轴
      }
      axis.plotRange = _self.get('plotRange');
      axis.autoPaint = false;  //暂时不绘制坐标轴,需要自动生成坐标轴

      type = type || 'number';
      name = BUI.ucfirst(type);
      C = Axis[name];
      if(C){
        return  _self.get('parent').addGroup(C,axis);
      }
      return null;
    },
    //获取y轴的坐标点
    _caculateAxisInfo : function(axis,name){
      if(axis.get('type') == 'category'){
        return this._caculateCategories(axis,name);
      }
      var _self = this,
        data = [],
        type = axis.get('type'),
        length = axis.getLength(),
        minCount = Math.floor(length / maxPixel),
        maxCount = Math.ceil(length / minPixel),
        stackType,
        series,
        min,
        max,
        interval,
        autoUtil,
        rst;
        if(type == 'number' || type == 'radius') {
          min = axis.getCfgAttr('min');
          max = axis.getCfgAttr('max');
          autoUtil = Axis.Auto;
        }else if(type == 'time'){
          var startDate = axis.get('startDate'),
            endDate = axis.get('endDate');
          if(startDate){
            min = startDate.getTime();
          }
          if(endDate){
            max = endDate.getTime();
          }
          autoUtil = Axis.Auto.Time;
        }

        interval = axis.getCfgAttr('tickInterval');

      series = _self.getSeries();

      var cfg = {
        min : min,
        max : max,

        interval: interval
      };
      if(name == 'yAxis'){
        cfg.maxCount = maxCount;
        cfg.minCount = minCount;
        stackType = series[0].get('stackType');
      }
      if(stackType && stackType != 'none'){
        data = _self.getStackedData(axis,name);
      }else{
        data = _self.getSeriesData(axis,name);
      }
      if(data.length){
        cfg.data = data;

        rst =  autoUtil.caculate(cfg,stackType);
      }else{
        rst = {
          ticks : []
        };
      }


      return rst;

    },
    _caculateCategories : function(axis,name){
      var _self = this,
        data = _self.getSeriesData(axis,name),
        categories = [];
        if(data.length){
          categories = categories.concat(data[0]);
        }
      if(data.length > 1 && !_self.get('data')){ //不共享data时
        for (var i = 1; i < data.length; i++) {
          var arr = data[i];
          BUI.each(arr,function(value){
            if(!BUI.indexOf(value)){
              categories.push(value);
            }
          });
        };
      }
      return {
        categories : categories
      };
    },
    /**
     * 获取数据序列的数据
     * @protected
     * @param  {BUI.Chart.Axis} axis 坐标轴
     * @param  {String} name 坐标轴名称
     * @return {Array} 数据集合
     */
    getSeriesData : function(axis,name){
      var _self = this,
        data = [],
        series = _self.getVisibleSeries();
      axis = axis || _self.get('yAxis');
      name = name || 'yAxis';

      BUI.each(series,function(item){
        if(item.get(name) == axis){
          var arr = item.getData(name);
          if(arr.length){
            data.push(arr);
          }

        }
      });

      return data;
    },
    //转换数据,将json转换成数组
    _parseData : function(obj,fields){
      var rst = [];
      BUI.each(fields,function(key){
        rst.push(obj[key]);
      });
      return rst;
    },
    /**
     * @protected
     * 获取层叠数据
     * @param  {String} stackType 层叠类型
     * @param  {BUI.Chart.Axis} axis 坐标轴
     * @param  {String} name 坐标轴名称
     * @return {Array} 数据集合
     */
    getStackedData : function(axis,name){
      var _self = this,
        data,
        first
        stackedData = _self.get('stackedData'),
        arr = [];
      if(stackedData){
        arr = stackedData;
      }else{
        data = _self.getSeriesData(axis,name);
        first = data[0];

        BUI.each(first,function(value,index){
          var temp = value;
          for(var i = 1 ; i< data.length; i++){
            temp += data[i][index];
          }
          arr.push(temp);
        });
        _self.set('stackedData',arr);
      }

      return arr;
    },
    //name 标示是xAxis ,yAxis and so on
    _paintAxis : function(axis,name){
      var _self = this,
        arr;

      if(BUI.isArray(axis)){
        arr = axis;
      }else{
        arr = [axis];
      }

      BUI.each(arr,function(item,index){
        if(_self._hasRelativeSeries(item,name)){
          if(item.get('autoTicks')){
            var info = _self._caculateAxisInfo(item,name);
            item.changeInfo(info);

          }

          item.paint();
        }

      });

    },
    //是否存在关联的数据序列
    _hasRelativeSeries : function(axis,name){
      var _self = this,
        series = _self.getVisibleSeries(),
        rst = false;

      BUI.each(series,function(item){
        if(item.get(name) == axis){
          rst = true;
          return false;
        }
      });
      return rst;

    },
    //数据变化或者序列显示隐藏引起的坐标轴变化
    _resetAxis : function(axis,type){

      if(!axis.get('autoTicks')){
        return;
      }
      type = type || 'yAxis';

      var _self = this,
        info = _self._caculateAxisInfo(axis,type),
        series = _self.getSeries();

      _self.set('stackedData',null);
      //如果是非自动计算坐标轴,不进行重新计算

      axis.change(info);
    },
    _resetSeries : function(){
      var _self = this,
        series = _self.getSeries();
      BUI.each(series,function(item){
        if(item.get('visible')){
          item.repaint();
        }
      });
    },
    /**
     * 重新绘制数据序列
     */
    repaint : function(){
      var _self = this,
        xAxis = _self.get('xAxis'),
        yAxis = _self.get('yAxis');
      xAxis && _self._resetAxis(xAxis,'xAxis');
      if(yAxis){
        if(BUI.isArray(yAxis)){
          BUI.each(yAxis,function(axis){
            _self._resetAxis(axis,'yAxis');
          });
        }else{
          _self._resetAxis(yAxis,'yAxis');
        }
      }
      _self._resetSeries();
    },
    /**
     * 改变数据
     * @param  {Array} data 数据
     */
    changeData : function(data){
      var _self = this,
        series = _self.getSeries(),
        fields = _self.get('fields');

      _self.set('data',data);

      BUI.each(series,function(item,index){
        if(fields){
          var arr = _self._getSeriesData(item.get('name'),index);
          item.changeData(arr);
        }else{
          item.changeData(data);
        }
      });
      _self.repaint();
    },
    //根据series获取data
    _getSeriesData : function(name,index){
      var _self = this,
        data = _self.get('data'),
        fields = _self.get('fields'),
        obj = data[index];
      if(name){
        BUI.each(data,function(item){
          if(item.name == name){
            obj = item;
            return false;
          }
        });
      }
      return _self._parseData(obj,fields);
    },
    //获取默认的类型
    _getDefaultType : function(){
      var _self = this,
        seriesCfg = _self.get('seriesOptions'),
        rst = 'line'; //默认类型是线
      BUI.each(seriesCfg,function(v,k){
        rst = k.replace('Cfg','');
        return false;
      });
      return rst;
    },
    /**
     * 获取显示的数据序列
     * @return {BUI.Chart.Series[]} 数据序列集合
     */
    getVisibleSeries : function(){
      var _self = this,
        series = _self.getSeries();
      return BUI.Array.filter(series,function(item){
        return item.get('visible');
      });
    },
    /**
     * 添加数据序列
     * @param {BUI.Chart.Series} item 数据序列对象
     */
    addSeries : function(item,index){
      var _self = this,
        type = item.type || _self._getDefaultType(),
        cons = _self._getSeriesClass(type),
        cfg = _self._getSeriesCfg(type,item,index),
        series ;
      cfg.autoPaint = cfg.autoPaint || false;

      series  = _self.addGroup(cons,cfg);
      _self._addLegendItem(series);
      return series;
    },
    //绘制数据线
    _paintSeries : function(){
      var _self = this,
        series = _self.getSeries();

      BUI.each(series,function(item){
        item.paint();
      });
    },
    _addSeriesAxis : function(){
      var _self = this,
        series = _self.getSeries();

      BUI.each(series,function(item){
        if(item.get('type') == 'pie'){
          return true;
        }
        //x轴
        if(!item.get('xAxis')){
          item.set('xAxis', _self.get('xAxis'));
        }
        //y轴
        var yAxis = _self.get('yAxis');

        if(item.get('yAxis') == null){
          if(BUI.isArray(yAxis)){
            item.set('yAxis',yAxis[0]);
          }else{
            item.set('yAxis',yAxis);
          }
        }
        //多个y轴时
        if(BUI.isNumber(item.get('yAxis'))){
          item.set('yAxis',yAxis[item.get('yAxis')]);
        }
      });

    },
    /**
     * 显示series
     * @param  {BUI.Chart.Series} series 数据序列对象
     */
    showSeries : function(series){
      var _self = this,
        yAxis = _self.get('yAxis');
      if(!series.get('visible')){
        series.show();
        if(yAxis){
          _self._resetAxis(yAxis);
          _self._resetSeries();
        }
      }
    },
    /**
     * 隐藏series
     * @param  {BUI.Chart.Series} series 数据序列对象
     */
    hideSeries : function(series){
      var _self = this,
        yAxis = _self.get('yAxis');
      if(series.get('visible')){
        series.hide();
        if(yAxis){
          _self._resetAxis(yAxis);
          _self._resetSeries();
        }
      }
    },
    _addLegendItem : function(series){
      var _self = this,
        legendGroup = _self.get('legendGroup');
      legendGroup && legendGroup.addItem({
        series : series
      });
    },
    //获取序列的配置信息
    _getSeriesCfg : function(type,item,index){
      var _self = this,
        seriesCfg = _self.get('seriesOptions'),
        colors = _self.get('colors'),
        data = _self.get('data'),
        fields = _self.get('fields'),
        symbols = _self.get('symbols');

      item = BUI.mix(true,{},seriesCfg[type + 'Cfg'],item);

      //颜色
      if(!item.color && colors.length){
        item.color = colors[index % (colors.length)];
      }
      //marker的形状
      if(item.markers && item.markers.marker && !item.markers.marker.symbol){
        item.markers.marker.symbol = symbols[index % symbols.length];
      }
      if(data && !item.data){
        if(fields){
          item.data = _self._getSeriesData(item.name,index);
        }else{
          item.data = data;
        }

      }

      return item;
    },
    //根据类型获取构造函数
    _getSeriesClass : function(type){
      var name = BUI.ucfirst(type),
        c = Series[name] || Series;
      return c;
    },
    remove : function(){
      var _self = this,
        canvas = _self.get('canvas');
      canvas.off('mousemove',BUI.getWrapBehavior(_self,'onCanvasMove'));
      canvas.off('mouseout',BUI.getWrapBehavior(_self,'onMouseOut'));

      Group.superclass.remove.call(_self);
    }

  });

  return Group;
});