/* Steven Stanek & Woodley Packard
* datasource.js [new edition]
* Used for the redesigned datasource interface.
*/
/************** Global Variables *************/
/* DOCUMENTATION: mydata's fields
* tablesets: (name, id, cat)
* workspaces: (name, id)
* surveys: (name, id)
* accessible: (name, id)
* admined: (name, gid)
* grantedACLs: (userName, uid, isGroup, tsName, tsid)
*/
var myData=null;
// info about the system-wide list of data library categories
var catsList=null;
var catNames=null;
// pointers to the DIs that are currently selected in col1 and col2
var col1SelDI = null;
var col2SelDI = null;
// the list of DIs currently being displayed in col2, if any
var col2DIs=null;
/*************************DataItemClass******************************/
/* This interface is defined by the DataItemClass. It's purpose is contain all
* state and functionality associated with a DataItem (something that's clicked
* on in the left hand side bar.
*/
var idCount=0;
function DataItemClass(name, col, requiresLogin) {
if(requiresLogin == null)
requiresLogin = false;
if(name == "")
name = "Untitled Dataset";
this.name = name;
this.col=col; //Is it col1 or col2?
var nameEscaped = name.replace(" ", "_");
this.id = "DIC_col" +this.col + "_"+nameEscaped+"_"+(idCount++);
this.requiresLogin = requiresLogin;
}
DataItemClass.prototype.onclick= function() {
deselectAllDatasources(this.col);
if(this.col == 1) {
col1SelDI = this;
col2SelDI = null;
} else
col2SelDI = this;
document.getElementById(this.id).className = "dataSourceSelected";
this.renderNextCol();
saveNavigation();
}
DataItemClass.prototype.deselect = function() {
document.getElementById(this.id).className = "dataSource";
}
DataItemClass.prototype.createUIDiv = function() {
var daDiv = document.createElement("div");
daDiv.className = 'dataSource';
//Done to make "this" correct in the closure
var alsoThis = this;
daDiv.onclick= function(){alsoThis.onclick();};
var id = this.id;
id.replace(" ", "_");
daDiv.id = id;
daDiv.appendChild(document.createTextNode(addBreaksToString(this.name,24)));
if(this.requiresLogin && loggedinas == null)
daDiv.style.display='none';
return daDiv;
}
//This function is called to render the next right column
DataItemClass.prototype.renderNextCol = function() {
return null;
}
//////THE BELOW ARE RENDERING FUNCS THAT MAY BE CALLED IN RENDERNEXTCOL
//////THEY ARE NOT CALLED BY DEFAULT
//Creates a one line div that tells the name of this col
DataItemClass.prototype.createColHeader = function() {
var returnme = document.createElement("div");
var innerHTML = "
";
innerHTML += "Quick Help ";
innerHTML += helpStr;
helpDiv.innerHTML = innerHTML;
return helpDiv;
}
/************************CenterColDataItem Class*******************************/
/* This class is used as a superclass for columns that render in column 2 (center).
* It's principle feature if a uniform renderNextCol function. All implementers
* must provide :
* -HelpText: A string for the help to be rendered
-If help text = null, no help is rendered
* -createColItems: A function that takes the center col and adds whatever it likes
* to it. These should be the items that the user clicks on in this column
-Note: You do not need to clear col2DIs, but should add to it
*/
function CenterColDataItem(name, requiresLogin) {
this.helpText=null;
this.inheritFrom = DataItemClass;
this.inheritFrom(name, 1, requiresLogin);
}
extend(CenterColDataItem, DataItemClass);
CenterColDataItem.prototype.createColItems= function(centerCol){}
CenterColDataItem.prototype.renderNextCol = function() {
var centerCol = document.getElementById("centerCol");
centerCol.innerHTML = "";
centerCol.appendChild(this.createColHeader());
if(this.helpText != null)
centerCol.appendChild(this.createHelpDiv(this.helpText));
centerCol.appendChild(document.createElement("hr"));
col2DIs = new Array();
this.createColItems(centerCol);
}
/************************RightColDataItem Class*******************************/
/* This class is used as a superclass for columns that render in column 3 (right).
* It's principle feature if a uniform renderNextCol function. All implementers
* must provide :
* -helpText: A string for the help to be rendered
-If help text = null, no help is rendered
* -createColItems: A function that takes the right col and adds whatever it likes.
*/
function RightColDataItem(name, requiresLogin) {
this.helpText=null;
this.inheritFrom = DataItemClass;
this.inheritFrom(name, 2, requiresLogin);
}
extend(RightColDataItem, DataItemClass);
RightColDataItem.prototype.createColItems= function(rightCol){}
RightColDataItem.prototype.renderNextCol = function() {
var rightCol = document.getElementById("rightCol");
rightCol.innerHTML = "";
rightCol.appendChild(this.createColHeader());
if(this.helpText != null)
rightCol.appendChild(this.createHelpDiv(this.helpText));
rightCol.appendChild(document.createElement("hr"));
this.createColItems(rightCol);
}
RightColDataItem.prototype.createSection = function(name, html) {
var div = document.createElement("div");
div.innerHTML = "" + name + " " + html;
div.className = "insetDataBrowse";
document.getElementById("rightCol").appendChild(div);
}
/************************CatDataItem Class*******************************/
/* A subclass of DataItemClass for use with the cat clicks. Used to handle clicks on
* columns in
*/
//All Cats do not require a login
function CatDataItem(name, catid) {
this.inheritFrom = CenterColDataItem;
this.inheritFrom(name, false);
this.catid = catid;
this.helpText = "The " + name + " category contains publicly shared data sets. Click on data sets to view or analyze them.";
}
extend(CatDataItem, CenterColDataItem);
CatDataItem.prototype.createColItems = function(centerCol) {
eval("var clist = " + ajaxGet("/clist?" + this.catid));
for(var i=0; i < clist.length; i++) {
var w = clist[i];
var TSData = new TSSetData(w.name, w.id);
col2DIs.push(TSData);
centerCol.appendChild(TSData.createUIDiv());
}
}
/************************MyData Classes*******************************/
//DataItems for data associated with an account
/*Allowed to do
* -Tables: (View, Add)
* -Sharing: (Share with other users, createGroups); should list who it's shared with
* -Options: Delete, Rename, Input Settings
*/
function MyPrivDataItem() {
this.inheritFrom = CenterColDataItem;
this.inheritFrom("My Private Data", 1, true);
this.helpText = "These are tables that you own. Click on them to view, analyze, share or add to them.";
}
extend(MyPrivDataItem, CenterColDataItem);
MyPrivDataItem.prototype.createColItems = function(centerCol) {
for(var i=0; i < myData.workspaces.length; i++) {
var ws = myData.workspaces[i];
var presDI = new PrivWSData(ws.name, ws.id);
col2DIs.push(presDI);
centerCol.appendChild(presDI.createUIDiv());
}
}
/* Allowed to do
* -Tables: (View)
* -Sharing: Say it's already shared with everyone
* -Options: Delete (unshare)
*/
function MyPubDataItem() {
this.inheritFrom = CenterColDataItem;
this.inheritFrom("My Public Data", true);
this.helpText = "These are data sets that you are sharing with the rest of the Covariable community. Click on them to analyze them, view them or stop sharing them.";
}
extend(MyPubDataItem, CenterColDataItem);
MyPubDataItem.prototype.createColItems = function(centerCol) {
for(var i=0; i < myData.tablesets.length; i++) {
var ts = myData.tablesets[i];
var presDI = new PubTSData(ts.name, ts.id, ts.cat);
col2DIs.push(presDI);
centerCol.appendChild(presDI.createUIDiv());
}
}
/* Allowed to do
* -Tables: (View, Add)
* -Sharing: Always say how it is shared (group or individually) and who the owner is
* -Options: None
*/
function MySharedDataItem() {
this.inheritFrom = CenterColDataItem;
this.inheritFrom("Data Shared With Me", true);
this.helpText = "These are data sets that other Covariable members are sharing with you. Click on them to view or analyze them.";
}
extend(MySharedDataItem, CenterColDataItem);
MySharedDataItem.prototype.createColItems = function(centerCol) {
for(var i=0; i < myData.accessible.length; i++) {
var ts = myData.accessible[i];
var presDI = new sharedTSData(ts.name, ts.id, "ts");
col2DIs.push(presDI);
centerCol.appendChild(presDI.createUIDiv());
}
}
/************************SurveyDataItem Subclass******************************/
function MySurveysDataItem() {
this.inheritFrom = CenterColDataItem;
this.inheritFrom("My Surveys", 1, true);
this.helpText = "Surveys are lists of questions that you can send to anyone you choose. Visible Datasets will record their responses in a dataset for you. You can create a new survey by clicking \"Add New Data\" to the left. Below is a list of your surveys.";
}
extend(MySurveysDataItem, CenterColDataItem);
MySurveysDataItem.prototype.createColItems = function(centerCol) {
for(var i=0; i < myData.surveys.length; i++) {
var s = myData.surveys[i];
var di = new surveyData(s.name, s.id);
centerCol.appendChild(di.createUIDiv());
col2DIs.push(di);
}
}
/************************GroupDataItem Class*******************************/
function groupDataItem() {
this.inheritFrom = CenterColDataItem;
this.inheritFrom("My Groups", 1, true);
this.helpText = "Groups consist of data sets that are shared among all of their user members. Special group members called Administrators can add new users to a group. Below is a list of groups that you administer.
Also see our video tutorial: Intro to Groups (1.7 MB Quicktime)";
}
extend(groupDataItem, CenterColDataItem);
groupDataItem.prototype.createColItems = function() {
var centerCol = document.getElementById("centerCol");
centerCol.insertBefore(this.createNewGroupDiv(), centerCol.lastChild);
for(var i=0; i < myData.admined.length; i++) {
var presGroup = myData.admined[i];
var presDI = new groupData(presGroup.name, presGroup.gid);
centerCol.appendChild(presDI.createUIDiv());
col2DIs.push(presDI);
}
}
groupDataItem.prototype.createNewGroupDiv = function() {
var returnme = document.createElement("div");
returnme.className = "insetDataBrowse";
var innerHTML = "Create A New Group ";
innerHTML += "Create a new group to share data with other users. You will automatically be an administrator of this group. ";
innerHTML += "Group Name: ";
innerHTML += "";
returnme.innerHTML = innerHTML;
return returnme;
}
/************************APIUsers Class******************************/
function apiUsersDataItem() {
this.inheritFrom = CenterColDataItem;
this.inheritFrom("My API Users", true);
this.helpText = "You can create a new API user, or you can examine an existing API user. API users have access to datasets that you have specified as API-accessible."
}
extend(apiUsersDataItem, CenterColDataItem);
apiUsersDataItem.prototype.getList = function() {
var res = ajaxPost("/data/listapiusers", "text/plain", "");
eval("this.list = " + res);
}
apiUsersDataItem.prototype.createColItems = function() {
var centerCol = document.getElementById("centerCol");
centerCol.insertBefore(this.createNewUserDiv(), centerCol.lastChild);
this.getList();
for(var i=0; i < this.list.length; i++) {
var au = this.list[i];
var di = new apiUser(au);
centerCol.appendChild(di.createUIDiv());
col2DIs.push(di);
}
}
apiUsersDataItem.prototype.createNewUserDiv = function() {
var returnme = document.createElement("div");
returnme.className = "insetDataBrowse";
var innerHTML = "Create A New API User ";
innerHTML += "Create a new API user account which will have access to your API-enabled datasets. ";
innerHTML += "Account: " + uid + " ";
innerHTML += "
";
returnme.innerHTML = innerHTML;
return returnme;
}
function handleNewAPIUser()
{
var user = document.getElementById("newAPIUserName").value;
var pass = document.getElementById("newAPIUserPass").value;
var admin = "no";
var res = ajaxPost("/data/newapiuser", "text/plain", "user=" + urlencode(user) + "&pass=" + urlencode(pass) + "&admin=" + admin);
if(res != "success")alert("Sorry, the new user could not be created.\n" + res);
else col1SelDI.renderNextCol();
}
/************************AddData Class*******************************/
//For rendering/handling clicks in on AddData in COL1
function addDataItem() {
this.inheritFrom = CenterColDataItem;
this.inheritFrom("Add New Data", false);
this.helpText = "Choose a method of adding data to Covariable for your analysis, viewing, sharing and manipulation. If you are logged in, this data will be added to your account."
this.addMethods = ["Add From CSV File", "Add From TDV File", "Add From Excel File"];
this.addActions = ["/csvfilenew", "/tdvfilenew", "/xlfilenew"];
}
extend(addDataItem, CenterColDataItem);
addDataItem.prototype.createAddItems = function() {
if(this.addItems !=null)
return this.addItems;
this.addItems = new Array();
this.addItems.push(new addWebItem());
for(var i=0; i < this.addMethods.length; i++)
this.addItems.push(new addFileItem(this.addMethods[i], this.addActions[i]));
this.addItems.push(new addManualItem());
this.addItems.push(new addSurveyItem());
return this.addItems;
}
addDataItem.prototype.createColItems = function(centerCol) {
var addItems = this.createAddItems();
for(var i=0; i < addItems.length; i++) {
centerCol.appendChild(addItems[i].createUIDiv());
col2DIs.push(addItems[i]);
}
}
/************************SearchDataItem Class*******************************/
//For rendering results of search
function searchDataItem(query, results) {
this.inheritFrom = CenterColDataItem;
this.inheritFrom("Search Results", false);
this.query = query;
this.results=results;
this.helpText = "These are the results that matched your search \""+query+"\". Click on a data set to view or analyze it";
}
extend(searchDataItem, CenterColDataItem);
searchDataItem.prototype.createColItems = function(centerCol) {
if(this.results.length == 0) {
var noResDiv = document.createElement("div");
noResDiv.className = "noResDiv";
noResDiv.innerHTML = "No Results Found";
centerCol.appendChild(noResDiv);
return;
}
for(var i=0; i < this.results.length; i++) {
var r = this.results[i];
var pres=null;
if(r.type=='published')
pres = new TSSetData(r.name, r.id);
else if(r.type == 'mypublic')
pres = new PubTSData(r.name, r.id, r.category);
else if(r.type == 'shared')
pres = new sharedTSData(r.name, r.id);
else if(r.type == 'private')
pres = new PrivWSData(r.name, r.id);
col2DIs.push(pres);
centerCol.appendChild(pres.createUIDiv());
}
}
/************************AddWeb Class*******************************/
function addWebItem() {
this.inheritFrom = DataItemClass;
this.inheritFrom("Add Data From A Web Site", 2, false);
}
extend(addWebItem, DataItemClass);
addWebItem.prototype.renderNextCol = function() {
var innerHTML ="
";
innerHTML += this.name+"
";
innerHTML += "";
innerHTML += "
"
innerHTML += "Quick Help "
innerHTML += "Create a new dataset by importing tables from a web page. Enter a name and url, then click [Import] to import your web page and open in Visible Statistics, our data analysis tool. If you are logged in, this data set will be stored in your account and available through the [My Private Data] tab on this screen."
innerHTML += "
";
document.getElementById("rightCol").innerHTML = innerHTML;
}
/************************AddManual Class*******************************/
function addManualItem() {
this.inheritFrom = DataItemClass;
this.inheritFrom("Add Data Directly", 2, false);
}
extend(addManualItem, DataItemClass);
addManualItem.prototype.renderNextCol = function() {
var innerHTML ="
";
innerHTML += this.name+"
";
innerHTML += "";
innerHTML += "
"
innerHTML += "Quick Help "
innerHTML += "Create a new dataset by entering data yourself. Enter a name then click [Enter Data] to get started entering your data. If you are logged in, this data set will be stored in your account and available through the [My Private Data] tab on this screen."
innerHTML += "
";
document.getElementById("rightCol").innerHTML = innerHTML;
}
/************************AddFile Class*******************************/
//Used for col 2 in Add File
function addFileItem(name, formAction) {
this.inheritFrom = DataItemClass;
this.formAction = formAction;
this.inheritFrom(name, 2, false);
}
extend(addFileItem, DataItemClass);
addFileItem.prototype.renderNextCol = function(){
var innerHTML ="
";
innerHTML += this.name+"
";
innerHTML += "";
innerHTML += "
"
innerHTML += "Quick Help "
innerHTML += "Create a new dataset by importing a file by choosing it below. Enter a name and click the [Browse] button to select your file. Click [Import] to import your file and open it, our data analysis tool. If you are logged in, this data set will be stored in your account and available through the [My Private Data] tab on this screen."
innerHTML += "
";
document.getElementById("rightCol").innerHTML = innerHTML;
}
/************* AddSurveyItem *************/
function addSurveyItem() {
this.inheritFrom = RightColDataItem;
this.inheritFrom("Create a Survey", true);
this.helpText = "Give your survey a name below, and push 'Create'. You will be taken to the survey editor, where you can start building your survey's questions. To come back to your survey later, select it from the 'My Surveys' option on the left of this screen.";
}
extend(addSurveyItem, RightColDataItem);
addSurveyItem.prototype.createColItems = function(dom) {
var html = "";
this.createSection("Survey Setup", html);
}
/************************TableSetData Class*******************************/
/* This class is used for the UI in the third column and displaying the
* div in the second.
* This class takes a type string which can have any of the following as valid
* kinds of tablesets to examine:
* 1. TS: Tableset--can view, but not touch [Used for public data]
* 2. WS: Workspace--can view and touch [Used for workspaces]
* 3. AC: Accessible--can view and touch, but not yours and not admined by you
* 4. AD: Admined--can view and touch, can grant access to others
* Special features & functions:
* -The tableOperations Array contains the operations to display in the tables menu. This can be
* overridden by a sub class to change the set of operations
* -For each tab, two items are rendered:
* -A exeBtn that can be turned on and off depending on operation
* -An tabOptionDiv that can have options rendered in it
* -The handleTabOpSel function runs when an operation is selected from the menu. Generally
* this is used to populate the optionsDiv or turn the exeBtn on and off.
* -The handleTopOperation function runs when the execute button for an operation is clicked
*/
function TableSetData(name, tsid, type) {
this.inheritFrom = DataItemClass;
this.tsid=tsid;
this.type = type;
if(this.tableOperations == null){
if(type =='ws')
this.tableOperations = ["View", "Add", "Download", "Rename", "Delete"];
else
this.tableOperations = ["View", "Download", "Make Flashcards"];
}
this.inheritFrom(name, 2, false);
}
extend(TableSetData, DataItemClass);
TableSetData.prototype.renderNextCol = function() {
var res = ajaxGet("/tlist?ts=" + this.tsid);
eval("var tables=" + res); //Returns a struct with [name, row, col, tid] for each table
this.tables = tables;
var innerHTML ="
";
return innerHTML;
}
//Override this to add additional content to the bot of tables
TableSetData.prototype.renderMoreTablesData = function() {return "";}
TableSetData.prototype.handleTabOpSel=function(id, tabNum) {
var operation = document.getElementById(id).value;
var optionsDiv = document.getElementById("tab" + tabNum + "OptionsDiv");
var exeBtn = document.getElementById("exeBtn" + tabNum);
if(operation == "[Operations]") {
optionsDiv.style.display='none';
exeBtn.style.display = 'none';
} else if(operation == "Rename") {
var innerHTML = "Rename to: ";
innerHTML+="";
optionsDiv.innerHTML = innerHTML;
optionsDiv.style.display='block';
exeBtn.style.display = 'none';
} else {
optionsDiv.style.display='none';
exeBtn.style.display = 'inline';
}
}
TableSetData.prototype.handleTabOperation=function(id, tabNum) {
var operation = document.getElementById(id).value;
var optionsDiv = document.getElementById("tab" + tabNum + "OptionsDiv");
var exeBtn = document.getElementById("exeBtn" + tabNum);
optionsDiv.style.display='none';
exeBtn.style.display = 'inline';
switch(operation) {
case "View":
window.location = '/dbComb?ts=' + this.tsid + "&id=" + tabNum;
break;
case "Add":
window.location = '/dbComb?ts=' + this.tsid + "&id=" + tabNum +"&mode=add";
break;
case "Download":
window.location = '/export?ts=' + this.tsid + "&id=" + tabNum + "&format=csv";
break;
case "Delete":
var c = confirm("Are you sure that you want to delete this table?");
if(c != true)
return;
var request = "ts=" + this.tsid + "&id=" + id;
var res = ajaxPost("/wstabdelete", "text/plain", request);
if(res != "success")
alert(res);
updateAllColsAndData(3);
break;
case "Make Flashcards":
window.location = '/newflash.html?ts=' + this.tsid + "&id=" + tabNum + "&name=" + urlencode(this.name);
break;
}
}
/************************TableSetData Subclass*******************************/
function TSSetData(name, tsid) {
this.inheritFrom = TableSetData;
this.inheritFrom(name, tsid, "ts");
}
extend(TSSetData, TableSetData);
TSSetData.prototype.renderSharingHTML = function() {
var innerHTML = "
";
innerHTML += "Sharing ";
innerHTML += "This is a publicly viewable Data Set. You may view or analyze it or you may make your own copy and modify it. The original public copy will remain unchanged.";
innerHTML += "
";
innerHTML += "Sharing ";
innerHTML += "You own this data set. You may share it with other users or groups. To share it, simply enter the user or group name in the field below and click [Share]."
innerHTML += "
";
innerHTML += "User or Group Name: "
innerHTML += " ";
innerHTML += "";
innerHTML += "
";
innerHTML += "";
innerHTML += "[Show Sharing Info] ";
innerHTML += "";
innerHTML += "";
innerHTML += "";
innerHTML += "";
innerHTML += "You may publish this data set to share it with the entire Covariable community. To publish it, provide a published name and category for it below and click [Publish].";
innerHTML += "
";
} else {
innerHTML += "You are not sharing this data set with any users. ";
}
if(groupData.groups.length !=0){
innerHTML += "You share this with the following groups:";
innerHTML += "
";
for(var i=0; i < groupData.groups.length; i++) {
var g = groupData.groups[i];
innerHTML += "
";
return innerHTML;
}
PrivWSData.prototype.handleImportMethodSel = function() {
var selIdx = document.getElementById("tsDataAddSel").selectedIndex;
// var importOptionsIframe = document.getElementById("importOptionsIframe");
// importOptionsIframe.style.display = "block";
// var daBody = importOptionsIframe.contentDocument.body;
var importOptionsSpan = document.getElementById("importOptionsSpan");
var baseURL = window.location.protocol+"//"+ window.location.hostname+":"+window.location.port;
switch(selIdx){
case 0:
importOptionsSpan.innerHTML = this.webImportPostHTML(baseURL+"/dswebimport");
break;
case 1:
importOptionsSpan.innerHTML = this.fileImportPostHTML(baseURL +"/dscsvimport");
break;
case 2:
importOptionsSpan.innerHTML = this.fileImportPostHTML(baseURL +"/dstdvimport");
break;
case 3:
importOptionsSpan.innerHTML = this.fileImportPostHTML(baseURL + "/dsxlimport");
break;
case 4:
importOptionsSpan.innerHTML = this.directAddPostHTML(baseURL + "/dsnewblanktab");
break;
}
}
PrivWSData.prototype.webImportPostHTML = function(postMethod) {
var innerHTML = "";
innerHTML += "";
return innerHTML;
}
PrivWSData.prototype.fileImportPostHTML = function(postMethod) {
var innerHTML = "";
innerHTML += "";
// alert(innerHTML);
return innerHTML;
}
PrivWSData.prototype.directAddPostHTML = function(postMethod) {
var innerHTML = "";
innerHTML += "";
return innerHTML;
}
/************************PubTS Subclass*******************************/
function PubTSData(name, tsid, cat) {
this.cat = cat;
this.inheritFrom = TableSetData;
this.inheritFrom(name, tsid, "ts");
}
extend(PubTSData, TableSetData);
PubTSData.prototype.renderSharingHTML = function() {
var innerHTML = "
";
innerHTML += "Sharing ";
innerHTML += "You own this data set and have made it publicly available so that everyone can see and use it. It is presently available in our data library. You can change the category it is shared as below or you can stop sharing this dataset by clicking on the [Stop Sharing] button below.";
innerHTML += "
";
innerHTML += "Sharing ";
innerHTML += "This dataset is being shared with you by another user. You may view it or make your own copies and manipulate them, but you cannot modify the original. ";
innerHTML += "";
innerHTML += "[More Info]";
innerHTML += "";
innerHTML += "";
innerHTML += "
";
return innerHTML;
}
sharedTSData.prototype.renderSharingInfo = function() {
var res = ajaxGet("/accessTypeQuery?ts="+this.tsid);
eval("var accessData = " + res);
var innerHTML = "";
innerHTML += "More Sharing Info: ";
innerHTML += "This data set is owned by: "+HTMLSafeText(accessData.owner.name) + ". ";
innerHTML += "You have access to this data set for the following reasons:";
innerHTML += "
";
html += "This survey is accessible to anyone who knows its URL or finds a link to it. ";
html += "A total of " + this.nresponses + " response" + ((this.nresponses==1)?" has":"s have") + " been received.";
html += "
The public URL of this survey is:
http://www.covariable.com/survey?" + this.sid + "
";
if(!advanced) html += "
With an Advanced Account, you could make secure invitation-only surveys.";
}
this.createSection("Respondents", html);
if(!this.byInviteOnly)
{
var html = "";
html += "
Cookie-based protection is " + (this.check_cookie?"on":"off") + " [toggle]
";
html += "
IP address-based protection is " + (this.check_ip?"on":"off") + " [toggle]
";
this.createSection("Multiple-vote Protection", html);
}
}
function handleChangeSurveyTheme(sid) {
var themes_str = ajaxGet("/survey_themes");
eval("var themes = " + themes_str);
var html = "Apply which theme?
";
document.getElementById("surveyTheme").innerHTML = html;
}
function handleSetSurveyTheme(sid, url) {
ajaxPost("/surveySetTheme?" + sid, "text/plain", url);
junk++;
col2SelDI.gotData = 0;
col2SelDI.renderNextCol();
}
function handleSetSurveyAccess(sid, access) {
ajaxPost("/surveySetAccess?" + sid, "text/plain", access?"public":"private");
junk++;
col2SelDI.gotData = 0;
col2SelDI.renderNextCol();
}
function handleInviteSurveyParticipants(sid) {
var url = ajaxPost("/surveyInvite?" + sid, "text/plain", "");
junk++;
col2SelDI.ninvitations++;
col2SelDI.renderNextCol();
var html = "This URL is good for one survey response; once it has been used, no more responses will be accepted from it. To generate another URL, click the link above again. Here is the URL:
";
innerHTML += "Quick Info ";
innerHTML += "This is a group that you administer. You can add new users, promote existing users to administrators or delete users.";
innerHTML += "
";
innerHTML += "
";
innerHTML += "Users ";
innerHTML += "There are " + groupData.users.length + " users in this group. They are: ";
innerHTML += "
";
for(var i=0; i < groupData.users.length; i++) {
var user = groupData.users[i];
innerHTML += "
";
document.getElementById("rightCol").innerHTML = innerHTML;
}
/************************APIUser Class****************************************/
function apiUser(au) {
this.inheritFrom = RightColDataItem;
this.inheritFrom(au.name, true);
this.helpText = "I'll tell you the user's name and ID, and whether they're an admin.";
this.au = au;
}
extend(apiUser, RightColDataItem);
apiUser.prototype.createColItems = function(div) {
this.createSection("User Name", this.au.name);
this.createSection("ID", this.au.id);
var html = this.au.admin?"yes":"no";
html += " [toggle]";
this.createSection("Admin?", html);
}
function handleSetAPIAdmin(api_uid, admin) {
var res = ajaxPost("/data/setapiadmin", "text/plain", "id=" + api_uid + "&admin=" + (admin?"yes":"no"));
if(res != "success")alert("Unable to toggle the user's admin status!\n" + res);
else col2SelDI.au.admin = admin;
col2SelDI.renderNextCol();
}
/************************DataContainer Function*******************************/
//Gets "MyData" and saves it in a global structure of that name.
//Also gets the cats and saves them in catsList and catNames
//Note: there are global fields for loggedinas (null if N/A)
function getMyData() {
var res = ajaxGet("/allCats");
eval("var daList = " + res);
catsList = daList;
catNames = new Array;
for(var i=0; i < catsList.length; i++)
catNames.push(catsList[i].name);
if(loggedinas == null)
return;
var res = ajaxGet("/list");
if(res.substring(0, "error".length) =="error")
return;
eval("var data = " + res);
myData = data;
}
/************************Handlers*******************************/
function handleTabOpSel(id, tabNum) {
col2SelDI.handleTabOpSel(id, tabNum);
}
function handleTabOptionExe(id, tabNum) {
col2SelDI.handleTabOperation(id, tabNum);
}
function handleTabImportExp() {
document.getElementById("tabAddData").style.display = "block";
document.getElementById("tabImportBtnSpan").style.display="none";
}
function handleTabAddMoreDataSel(id) {
col2SelDI.handleImportMethodSel();
}
function handleShowSharing() {
col2SelDI.renderSharingInfo();
document.getElementById("sharingInfo").style.display = 'block';
document.getElementById("shareShowSpan").style.display='none';
}
function handleShareClick(tsid) {
var shareName = document.getElementById("shareName").value;
var request = "username=" + urlencode(shareName) + "&tsid=" + tsid;
var res = ajaxPost("/aclAddUserByName", "text/plain", request);
junk++;
if(res != "success")
alert(res);
else
handleShowSharing();
}
function handleRevokeACL(tsid, uid) {
c = confirm("Are you sure you want to revoke access for this user?");
if(c != true)
return;
var request = "tsid= " + tsid+ "&uid=" + uid;
var res = ajaxPost("/aclDeleteUser", "text/plain", request);
junk++;
if(res != "success")
alert(res);
else
handleShowSharing();
}
function handleStopSharing(tsid) {
var c =confirm("Are you sure you want to stop sharing this data set?");
if(c != true)
return;
var request = "ts=" + tsid;
var res = ajaxPost("/tsToWS", "text/plain", request);
if(res != "success")
alert(res);
updateAllColsAndData(2);
}
function handleTabRename(tsid, tabNum) {
var newName = document.getElementById("tab" + tabNum+ "RenameField").value;
var request = "ts=" + tsid+"&id=" + tabNum + "&title=" + urlencode(newName);
var res = ajaxPost("/wsrenametab", "text/plain", request);
if(res != "success")
alert(res);
updateAllColsAndData(3);
}
function handleDeleteDataSet(tsid) {
var c =confirm("Are you sure you want delete this dataset?");
if(c != true)
return;
var request = "ts=" + tsid;
var res = ajaxPost("/tsdel", "text/plain", request);
if(res != "success")
alert(res);
updateAllColsAndData(2);
}
function handleRenameDataSet(tsid) {
var newNameInput = document.getElementById("newNameInput");
var newName = newNameInput.value;
var request = 'ts=' + tsid + "&name=" + urlencode(newName);
var res = ajaxPost("/tsrename", "text/plain", request);
if(res != "success")
alert(res);
updateAllColsAndData(2);
for(var i=0; i < col2DIs.length; i++) {
if(col2DIs[i].name == newName) {
col2DIs[i].onclick();
return;
}
}
}
function handlePublishDS(tsid) {
var pubNameInput = document.getElementById("pubNameInput");
var pubName = pubNameInput.value;
var pubCatSel = document.getElementById("pubCatSel");
var c = confirm("Are you sure you want to publish this data set?");
if(c != true)
return;
var request = "ts=" + tsid + "&name="+urlencode(pubName) + "&cat=" +(pubCatSel.selectedIndex+1);
var res = ajaxPost("/publish", "text/plain", request);
if(res != "success")
alert(res);
updateAllColsAndData(2);
}
function handlePubCatChange(selName, tsid) {
var catSel = document.getElementById(selName);
var request = "ts=" + tsid + "&cat=" + catSel.selectedIndex;
var res = ajaxPost("/setcat", "text/plain", request);
if(res != "success")
alert(res);
}
function handleShowGroupData(tsid) {
//Select the right field in the first col
for(var i=0; i < allDataItemsTop.length; i++) {
if(allDataItemsTop[i].name == "Data Shared With Me") {
allDataItemsTop[i].onclick();
break;
}
}
//Select the right field in the second col
for(var i=0; i < col2DIs.length; i++) {
if(col2DIs[i].tsid == tsid) {
col2DIs[i].onclick();
break;
}
}
}
function handleShowShareType() {
col2SelDI.renderSharingInfo();
document.getElementById('shareShowSpan').style.display="none";
}
function handleSearch(){
doSearch(document.getElementById("inputSearch").value);
}
function doSearch(str) {
document.getElementById("inputSearch").value = str;
var request = "/search?query=" + urlencode(str);
var res = ajaxGet(request);
eval("var results = " + res);
deselectAllDatasources(1);
var sdi = new searchDataItem(str, results);
sdi.renderNextCol();
}
function handlePromoteToAdmin(uid, gid){
var c = confirm("Are you are sure you want to make this user an admin?");
if(c != true)
return
var request = "gid="+gid+"&uid="+uid;
var res = ajaxPost("/groupAdminAdd", "text/plain", request);
if(res != "success")
alert(res);
updateAllColsAndData(3);
}
function handleNewGroup() {
var name = document.getElementById("newGroupName").value;
var c=confirm("Are you sure you want to create a group called " + name);
if(c != true)
return;
var request = "name=" + urlencode(name);
var res = ajaxPost("/groupCreate", "text/plain", request);
if(res != "success")
alert(res);
updateAllColsAndData(2);
}
function handleGroupUserAdd(gid){
var addUserField = document.getElementById("addUserField");
var request = "gid=" + gid + "&name=" + addUserField.value;
var res = ajaxPost("/groupUserAdd", "text/plain", request);
if(res != "success")
alert(res);
updateAllColsAndData(3);
}
function handleUserDelete(ruid, gid) { //Deletes a user from the group
var request = "ruid=" + ruid + "&gid=" + gid;
var res = ajaxPost("/groupUserRemove", "text/plain", request);
if(res !="success")
alert(res);
updateAllColsAndData(3);
}
function handleCloseHelp(helpid) {
document.getElementById(helpid).style.display = 'none';
}
function handleShowAPI(tsid) {
var div = document.getElementById("apiAccess");
var html = "Public API:
";
var request = "ts=" + tsid + "&uid=-1&bit=36";
var res = ajaxPost("/aclGetBit", "text/plain", request);
if(res!="1")html += "Query access is not enabled. [Enable]";
else html += "Query access is enabled. [Disable]";
html+=" ";
var request = "ts=" + tsid + "&uid=-1&bit=37";
var res = ajaxPost("/aclGetBit", "text/plain", request);
if(res!="1")html += "Insert access is not enabled. [Enable]";
else html += "Insert access is enabled. [Disable]";
html+=" ";
var request = "ts=" + tsid + "&uid=-1&bit=38";
var res = ajaxPost("/aclGetBit", "text/plain", request);
if(res!="1")html += "Update access is not enabled. [Enable]";
else html += "Update access is enabled. [Disable]";
html+=" ";
var request = "ts=" + tsid + "&uid=-1&bit=39";
var res = ajaxPost("/aclGetBit", "text/plain", request);
if(res!="1")html += "Delete access is not enabled. [Enable]";
else html += "Delete access is enabled. [Disable]";
html+="
";
html += "Your account ID is " + uid + ".";
html += "
";
for(var i=0;i" + t.tid + " is the table ID for " + t.name + "";
}
html += "
";
html += "
Note that even if you enable insert, update, or delete access to this tableset, only tables with a column named 'API User' will be accessible. Covariable keeps track of what user inserted each row, and only allows users to modify or delete rows that they inserted. If insert access is enabled, any API user can insert rows into tables with a column named 'API User'.
";
html += "
";
div.innerHTML = html;
}
function handleSetAPI(tsid,bit,value) {
var request = "ts=" + tsid + "&uid=-1&bit="+bit+"&val=" + value;
var res = ajaxPost("/aclSetBit", "text/plain", request);
handleShowAPI(tsid);
}
/************************Creating DataItemClasses*******************************/
var allDataItemsTop = new Array();
var allDataItemsBot = new Array();
function createAllDataItems() {
//Create Top
allDataItemsTop.push(theMyPrivateDataItem = new MyPrivDataItem());
allDataItemsTop.push(new MyPubDataItem());
allDataItemsTop.push(new MySharedDataItem());
allDataItemsTop.push(new MySurveysDataItem());
allDataItemsTop.push(new groupDataItem());
allDataItemsTop.push(new apiUsersDataItem());
allDataItemsTop.push(theAddDataItem = new addDataItem());
// allDataItemsTop.push(new DataItemClass("Search", 1, false));
//Create Bottom
for(var i=0; i < catsList.length; i++)
allDataItemsBot.push(new CatDataItem(catsList[i].name, catsList[i].id));
}
/************************Setting up the Page*******************************/
function setupDatasources() {
var leftTopData = document.getElementById("leftTopData");
var leftBotData = document.getElementById("leftBotData");
for(var i=0; i < allDataItemsTop.length; i++) {
var addMe = allDataItemsTop[i].createUIDiv();
if(addMe!=null)
leftTopData.appendChild(addMe);
}
for(var i=0; i < allDataItemsBot.length; i++) {
var addMe = allDataItemsBot[i].createUIDiv();
if(addMe)
leftBotData.appendChild(addMe);
}
loadNavigation();
}
/****************Saving/Restoring Where The User Navigated To In A Cookie*************/
function saveNavigation() {
var name1 = col1SelDI?col1SelDI.name:"";
var name2 = col2SelDI?col2SelDI.name:"";
name1 = name1.replace(new RegExp("%","g"), "%1");
name1 = name1.replace(new RegExp(";","g"), "%2");
name2 = name2.replace(new RegExp("%","g"), "%1");
name2 = name2.replace(new RegExp(";","g"), "%2");
var exptime = new Date();
// remember location for 1 hour
exptime.setTime(exptime.getTime() + 60*60*1000);
document.cookie = 'col1=' + name1 + '; expires=' + exptime + '; path=/data/';
document.cookie = 'col2=' + name2 + '; expires=' + exptime + '; path=/data/';
}
function loadNavigation() {
var cookies = document.cookie.split(';');
var defname1 = (myData && myData.workspaces && myData.workspaces.length)?"My Private Data":"Add New Data", name1;
var name2 = "";
for(var i=0;i