Massemassimo Posted May 12, 2014 Share Posted May 12, 2014 Hey guys, I added a form to my game, wanting to let the user choose a seed.<form onsubmit="getSeed(event)"> <span>Seed:</span> <input id="seed" type="number" name="seed" value="111" /></form>My structure of my code is like so:module ModuleName { export class World extends Phaser.State { ... create() { ... } getSeed(event) { event.preventDefault(); console.log("submitted"); var seed = document.getElementById('seed')["value"]; ... }}How can I get my function to run, how do I target it? I obviously get an error (ReferenceError: getSeed is not defined) since it can't find my getSeed function. Is it even targetable from outside? Putting "public" infront of the function didn't help, I also tried game.getSeed(), this.game.getSeed(), game.World.getSeed() and a few others to no avail. :/ Also, a bit off topic: Would you take another route than adding an html form? Link to comment Share on other sites More sharing options...
AngryMoose Posted May 12, 2014 Share Posted May 12, 2014 Cool syntax for your class. Do you know what it's called? Link to comment Share on other sites More sharing options...
jpdev Posted May 13, 2014 Share Posted May 13, 2014 Don't work with "onSubmit" because that triggers reloads of the page and your javascript ends up beeing reloaded too and reset and you want nothing of that. Just use buttons that directly call your javascript functions and check what the user has entered in the dom-tree. (You can also hide the form stuff, or maybe the hole div that contains it after the user clicks the button, using javascirpt too) I like to use jquery for stuff like that, but you will have to invest a few hours to get comfortable with that. Without jquery it should look something like this:<input type="text" name="seed" id="seed" value="1234"><button onclick="getSeedAndStart()">Start</button>function getSeedAndStart() {var seedValue = document.getElementsByName('seed')[0].value;//do cool stuff, start the game} Link to comment Share on other sites More sharing options...
Massemassimo Posted May 13, 2014 Author Share Posted May 13, 2014 @angrymoose: I really don't get what you mean. @jpdev: thanks, I just got rid of the form tags and added a button as you suggested. No more page reloading, yay! Still the problem remains that I cannot "find" my function. Any tips? My typescript gets compiled down to one javascript file called output.js in the same folder als the html file (where my function-calling button resides). P.S.: I do know my way around jquery, I just thought I'd forego using it in this project since it's another source and a few more kb bandwidth. For simply calling a function I didn't see the need for jquery. Link to comment Share on other sites More sharing options...
jpdev Posted May 13, 2014 Share Posted May 13, 2014 Sorry, I don't use typescript.If you post the (relevant parts of) your output.js maybe we can figure out why your function can't be called. My example works, because the function is simply global.If the getSeedAndStart was a function defined on the prototype of for example the phaser game object, then the button would have to be defined this way:<button onclick="game.getSeedAndStart()">Start</button>(assuming the game object is global, as it is in most phaser examples) Link to comment Share on other sites More sharing options...
Massemassimo Posted May 13, 2014 Author Share Posted May 13, 2014 Ok, I shortened the output.js, I hope the relevant information is still in there.window.onload = function () { var game = new SpaceGen.Game();};var __extends = this.__extends || function (d, { for (var p in if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } __.prototype = b.prototype; d.prototype = new __();};var SpaceGen;(function (SpaceGen) { var Game = (function (_super) { __extends(Game, _super); function Game() { _super.call(this, 512, 640, Phaser.AUTO, 'content'); this.state.add('state_World', SpaceGen.World, false); this.state.start('state_World'); } return Game; })(Phaser.Game); SpaceGen.Game = Game;})(SpaceGen || (SpaceGen = {}));var SpaceGen;(function (SpaceGen) { var World = (function (_super) { __extends(World, _super); function World() { _super.apply(this, arguments); ... } World.prototype.getSeed = function () { console.log("submitted"); var seed = document.getElementById('seed')[0].value; }; return World; })(Phaser.State); SpaceGen.World = World;})(SpaceGen || (SpaceGen = {})); Link to comment Share on other sites More sharing options...
jpdev Posted May 14, 2014 Share Posted May 14, 2014 Yep, your snipped is good Here is how it works: 1. Make "game" a variable, that is accessible to the rest of the page (not just within the onload function)var game = null;window.onload = function () { game = new SpaceGen.Game();};This is the button code:<body><input id="seed" type="text"/><button onClick="game.state.states.state_World.getSeed()">test</button></body></html>And lastly, there is a small bug in how you access the seed value. getElementById returns only the one element that has this id. (not an array, because there can only be one element with the id seed.) Therefor remove the "[0]": World.prototype.getSeed = function () { var seed = document.getElementById('seed').value; console.log("submitted:" + seed); };Hope this helps, JP PS: how I found that out:- Instead of calling what we want, I called a global test() function with a console.log in it.- Put a breakpoint on the log and went searching for the desired object with the webstorm debugger - found it, and changed the onClick to the state object PPS: If you don't want to make your game variable a global one for some reason, you could add the on click event to the button not by designing it into the button tag, but by adding it later in the onload function, this way the game var could stay in the onLoad scope. But I have to get to work now. Link to comment Share on other sites More sharing options...
Massemassimo Posted May 14, 2014 Author Share Posted May 14, 2014 Will test later but let me thank you right now for not only supplying the answer but explaining how you found it out!! Help me help myself! Yay! Edited: Ok, I tested it and it works like a charm. I had been able to get it working earlier by using a phaser.button instead of the HTML button, circumventing the scoping problem. The "seed = document.getElementById('seed').value;" would actually work in JS (at least I think so), but Typescript doesn't like it because "The Property 'value' does not exist on value of type 'HTMLElement'." I searched a bit on stackoverflow and got different workarounds and fixes, and I decided on "seed = document.getElementById('seed')["value"];" which works just fine. Link to comment Share on other sites More sharing options...
Elvis Posted August 25, 2016 Share Posted August 25, 2016 This topic (the question of the author and the answer of jpdev) helped me a lot!!!! thank you guys Link to comment Share on other sites More sharing options...
Anvay Posted February 18, 2020 Share Posted February 18, 2020 If you want to stop the reloading, you can use this jQuery code. //needs <form> to have an id $("#form").submit(function(e) { e.preventDefault(); }); Link to comment Share on other sites More sharing options...
Recommended Posts