Interface elements and IDs


#1

Is it possible in JavaScript to place the same interface element on more than one screen/web page? For example, if you have a play again button for a win screen and a lose screen, could you use the same button on both screens because the response is the same, to go back to the start screen? We can’t in App Lab, but is it even possible?

Thanks!


#2

@p00057079 I don’t think so. Usually students add a new button to each screen or have a “clearScreen” function which hides all elements on the screen as needed.

I don’t think it is possible to have a button with the same ID appear on every screen.


#3

@kaitie_o_bryan is correct.

The way screens are implemented - they are html <div> tags with all elements on the screen embedded within them. When you switch screens the entire <div> of non-active screens becomes hidden and all descendants embedded within it inherit that hidden-ness as well.

The “fancy” way to get behavior like this is, as Kaitie suggests, to just use one screen. You can “fake” having multiple screens by simply showing/hiding the right elements at the right time. I have done this before, but using more sophisticated techniques than are probably available to your students if they are lesson 5.5.

I have a clever way to cheat though - you can take advantage of the fact that if you show a button on a hidden screen it stays hidden. So, if for example, you want the button on 4 different screens, just create 4 different buttons, one on each screen. Whenever you want to show one, just show them all! Make a function that shows/hides these buttons:

function showAllSaveBtns(){
    showElement('saveBtn1');
    showElement('saveBtn2');
    showElement('saveBtn3');
    showElement('saveBtn4');
}

And then you can call that function when you need to switch screens. (make a similar one for hideAll.) For example, assuming you’re changing screens based on a button click:

onEvent("nextScreenBtn","click",function(){
    setScreen("screen2");
    showAllSaveBtns();
}

You can’t really get around needing separate event handlers for each of the buttons, but if they really all have the same functionality, you could write a function to handle that functionality and simply call it directly from each of the onEvent calls.

function handleSaveBtnClick(){
   ...
   // do stuff that should be done when Save button is clicked
   ...
}

onEvent("saveBtn1","click", handleSaveBtnClick);
onEvent("saveBtn2","click", handleSaveBtnClick);
onEvent("saveBtn3","click", handleSaveBtnClick);
onEvent("saveBtn4","click", handleSaveBtnClick);

Not that in the above I’m also using a short cut to call the function. What’s above is equivalent to the more verbose inline function definition you get when you drag the onEvent block out of the tool box. This works too:

onEvent("saveBtn1","click", function(){
    handleSaveBtnClick();
});

Hope that helps?

Baker
CSP Team

P.S. The “sophisticated” version I mentioned is to maintain lists, also called arrays, of the elementIDs that represent the items on each each screen. When you want to show a new “screen” you iterate over the lists of elements to hide what needs to be hidden and showing what you want to show. Composing this screen in Design Mode is a bit nightmarish because you have to see ALL possible elements at the screen at the same time…but it can be done!


#4

So no arrays of elements in code.org Baker? I tried creating a page with a “roster” of names, each name being a label (but could have been a button or whatever). When a name on the roster is clicked, I wanted to open up a page displaying that person’s name and photo. In pure JS, I would just pass some ID related to the name clicked on, and display the name and picture associated with that ID. But in code studio it appears I have to have a different screen for each person on the roster… or do some kind of workaround with arrays (as suggested). Ideas?


#5

I think all you need are local arrays containing the information you want, combined with liberal use of the setProperty(...) command.

I’m on the run but here’s the short version. Let me know if you want me to expand further.

setProperty("myImg", photoList[ getText("pulldown_menu")]);

#6

Example: https://studio.code.org/projects/applab/n07YvYKR52p1BUMxoaWxXQ/


#7

Thanks Baker. This is the workaround I ended up doing without the drop-down list-box, using a naming standard for my photos.
Array of student names
var studentNames = [];
studentNames[1] = “Alfred Anteater”;
studentNames[2] = “Boris Britanica”;

studentNames[22] = “Zoe Zebra”;

Event handlers for all 22 labels.
onEvent(“label01”, “click”, function() {
showStudent(1);
});
onEvent(“label02”, “click”, function() {
showStudent(2);
});

A function called showStudent that shows the appropriate student image and student name on the student screen.
function showStudent(thisStudent) {
hideElement(“studentImage”);
setImageURL(“studentImage”,"");
var thisPic = “”;
if (thisStudent < 10) {thisPic = “0”}
thisPic = “student” + thisPic + thisStudent + “.png”;
setImageURL(“studentImage”,thisPic);
setText(“studentLabel”,studentNames[thisStudent]);
setScreen(“studentScreen”);
showElement(“studentImage”);
}

I’ve done drop downs in HTML/JS but I’ve never used the drop down in code studio.

Can I do “getSelected” rather than “getText” to get the index of the item selected from the drop-down?

Thanks again!

Jay


#8

Yeah…to simplify things in applab the value that shows in the pulldown is the same as getSelected. Sorry. That’s why I suggested the dictionary with list-options-as-keys.

Oh…and FWIW you can get the array of options from the pulldown menu using getProperty…

var menuOptions = getProperty("myDropdown", "options");


#9

Okay…also, recalling this from earlier. There is an easier way to capture multiple events with one event handler. the trick is to attach the event handler to the screen. Then you can probe the event object to figure out what else it touched, like so:

onEvent("screen1", "click", function(event) {
  var clicked_id = event.srcElementId;
  ...
   setText("studentLabel",studentNames[clicked_id]);
....
});

I don’t know that’s how’d you’d actually do it the point is event.srcElementId.

To see a list of everything that comes in the event object that gets passed to the onEvent function just dump it to the console, like so:

onEvent("screen1", "click", function(event) {
  console.log(event);
});