/** * @author Peter Alexandersson */function WebQueryList(settings){		this.instanceId = WebQueryList.instances.length;	this.strRef = 'WebQueryList.instances[' + this.instanceId + ']';	WebQueryList.instances[this.instanceId] = this;}//Class static membersWebQueryList.instances = new Array();WebQueryList.eventStack = new Array();function WebQuery(settings){	//call super class	WebQueryList.call(this, settings);	this.graphSettings = new GraphProperties();	this.init(settings);}WebQuery.prototype={	//PROPERTIES =========================================================================================	className:'WebQuery',					//Used by debug alert	dbUrl:'',								//Url used by ajax request	contentQueryDiv:'',						//Target div/span id where the query will appear	contentResultDiv:'',					//Target div/span id where the result will appear	id:'',									//webquery id to extract	mode:'query',							//Selects start mode 'query' or 'result'	submitmessage:'Tack, din r\u00F6st har registrerats!',		//Response message upon a successful vote	showIntroText:0,						//Should attribute be displayed. 0=Not displayed, 1=Displayed	showCommentBox:0,						//Should attribute be displayed. 0=Not displayed, 1=Displayed	showResultButton:0,						//Should attribute be displayed. 0=Not displayed, 1=Displayed	showResultOnVote:0,						//Should a 'getResult' call follow a vote submission 	showResultQuestion:0,					//Should the webquery question with alternatives be displayed in the result	showResultIntro:0,						//Should the webquery intro text be displayed in the result	showResultComment:1,					//Should the webquery result comment text be displayed in the result	useLabelsOrColors:'labels',				//Should the webquery colors be used or labels	postSubmitCall:null,					//May be assigned to any function that should be called after a submit/vote	graphSettings:null,						//Graph setting is set in constructor	graphShowLegend:0,						//Controls if graph legend should be displayed: 0=Not displayed, 1=Displayed	graphShowLegendStyle:'short',			//Controls how graph legend should be displayed: long/short version	commentBoxRows:3,						//ROWS attribute for comments box	commentBoxCols:20,						//COLS attribute for comments box	maxlonglegend:10,						//max characters used for long legends	debugLevel:0,							//Selects debug mode. 0=Off, 1=On, but no alerts, 2=On, with alerts	debugDiv:'debuginfo',					//Debug div/span id where the debug info will appear	lastAction:null,						//Last WQEvent issued	lastRequestString:'',					//Last AJAX request	lastResponseString:'',					//Last AJAX response	labelbuttonvote:'R\u00F6sta',				//Label Vote button	labelbuttonresult:'Resultat',			//Label Result button	//METHODS =============================================================================================	//===== used to initialize the query	init:function(settings){						if (settings){			if (settings.dbUrl) this.dbUrl=settings.dbUrl;			if (settings.id) this.id=settings.id;			if (settings.bargraphtype) this.bargraphtype=settings.bargraphtype;			if (settings.contentQueryDiv) this.contentQueryDiv=settings.contentQueryDiv;			if (settings.contentResultDiv) this.contentResultDiv=settings.contentResultDiv;			if (settings.showIntroText!=null) this.showIntroText=settings.showIntroText; 			if (settings.showCommentBox!=null) this.showCommentBox=settings.showCommentBox; 			if (settings.showAlias!=null) this.showAlias =settings.showAlias; 			if (settings.showImage!=null) this.showImage =settings.showImage; 			if (settings.debugLevel!=null) this.debugLevel=settings.debugLevel; 			if (settings.debugDiv) this.debugDiv=settings.debugDiv; 		}		},	//===== Used to send an Ajax request to server to get data	sendRequest:function(wqevent){				if (this.debugLevel==2) alert(this.className+'.sendRequest()');		var pars;		var ajaxreq;		var agentused;		var targetDiv = (this.mode=='query') ? this.contentQueryDiv:this.contentResultDiv;		//verify that we have an event		if (wqevent){			switch(wqevent.type){				case WQEvent.EVT_GET_QUERY:		//get web query					agentused = 'webqueryController';					pars = "task=query&topicid="+ wqevent.fetchObject;					pars += (wqevent.dataString)?wqevent.dataString:'';					//alert('pars: '+ pars);					//ajaxreq = {method:'get', onSuccess:new Function('data', 'WebQueryList.instances['+this.instanceId+'].recieveData(data)'), parameters: pars, onFailure:this.handleError };					break;				case WQEvent.EVT_GET_RESULT:	//get web query result					agentused = 'webqueryController';					pars = "task=result&topicid="+ wqevent.fetchObject;					pars += (wqevent.dataString)?wqevent.dataString:'';					//alert('pars: '+ pars);					//ajaxreq = {method:'get', onSuccess:new Function('data', 'WebQueryList.instances['+this.instanceId+'].recieveData(data)'), parameters: pars, onFailure:this.handleError };					break;				case WQEvent.EVT_SUBMIT_VOTE:	//submit a vote					agentused = 'webqueryController';					pars = "task=submit&topicid="+ wqevent.fetchObject;					pars += (wqevent.dataString)?wqevent.dataString:'';					//alert('pars: '+ pars);					//ajaxreq = {method:'get', onSuccess:new Function('data', 'WebQueryList.instances['+this.instanceId+'].recieveData(data)'), parameters: pars, onFailure:this.handleError };					break;				default:						//an unrecognised/invalid event					alert('Error-Invalid event:'+wqevent.type);					return false;			}		} else {			alert(this.className+'.sendRequest: Missing a valid event object.' );			return		}		//send request to server		try{			this.lastRequestString = pars;			agentused = 'webqueryController';			var url = this.dbUrl+'/' + agentused +'?OpenAgent';			if (typeof jQuery != 'undefined') {        		// use jQuery style call				//jQuery.noConflict();				ajaxreq = {type: "GET",url: url, data: pars, success: new Function('data', 'WebQueryList.instances['+this.instanceId+'].recieveData(data)')	 }				this.lastRequest = $.ajax(ajaxreq);				//alert('x:' + url + ' pars: ' +pars);			} else {				//assume prototype.js style call				ajaxreq = {method:'get', onSuccess:new Function('data', 'WebQueryList.instances['+this.instanceId+'].recieveData(data)'), parameters: pars, onFailure:this.handleError };				this.lastRequest = new Ajax.Request(url, ajaxreq);				//alert('x:' + url + ' pars: ' +pars);			}		}catch (e){			alert('Kommunikationsproblem med server: ' + e.message + '\nParams: ' + pars);			location.reload();		}		//show progress icon 		if (wqevent.type!=WQEvent.EVT_SUBMIT_VOTE){			try{				document.getElementById(targetDiv).innerHTML = '<img src="'+this.dbUrl+'/img/indicator.gif">';			} catch(e) { alert(this.className+'.sendRequest():' + e.message + ', targetDiv:' + targetDiv); }		} 	},		//===== Callback method for Ajax communication errors	handleError:function(){							if (this.debugLevel==2) alert(this.className+'.handleError()');		alert('Kommunikationsfel - F\u00E5r ej svar fr\u00E5n AJAX server.')	},	//===== Callback method for successfull Ajax response	recieveData:function(originalRequest){			var responseText;		//alert('recieveData');		if (this.debugLevel==2) alert(this.className+'.recieveData()');		if (typeof originalRequest == 'object'){			responseText = originalRequest.responseText;		}else{			responseText = originalRequest;		}		this.lastResponseString = responseText ;		if (this.debugLevel>0){			this.printDebug();		}		//alert('recieveData:' + responseText);		var jsondata;		try{			jsondata = eval('(' + responseText + ')')		}catch(e){			//alert('catch:' + originalRequest.Status + e.message);			if (responseText.substring(0,1)=="<"){				//no JSON object, assumes an html page, probably logged out				location.reload(true);			} else {				//something wrong in the viewdata				alert('Problem with view data:' + e.message);			}		}			if (jsondata){			switch(jsondata.task){				case 'submit':					this.getQuery();					if (this.showSubmitMessage)alert(this.submitmessage);					if (this.showResultOnVote) this.getResult();					try{						if (this.postSubmitCall) this.postSubmitCall();					}catch(e){}					break;				case 'query':					this.renderQuery(jsondata);					break;				case 'result':					this.renderResult(jsondata);					break;				default:					//invalid task					alert(this.className+'.recieveData()-Invalid task:'+jsondata.task)			}		}	},	//===== Render the JSON data to HTML code	renderResult:function(jsondata){		if (this.debugLevel==2) alert(this.className+'.renderResult()');		var html='';		var graphhtml='';		var graph = null;		var graphlabels = '';		var graphvalues = '';		var graphcolorvalues = '';		var graphtitles = '';		var graphlegendshort = '';		var graphlegendlong = '';		var graphbarcolors = '';		if (jsondata.webquery.unid!=null){			try{				graph = new BAR_GRAPH('hBar');				for (var i=0;i< (jsondata.votes.length);i++){					graphbarcolors += jsondata.webquery.options[i].color;					if (i<(jsondata.votes.length-1)) graphbarcolors +=','					if (jsondata.webquery.options[i].text.length > this.maxlonglegend){						graphlegendlong += jsondata.webquery.options[i].text.slice(0,this.maxlonglegend)+ '...';					}else{						graphlegendlong += jsondata.webquery.options[i].text;					}					if (i<(jsondata.votes.length-1)) graphlegendlong +=',';					graphlegendshort += 'Alt. '+ jsondata.votes[i].voteid;					if (i<(jsondata.votes.length-1)) graphlegendshort +=',';					graphlabels += jsondata.votes[i].voteid;					if (i<(jsondata.votes.length-1)) graphlabels +=',';					graphvalues += jsondata.votes[i].count;					if (i<(jsondata.votes.length-1)) graphvalues +=',';					graphcolorvalues += jsondata.votes[i].count;					if (i<(jsondata.votes.length-1)) graphcolorvalues +=';'				}				graph.type = this.graphSettings.type;                         				graph.graphBGColor = this.graphSettings.graphBGColor;                     				graph.graphBorder = this.graphSettings.graphBorder;                      				graph.graphPadding = this.graphSettings.graphPadding;                      				graph.titleColor = this.graphSettings.titleColor;                  				graph.titleBGColor = this.graphSettings.titleBGColor;              				graph.titleBorder = this.graphSettings.titleBorder;      				graph.titleFont = this.graphSettings.titleFont;        				graph.titleSize = this.graphSettings.titleSize;                        				graph.titleAlign = this.graphSettings.titleAlign;                 				graph.titlePadding = this.graphSettings.titlePadding;                      				graph.labelColor = this.graphSettings.labelColor;                  				graph.labelBGColor = this.graphSettings.labelBGColor;              				graph.labelBorder = this.graphSettings.labelBorder;      				graph.labelFont = this.graphSettings.labelFont;        				graph.labelSize = this.graphSettings.labelSize;                        				graph.labelAlign = this.graphSettings.labelAlign;                 				graph.labelSpace = this.graphSettings.labelSpace;                        				graph.barWidth = this.graphSettings.barWidth;                         				graph.barLength = this.graphSettings.barLength;                       				graph.barBorder = this.graphSettings.barBorder;        				graph.showValues = this.graphSettings.showValues;                        				graph.absValuesColor = this.graphSettings.absValuesColor;              				graph.absValuesBGColor = this.graphSettings.absValuesBGColor;          				graph.absValuesBorder = this.graphSettings.absValuesBorder;  				graph.absValuesFont = this.graphSettings.absValuesFont;    				graph.absValuesSize = this.graphSettings.absValuesSize;                    				graph.absValuesPrefix = this.graphSettings.absValuesPrefix;                  				graph.absValuesSuffix = this.graphSettings.absValuesSuffix;                  				graph.percValuesColor = this.graphSettings.percValuesColor;             				graph.percValuesFont = this.graphSettings.percValuesFont;   				graph.percValuesSize = this.graphSettings.percValuesSize;                   				graph.percValuesDecimals = this.graphSettings.percValuesDecimals;                				graph.charts = this.graphSettings.charts;                            				graph.legendColor = this.graphSettings.legendColor;                 				graph.legendBGColor = this.graphSettings.legendBGColor;             				graph.legendBorder = this.graphSettings.legendBorder;     				graph.legendFont = this.graphSettings.legendFont;       				graph.legendSize = this.graphSettings.legendSize;                       				graph.titles = this.graphSettings.titles;				if (this.useLabelsOrColors=='colors'){					graph.barColors = graphbarcolors;					graph.labels = '';					graph.values = graphcolorvalues;					graph.labelSize = 6;					//graph.labelBGColor = '#f0f0f0';					graph.labelColor = graph.labelBGColor;					graph.labelBorder ='2px groove white';				} else{					graph.values = graphvalues;					graph.labels = graphlabels;				}				if (this.graphShowLegend){					graph.legend = graphlegendshort;					if (this.graphShowLegendStyle=='long'){						graph.legend = graphlegendlong;					}				}				graphhtml=graph.create();				html +='<div align="center" class="wqgraph">'+graphhtml + '</div>';				if (this.showResultQuestion){					html +='<table align="center">';					html +='<tr><td colspan="3"><div class="wqquestion">'+jsondata.webquery.question + '</div></td><tr>';					html +=(this.showResultIntro)?'<tr><td colspan="3"><div class="wqintro">'+jsondata.webquery.intro + '</div></td><tr>':'';					for (var i=0;i<jsondata.webquery.options.length;i++){						html +='<tr><td>&nbsp;</td><td>'+ jsondata.webquery.options[i].oid +'.&nbsp;'+jsondata.webquery.options[i].text+'</td><td>&nbsp;</td></tr>';					}					html +='</table>';				}				html +=(this.showResultComment)?'<div class="wqresultcomment">'+jsondata.webquery.resultcomment + '</div>':'';							}catch(e){				alert(this.className+'renderResult().error:' + e.message)			}		}else{			//query not found!			html += 'Webbfr\u00E5ga med id '+jsondata.webquery.topicid + ' kunde ej hittas!';		}		//update target div		//document.getElementById(this.contentResultDiv).innerHTML ='<div align="center">'+html+'</div>';		document.getElementById(this.contentResultDiv).innerHTML =html;	},		//===== Render the JSON data to HTML code	renderQuery:function(jsondata){			if (this.debugLevel==2) alert(this.className+'.renderQuery()');		var html='';		var i;		var formid = 'wqform'+jsondata.webquery.topicid;		if (jsondata.webquery.unid!=null){			try{				html+='<form method="get" id="'+formid+'" name="'+formid+'" action="javascript:WebQueryList.instances['+this.instanceId+'].validateSubmit(\''+formid+'\',\'voteid\');return false;">';				html += '<table class="wqcontainer"  width="95%" cellspacing="0" cellpadding="1" border="0" align="center">';				html += '<tr><td align="center"><div class="wqquestion">'+jsondata.webquery.question +'</div></td></tr>';				html += (this.showIntroText)?'<tr><td align="center"><div class="wqintro">'+jsondata.webquery.intro +'</div></td></tr>':'';				html += '<tr><td align="center"><table class="wqchoices" cellspacing="0" cellpadding="0" border="0">';				for (i=0;i<jsondata.webquery.numopt;i++){					var voteid = 'voteid'+jsondata.webquery.options[i].oid;					html += '<tr>';					html += '<td valign="top"><input type="radio" id="'+voteid+'" name="voteid" value="'+jsondata.webquery.options[i].oid + '"></td>';					html += '<td class="wqchoice"><label for="'+voteid+'">'+jsondata.webquery.options[i].text + '</label></td>';					html += '</tr>';				}				html += '</table></td></tr>';				if (this.showCommentBox){					html += '<tr><td><div class="wqcomment">';					html += '<textarea id="content" rows="'+this.commentBoxRows+'" cols="'+this.commentBoxCols+'"  name="content" ></textarea>'					html += '</div></td></tr>';				}				html += '<tr><td  align="center"><div class="wqbuttonbar">';				html += '<input type="button" onclick="WebQueryList.instances['+this.instanceId+'].validateSubmit(\''+formid+'\',\'voteid\')" value="'+this.labelbuttonvote+'" class="wqbutton">';				html += (this.showResultButton)?'&nbsp;<input type="button" onclick="WebQueryList.instances['+this.instanceId+'].getResult()" value="'+this.labelbuttonresult+'" class="wqbutton">':'';				html += '</div></td></tr>';				html += '<div style="visibility:hidden;display:none;">';				html += '<input type="hidden" id="category" name="category" value="'+jsondata.webquery.category+'">';				html += '<input type="hidden" id="unid" name="unid" value="'+jsondata.webquery.unid+'">';				html += '<input type="hidden" id="topicid" name="topicid" value="'+jsondata.webquery.topicid+'">';				html += '</div>';				html += '</table></form>';				html += '</div>';			}catch (e){				alert(this.className+'.render:'+e.message)			}		}else{			//query not found!			html += 'Webbfr\u00E5ga med id '+jsondata.webquery.topicid + ' kunde ej hittas!';		}		//update target div		document.getElementById(this.contentQueryDiv).innerHTML =html;	},					//===== Resends the last request to server	refresh:function(){								if (this.debugLevel==2) alert(this.className+'.refresh()');		//abort if we don't have and query id		if (this.id==''){			alert('Saknar id p\u00E5 webbfr\u00E5ga/resultat!\nAvbryter, kan ej utf\u00F6ra \u00E5tg\u00E4rden.')			return false;		}		//check if first time its called		if (this.lastAction==null){			if (this.mode=='query') this.getQuery();			else this.getResult();		} else {			this.sendRequest(this.lastAction);		}			},	//===== submit a vote to server	submitVote:function(strVote,strComment){		if (this.debugLevel==2) alert(this.className+'.submitVote()');	},	//===== request result info from server	getResult:function(){		if (this.debugLevel==2) alert(this.className+'.getResult()');		this.mode='result';		var wqe=new WQEvent({type:WQEvent.EVT_GET_RESULT,fetchObject:this.id});		this.lastAction = wqe;		this.sendRequest(wqe);			},	//===== request query info from server	getQuery:function(){		if (this.debugLevel==2) alert(this.className+'.getQuery()');		this.mode='query';		var wqe=new WQEvent({type:WQEvent.EVT_GET_QUERY,fetchObject:this.id});		this.lastAction = wqe;		this.sendRequest(wqe);			},	//===== converts cr's to html <br>	getNiceOutput:function(str) {		var newstr=''; 		var re = /\r/gi;		newstr = str.replace(re,'<br />');		return newstr;			},	//===== Prints debug information	getVoteValue:function(f){		try{			for (var i=0; i < f.voteid.length; i++){	   			if (f.voteid[i].checked){	      			return f.voteid[i].value;	      		}	   		}		} catch(e){}		return '';				},	//===== Validates and submit a vote	validateSubmit:function(frmName,rbName){		try{			var f = document.forms[frmName];			var voteid = this.getVoteValue(f);			if (voteid==''||voteid=='undefined'){				alert('Du m\u00E5ste v\u00E4lja ett av alternativen!');				return false;			}			var strUnid = f.unid.value;			var strTopicId = f.topicid.value;			var strCat = f.category.value;			var strPostData = '&topicid='+ encodeURIComponent(strTopicId);			strPostData += '&parentunid='+ strUnid;			strPostData += '&cat='+ encodeURIComponent(strCat);			strPostData += '&alias=Anonym';			strPostData += '&voteid='+ voteid;			if (this.showCommentBox){				var strContent = f.content.value;				strPostData += '&content='+ encodeURIComponent(strContent);			}			this.submitVote(strPostData);			return true;		} catch(e){			alert('Ett fel uppstod vid validering. Felmeddelande:' + e.message);				return false;		}	},	submitVote:function(strData){		if (this.debugLevel==2) alert(this.className+'.submitVote()');		var wqe=new WQEvent({type:WQEvent.EVT_SUBMIT_VOTE,fetchObject:this.id,dataString:strData});		this.lastAction = wqe;		this.sendRequest(wqe);			},	//===== Prints debug information	printDebug:function() {		try{			var divDebug = document.getElementById(this.debugDiv);			var html = '<div id="debugrequest">LAST REQUEST:<br />' + this.lastRequestString + '</div><br />';			html +='<div id="debugresponse">LAST RESPONSE:<br />' + this.getNiceOutput(this.lastResponseString) + '</div>';			divDebug.innerHTML = html;		} catch(e){alert('printDebug:'+e.message);}	}	} //end of WebQuery class//==== used to signal query eventsfunction WQEvent(settings){	this.type = (settings.type) ? settings.type :0; // type of event one of WebEvent constants	this.dataString = (settings.dataString) ? settings.dataString :null; // the post string	this.fetchObject = (settings.fetchObject) ? settings.fetchObject :null; //Data range to request (WebFetchObject)}//Class ConstantsWQEvent.EVT_GET_QUERY = 1;WQEvent.EVT_GET_RESULT = 2;WQEvent.EVT_SUBMIT_VOTE = 3;//==== used to set graph characteristicsfunction GraphProperties(){  this.type = 'hBar';                        // graph type: "hBar", "vBar", "pBar", or "fader"  this.graphBGColor = '';                    // graph background color: string  this.graphBorder = '';                     // graph border: string (CSS specification; doesn't work with NN4)  this.graphPadding = 0;                     // graph padding: integer (pixels)  this.titleColor = 'black';                 // title font color: string  this.titleBGColor = '#C0E0FF';             // title background color: string  this.titleBorder = '2px groove white';     // title border: string (CSS specification)  this.titleFont = 'Arial, Helvetica';       // title font family: string (CSS specification)  this.titleSize = 12;                       // title font size: integer (pixels)  this.titleAlign = 'center';                // title text align: "left", "center", or "right"  this.titlePadding = 2;                     // title padding: integer (pixels)  this.labelColor = 'black';                 // label font color: string  this.labelBGColor ='#C0E0FF';              // label background color: string  this.labelBorder = '2px groove white';     // label border: string (CSS specification)  this.labelFont = 'Arial, Helvetica';       // label font family: string (CSS specification)  this.labelSize = 12;                       // label font size: integer (pixels)  this.labelAlign = 'center';                // label text align: "left", "center", or "right"  this.labelSpace = 0;                       // additional space between labels: integer (pixels)  this.barWidth = 20;                        // bar width: integer (pixels)  this.barLength = 3.0;                      // bar length ratio: float (from 0.1 to 2.9)  this.barBorder = '2px outset white';       // bar border: string (CSS specification)  this.showValues = 0;                       // show values: 0 = % only, 1 = abs. and %, 2 = abs. only, 3 = none  this.absValuesColor = 'black';             // abs. values font color: string  this.absValuesBGColor = '#C0E0FF';         // abs. values background color: string  this.absValuesBorder = '2px groove white'; // abs. values border: string (CSS specification; doesn't work with NN4)  this.absValuesFont = 'Arial, Helvetica';   // abs. values font family: string (CSS specification)  this.absValuesSize = 12;                   // abs. values font size: integer (pixels)  this.absValuesPrefix = '';                 // abs. values prefix: string (e.g. "$")  this.absValuesSuffix = '';                 // abs. values suffix: string (e.g. " kg")  this.percValuesColor = 'black';            // perc. values font color: string  this.percValuesFont = 'Arial, Helvetica';  // perc. values font family: string (CSS specification)  this.percValuesSize = 12;                  // perc. values font size: integer (pixels)  this.percValuesDecimals = 0;               // perc. values number of decimals: integer  this.charts = 1;                           // number of charts: integer  this.legendColor = 'black';                // legend font color: string  this.legendBGColor = '#F0F0F0';            // legend background color: string  this.legendBorder = '2px groove white';    // legend border: string (CSS specification)  this.legendFont = 'Arial, Helvetica';      // legend font family: string (CSS specification)  this.legendSize = 11;                      // legend font size: integer (pixels)  this.titles = '';                      	 // titles comma separated, e.i. "Month,Count,Sales"}//utility functionsfunction loadScript(sScriptSrc, oCallback) {	//var oHead = document.getElementById('head')[0];	var oHead = document.getElementById('head');	var oScript = document.createElement('script');	oScript.type = 'text/javascript';	oScript.src = sScriptSrc;	// most browsers	oScript.onload = oCallback;	// IE 6 & 7	oScript.onreadystatechange = function(){		if (this.readyState == 'complete') {			oCallback();		}	}	oHead.appendChild(oScript);}function onFunctionAvailable(sMethod, oCallback, oObject, bScope) {	if (typeof(eval(sMethod)) === 'function') {		bScope ? oCallback.call(oObject) : oCallback(oObject);	} else {		setTimeout(function (){onFunctionAvailable(sMethod, oCallback, oObject, bScope);}, 50);	}}