Dynamic Character Sheet Tips, Please?

Langy
Langy
edited June 2012 in Campaign Portal Building
So, as I've mentioned in a few other threads now, I just took my first foray into dynamic character sheet creation. You can see the results here:

"Image One":http://cdn.obsidianportal.com/assets/133392/Sheet1.png
"Image Two":http://cdn.obsidianportal.com/assets/133393/Sheet2.png
"Image Three":http://cdn.obsidianportal.com/assets/133394/Sheet3.png
"Image Four":http://cdn.obsidianportal.com/assets/133395/Sheet4.png

"In Sheet Database":http://www.obsidianportal.com/dynamic_sheet_templates/108

Now, when I started work on this Tuesday, I didn't really have much experience with HTML or CSS except on OP (my campaign "Edgerunners":http://www.obsidianportal.com/campaigns/edgerunners has been pretty much the epitome of my HTML and CSS prowess up until now), and I had zero experience with Javascript or JQuery (though luckily I do know Java, so it wasn't like I had to learn programming from nothing). Anyways, I learned a whole bunch while building this thing (like how the site's native CSS styles can really screw up your perfectly crafted sheet when uploaded to the server:/), and I stole several bits of code from other DSTs out there (the AlphaOmega one by Karelzarath and ChainsawXIV's Exalted and D&D4e sheets especially). Different DST authors have pretty different coding styles - Karelzarath's is all in JQuery, for example, while ChainsawXIV does his in pure Javascript; mine's a bit of a kludge, because I stole from both sources, but I primarily utilized ChainsawXIV's code.

And that brings me to the point of this thread. Finding the actual code to do the things I wanted wasn't exactly simple (there are over 100 DSTs now!), and the documentation is a bit lacking even in the places that use lots of comments - you still need to figure out how everything works in order to modify it so it works how you want it. So I thought a thread where we could post our own tips and solutions for solving DST issues could be rather helpful, and would be a good place for others to ask questions on how to get their coding to work out correctly. Right now, I have a few things to contribute, both dealing with modifying ChainsawXIV's list objects, and one question dealing with the text area objects.

First, the tips:

ChainsawXIV's default list interface doesn't handle trying to move the top item down a spot very well. You can't utilize the nice 'move this item down' button on the first item in a list. The reason for this is the iIndex variable in the oDemote method becomes Not a Number when it's the first item in the list. I honestly have no idea why; I could probably try and figure it out, but instead I just kludged a solution together. Right above where the iIndex bit is used to move the objects around, I just stuck the following bit of code:

if (isNaN(iIndex)) iIndex = 0;

Yeah, it's cheap, but it works and makes the list interface work as expected, which was the entire goal. It's possible that it could cause a bit of trouble if something unexpected happens, but I have no idea what could cause that to be problematic. Anyways, that was the kludge tip - maybe it'll help someone figure out the actual issue and fix it properly; I don't have enough Javascript experience to do so easily.

My second tip again deals with the list interface that ChainsawXIV worked up. By default, it doesn't handle nested divs or tables very well - you basically need to keep the exact structure that he utilized, or it doesn't work out right. I altered his code a little to make it able to intelligently search for the parent list, rather than assuming the list was always either the grandparent or great-grandparent of the control buttons. Replace his list parent-finding code with the following bit, right where the comment says 'activate the list the item belongs to':

var oItem = this;
var lList;
while(oItem.parentNode){
if (oItem.parentNode.className.match(/list/)){
lList = oItem.parentNode;
break;
}
else oItem = oItem.parentNode;
}

Just do that wherever that comment appears; look at my DST's code for an example - it can be found at line 648 of the javascript file, and elsewhere.


Now, a question. I wanted to add a 'description' text area for my DST. It didn't work; the area appeared, everything seemed to work right, I could type in it, etc. But when I click 'save' on my test character, the description bit doesn't get saved. This disappoints me; anyone have any ideas on why it might not save properly? I might be able to figure it out by myself, but right now my brain is a bit mushy from coding that DST for 12 hours straight today and it needs some rest.

