Rails form post creates a 'Do you want to download “<form target>”' prompt on mobile

I’m just testing my first Rails app on mobile and whenever I submit a form I get a prompt to download the form target. See the screenshot below:

Here is my form tag for the form im working with:

<%= form_with(url: "/stock/createOrderBuy",remote: true, method: "post", id: "buyForm", html: { class: "needs-validation", novalidate: true }) do %>

And here is the function on the back end the form is posting to. As you can see, it’s just supposed to receive a post and send no response or redirect the user:

def createOrderBuy
        shares = params[:shares_buy][:number]
        type = params[:buyType]
        limit = 0 
        if params[:limitBuy][:limitPrice] != ""
            limit = params[:limitBuy][:limitPrice].to_f
        end
        stop = 0
        if params[:stopBuy][:stopPrice] != ""
            stop = params[:stopBuy][:stopPrice] .to_f
        end


        order = Order.create(typeId: type, quantity: shares, symbol: params[:symbolHidden], portfolioId: params[:portfolioIdHidden], processed: false, limit: limit, stop: stop, crypto: false, company_name: params[:companyHidden])
        puts "typeid = " + type.to_s

        if Stock.isMarketOpen && type.to_s == "1"

                quoteObj = StockQuote::Stock.new(api_key: 'API KEY HERE')
                stock = StockQuote::Stock.quote(order.symbol)
                latestPrice = stock.latest_price
                orderCost = (stock.latest_price.to_f*shares.to_f).round(2)
                order.cost = orderCost
                order.save
                #this will go in a processor later
                Stock.buyStock(latestPrice, order)
        end

    end

If anyone could advise me on how to prevent these popups in mobile on my rails app Id really appreciate it!

Using - Ruby on Rails 5.1.7, running in Safari on an iPhone8

I’m guessing it has something to do with the html. Also, why are you using not using a route? The `remote: true`` should be unnecessary too btw because the forms are remote by default. I don’t even see remote as a valid listed parameter. It should be :local.

:local - By default form submits are remote and unobtrusive XHRs. Disable remote submits with local: true.

I don’t really see anything here that would trigger the popup unless you have some JS targeting the form somewhere?

Could you paste a source of the raw HTML? And this is only happening on mobile?

Try removing the novalidate: true and see what happens.

Hey, thanks for the response. I tried removing novalidate: true and I still have the popup. Yes its only on mobile. Not only that, but only literally on phones. Running mobile emulation in my browser doesn’t reveal the issue. Here is the html for the form:

<form id="buyForm" class="needs-validation" action="/stock/createOrderBuy" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="lPU07yQlIZITBdeL3atuUId4mlG4FTSCjqmYt/xtoVyhtkZ/rkQFtmcYe/AWrtg/Eo60k4OTetPxaLRE///K/g==">
  <select name="buyType" id="buyType"><option value="1">Market</option>
<option value="7">Limit</option>
<option value="8">Stop</option></select>
			</form>

Also, this is happening when I use javascript to submit the form after a button click, like this:

document.getElementById('confirmBuyButtonAffirm').addEventListener('click', function() {
			$("#buyForm").submit(); //<-- Submits the form causing issues
			postSubmitBuyForm();
		});

Maybe the JS submitting the form could be causing some issue?

That’s very odd. Yeah, I don’t see anything that jumps out. If you have the codebase on GitHub or something I could take a look for you.

Hey @TensAndTwenties! There are multiple things I suggest you improve to follow Rails’ conventions better (some structural, some style related) and might help you with that weird bug.

form_with(url: "/stock/createOrderBuy",remote: true, method: "post", id: "buyForm", html: { class: "needs-validation", novalidate: true }
  1. Use route helpers. If you visit localhost:3000/rails/info/routes or run rake routes in your terminal, you’ll see a list of all the routes with their equivalent helpers. If you define a route using the resources keyword, you’ll get the helper for free. If you define your route manually post '/stock/createOrderBuy you can use the as keyword to assign a helper yourself. That way, you’ll end up using a helper method rather than a string that’s much more maintainable.
url: stock_create_order_buy
  • bonus: This article outlines the best way I’ve found to organise rails controllers
  1. form_with does an ajax call by default so you don’t need to declare remote: true yourself.

  2. If possible, don’t use Javascript to send the form. Simply adding a form.button 'Submit' to the form should allow you to send the form without the need of any extra JS. Make sure you’re passing the form object as a parameter of the form’s block like so:

form_with(url: ...) do |form|
  form.button 'Submit'
  1. Ruby has the following conventions for naming things:
  • snake_case for method names and variables
  • PascalCase for Classes and Modules

Rubocop or SantardRb might be a good idea to learn and enforce these. (I’m not sure if this project of yours is new or old but it’s good to learn this anyway)

  1. The create method will fail silently Ordrer.create(...) will return either true or false and it seems that your code doesn’t check if the order was actually saved. Check this resource to learn more about that (check out save vs save! which has the same behavior.

  2. Sending a form with JS in rails isn’t as straight forward as calling submit

document.getElementById('confirmBuyButtonAffirm').addEventListener('click', function() {
  $("#buyForm").submit(); //<-- Submits the form causing issues
  postSubmitBuyForm();
});

You’ll have to use some low level rails-ujs or jquery-ujs (depending on your rails version) to send it. Check out this resource

  1. If you need to do something else in JS after sending the form you can either attach some behavior to the ajax::success event or use a js.erb file as your response where you’ll add the relevant JS to run after the controller action is finished.

Now to your specific bug: My guess is that it can be related to a clash in function names that might be triggering something unintended. Throw some debuggers in your js code to see if it’s actually getting run and if it’s doing what you expect it to.

Check if your submit button submits form without your event listener. If it does, this is most likely the issue. Your controller doesn’t redirect anywhere, resulting in the outcome you have now on mobile.

@TensAndTwenties I think you can checkout this stackoverflow post to get more details about the remote forms.

An excellent suggestion . . .