zoukankan      html  css  js  c++  java
  • datagrid

    /**
    * DataGrid widget
    *
    * @param appendTo   		{String}		element id which will be appended.
    * @param target     		{HTMLELement}	data element.
    * @param aData      		{Array}			[[],[],...,[]].
    * @param aNames   	  		{Array}       	["name1", "name2",...].
    * @param isEdit    			{Boolean}     	decide whether datagrid can be edited
    * @param hasHeader  		{Boolean}
    * @param headerCont 		{Array}
    * @param hasTotal   		{Boolean}
    * @param trEvent    		{JSON}        	ex. {event:function}.
    * @param tdEvent    		{JSON}       	ex. {event:function}.
    * @param tdUnbind  	 		{Array}      	the cell index which event do not bind.
    * @param zebras    			{JSON}        	tr css.
    * @param norTrCss   		{JSON}        	tr css.
    * @param curTrCss   		{JSON}        	tr css.
    * @param align      		{String} 	  	td align.
    * @param editPos    		{String} 	  	row edit area position.
    * @param editBtns    		{Array}       	array of edit buttons.
    * @param editBtnHandler 	{Array}    	 	event function of edit buttons. ex.[{event1:function}, {event1:function},...].
    * @param deleteBtnCss    	{String}  		default delete button style.
    * @param deleteRowCallback 	{Function} 		delete callback function.
    * @param batchBarPos 		{String} 		batch bar position
    * @param batchBtns 			{Array} 		array of batch buttons
    * @param batchBtnHandler 	{Array} 		the same with editBtnHandler
    * @param selectAllCss 		{String} 		the style of select all checkbox
    * @param batchDeleteCss  	{String}  		default batch delete button style.
    * @param batchDeleteCallback{Function} 		batch delete callback function.
    *
    */
    var datagrid = function(params, undefined){
    	this.options = {
    		appendTo:"",
    		target:"",
    		
    		//data and post names
    		aData:[],
    		aNames:[],
    		
    		
    		isEdit:true,
    		
    		//header and total handler
    		hasHeader:false,
    		headerCont:[],
    		hasTotal:false,
    		//totalCells:[],
    		//totalHandler:{},
    		
    		//td event
    		trEvent:{},
    		tdEvent:{},	
    		tdUnbind:[],
    		
    		//tr css
    		zebras:{background:"#d4e4ff"},
    		norTrCss:{background:""},
    		curTrCss:{background:"#dddddd"},
    		
    		align:"center",
    		
    		//edit area
    		editPos:"right",		
    		editBtns:[],
    		editBtnHandler:[],
    		deleteBtnCss:"",
    		deleteRowCallback:function(){},
    		
    		
    		
    		//batch area
    		batchBarPos:"top",
    		batchBtns:[],
    		batchBtnHandler:[],
    		selectAllCss:"",
    		batchDeleteCss:"",
    		batchDeleteCallback:function(){}
    		
    	};
    	
    	wapi.extend(this.options, params);
    	
    	
    	if(this.options.appendTo != "" && document.getElementById(this.options.appendTo)) wapi("#" + this.options.appendTo).append(this.options.target);
    	else if(this.options.target == ""){
    		this.options.target =  wapi("<table>").attr({cellspacing:0, cellpadding:0})[0];
    		wapi("body").append(this.options.target);
    	}
    	
    	//default edit button and handler
    	this.editBtns = [wapi("<a>").html("DELETE").attr("style", this.options.deleteBtnCss)];
    	this.editBtnHandler = [{click:function(){
    			if(this.datagrid.block) return; //block edit mode
    		
    			wapi(this.tr).remove();
    			
    			this.datagrid.block = false;
    			
    			this.datagrid.options.deleteRowCallback.apply(this, arguments);
    		}
    	}];
    	
    	//default batch button and handlers
    	this.batchBtns = [wapi("<input>").attr({type:"checkbox", name:"selectAll"}).attr("style", this.options.selectAllCss), wapi("<a>").html("DELETE").attr("style", this.options.batchDeleteCss)];
    	this.batchBtnHandler = [
    		{
    			click:function(){
    				var chkBox = this.datagrid.getChkbox();
    				
    				function set(chk){
    					wapi.each(chkBox.chkBox, function(i, elem){
    						elem.checked = chk;
    					});
    				}
    				
    				if(chkBox.chkBox.length > 0) set(!(chkBox.selectAllBox.checked == false));
    				
    			}
    		},
    	
    		{
    			click:function(){
    				if(this.datagrid.block) return; //block edit mode
    				
    				if(this.tr.length > 0){
    					var chkBox = this.datagrid.getChkbox(true);
    					chkBox.selectAllBox.checked = false;
    				}
    				
    				wapi.each(this.tr, function(i, elem){
    					wapi(this).remove();
    				});
    				
    				this.datagrid.block = false;
    				
    				this.datagrid.options.batchDeleteCallback.apply(this, arguments);
    			}
    		}
    	];
    	
    	//handler array
    	this.curTr = [];
    	this.curTd = [];
    	
    	//edit block	
    	this.block = false;
    	
    	this.cellsNum = 0;
    	
    	this.init();
    };
    datagrid.prototype = {
    	init:function(){
    		this.createHeader();
    		
    		if(this.options.isEdit) {
    			this.bindBtnHandler(this.batchBtns.concat(this.options.batchBtns), this.batchBtnHandler.concat(this.options.batchBtnHandler), this.batchBar = wapi(this.options.target.insertRow((this.options.batchBarPos === "bottom" ? this.options.target.rows.length : 0)).insertCell(0)).attr({colspan:this.cellsNum}));
    		}
    		
    		var add = wapi.bindScope(this, this.add);
    		
    		wapi.each(this.options.aData, function(index, dataItem){
    			if(dataItem.length > 0) add(dataItem);
    		});		
    	},
    	
    	createHeader:function(){
    		if(this.options.hasHeader){
    			if(this.options.headerCont.length > 0) {
    				var tr = this.options.target.insertRow(0);
    				this.setCellsNum(this.options.headerCont);
    				for(var i=0; i<this.cellsNum; i++){
    					if(i == this.cellsNum -1 && this.options.isEdit){
    						if(this.options.editPos == "left") tr.insertCell(1);
    						else tr.insertCell(i);
    					}else wapi(tr.insertCell(i)).html(this.options.headerCont[i]);
    					
    				}
    			}else{
    				this.setCellsNum(this.options.aData[0]);
    				var tr = this.options.target.rows[0];
    				if(this.options.isEdit){
    					if(this.options.editPos == "left") tr.insertCell(1);
    					else tr.insertCell(tr.cells.length);
    				}
    			}
    		}
    	},
    	
    	setCellsNum:function(aData){
    		//if(this.cellsNum != 0) return;
    		
    		if(!!aData) this.cellsNum = aData.length > 0 ? this.options.isEdit ? aData.length + 1 : aData.length : 0;
    		
    		if(typeof this.headerCellsNum === "undefined" && this.options.hasHeader) this.headerCellsNum = this.options.isEdit ? this.options.target.rows[0].cells.length + 1 : this.options.target.rows[0].cells.length;
    		
    		this.cellsNum = Math.max(this.headerCellsNum, this.cellsNum);
    	},
    	
    	bindBtnHandler:function(aElem, aFn, target, source){
    		var getSelected = wapi.bindScope(this, this.getSelected);
    		var bindTrEvent = wapi.bindScope(this, this.bindTrEvent);
    		
    		wapi.each(aElem, function(i, btn){
    			btn = wapi(btn[0].cloneNode(true));
    			if(!!aFn[i] && !wapi.isEmptyObject(aFn[i])){
    				wapi.each(aFn[i], function(pro, fn){
    					target.append(
    						btn[pro](function(){
    							fn.apply(getSelected(source), arguments);
    							bindTrEvent();
    						})
    					);
    				});
    			}else target.append(btn);
    		});
    	},
    	
    	bindTdEvent:function(td, fn, event){
    		var datagrid = {
    			td:td,
    			datagrid:this
    		};
    		
    		this.curTd = td;
    		
    		this.cancelBubble(event);
    		
    		if(!this.options.isEdit) return;
    		if(!this.block)	fn.call(datagrid, event);
    	},
    	
    	bindTrEvent:function(tr){
    		var target = this.options.target;
    		var isEdit = this.options.isEdit;
    		var hasTotal = this.options.hasTotal;
    		var hasHeader = this.options.hasHeader;
    		
    		var mouseOver = wapi.bindScope(this, function(tr){
    			if(!this.block) wapi(tr).css(this.options.curTrCss);
    		});
    					
    		var norMouseout = wapi.bindScope(this, function(tr){
    			wapi(tr).css(this.options.norTrCss);
    		});
    		
    		var zebrasMouseout = wapi.bindScope(this, function(tr){
    			wapi(tr).css(this.options.zebras);
    		})
    		
    		var bindMouseEvent = wapi.bindScope(this, function(a, tr){
    			if(a) tr.css(this.options.zebras).mouseout(function(){zebrasMouseout(this)});
    			else tr.mouseout(function(){norMouseout(this)});
    			
    			tr.mouseover(function(){
    				mouseOver(this);
    			});
    		});
    		
    		var setEvent = wapi.bindScope(this, function(tr){
    			var index = tr.rowIndex;
    			
    			tr = wapi(tr);
    			
    			tr.css(this.options.norTrCss);
    			
    			switch(this.options.batchBarPos)
    			{
    				case "bottom":
    					if(isEdit && index == target.rows.length - 1) return;
    					if(isEdit && index == 0 && hasHeader) return;
    					if(hasTotal && ((isEdit && index == target.rows.length - 2) || (!isEdit && index == target.rows.length - 1))) return;
    					
    					bindMouseEvent(index%2 != 0, tr);
    					
    					break;
    				case "top":
    					if(isEdit && index == 0) return;
    					if(isEdit && index == 1 && hasHeader) return;
    					if(hasTotal && index == target.rows.length - 1) return;
    					
    					bindMouseEvent(index%2 == 0, tr);
    					break;
    			}
    		});
    		
    		if(tr) {
    			setEvent(tr);
    			this.curTr = tr;
    		} else {
    			var _target = wapi(this.options.target);
    			if(_target.child("tbody").length > 0) _target = _target.child("tbody");
    			
    			_target.child("tr").each(function(i, tr){
    				setEvent(tr);
    			});
    		}
    	},
    	
    	update:function(aData){
    		var index = 0;
    		var endIndex = 0;
    		
    		if(this.block) return;
    		
    		if(this.options.hasHeader){
    			if(this.options.isEdit && this.options.batchBarPos == "top") index = 2;
    			else index = 1;
    		}else if(this.options.isEdit && this.options.batchBarPos == "top") index = 1;
    		
    		if(this.options.hasTotal ){
    			if(this.options.isEdit && this.options.batchBarPos == "bottom") endIndex = 2;
    			else endIndex = 1;
    		}else if(this.options.isEdit && this.options.batchBarPos == "bottom") endIndex = 1;
    		
    		while(this.options.target.rows.length > index + endIndex){
    			this.options.target.deleteRow(index);
    		}
    		
    		this.options.aData = aData;
    		
    		var add = wapi.bindScope(this, this.add);
    		
    		wapi.each(this.options.aData, function(index, dataItem){
    			if(dataItem.length > 0) add(dataItem);
    		});	
    		
    		this.resetSelectAll();
    	},
    	
    	add:function(aData){
    		var target = this.options.target;
    		var tick = this.options.isEdit && this.options.batchBarPos === "bottom" ? 1 : 0;
    		var index = this.options.hasTotal ? target.rows.length - 1 - tick : target.rows.length - tick;
    		var tr = target.insertRow(index);
    		this.bindTrEvent(tr);
    		
    		this.items(tr, aData, this.options.aNames);
    		
    		wapi(tr).css("opacity", 0).animate({opacity:"=1"}, 300);
    		
    		this.resetSelectAll();
    	},
    	
    	items:function(tr, aData, aNames){
    		var bindTdEvent = wapi.bindScope(this, this.bindTdEvent);
    		
    		if(this.cellsNum === 0) {
    			this.setCellsNum(aData);
    			if(this.options.isEdit && this.batchBar.attr("colspan") == 0) this.batchBar.attr("colspan", this.cellsNum);
    		}
    		
    		for(var i = 0; i < this.cellsNum; i++){
    			(function(i, datagrid){
    				var td = tr.insertCell(i);
    				var name = typeof aNames[i] !== "undefined" ? aNames[i] : "";
    				var data = aData[i];
    				
    				td.align = datagrid.options.align;
    				td.data = wapi("<input>").attr({name:name, type:"hidden", value:data});
    				
    				if(datagrid.options.isEdit){
    					if(i == 0) {
    						var chkBox = datagrid.getChkbox();
    						wapi(td).append(wapi("<input>").attr({type:"checkbox", name:name, value:data})).append(td.data).click(function(){
    							chkBox.selectAllBox.checked = false;
    						}); //for batch edit
    						return;
    					}
    					else if(i == datagrid.cellsNum - 1){
    						if(datagrid.options.editPos === "left") td = tr.insertCell(1);
    						datagrid.bindBtnHandler(datagrid.editBtns.concat(datagrid.options.editBtns), datagrid.editBtnHandler.concat(datagrid.options.editBtnHandler), wapi(td), td);
    						return;
    					}
    				}
    				
    				if(typeof data === "undefined" || data == "" || data == 0 || data == "disabled" || data == "none") td.innerHTML = "-";//no data					
    				else {
    					wapi(td).html(data).append(td.data);
    					
    					var isBind = true;
    					if(datagrid.options.tdUnbind.length > 0) wapi.each(datagrid.options.tdUnbind, function(i, index){
    						if(td.cellIndex == index) isBind = false;
    					});
    					if(isBind && !wapi.isEmptyObject(datagrid.options.tdEvent)) wapi.each(datagrid.options.tdEvent, function(pro, fn){
    						wapi(td)[pro](function(event){
    							bindTdEvent(this, fn, event);
    						});
    					});
    				}
    			})(i, this)
    		}
    		return tr;
    	},
    				
    	getSelected:function(elem){
    		var curTr = [];
    		var curTd = [];
    		var datagridObject = this;
    		var getIt = wapi.bindScope(this, this.getIt);
    		
    		if(elem !== undefined && elem){
    			var aSelect = this.getIt(elem);
    			curTr = aSelect.tr;
    			curTd = aSelect.td;
    		}else{
    			wapi.each(this.getChkbox(true).chkBox, function(i, elem){
    				curTr.push(getIt(elem).tr);
    			});
    		}
    		
    		this.curTr = curTr;
    		this.curTd = curTd
    		
    		return {
    			tr:curTr,
    			td:curTd,
    			datagrid:datagridObject
    		}
    	},
    	
    	resetSelectAll:function(){
    		var chkbox = this.getChkbox();
    		if(this.options.isEdit) chkbox.selectAllBox.checked = false;
    	},
    	
    	getIt:function(elem){
    		var _tr, _td;
    		while(elem){
    			if(elem.tagName === "TR"){
    				_tr = elem;
    				break;
    			}
    			if(elem.tagName === "TD") _td = elem;
    			elem = elem.parentNode;
    		}
    		
    		return{
    			tr:_tr,
    			td:_td
    		}
    	},
    /*
    * get checkbox
    * 
    * @param filter {Boolean}	filter checkbox
    *
    * return {JSON}
    */
    	getChkbox:function(filter){
    		var inputs = this.options.target.getElementsByTagName("input");
    		var selectAllBox = [];
    		var chkBox = [];
    		
    		if(typeof filter !== "undefined") wapi.each(inputs, function(i, elem){
    			if(wapi(elem).attr("type") === "checkbox"){
    				if(wapi(elem).attr("name") === "selectAll") selectAllBox = elem;
    				else if(elem.checked == filter) chkBox.push(elem);
    			}
    		});
    		else  wapi.each(inputs, function(i, elem){
    			if(wapi(elem).attr("type") === "checkbox" ) {
    				if(wapi(elem).attr("name") === "selectAll") selectAllBox = elem;
    				else chkBox.push(elem);
    			}
    		});
    		
    		return {
    			chkBox:chkBox,
    			selectAllBox:selectAllBox
    		}
    	},
    	
    	cancelBubble:function(e){
    		e = e || window.event;
    		window.event ? e.cancelBubble = true : e.stopPropagation();
    	}
    };
    

    test page:

    <!DOCTYPE HTML>
    <html>
    <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>data grid</title>
    <script src="wishfi.js" type="text/javascript"></script>
    <script src="dataGrid.js" type="text/javascript"></script>
    </head>
    
    <body>
    <input id="minimum_impression" name="" type="text">
    <div style="660px;">
    <table  id="categoryData" width="100%" border="0" cellspacing="0" cellpadding="3">
      <tbody>
        <tr>
            <th width="30"></th>
            <th width="180">Category Name</th>
            <th width="170">Impressions Budget</th>
            <th width="170">Percentage(%)</th>
        </tr>
        <tr> 
            <th width="30"> </th> 
            <th width="180">total</th> 
            <th width="170" id="impressionTotal">0</th> 
            <th width="170" id="percentTotal">0%</th> 
        </tr>
      </tbody>
    </table>
    <div id="addCategory" style="position:relative; height:27px; overflow:hidden;">
        <table cellspacing="0" cellpadding="3" border="0" width="100%"  style="position:absolute; top:-35px;">
            <tbody>
                <tr>
                    <td width="30"> </td>
                    <td align="center" width="180" valign="middle">
                    <select style="height: 18px;  130px; display: block;" name="category" class="category" id="category">
                    <option selected="" value="">Choose an category</option>
                    <option value="1">	TELECO NETWK,FIXED&MOBILEPHONE</option><option value="2">INTERNET SP/ PORTAL ALL</option><option value="3">BANKING/FINANCE</option><option value="4">AIRLINES</option><option value="5">GOVT SVCS (STAT BOARD,GOVT CAMPAIGN)</option><option value="6">CREDIT/CHARGE/DEBIT CARD/TRAVEL</option><option value="7">MOVIE</option><option value="8">INSURANCE</option><option value="9">LOTTERIES/COMPETITIONS</option><option value="10">HOTELS/RESORTS</option><option value="11">PHOTOGRAPHIC</option><option value="12">HAIR CARE PRODUCTS</option><option value="13">FASTFOOD OUTLETS</option><option value="14">EDUCATION (OTHERS)</option><option value="15">BEAUTY & FITNESS SVCS</option><option value="16">TRAVEL AGENCIES/TOURIST COMMIS</option><option value="17">ALL CARS + MOTORING</option><option value="18">SPORTS/GYM EQUIPMENT/SPORTS CTR/CLUB</option><option value="19">PC/NOTEBOOK/TABLET PC/SERVER/N</option><option value="20">SKIN CARE PRODUCTS</option><option value="21">OPTICALS</option><option value="22">FREIGHT/LOGISTICS/COURIER/SHIP</option><option value="23">EVENTS/ CONCERTS/ EXHIBTIONS ALL</option><option value="24">TELEVISION</option><option value="25">INVESTMENT/FUNDS</option><option value="26">CONFECTIONARY ALL</option><option value="27">BEER & STOUT ALL</option><option value="28">SUPER/HYPER/MINI MARKET/FOOD STORES</option><option value="29">PERFUME/COLOGNE</option><option value="30">AUDIO VISUAL EQUIPMENT</option>                                            </select>
                    </td>
                    <td align="center" width="170" valign="middle"><input type="text" style=" 130px; text-align: center;" id="impressions" name="impressions_temp[]" class="impressions[]" value=""></td>
                    <td align="center"  width="170" valign="middle"><input type="text" style=" 130px; text-align: center;" id="percentage" name="percentage_temp[]" class="percentage[]" value=""></td>
                    <td align="center" width="">
                    <a id="upload">upload</a>  <a id="exitAdd">exit</a>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
    </div>
    <script>
    (function(){
    
    /**
    * init category datagrid
    *
    */
    var categoryData = new datagrid({
    	target:wapi("#categoryData")[0],
    	aData:[
    		[3, "a", "10"],
    		[4, "b", "10"]
    	],
    	aNames:["category_id[]", "category_name[]", "impressions[]", "percentage[]"],
    	
    	isEdit:true,
    	hasHeader:true,
    	hasTotal:true,
    	
    	//row edit
    	deleteRowCallback:function(){
    		deleteTotal(this.tr);
    	},
    	
    	//batch handler area
    	selectAllCss:"margin:0 9px; padding:0;",
    	batchBarPos:"bottom",
    	batchDeleteCallback:function(){
    		wapi.each(this.tr, function(i, tr){
    			deleteTotal(tr);
    		})
    	},
    	batchBtns:[
    		wapi("<input>").attr({type:"button", value:"add"})
    	],
    	batchBtnHandler:[
    		{
    			click:function(){			
    				if(!this.datagrid.block) wapi("#addCategory").child("table").animate({top:"=0"}, 300);
    				this.datagrid.block = true; //enter edit mode
    				
    				var i = 0;
    				if(categoryData.options.isEdit) i++;
    				if(categoryData.options.hasTotal) i++;
    				if(categoryData.options.hasHeader) i++;
    				if(categoryData.options.target.rows.length == i) {
    					impressions.attr("value", "").css("color", "")[0].removeAttribute("disabled");
    					percentage.attr("value", "").css("color", "")[0].removeAttribute("disabled");
    				}
    				
    				var exitAdd = wapi.bindScope(this, function(){
    					wapi("#addCategory").child("table").animate({top:"=-35"}, 300);
    					
    					hidErro(category[0]);
    					hidErro(impressions[0]);
    					hidErro(percentage[0]);
    										
    					this.datagrid.block = false; //exit edit mode
    				});
    				
    				wapi("#exitAdd").click(exitAdd);
    			}
    		}
    	],
    	
    	tdUnbind:[1],
    	tdEvent:{
    		click:editCell
    	}
    });
    
    var categoryReg = {
    	reg:/^[1-9]\d*$|^[0]\d+$/i,
    	msg:"Integer required."
    }
    
    var emptyFN = function(){};
    
    var upload = wapi("#upload");
    
    var category = wapi("#category").change(function(){
    	chkData({
    		reg:/^[1-9]\d*$|^[0]\d+$/i,
    		msg:"Select a category."
    	}, this);
    });
    
    var impressions = wapi("#impressions").keyup(function(){
    	keyuphandler(impressions, percentage);
    });
    
    var percentage = wapi("#percentage").keyup(function(){
    	keyuphandler(percentage, impressions);
    });
    
    initTotal();
    
    /*total handler*/
    
    function initTotal(){
    	var percentageTotal = 0
    	var impressionsTotal = 0;
    	
    	function disabled(elem){
    		elem.attr({value:"disabled", disabled:"disabled"}).css("color", "#cccccc");
    	}
    	
    	wapi.each(categoryData.options.target.rows, function(i, tr){
    		wapi.each(tr.cells, function(i, td){
    			if(typeof td.data !== "undefined"){
    				var input = td.data
    				var name = input.attr("name");
    				var value = parseFloat(input.attr("value")) + "" === "NaN" ? 0 :parseFloat(input.attr("value"))
    				
    				if(name == "percentage[]") percentageTotal += value;
    				else if(name == "impressions[]") impressionsTotal += value;
    			}
    		});
    	});
    	wapi("#percentTotal").html(percentageTotal + "%");
    	wapi("#impressionTotal").html(impressionsTotal);
    	
    	if(percentageTotal == 0) disabled(percentage);
    	else if(impressionsTotal == 0) disabled(impressions);
    }
    
    function deleteTotal(tr){
    	var td = tr.cells;
    	for(var i = 0 , l = td.length; i < l; i++){			
    		if(typeof td[i].data !== "undefined") {
    			if(i == 1){
    				category.child("option").each(function(n, elem){
    					if(elem.innerHTML == td[i].data.attr("value")) elem.removeAttribute("disabled");
    				});
    			}
    			
    			var total = 0;
    			var input = td[i].data
    			var name = input.attr("name");			
    			var percentTotal = parseFloat(wapi("#percentTotal").html());
    			var impressionTotal = parseFloat(wapi("#impressionTotal").html());
    			
    			if(name == "percentage[]" && percentTotal > 0) {
    				percentTotal -= parseFloat(input.attr("value"));
    				wapi("#percentTotal").html(percentTotal + "%");
    			}
    			else if(name == "impressions[]" && impressionTotal > 0) {
    				impressionTotal -= parseFloat(input.attr("value"));
    				wapi("#impressionTotal").html(impressionTotal);
    			}
    		}
    	}
    }
    
    function totalHandler(name){
    	var total = 0;
    	var isPass = true;
    	
    	wapi.each(categoryData.options.target.getElementsByTagName("input"), function(i, elem){
    		elem = wapi(elem);
    		if(elem.attr("type") === "hidden" && elem.attr("name") === name){
    			total += parseFloat(elem.attr("value"));
    		}
    	});
    	
    	if(name == "percentage[]"){
    		if(total / 100 > 1) isPass = false;
    		else wapi("#percentTotal").html(total + "%");
    	}else if(name == "impressions[]"){
    		var totalLimit = parseFloat(wapi("#minimum_impression").attr("value")) + "" !== "NaN" ? parseFloat(wapi("#minimum_impression").attr("value")) : 0;
    		
    		if(totalLimit != 0){
    			if(total > totalLimit) isPass = false;
    			else wapi("#impressionTotal").html(total);
    		}
    		else if(totalLimit == 0) wapi("#impressionTotal").html(total);
    		else wapi("#impressionTotal").html(total);
    	}
    	
    	return {
    		isPass:isPass,
    		total:total
    	}
    }
    
    /*-- total handler end --*/
    
    function keyuphandler(a, b){
    	var name = a.attr("name");
    	name = name.slice(0, name.indexOf("_")) + "[]";
    	
    	var total = totalHandler(name).total;
    	total = total + parseFloat(a.attr("value"));
    	
    	var totalLimit = parseFloat(wapi("#minimum_impression").attr("value")) + "" !== "NaN" ? parseFloat(wapi("#minimum_impression").attr("value")) : 0;
    	totalLimit = name == "percentage[]" ? 100 : totalLimit;
    	
    	if(a.attr("value") == "") {
    		hidErro(a[0]);
    		return;
    	}
    	
    	if(chkData(categoryReg, a[0])){
    		if(total > totalLimit && totalLimit != 0){
    			showErro(a[0], "Out of limit.");
    			upload.click(emptyFN);
    		}else{
    			hidErro(b[0]);
    			b.attr({value:"disabled", disabled:"disabled"}).css("color", "#cccccc");		
    			upload.click(addCategory);
    		}		
    	}else if(a.attr("value") == ""){
    		hidErro(a[0]);
    		var i = 0;
    		if(categoryData.options.isEdit) i++;
    		if(categoryData.options.hasTotal) i++;
    		if(categoryData.options.hasHeader) i++;
    		if(categoryData.options.target.rows.length == i) b.attr("value", "").css("color", "")[0].removeAttribute("disabled");
    		upload.click(emptyFN);
    	}else upload.click(emptyFN);
    }
    
    function addCategory(){
    	var v0 = category[0].value;
    	var v1 = category[0].options[category[0].selectedIndex].innerHTML;
    	var v2 = impressions.attr("value") === "disabled" ? "" : impressions.attr("value");
    	var v3 = percentage.attr("value") === "disabled" ? "" : percentage.attr("value");
    	
    	if(v0 == ""){
    		chkData({
    			reg:/^[1-9]\d*$|^[0]\d+$/i,
    			msg:"Select a category."
    		}, category[0]);
    		return;
    	}
    	
    	categoryData.add([v0, v1, v2, v3]);
    	
    	//reset select&input element
    	category[0].options[category[0].selectedIndex].disabled = "disabled";
    	category[0].options[0].selected = "selected";
    	if(v2 !== "") impressions.attr("value","");
    	if(v3 !== "") percentage.attr("value","");
    	
    	initTotal();
    }
    
    /**
    * category cell edit method
    *
    */
    function editCell(){
    	var td = wapi(this.td);
    	var datagrid = this.datagrid;
    	var name = td[0].data.attr("name");
    	var oldValue = td.child("input").attr("value");
    	var oldTotal = totalHandler(name).total - parseFloat(td[0].data.attr("value"));
    	
    	var input = wapi("<input>").attr({type:"text", value:oldValue}).css({"80px", height:"16px", textAlign:"center"}).click(function(event){
    		datagrid.cancelBubble(event);
    	}).blur(function(){
    		if(chkData(categoryReg, this)){			
    			td[0].data.attr("value", this.value);
    			if(!totalHandler(name).isPass){
    				td[0].data.attr("value", oldValue);
    				showErro(input[0], "Out of limit.");
    			}else{
    				td.html(this.value);
    				td.append(td[0].data).css("background", "");
    				datagrid.block = false;
    				
    				hidErro(input[0]);
    				input = null;
    			}
    		}
    	}).keyup(function(event){
    		if(this.value == ""){
    			hidErro(this);
    			if(name == "percentage[]") wapi("#percentTotal").html(oldTotal + "%");
    			else if(name == "impressions[]") wapi("#impressionTotal").html(oldTotal);
    		}else {
    			if(chkData(categoryReg, this)){
    				td[0].data.attr("value", this.value);//set current data
    				if(!totalHandler(name).isPass){//check total limite and calculate
    					td[0].data.attr("value", oldValue);
    					totalHandler(name) //restore last total
    					showErro(input[0], "Out of limit.");
    				}else hidErro(input[0]);
    				td[0].data.attr("value", oldValue);//restore original data
    			}
    		}
    		
    		if(event.keyCode == 27){
    			this.onblur = function(){}; // unbind onblur event
    			hidErro(this);
    			
    			td[0].data.attr("value", oldValue);
    			td.html(oldValue);
    			td.append(td[0].data).css("background", "");
    			datagrid.block = false;
    			
    			input = null;
    		}
    	});
    	
    	td.html("").append(input).append(td[0].data).css("background", "#F60");
    	
    	input[0].focus();
    	
    	this.datagrid.block = true;
    }
    
    /*-- cell edit method end --*/
    
    /**
    * check data format
    *
    */
    function chkData(reg, elem){
    	var value = elem.value;
    	
    	if(!reg.reg.test(elem.value)) {
    		showErro(elem, (typeof reg.msg === "undefined" ? "" : reg.msg));
    		return false;
    	} else{
    		hidErro(elem);
    		return true;
    	}
    }
    
    function showErro(elem, msg){
    	var erroCss = {
    		height:"16px", 
    		lineHeight:"16px", 
    		padding:"0 3px", 
    		border:"1px solid #666666", 
    		background:"#FFFFFF"
    	};
    	
    	msg = wapi("<div>").css(erroCss).html(msg);
    	
    	if(typeof elem.hover !== "undefined"){
    		if(elem.hover.element.css("display") == "none") {
    				elem.hover.element.html("").append(msg);
    				elem.hover.show("fast");
    		}else elem.hover.element.html("").append(msg);
    	}else {
    		wapi(elem).hover("right", msg, {left:1});
    		elem.hover.show("fast");
    	}
    }
    
    function hidErro(elem){
    	if(typeof elem.hover !== "undefined" && elem.hover.element.css("display") != "none") elem.hover.hidden("fast");
    }
    
    /*-- check format end --*/
    })()
    </script>
    </body>
    </html>
    
  • 相关阅读:
    css3360度旋转动画
    PAT 1084 外观数列(20)(代码+思路+推荐测试用例)
    PAT 1083 是否存在相等的差(20)(代码+思路)
    PAT 1082 射击比赛(20)(代码+思路)
    PAT 1079 延迟的回文数(代码+思路)
    PAT 1078 字符串压缩与解压(20)(代码+思路)
    PAT 1077 互评成绩计算(20)(代码+思路)
    PAT 1073 多选题常见计分法(20)(代码+思路)
    PAT 1072 开学寄语(20)(代码+思路)
    PAT 1069 微博转发抽奖(20)(代码+思路+测试点4)
  • 原文地址:https://www.cnblogs.com/yili/p/1979971.html
Copyright © 2011-2022 走看看