App Lab - How to create a home button across multiple screens

applab

#1

I have students playing with App Lab and attempting to make multi-screen apps. They are running into issues where they want a button that persists across the screens so they don’t have to duplicate the code for each button. Is this possible, or should I just have them create a function that does the screen swapping and have them call that function for each button they make?


#2

I don’t think there is a way to make a button that lives across different screens. Having the onEvent for each of the buttons simply call the same function is certainly one way to do this and will keep the code minimized.


#3

This does work, though you can’t call the function in the onEvent without using a function to call it, which seems weird. Why can’t you use a function call as your OnEvent. I’ve attached a link to a program that shows this issue for any that care to look into it. Perhaps I’m missing something.

You’ll notice that the onEvents for meme1 through mem3 work as intended. They have a wrapper function calling the desired function. However, meme4 through meme6 do not work by just putting the function call inside the onEvent. I would expect it to work the same.

Also, I’ve noticed that the hidephotos function is called three times, even though the events aren’t called. Why would that be?


#4

I figured out why it is calling the hidephotos multiple times. It turns out that if you put the function inside the onEvent like I do for meme4 through meme6, it calls that function immediately. This also seems to act differently as to how I would expect it to work. Shouldn’t it call the function when the event happens.


#5

The tricky bit here is that the callback function for onEvent has to be a function reference and not a function call. Eg: onEvent("meme1", "click", hidephotos); instead of onEvent("meme1", "click", hidephotos("meme1"));

This means that you can’t pass a different parameter to each of the events. However, any function used as an onEvent callback gets passed an object that contains information about the event, including the ID of the element that was clicked on. So one approach to solving this problem is to pass hidephotos as the callback to each of the event handlers, and then modify hidephotos so that it takes the event object instead of the id directly. Eg:

function hidephotos(event) {
  // pull the element ID out of the event object
  var memeID = event.targetId;
  ...
}

Here’s a remix of the project showing this method in action


#6

Yes that’s it. Not realizing that it had that specific syntax is why we were having issues. Why does it call the function if it is not a reference? Should that happen, or could it show a warning message that might make the problem more clear instead?


#7

In the original app you sent I see the error WARNING: Line: 30: onEvent() callback parameter value (undefined) is not a function. which could definitely be clearer, but is happening because the function call returns undefined. The events that were working are using function references, they just happen to be anonymous functions that are defined in place. Ie

onEvent("meme1", "click", function() {
  hidephotos("meme1");
});

is equivalent to

onEvent("meme1", "click", function showphotos() {
  hidephotos("meme1");
});

is equivalent to

function showphotos() {
  hidephotos("meme1");
}
onEvent("meme1", "click", showphotos);

#8

And to make the final leap to my example

function showphotos(event) {
  var memeID = event.targetId;
  hidephotos(memeID);
}
onEvent("meme1", "click", showphotos);

#9

Thanks that helped. We adjusted to your examples, and it works well now.