Full screen games with Viewport Units & On Page Editing

Nerd Notes
10.07.14

One of my top challenges when developing Jeopardy Rocks was ensuring that the game displays just as well on a projector as it does on a computer or a tablet.  

We didn't want any scrolling down, misplaced podiums, or numbers that were too big.  After some research, I discovered what I think is the best approach to the issue:

CSS Viewport Units

Introduced in CSS3, viewport units are based on the size of the viewport (or visible screen) of the browser.  The two units are viewport height and viewport width. They can be used as follows:

  width: 100vw;
  font-size: 2.5vw;

One hundred viewport height units make up the height of the viewable screen, and one hundred viewport width units make up the width of screen. In the scenario above, the width will be calculated the same as 100% of the screen and the font size will be 2.5% of the screen width.

Using this technique, I was able to scale the font at the same rate as the Jeopardy boxes and vegetables. Because of this, the document looks just as good here:

Full screen on 23 inch monitor

As it does here:

Small on 23 inch monitor

Now, you can play anywhere!

Auto Saving with AJAX & Rails

One of the concerns teachers raised was if they could leave the game creator and return later to make additional edits. After all, it's tough to create an entire game in one sitting. So we took a page from Google Docs' book, and decided that users shouldn't have to press save at all.

I had to implement this in two different contexts: when a user changes the game title or category title, and when the user changes a question.  Below, I will discuss how I worked on the game titles.

CHANGING CATEGORY TITLES WITH INPUT LISTENERS

As you see in the picture below, when a user creates a game, they are presented with a screen that allows them to type in to the title and category fields.

Input Listeners

Each category title is actually an individual form.  For example, here is one of the form for Category One (remember that this site is made in Rails - check here for more documentation on forms):

<%= form_for(@categories.column_one.first, remote: true, method: :patch, html: {id: 'categoryOneForm'}) do |f| %>
  <%= f.text_area :title, value: @categories.column_one.first.title, rows: 2, placeholder: 'Category One', maxlength: Category::MAX_LENGTH, id: 'categoryOneTitle', class: 'inputLine impCatTitle' %>
<% end %>

The code snipped above does the following:

  • The *@categories.column_one.first *grabs the first column from the database

  • *remote: true *sets the form so that its submits to the server with JavaScript

  • *method: :patch *signifies that the field is being updated

  • Finally, the id and class will allow me to find the variables using JavaScript

In order to submit a field as soon as a user leaves it, I used the following functions:

    submitOnClick($('#categoryOneForm'), $('#categoryOneTitle'));

    function submitOnClick (form, input) {
        $(input).change(function() {
            $(form).submit();
        });
    }

Pretty simple!  I can call this function for every title field, and each time the user changes and leaves a field, the form will be submitted to the server via JavaScript.  Be sure to include the correct response in your controller as follows (just an example):

    def update
      respond_to do |format|
        if @game.update(game_params)
          format.html { redirect_to @game, notice: 'Game was successfully updated.' }
          format.json { render :show, status: :ok, location: @game }
        else
          format.html { render :edit }
          format.json { render json: @game.errors, status: :unprocessable_entity }
        end
      end
    end

And that's it!  If you have any questions about the topics above or want to know how anything else was built, just comment below!  Or feel free to reach out to us on Twitter @TeamMuno.

Ruben