Comments

  • Langy
    Langy
    Posts: 364 edited June 2012
    Oh, and I'd like to make it so that the jEditable forms save automatically when you click outside their area - it's really annoying that they don't do so by default. There's a setting in jEditable to make this happen, too - onBlur:submit would make them work correctly - but I have no idea if it's even possible to set any jEditable settings from within our javascript.

    Similarly, I'd like to make it so that list items are saved even if they're currently empty. This is for structural reasons while statting up a character - sometimes you just want a little space between some skills, for example. I may eventually just make it possible to set something up as a subheading on my current lists, but that'll take a bit more work.

    EDIT: I figured the second bit out - you can force them to be saved by sticking a few bits into the presave and preload codes. Presave gets something like this:

    //Save whitespaced areas in order to preserve table structures
    $(containerId + " .dsf").each(function(index,element) {
    var tester = $(element).text().replace(/^\s+/, '').replace(/\s+$/, '');
    if (tester === '') {
    // text was all whitespace
    $(element).text(" ");
    }
    if ($(element).text() === 'Edit') {
    // text was default
    $(element).text(" ");
    }
    });

    Preload gets something like this:

    //Replace fake-nbsp with real-nbsp
    for(var key in dynamic_sheet_attrs){
    if (dynamic_sheet_attrs[key] === ' ') {
    // text was fake nbsp
    dynamic_sheet_attrs[key] = ' ';
    }
    };

    If you don't have the preload bit, the non-breaking spaces don't appear properly - instead, they appear as  , which is totally not what was intended.

    Anyways, looking forwards to any comments, questions, answers, or other tips!
    Post edited by Langy on
  • Langy
    Langy
    Posts: 364 edited June 2012
    Well, I figured out how to make the text area work properly - the only problem appears to have been the fact that 'dsf_description' is a reserved word for the DSTs, so it wasn't being saved. Once I changed it to 'dsf_desc' it worked fine.

    I will say that I kinda wanted the 'dsf_description' bit to use the description that you can input in via the normal character input methods (not using the DST); would have been nice. Not really that big of a deal, though I do question why dsf_description is reserved if it isn't utilized.

    EDIT:

    Oh, and you can make a textarea save on loss of focus by using code something like this at the bottom of the oElement.edit function in ChainsawXIV's code:

    // Convert content into form with button
    this.innerHTML = '' + sText + '';
    //this.innerHTML += '✓';

    // Set the user's focus to the textarea and set it to save on loss-of-focus
    //var focusRef = function(){oElement.getElementsByTagName('textarea')[0].focus();};

    var focusRef = function(){$('.lmdgurps_textarea').focus();};
    var submitRef = function(){$('.lmdgurps_textarea').parent().submit();};
    var unfocusRef = function(){$('.lmdgurps_textarea').blur(submitRef)};

    this.focusTimeout = setTimeout(focusRef,50);
    this.unfocusTimeout = setTimeout(unfocusRef,60);
    Post edited by Langy on
  • Langy
    Langy
    Posts: 364
    I keep trying to figure out how to make it so that losing focus on a jeditable element makes it save the item rather than revert the changes, and it's annoying me. It would be a single-line alteration of characters.js if I could alter that (just create a new line at line 201 and stick in "onblur : 'submit',"), but without access to that it's complicated and difficult.

    Or not. I just figured it out, and it's wicked easy. The key is the little comment at the end of the jEditable source code: 'publicly accessible defaults'. The only thing you need to do in order to make this work (saving a field value by just clicking wherever rather than clicking the now-redundant submit button) is to add this to your JS file. I have it in the preload function, but it'd probably work almost anywhere:

    $.fn.editable.defaults['onblur'] = 'submit';

    Bam. Done. A one-line edit to your javascript, and you've got a pimpin' cool feature on your DST.
Sign In or Register to comment.

April 2024
Season of Strife

Read the feature post on the blog
Return to Obsidian Portal

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Discussions