Obsidian Portal
Menu
Sign In / Create Account
JavaScript is currently disabled. Obsidian Portal has a lot of really cool features that use JavaScript. You should check them out. We think you'll have a much more enjoyable experience.
Home
Campaigns
Games Nearby
Plans
Community
Help
Resources
dwaitas
Author:
Curufea
Slug:
dwaitas
Type:
GameCharacter
System:
Dr. Who: Adventures in Time and Space
DST Source Code
HTML Template
<table class="dwaitas"><tr><td class="left_column"> <div class="basic_info"> <div class="name"> <span>Name:</span> <span class="dsf dsf_name"></span> </div> <div class="player"> <span>Player:</span> <span class="dsf dsf_player"></span> </div> <div class="campaign"> <span>Campaign:</span> <span class="dsf dsf_campaign"></span> </div> </div> <div class="bio-data_extract"> <h3>Bio Data Extract</h3> <div class="appearance"> <span class="title">Appearance</span> <span class="dsf dsf_avatar_image"></span><br /> <span class="dsf dsf_appearance"></span> </div> <div class="personal_goal"> <span class="title">Personal Goal</span> <span class="dsf dsf_personal_goal"></span> </div> <div class="personality"> <span class="title">Personality</span> <span class="dsf dsf_personality"></span> </div> <div class="background"> <span class="title">Background</span> <span class="dsf dsf_bio"></span> </div> <div class="story_points"> <span class="title">Story Points <span class="dsf dsf_story_points"></span></span> </div> </div> <div class="equipment"> <h3>Equipment</h3> <div class="equipment"> <span class="title">Equipment</span> <span class="dsf dsf_equipment"></span> </div> <div class="home_tech_level"> <span class="title">Home Tech Level <span class="dsf dsf_home_tech_level"></span></span> </div> </div> </td><td class="right_column"> <div class="attributes"> <h3>Attributes</h3> <ul> <li>Awareness<span class="dsf dsf_awareness"></span></li> <li>Coordination<span class="dsf dsf_coordination"></span></li> <li>Ingenuity<span class="dsf dsf_ingenuity"></span></li> <li>Presence<span class="dsf dsf_presence"></span></li> <li>Resolve<span class="dsf dsf_resolve"></span></li> <li>Strength<span class="dsf dsf_strength"></span></li> </ul> </div> <div class="skills"> <h3>Skills</h3> <ul> <li>Athletics<span class="dsf dsf_athletics"></span></li> <li>Convince<span class="dsf dsf_convince"></span></li> <li>Craft<span class="dsf dsf_craft"></span></li> <li>Fighting<span class="dsf dsf_fighting"></span></li> <li>Knowledge<span class="dsf dsf_knowledge"></span></li> <li>Marksman<span class="dsf dsf_marksman"></span></li> <li>Medicine<span class="dsf dsf_medicine"></span></li> <li>Science<span class="dsf dsf_science"></span></li> <li>Subterfuge<span class="dsf dsf_subterfuge"></span></li> <li>Survival<span class="dsf dsf_survival"></span></li> <li>Technology<span class="dsf dsf_technology"></span></li> <li>Transport<span class="dsf dsf_transport"></span></li> </ul> </div> <!-- skills --> <div class="traitsOuter"> <h3>Traits</h3> <div class="traitsInner"> <a class="listAdd interface" style="top:-5px;right:2px;" title="Add Trait" onclick="dwaitas_getElementsByClassName('list_traits')[0].addItem();">+</a> <div class="list list_traits listColumns_1" style="margin-top:12px;"> <div class="template"> <div> <a class="listDelete interface" title="Delete this trait">✘</a> <a class="listPromote interface" title="Move this trait up">↑</a> <a class="listDemote interface" title="Move this trait down">↓</a> <span class="slimfield dsf dsf_traits_"></span> </div> </div> </div> </div> </div> </td></tr></table> <div class="author">Dynamic Character Sheet created by <div class="dsf dsf_dst_author"></div> </div>
CSS
.ds_dwaitas .dwaitas { padding:5px; border:2px solid #ff4040; background-color:#ffff40; border-spacing:0px 5px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; } .ds_dwaitas .dwaitas .left_column { width: 80%; vertical-align:top; } .ds_dwaitas .dwaitas .right_column{ width: 20%; vertical-align:top; } .ds_dwaitas input { padding:1px; margin:1px; font-family:arial; font-size:1em; color:#776655; z-index:4; } .ds_dwaitas .jeditable_submit{ position:absolute; height:24px; width:22px; z-index:5; } .ds_dwaitas .jeditable_submit_text { position:relative; font-size:1em; color:#070; } /**************************** * Basic Info *****************************/ .ds_dwaitas .basic_info { margin: 10px; padding:5px; border:2px solid #ff4040; background-color:#ffffff; border-spacing:0px 5px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; } .ds_dwaitas .basic_info .name, .ds_dwaitas .basic_info .player, .ds_dwaitas .basic_info .campaign { margin: 2px; padding:5px; border:2px solid #ff4040; background-color:#ffffff; border-spacing:0px 5px; -moz-border-radius: 5px; } /**************************** * Bio Data Extract *****************************/ .ds_dwaitas .bio-data_extract { padding:2px; border:2px solid #ff4040; background-color:#ffffff; border-spacing:0px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; align: top; } .ds_dwaitas .bio-data_extract h3 { display: block; width: 100%; border:2px solid #ffffff; background-color:#ff0000; border-spacing:0px 5px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; text-transform: uppercase; text-align: center; color: #ffffff; } .ds_dwaitas .bio-data_extract .appearance { display: block; width: 50%; float: left; } .ds_dwaitas .bio-data_extract .personal_goal { display: block; width: 50%; float: right; } .ds_dwaitas .bio-data_extract .personality, .ds_dwaitas .bio-data_extract .background, .ds_dwaitas .bio-data_extract .story_points { display: block; width: 100%; clear: both; padding: 10px; } .ds_dwaitas .bio-data_extract .title { display: block; width: 90%; margin: auto; text-align: center; text-transform: uppercase; font-size: 1.2em; padding:5px; border:2px solid #ff4040; background-color:#ffffff; border-spacing:0px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; } .ds_dwaitas .bio-data_extract .personal_goal .dsf_personal_goal, .ds_dwaitas .bio-data_extract .personality .dsf_personality, .ds_dwaitas .bio-data_extract .background .dsf_bio { display: block; margin: 5px 20px 5px 0px ; clear: both font-size: 1em; min-height: 3em; padding: 0; } .ds_dwaitas .bio-data_extract .appearance { display: block; text-align:center; } .ds_dwaitas .bio-data_extract .appearance img { margin-top:10px; } .ds_dwaitas .bio-data_extract .story_points .dsf_story_points { display: inline; float: right; width: 2em; min-height: 1em; padding: 5px; text-align: center; font-size:2em; border:2px solid #ff4040; background-color:#ffffff; border-spacing:0px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; } /**************************** * Equipment *****************************/ .ds_dwaitas .equipment { margin-top: 20px; padding:2px; border:2px solid #ff4040; background-color:#ffffff; border-spacing:0px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; align: top; } .ds_dwaitas .equipment h3 { display: block; width: 100%; border:2px solid #ffffff; background-color:#ff0000; border-spacing:0px 5px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; text-transform: uppercase; text-align: center; color: #ffffff; } .ds_dwaitas .equipment .title { display: block; width: 90%; margin: auto; text-align: center; text-transform: uppercase; font-size: 1.2em; padding:5px; border:2px solid #ff4040; background-color:#ffffff; border-spacing:0px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; } .ds_dwaitas .equipment .dsf_equipment { display: block; margin: 5px 20px 5px 0px ; min-height: 2em; clear: both font-size: 1em; padding: 5px; } .ds_dwaitas .home_tech_level .dsf_home_tech_level { display: inline; float: right; width: 2em; min-height: 1em; padding: 5px; text-align: center; font-size:2em; border:2px solid #ff4040; background-color:#ffffff; border-spacing:0px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; } /**************************** * Attributes *****************************/ .ds_dwaitas .attributes { padding: 2px; margin: 5px; border:2px solid #ff4040; background-color:#ffffff; border-spacing:0px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; align: top; } .ds_dwaitas .attributes h3 { display: block; width: 10em; border:2px solid #ffffff; background-color:#ff0000; border-spacing:0px 5px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; text-transform: uppercase; text-align: center; color: #ffffff; } .ds_dwaitas .attributes ul { list-style-type: none; width: 90%; padding: 0; } .ds_dwaitas .attributes li { display: block; clear: both; width: 100%; min-height: 1em; font-weight: bold; border-width:1px; border-color:#BBAA99; border-bottom-style:solid; } .ds_dwaitas .attributes .dsf { display: inline; float: right; font-size: 1em; width: 2em; min-height: 1em; border-width:1px; border-color:#BBAA99; border-style:solid; text-align: center; } /**************************** * Skills *****************************/ .ds_dwaitas .skills { margin: 5px; padding:2px; border:2px solid #ff4040; background-color:#ffffff; border-spacing:0px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; align: top; } .ds_dwaitas .skills h3 { display: block; width: 10em; border:2px solid #ffffff; background-color:#ff0000; border-spacing:0px 5px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; text-transform: uppercase; text-align: center; color: #ffffff; } .ds_dwaitas .skills ul { list-style-type: none; width: 90%; padding: 0; } .ds_dwaitas .skills li { display: block; clear: both; width: 100%; min-height: 1em; text-transform: uppercase; border-width:1px; border-color:#BBAA99; border-bottom-style:solid; } .ds_dwaitas .skills .dsf { display: inline; float: right; font-size: 1em; width: 2em; min-height: 1em; border-width:1px; border-color:#BBAA99; border-style:solid; text-align: center; font-weight: bold; } /**************************** * Traits *****************************/ .ds_dwaitas .traitsOuter{ padding:2px; margin: 5px; height: 100%; border:2px solid #ff4040; background-color:#ffffff; border-spacing:0px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; align: top; } .ds_dwaitas .traitsInner{ padding:2px; margin: 5px; min-height: 2em; border:2px solid #ff4040; background-color:#ffffff; border-spacing:0px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; align: top; } .ds_dwaitas .traitsOuter h3 { display: block; width: 10em; border:2px solid #ffffff; background-color:#ff0000; border-spacing:0px 5px; -moz-border-radius: 10px; -moz-box-shadow: black 2px 2px 5px; text-transform: uppercase; text-align: center; color: #ffffff; } .ds_dwaitas .slimfield { display:inline-block; min-height:1em; width:222px; border-width:1px; border-color:#BBAA99; border-bottom-style:solid; } div.editable .slimfield { width:200px; margin-left:22px; } .ds_dwaitas .slimfield .dsf { display:block; min-height:1em; width:222px; border-width:1px; border-color:#BBAA99; border-bottom-style:solid; } /**************************** * List Interface Styles *****************************/ .ds_dwaitas .list{ position:relative; width:232px; margin-left:auto; font-size:8pt; } .ds_dwaitas .listAdd{ position:relative; float:right; cursor:pointer; text-decoration:none; color:#776655; } .ds_dwaitas .listAdd:hover{ color:#AA9988; } .ds_dwaitas .listDelete{ color:#AA5544; cursor:pointer; letter-spacing:-1px; text-decoration:none; position:absolute; margin-top:1px; left:-1px; } .ds_dwaitas .listDelete:hover{ color:#CC7766; } .ds_dwaitas .listPromote{ cursor:pointer; letter-spacing:-1px; text-decoration:none; color:#776655; position:absolute; left:8px; } .ds_dwaitas .listPromote:hover{ color:#AA9988; } .ds_dwaitas .listDemote{ cursor:pointer; text-decoration:none; color:#776655; position:absolute; left:14px; } .ds_dwaitas .listDemote:hover{ color:#AA9988; } .ds_dwaitas .template{ display:none; }
JavaScript
// Note- All javascript is from ChainsawXIV's DD4E sheet and all credit belongs to him. I merely used bits of it. // Global Storage dwaitas_context = {}; /////////////////////////////////////////////////// // Event Hooks ///////////////////////////////////// /////////////////////////////////////////////////// // Called immediately before the script fills the Span fields with data function dwaitas_dataPreLoad(opts){ // Set the jeditable button aisleten.characters.jeditableSubmit = '<button class="jeditable_submit"><div class="jeditable_submit_text">✓</div></button>'; /* aisleten.characters.jeditablePlaceholder = function(){ if (this.className.match(/boxfield/)) return ''; else return 'Edit'; } */ aisleten.characters.jeditablePlaceholder = ''; } // Called immediately after the script fills the Span fields with data, before jeditable attachement function dwaitas_dataPostLoad(opts){ // Store global context for search by class name dwaitas_context = document.getElementById(opts['containerId']); // Set additional options opts['context'] = document.getElementById(opts['containerId']); opts['debugThreshold'] = -1; //Convert interface elements dwaitas_convertLists(opts); dwaitas_convertPips(opts); dwaitas_convertChecks(opts); dwaitas_convertAreas(opts); } // Called immediately before the sheet's data is saved function dwaitas_dataPreSave(opts) { // Set additional options opts['context'] = document.getElementById(opts['containerId']); dwaitas_unconvertPips(opts); dwaitas_unconvertChecks(opts); dwaitas_unconvertAreas(opts); } /////////////////////////////////////////////////// // Pips Interface Control ///////////////////////////// /////////////////////////////////////////////////// // Applies a bunch of pips functionality to the specified element function dwaitas_pips(oElement,opts){ // Store options oElement.setAttribute('optsImagePath',opts['imagePath']); oElement.setAttribute('optsIsEditable',opts['isEditable']); oElement.setAttribute('optsDebugThreshold',opts['debugThreshold']); // Gets the range of the element from its class name oElement.range = function(){ // Get the range from the element's class name var iRange = this.className.match(/pipsRange_[\d]+/)[0].substring(10); // Default if needed, and return if (iRange != 3 && iRange != 5 && iRange != 7 && iRange != 10){ this.error(1,"Invalid range specification in Pips Element (Element Class: " + this.className + ")"); return 10; } else return iRange; }; // Gets the field value from the embedded image or the text oElement.value = function(){ // Get the value from the image if there is one if (this.getElementsByTagName('img').length){ var sPath = this.getElementsByTagName('img')[0].src; var iValue = parseInt(sPath.substring(sPath.length - 9,sPath.length - 7),10); } // If there's no image, get the value from the text else{ var iValue = parseInt(this.innerHTML); if (this.innerHTML == '') iValue = 0; } // Check the value for bad data, default if needed, and return if (isNaN(iValue) || iValue > this.range() || iValue < 0){ this.error(1,"Invalid value for Pips Element (Element Class: " + this.className + ")"); return 0; } else return iValue; }; // Converts the associated span element's contents to a pips image oElement.showPips = function(){ // Get the image path from options or default if (this.getAttribute('optsImagePath')) var sPath = this.getAttribute('optsImagePath'); else{ this.error(2,'No imagePath specified in options for pips element (Element Class: ' + this.className + ')'); sPath = 'dynamic_sheets/exalted/0.1/images/'; } // Skip fields with a value of -1 if (this.value() == -1) return; // Replace the contents with the appropriate pips image this.innerHTML = '<img src="' + sPath + 'pips-' + this.padDigits(this.value(),2) + '-' + this.padDigits(this.range(),2) + '.png" />'; // Activate the pips this.activate(); }; // Converts the associated span element's contents to a text value oElement.showValue = function(){ // Replace the contents with the appropriate value string this.innerHTML = this.value(); }; // Assigns clickability to a pips image element oElement.activate = function(){ // Don't actualy activate anything if we're not in edit mode if (this.getAttribute('optsIsEditable') != 'true') return; // Activate the element's pips interface this.onclick = this.click; // Set the element's alt text this.title = 'Click to set value'; // Set the cursor for the item this.style.cursor = 'pointer'; }; // Click event handler for the pips interface oElement.click = function(e){ // Provide cross-browser support for the event information var oEvent; if (window.event) oEvent = window.event; else oEvent = e; // Set the pixel thresholds for each pip var aThresholds = [0,21,38,55,72,92,113,130,147,164]; // Get the pips image that was clicked as a pips object var oImage = this.getElementsByTagName('img')[0]; // Walk up the offset parent tree to get the true click coords var oTemp = oImage; var iX = oTemp.offsetLeft; if (oTemp.offsetParent){ while (oTemp = oTemp.offsetParent){ iX += oTemp.offsetLeft; } } // Determine which pip the click was on and change the image var iClickX = oEvent.clientX - iX; for (var iScore = this.range(); iScore >= 0; iScore--){ if (iClickX > aThresholds[iScore]){ // If the user clicks the current score, they probably want to reduce by one if ((iScore + 1) == this.value()){ oImage.src = oImage.src.substring(0,oImage.src.length - 9) + this.padDigits(iScore,2) + "-" + this.padDigits(this.range(),2) + ".png"; } else{ oImage.src = oImage.src.substring(0,oImage.src.length - 9) + this.padDigits(iScore + 1,2) + "-" + this.padDigits(this.range(),2) + ".png"; } // Once the image has been set, we're done return; // Call the onUpdate event this.onUpdate(); } } }; // Error handling function - alerts on errors if bug reporting is on oElement.error = function(iImportance,sText){ if (this.getAttribute('optsDebugThreshold')) var iThreshold = this.getAttribute('optsDebugThreshold'); else iThreshold = 0; if (iImportance < iThreshold){ alert(sText); } } // Converts a number to a string with prepended zeros to the specified character length oElement.padDigits = function(iNumber,iDigits){ var sNumber = iNumber.toString(); var sTemp = ''; if (iDigits > sNumber.length){ for (var i = 0; i < (iDigits - sNumber.length); i++){ sTemp += '0'; } } return sTemp + sNumber; } // On Update event function, typicaly overriden oElement.onUpdate = function(){ } // Return the pips element for ease of refference return oElement; } // Converts all properly classed spans in the context to pips elements function dwaitas_convertPips(opts){ // Get all the spans in the context, whatever it may be if (opts['context']) var aSpans = opts['context'].getElementsByTagName('span'); else var aSpans = document.getElementsByTagName('span'); // Convert all the potential values in the context to pips var pTemp = {}; for (var i = 0; i < aSpans.length; i++){ if (aSpans[i].className.match(/pips/)){ pTemp = dwaitas_pips(aSpans[i],opts); pTemp.showPips(); } } } // Converts all the pips in the context back to thier basic values for saving function dwaitas_unconvertPips(opts) { // Get the working context if (opts['context']) var aSpans = opts['context'].getElementsByTagName('span'); else var aSpans = document.getElementsByTagName('span'); // Flip all the pips in the context back to values for(var i = 0; i < aSpans.length; i++){ if(aSpans[i].className.match(/pips/)){ aSpans[i].showValue(); } } } /////////////////////////////////////////////////// // List Interface Control ///////////////////////////// /////////////////////////////////////////////////// // Applies a bunch of list functionality to the specified element function dwaitas_list(oElement,opts){ // Store options oElement.setAttribute('optsContainerId',opts['containerId']); oElement.setAttribute('optsIsEditable',opts['isEditable']); oElement.setAttribute('optsDebugThreshold',opts['debugThreshold']); // Parses the number of columsn the list has from its class name oElement.columns = function(){ // Get the column count from the element's class name var iColumns = this.className.match(/listColumns_[\d]+/)[0].substring(12); // Default if needed, and return if (isNaN(iColumns) || iColumns < 1){ this.error(1,"Invalid column count specification in List Element (Element Class: " + this.className + ")"); return 1; } else return iColumns; }; // Gets the list's list item template from the element based on class oElement.template = function(){ // The template is the first div in the list with the "template" class var aDivs = this.getElementsByTagName('div'); for (var i = 0; i < aDivs.length; i++){ if (aDivs[i].className.match(/template/)) return aDivs[i]; } // Create a semi-persistant default row template if needed if (!this.defaultTemplate){ this.defaultTemplate = document.createElement('div'); this.defaultTemplate.innerHTML = '<span class="dsf"></span>'; } // If we got here, there wasn't a template in the list, default and return this.error(1,"No template row found in List Element (Element Class: " + this.className + ")"); return this.defaultTemplate; }; // Gets an array of the fields in the template row oElement.fields = function(){ // This is easy assuming all the fields are span tags, and all the spans are fields //var TEST = this.template().getElementsByTagName('span'); //return this.template().getElementsByTagName('span'); var aFields = this.template().getElementsByTagName('span'); var aReduced = new Array(); var iCounter = 0; for (var i = 0; i < aFields.length; i++){ if (aFields[i].className.match(/dsf/)){ aReduced[iCounter] = aFields[i]; iCounter++; } } return aReduced; } // Gets an array of the rows in the list, excluding the template oElement.rows = function(){ // Initialize the list of rows var aRows = new Array(); // Getting the divs in the list the hard way to avoid nested divs making the cut var aElements = this.childNodes; var aDivs = new Array(); var iCounter = 0; for (var n = 0; n < aElements.length; n++){ if (aElements[n].tagName == 'DIV'){ aDivs[iCounter] = aElements[n]; iCounter++; } } // If we have multiple columns, then get the rows from inside each one if (this.columns() > 1){ var aTemp = new Array(); for (var x = 0; x < aDivs.length; x++){ if (!aDivs[x].className.match(/template/)){ aTemp = aDivs[x].getElementsByTagName('div'); for (var y = 0; y < aTemp.length; y++){ aRows[aRows.length] = aTemp[y]; } } } } // Otherwise just get them all from the main div else{ for (var i = 1; i < aDivs.length; i++){ aRows[aRows.length] = aDivs[i]; } } // Return the array of rows // This may have been dissacoiated by the splices, not sure yet return aRows; } // Generates a structure containing the list's data from the save object oElement.loadData = function(){ // Pattern match on the first field for simplicity's sake var iCounter = 0; var oData = {}; // Get the fields in order (doesn't allow missing fileds) var sClassPattern = this.fields()[0].className.match(/dsf_[\w\d]+/)[0].substring(4); while (dynamic_sheet_attrs[sClassPattern + this.padDigits(iCounter,2)] != undefined){ oData[iCounter] = new Array(); for (var i = 0; i < this.fields().length; i++){ oData[iCounter][i] = dynamic_sheet_attrs[this.fields()[i].className.match(/dsf_[\w\d]+/)[0].substring(4) + this.padDigits(iCounter,2)]; } iCounter++; } // Write the length oData.length = iCounter; // Write the completed data structure to the object this.data = oData; } // Generates a structure contianing the list's data form the list itself oElement.parseData = function(){ // Go through each row of each field and populate the structure var oData = {}; oData.length = 0; for (var i = 0; i < this.rows().length; i++){ oData[i] = new Array(); for (var n = 0; n < this.fields().length; n++){ oData[i][n] = this.rows()[i].getElementsByTagName('span')[n].innerHTML } oData.length = i + 1; } // Write the completed data structure to the object this.data = oData; } // Renders out the code for the list and puts it into the list element oElement.render = function(){ var sTemp = ''; var iCurrentColumn = 1; var iBreak = 0; var sClass = ''; // Add the first column opener if multiple columns, and calc first col break if (this.columns() > 1){ sTemp = '\n<div class="column column_spacing">'; iBreak += Math.floor(this.data.length / this.columns()) - 1; if (iCurrentColumn <= (this.data.length % this.columns())) iBreak++; } // Accumulate the list code for each row for (var i = 0; i < this.data.length; i++){ // Populate and class the fields for (var n = 0; n < this.fields().length; n++){ this.fields()[n].className = this.fields()[n].className.replace(/dsf_[\w\d]+/,this.fields()[n].className.match(/dsf_[\w\d]+/)[0] + this.padDigits(i,2)); this.fields()[n].innerHTML = this.data[i][n]; if (this.data[i][n] == undefined) this.fields()[n].innerHTML = ''; } // Add the list item to the code sTemp += this.template().innerHTML; // Reset the template if it was used for (var x = 0; x < this.fields().length; x++){ sClass = this.fields()[x].className.match(/dsf_[\w\d]+/)[0]; this.fields()[x].className = this.fields()[x].className.replace(/dsf_[\w\d]+/,sClass.substring(0,sClass.length - 2)); this.fields()[x].innerHTML = ''; } // Add column breaks where needed if (this.columns() > 1 && (i == iBreak)){ // Add the column opener for the last column if (iCurrentColumn == (this.columns() - 1)) sTemp += '</div>\n<div class="column">'; // Add the final column's column closer else if (i == (this.data.length - 1)) sTemp += '</div>'; // Add the column openers for other columns else sTemp += '</div>\n<div class="column column_spacing">'; // Update the column break and current column iCurrentColumn++; iBreak += Math.floor(this.data.length / this.columns()); if (iCurrentColumn <= (this.data.length % this.columns())) iBreak++; } } // Prepend the template to the list code sTemp = '<div class="template">' + this.template().innerHTML + '</div>' + sTemp; // Purge jquery expandos in explorer sTemp = sTemp.replace(/jQuery[\d]+="[\d]+"/g,''); // Put the code in the list this.innerHTML = sTemp; // Activate the interface if in edit mode if (this.getAttribute('optsIsEditable') == 'true'){ // Look through all the anchor elements in the list and activate by class name var aButtons = this.getElementsByTagName('a'); for (var y = 0; y < aButtons.length;y++){ if(aButtons[y].className.match(/listDelete/)) aButtons[y].onclick = this.deleteItem; else if(aButtons[y].className.match(/listPromote/)) aButtons[y].onclick = this.promoteItem; else if(aButtons[y].className.match(/listDemote/)) aButtons[y].onclick = this.demoteItem; } } // Hide them if not else{ // Look through all the anchor elements in the list and hide by class name var oContext = document.getElementById(this.getAttribute('optsContainerId')); if (oContext) var aButtons = oContext.getElementsByTagName('a'); else{ this.error(2,'No context specified in options for list element (Element Class: ' + this.className + ')'); var aButtons = document.getElementsByTagName('a'); } for (var y = 0; y < aButtons.length; y++){ if(aButtons[y].className.match(/interface/)) aButtons[y].style.display = 'none'; } } // Triger the list's onUpdate event this.onUpdate(); }; // Adds an blank element to the list oElement.addItem = function(){ // Get the latest data from the list this.parseData(); // Add a new row to the data, full of blank values var aRow = new Array(); for (var i = 0; i < this.fields().length; i++){ aRow[i] = ''; } this.data[this.data.length] = aRow; this.data.length++; // Re-render the list this.render(); }; // Deletes the specified element from the list oElement.deleteItem = function(){ // Activate the list the item belongs to var oItem = this.parentNode; if (oItem.parentNode.className.match(/list/)) var lList = oItem.parentNode; else var lList = oItem.parentNode.parentNode; // Stop here if we're editing things if (oItem.innerHTML.match(/input/)) return; // Delete the item from the DOM oItem.parentNode.removeChild(oItem); // Refresh the list to renew numbering lList.parseData(); lList.render(); }; // Moves the specified element up the list one place oElement.promoteItem = function(){ // Activate the list the item belongs to var oItem = this.parentNode; if (oItem.parentNode.className.match(/list/)) var lList = oItem.parentNode; else var lList = oItem.parentNode.parentNode; // Stop here if we're editing things if (oItem.innerHTML.match(/input/)) return; // Get the latest data from the list lList.parseData(); // Figure out what row number was clicked var sFieldClass = oItem.getElementsByTagName('span')[0].className.match(/dsf_[\w\d]+/)[0]; var sIndexString = sFieldClass.substring(sFieldClass.length - 2).replace(/^[0]+/,''); var iIndex = parseInt(sIndexString); // Stop right here if the clicked item is already at the top if (iIndex == 0) return; // Swap the row data with the one above it var aRowA = lList.data[iIndex]; var aRowB = lList.data[iIndex - 1]; lList.data[iIndex] = aRowB; lList.data[iIndex - 1] = aRowA; // Re-render the data lList.render(); }; // Moves the specified element down the list one place oElement.demoteItem = function(){ // Activate the list the item belongs to var oItem = this.parentNode; if (oItem.parentNode.className.match(/list/)) var lList = oItem.parentNode; else var lList = oItem.parentNode.parentNode; // Stop here if we're editing things if (oItem.innerHTML.match(/input/)) return; // Get the latest data from the list lList.parseData(); // Figure out what row number was clicked var sFieldClass = oItem.getElementsByTagName('span')[0].className.match(/dsf_[\w\d]+/)[0]; var sIndexString = sFieldClass.substring(sFieldClass.length - 2).replace(/^[0]+/,''); var iIndex = parseInt(sIndexString); // Stop right here if the clicked item is alreayd on the bottom if (iIndex == (lList.data.length - 1)) return; // Swap the row data with the one below it var aRowA = lList.data[iIndex]; var aRowB = lList.data[iIndex + 1]; lList.data[iIndex] = aRowB; lList.data[iIndex + 1] = aRowA; // Re-render the data lList.render(); }; // Error handling function - alerts on errors if bug reporting is on oElement.error = function(iImportance,sText){ if (this.getAttribute('optsDebugThreshold')) var iThreshold = this.getAttribute('optsDebugThreshold'); else iThreshold = 0; if (iImportance < iThreshold){ alert(sText); } } // Converts a number to a string with prepended zeros to the specified character length oElement.padDigits = function(iNumber,iDigits){ var sNumber = iNumber.toString(); var sTemp = ''; if (iDigits > sNumber.length){ for (var i = 0; i < (iDigits - sNumber.length); i++){ sTemp += '0'; } } return sTemp + sNumber; } // On Update event function, typicaly overriden oElement.onUpdate = function(){ } // Return the origenal element now that it's fully equipped return oElement; } // Converts all properly classed divs in the context to lists function dwaitas_convertLists(opts){ // Find all the divs on the page with "list" in their class name if (opts['context']) var aDivs = opts['context'].getElementsByTagName('div'); else var aDivs = document.getElementsByTagName('div'); var lTemp = {}; for (var i = 0; i < aDivs.length; i++){ if (aDivs[i].className.match(/list/)){ // Convert each element to a full featured list object lTemp = dwaitas_list(aDivs[i],opts); // Populate the list from the data variable lTemp.loadData(); lTemp.render(); // Assign the onUpdate function lTemp.onUpdate = function(){ dwaitas_convertPips(opts); aisleten.characters.bindAllFields(opts['slug'],opts['containerId']); //dst_devkit.bindDynamicAttributes(); } } } } /////////////////////////////////////////////////// // Text Area Edit Control //////////////////////////// /////////////////////////////////////////////////// // Core Textarea Class function dwaitas_area(oElement,opts){ // Store options oElement.setAttribute('optsIsEditable',opts['isEditable']); oElement.setAttribute('optsDebugThreshold',opts['debugThreshold']); // Attaches edit events to area text oElement.activate = function(){ // Don't activate the element if we're not in edit mode if (this.getAttribute('optsIsEditable') != 'true') return; // Activate the element oElement.onclick = this.edit; // Add default value if (this.innerHTML == '') this.innerHTML = 'Click to edit'; // Set the element's alt text this.title = 'Click to edit'; // Set the cursor for the item this.style.cursor = 'pointer'; }; // Converts the element to an editable area oElement.edit = function(){ // Abort click function if we just clicked submit if(this.getAttribute('eventLock') == 'locked'){ this.setAttribute('eventLock',null); return; } // Disable click functionality this.onclick = null; // Set pointer this.style.cursor = 'text'; // Remove default if (this.innerHTML == 'Click to edit') this.innerHTML = ''; // Convert <br /> tags to line breaks var sText = this.innerHTML.replace(/<br>/g,'\n'); // Convert content into form with button this.innerHTML = '<textarea class="area" style="width:' + (this.offsetWidth - 23) + 'px;height:' + (this.offsetHeight - 6) + 'px;">' + sText + '</textarea>'; this.innerHTML += '<button class="submit_button area_submit" onClick="this.parentNode.submit();"><div class="area_submit_text">✓</div></button>'; }; // Converts the edit box back into regular text form oElement.submit = function(){ // Get the data from the edit box var sContent = this.getElementsByTagName('textarea')[0].value.replace(/\n/g,'<br>'); // Remove the form elements this.innerHTML = sContent; // Lock out the click event until we're done this.setAttribute('eventLock','locked'); // Set pointer this.style.cursor = 'pointer'; // Reattach the click functionality this.onclick = this.edit; }; // Error handling function - alerts on errors if bug reporting is on oElement.error = function(iImportance,sText){ if (this.getAttribute('optsDebugThreshold')) var iThreshold = this.getAttribute('debugThreshold'); else iThreshold = 0; if (iImportance < iThreshold){ alert(sText); } } // Return the element for ease of refference return oElement; } // Converts all properly classed divs in the context to lists function dwaitas_convertAreas(opts){ // Find all the spans on the page with "area" in their class name if (opts['context']) var aSpans = opts['context'].getElementsByTagName('span'); else var aSpans = document.getElementsByTagName('span'); var taTemp = {}; for (var i = 0; i < aSpans.length; i++){ if (aSpans[i].className.match(/area/)){ // Convert each element to a full featured list object taTemp = dwaitas_area(aSpans[i],opts); taTemp.activate(); } } } // Sets the necesary class name on areas for themt o be saved function dwaitas_unconvertAreas(opts){ // Find all the spans on the page with "area" in their class name if (opts['context']) var aSpans = opts['context'].getElementsByTagName('span'); else var aSpans = document.getElementsByTagName('span'); // Add the necesary save key to the class name // Also close out any active edit boxes for (var i = 0; i < aSpans.length; i++){ if (aSpans[i].className.match(/area/)){ if (aSpans[i].innerHTML.match(/textarea/)) aSpans[i].submit(); if (aSpans[i].innerHTML == 'Click to edit') aSpans[i].innerHTML = ''; } } } /////////////////////////////////////////////////// // Check Interface Control /////////////////////////// /////////////////////////////////////////////////// // Applies a bunch of pips functionality to the specified element function dwaitas_check(oElement,opts){ // Store options oElement.setAttribute('optsImagePath',opts['imagePath']); oElement.setAttribute('optsIsEditable',opts['isEditable']); oElement.setAttribute('optsDebugThreshold',opts['debugThreshold']); // Gets the field value from the embedded image or the text oElement.value = function(){ // Get the value from the image if there is one if (this.getElementsByTagName('img').length){ var sPath = this.getElementsByTagName('img')[0].src; var sValue = sPath.substring(sPath.length - 5,sPath.length - 4); } // If there's no image, get the value from the text else{ var sValue = this.innerHTML; if (this.innerHTML == '') sValue = '0'; } // Check the value for bad data, default if needed, and return if (sValue != '1' && sValue != '0'){ this.error(1,"Invalid value for Check Element (Element Class: " + this.className + ")"); return 0; } else return sValue; }; // Converts the associated span element's contents to a pips image oElement.showCheck = function(){ // Get the image path from options or default if (this.getAttribute('optsImagePath')) var sPath = this.getAttribute('optsImagePath'); else{ this.error(2,'No imagePath specified in options for Checks element (Element Class: ' + this.className + ')'); sPath = 'dynamic_sheets/exalted/0.1/images/'; } // Replace the contents with the appropriate check image this.innerHTML = '<img src="' + sPath + 'check-' + this.value() + '.png" />'; // Activate the check this.activate(); }; // Converts the associated span element's contents to a text value oElement.showValue = function(){ // Replace the contents with the appropriate value string this.innerHTML = this.value(); }; // Assigns clickability to a pips image element oElement.activate = function(){ // Don't actualy activate anything if we're not in edit mode if (this.getAttribute('optsIsEditable') != 'true') return; // Activate the element's pips interface this.onclick = this.click; // Set the element's alt text this.title = 'Click to set value'; // Set the cursor for the item this.style.cursor = 'pointer'; }; // Click event handler for the pips interface oElement.click = function(){ // Get the pips image that was clicked as a pips object var oImage = this.getElementsByTagName('img')[0]; // Determine which pip the click was on and change the image if (this.value() == "1") oImage.src = oImage.src.substring(0,oImage.src.length - 5) + "0.png"; else oImage.src = oImage.src.substring(0,oImage.src.length - 5) + "1.png"; // Call the onUpdate event this.onUpdate(); }; // Error handling function - alerts on errors if bug reporting is on oElement.error = function(iImportance,sText){ if (this.getAttribute('optsDebugThreshold')) var iThreshold = this.getAttribute('optsDebugThreshold'); else iThreshold = 0; if (iImportance < iThreshold){ alert(sText); } } // On Update event function, typicaly overriden oElement.onUpdate = function(){ } // Return the pips element for ease of refference return oElement; } // Converts all properly classed spans in the context to pips elements function dwaitas_convertChecks(opts){ // Get all the spans in the context, whatever it may be if (opts['context']) var aSpans = opts['context'].getElementsByTagName('span'); else var aSpans = document.getElementsByTagName('span'); // Convert all the potential values in the context to pips var pTemp = {}; for (var i = 0; i < aSpans.length; i++){ if (aSpans[i].className.match(/check/)){ pTemp = dwaitas_check(aSpans[i],opts); pTemp.showCheck(); } } } // Converts all the pips in the context back to thier basic values for saving function dwaitas_unconvertChecks(opts) { // Get the working context if (opts['context']) var aSpans = opts['context'].getElementsByTagName('span'); else var aSpans = document.getElementsByTagName('span'); // Flip all the pips in the context back to values for(var i = 0; i < aSpans.length; i++){ if(aSpans[i].className.match(/check/)){ aSpans[i].showValue(); } } } /////////////////////////////////////////////////// // General Utility Functions ////////////////////////// /////////////////////////////////////////////////// // Gets an array of elements with a particular class from the context function dwaitas_getElementsByClassName(sClassName,sElementType){ // Provide default element type if (!sElementType) sElementType = 'div'; var aList = new Array(); var aDivs = dwaitas_context.getElementsByTagName(sElementType); for (var i = 0; i < aDivs.length; i++){ if (aDivs[i].className.match(sClassName)) aList[aList.length] = aDivs[i]; } return aList; }
Submit Notes
Back