Home Posts Tags Post Search Tag Search

Post 14

Game Site Journal - 05

Published on: 2025-04-13 Tags: elixir, Blog, Side Project, LiveView, Game Site, Html/CSS, Buttons
So for this post I wanted to go over something that I wanted to add to my games. A Wager button.

So for this to work I wanted to be able to send the info for the amount wagered as well as the answer. In the case for the Guessing Game I have hard coded a few buttons (10 that is) that are the number that a player would submit. 

<div class="grid grid-cols-5 gap-x-3 gap-y-1 max-w-md mx-auto mt-4">
      <%= for guess <- 1..10 do %>
        <.simple_form for={@form} phx-submit="answer" class="text-center">
          <.input type="hidden" field={@form[:guess]} value={guess} />

          <.button type="submit" class="w-full" phx-hook="CopyBonus">
            {guess}
          </.button>
        </.simple_form>
      <% end %>
 </div>

This will create 10 buttons for the user to submit. When I wanted to add a cell for a player to increase their bet simply adding a new .input added it to every cell... Adding it to a single button made it so only the button in question had the wager param sent... This is where adding a hidden field from an other section comes in handy. First create your new cell

<div class="max-w-md mx-auto mt-4">
      <label for="bonus_input" class="block text-sm font-medium text-gray-700 mb-1">
        Wager
      </label>
      <input
        type="number"
        id="wager_input"
        name="wager_visible"
        min="1"
        value="1"
        max={@score}
        step="1"
        class="w-full rounded-md border-gray-300 shadow-sm"
      />
    </div>

Then add this to the .simple_form as an other input
<div class="grid grid-cols-5 gap-x-3 gap-y-1 max-w-md mx-auto mt-4">
      <%= for guess <- 1..10 do %>
        <.simple_form for={@form} phx-submit="answer" class="text-center">
          <.input type="hidden" field={@form[:guess]} value={guess} />
          <input type="hidden" name="wager" id={"wager_hidden_#{guess}"} />

          <.button type="submit" class="w-full" phx-hook="CopyBonus">
            {guess}
          </.button>
        </.simple_form>
      <% end %>
    </div>

You can see that the id is a string interpolation, so that we can add in the guess id as a well as call the input that is outside the current loop for the buttons. 

So in the end we have a new input that we can take a wager. In order to add the wager to the score calculation. 

Now that that is in place we need to add in a Hook on the app.js code:

Hooks.CopyBonus = {
  mounted() {
    this.el.addEventListener("click", (e) => {
      const visible = document.getElementById("wager_input")
      const guess = this.el.getAttribute("data-guess")
      const hidden = document.getElementById(`wager_hidden_${guess}`)
      if (visible && hidden) {
        hidden.value = visible.value || "1"
      }
    })
  }
}

This sets the phx-hook

let liveSocket = new LiveSocket("/live", Socket, {
  hooks: Hooks,  // Make sure this is capitalized this adds in the new Hook
  longPollFallbackMs: 2500,
  params: { _csrf_token: csrfToken }
})

The last bit after this was to be sure that the different params were being used correctly. So I made a check for a win or a loss and changed all the score changes to:

parsed_wager =
      parse_wager(wager)
      |> add_subtract_wager(guess, to_string(socket.assigns.answer))
socket.assigns.score + parsed_wager

defp parse_wager(nil), do: 1
  defp parse_wager(""), do: 1

  defp parse_wager(wager) do
    case Integer.parse(wager) do
      {int, _} -> int
      :error -> 1
    end
  end

  defp add_subtract_wager(wager, guess, answer) do
    if guess == answer do
      wager
    else
      wager * -1
    end
  end

This was all the new functions needed.