Howdy, Stranger!

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

JQuery Question(s)

Hi everyone!

When I saw that Sugarcube had jquery support I got really excited, but I'm struggling with what I assume is a simple issue related to not understanding how the story format is implemented. Maybe it's better to just show what I want to do:

https://jqueryui.com/

I want to add this library to my story and then use some of the UI widgets in it!

So... questions:

1) Hey, is this a good idea even? Like will this seriously break anything if I try to do this?
2) If it's fine, where should I add this at or how should I add it so that it doesn't break anything?
3) Maybe more of a sub question but: Is extending Sugarcube this way even a good idea?
4) Do I need to do anything special to use this library once it's installed? Like... do I need to attach jquery handlers in a specific place to make them work?
5) If anyone can point me to a blog post or something where someone has already done something like this: Please do!

I'm pretty handy with Javascript and I've become pretty comfortable with the way that twine/sugarcube processes it within the context of the story, but that's only with code that I write and then specifically attach through either the window namespace or through the documented handlers, so I just really want to make sure that I do things in such a way where I don't reinvent the wheel or make an error in planning that will cause me to have to do a big refactor later if I want to update Sugarcube to a new version.

Thanks!

Comments

  • Like most questions of this nature, the answer depends on what exactly you want to so using jQuery UI.

    Adding the contents of the jquery-ui.min.js and jquery-ui.min.css files to your story is straight forward, open each of those files and copy their contents into b]Story Javascript[/b] and Story Stylesheet areas of your story.

    The first issue you will run into if one of timing, you will want to attach UI behaviours to HTML elements contained within your passages but those elements don't exist until the contents of the current passage being shown has being generated and attached to the DOM.
    This means you will need ways to delay the attaching of the behaviour until after the HTML exists and the following datepicker example shows one way of using a temporary postdisplay task within a passage to do this.
    Please enter a date.
    <input type="text" name="date" id="date">
    
    <<script>>
    postdisplay["Datepicker"] = function (taskName) {
    	$("#date").datepicker();
    	delete postdisplay[taskName];
    };
    <</script>>
    
    ... the above example leads into the second issue you will likely have which is, how do you access story variables within your Javascript code and the answer is the State.active.variables collection documented in the State API.

    The following datepicker example shows two ways to do the same thing:
    a. using an option.
    <<set $date to "">>
    
    <input type="text" name="date" id="date">
    
    <<script>>
    postdisplay["Datepicker"] = function (taskName) {
    	$("#date").datepicker({
    		onSelect: function(date) {
    			State.active.variables.date = date;
    		}
    	});
    	delete postdisplay[taskName];
    };
    <</script>>
    
    b. using an event.
    <<set $date to "">>
    
    <input type="text" name="date" id="date">
    
    <<script>>
    postdisplay["Datepicker"] = function (taskName) {
    	$("#date").datepicker().on("input change", function (e) {
    		State.active.variables.date = e.target.value;
    	});
    	delete postdisplay[taskName];
    };
    <</script>>
    

    Without knowing exactly which features of jQuery UI you will be using, it is hard to give specific help.
  • Hey GreyElf, thanks for the response. A lot of what you said makes sense to me.

    I was imagining that copying the JS into the story java-script would work at a basic level but I was a little hesitant at doing this because it just seems so messy so I was hoping there was a better way :)

    What you said about the display tasks makes sense. I assume from the name that this is a post rendering task that gets run as part of the overall rendering pipeline of the story?

    So.. the parser will catch my <<script>> macro declaration, then add my function to the pipeline as a task? It then does its other parsing activities, outputs that to the dom, then runs my postdisplay task?

    Is this the best way to organise everything? Basically on a passage by passage basis?

    As for what I was specifically looking at doing, it was just the tabs functionality to start with.

    So, from your example I should be able to do this (assuming my tabs are in a div with an id of "tabs"):
    <<script>>
    postdisplay["tabsTask"] = function(taskName) {
            $( "#tabs" ).tabs();
            delete postdisplay[taskName];
    };
    <</script>>
    

    From memory all this really does is some CSS styling and then onclick events to show/hide display divs, so it's not like I couldn't do it with just inline javascript on the page itself, but I was kinda curious about this anyway.

    Thanks I'll give this a shot soon 'nuff.
  • Hahaha, wow.

    I literally cut and pasted my own code out of this post (as well as the the correct js-min and css-min files) and it worked right away.

    So, I guess I'm marking this as answered... I don't know if this is the best way to do this, but it seems somewhat non-obtrusive.

    Thanks!
  • For information about the postdisplay task read the Task Objects section of the SugarCube 2 documentation.

    If you are planing to have the same content on many passages then you may want to switch from using a temporary task in the passage to a general task created in Story Javascript.
  • Say, you have an inventory system and you have two containers (Array), how would a drag-and-drop mechanic work in Twine using jQuery Draggable? When my item is dragged and dropped into another container, do I need to refresh the passage in order to view the results?
Sign In or Register to comment.