Dropdown list of Humberger button in Rails 7 + Stimulus not correct working in production (mobile) - drop-down-menu

There is no problem in the development environment, but when operating from a smartphone in the production environment, touches other than the hamburger menu button doesn't work correctly.
The code of the stimulus part is as follows.
import { Controller } from "#hotwired/stimulus"
import { useClickOutside,useIntersection } from "stimulus-use"
export default class extends Controller {
static targets = ["toggleable"]
static values = {
mobile: Boolean,
visible: Boolean
}
options = {
element: this.element.querySelector("#dropdown_menu")
}
initialize() {
if (navigator.userAgent.match(/iPhone|Android.+Mobile/)) {
this.mobileValue = true
} else {
this.mobileValue = false
}
}
connect() {
if (this.mobileValue === true ) {
useClickOutside(this)
useIntersection(this, this.options)
}
}
toggle(event) {
event.preventDefault()
this.toggleableTargets.forEach((target) => {
target.classList.toggle(target.dataset.cssClass)
})
}
appear(entry) {
this.visibleValue = true
}
disappear(entry) {
this.visibleValue = false
}
clickOutside(event) {
event.preventDefault()
if (this.visibleValue === true) {
this.toggleableTargets.forEach((target) => {
target.classList.add(target.dataset.cssClass)
})
}
}
}
The corresponding view file is as follows.
It may be hard to see because it uses tailwind.
<header>
<!-- logo -->
<div class="container mx-auto flex flex-wrap flex-col lg:flex-row lg:pl-10">
<%= link_to '#', class: "flex order-first title-font font-medium items-center text-gray-900 mb-4 md:mb-0" do %>
<%= image_tag 'xxx.png', class: "rounded-full w-10 h-10 bg-indigo-200"%>
<span class="ml-3 text-xl"><%= t'defaults.app_name' %></span>
<% end %>
</div>
<!-- end logo -->
<!-- menu -->
<div data-controller="menu" class="flex-initial relative lg:hidden">
<!-- Dropdown toggle button -->
<div data-action="click->menu#toggle">
<button type="button" class="inline-flex justify-center w-full px-4 py-2 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-indigo-500", id="options-menu" aria-haspopup="true" aria-expanded="true">
<svg viewBox="0 0 100 80" width="30" height="30">
<rect width="100" height="20" rx="8"></rect>
<rect y="30" width="100" height="20" rx="8"></rect>
<rect y="60" width="100" height="20" rx="8"></rect>
</svg>
</button>
</div>
<!-- Dropdown menu -->
<div data-menu-target="toggleable" data-css-class="hidden" id="dropdown_menu" class="hidden absolute right-0 z-20 w-56 py-2 mt-2 overflow-hidden bg-white rounded-md shadow-xl">
<%= link_to "#", class: "flex items-center p-3 -mt-2 text-sm text-gray-600 transition-colors duration-200 transform hover:bg-gray-100" do %>
<svg class="w-9 h-9" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-6-3a2 2 0 11-4 0 2 2 0 014 0zm-2 4a5 5 0 00-4.546 2.916A5.986 5.986 0 0010 16a5.986 5.986 0 004.546-2.084A5 5 0 0010 11z" clip-rule="evenodd"></path>
</svg>
<div class="mx-1">
<h1 class="text-sm font-semibold text-gray-700"><%= current_user.name %></h1>
<p class="text-sm text-gray-500 dark:text-gray-400"><%= current_user.email %></p>
</div>
<% end %>
<hr class="border-gray-200">
<%= link_to "#", class: "flex items-center p-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform hover:bg-gray-100" do %>
<span class="mx-1">
<%= t('defaults.profile') %>
</span>
<% end %>
<%= link_to "#", class: "flex items-center p-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform hover:bg-gray-100" do %>
<span class="mx-1">
<%= t('.information') %>
</span>
<% end %>
<%= link_to "#", class: "flex items-center p-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform hover:bg-gray-100" do %>
<span class="mx-1">
<%= t('defaults.list') %>
</span>
<% end %>
<hr class="border-gray-200">
<%= link_to logout_path, data: { turbo_method: :delete, turbo_confirm: t('.logout_confirmation') }, class: "flex items-center p-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform hover:bg-gray-100" do %>
<span class="mx-1">
<%= t('defaults.logout') %>
</span>
<% end %>
</div>
</div>
</header>
The browser of the development environment is chrome, I switched the device toolbar size to mobile and confirmed that it works.
In the production environment, the mobile model was iPhone SE and the browser is safari.
Tap the hamburger button to open the menu, but tapping any other on-screen button doesn't work. (Sometimes, but it's useless)
If you have any idea, please point it out.

Related

Bootstap carousel with Ruby keeps showing the last image

I am working on a dinamic photos carousel using Ruby and bootstrap ligthbox carousel, but i cannot make it work properly. when clicking on an image of the carousel to open that image in a modal keeps showing the last closed photo and not the photo I am clickin on. Any help will be appreciated, thanks.
<div class="container">
<div class="row d-flex flex-wrap align-items-center" data-toggle="modal" data-target="#lightbox">
<% #photos.each do |photo| %>
<div class="col-12 col-md-6 col-lg-3">
<img src="<%= cl_image_path photo.photo.key %>"/>
</div>
<% end %>
</div>
<!-- Modal -->
<div class="modal fade" id="lightbox" role="dialog" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<button type="button" class="close text-right p-2" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<div id="myCarousel" data-ride="carousel" class="carousel slide">
<ol class="carousel-indicators">
<% #photos.each_with_index do |photo, n| %>
<li data-target='#MyCarousel' data-slide-to="#{n}" class="#{'active' if n == 0}"></li>
<% end %>
</ol>
<div class="carousel-inner" role="listbox">
<div class="carousel-item active">
<img class="d-block w-100" src="<%= cl_image_path #photos.first.photo.key %>">
</div>
<% #photos.drop(1).each do |photo| %>
<div class="carousel-item">
<img class="d-block w-100" src="<%= cl_image_path photo.photo.key %>">
</div>
<% end %>
</div>
<a class="carousel-control-prev" href="#myCarousel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#myCarousel" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
</div>
</div>
`

How to manipulate specific div inside a for-loop of EJS?

Been googling around for multiple hours, I want to change the color of the svg of one element during the onClick event, turns out it either style all the elements in the for loop, or just the first one. I added my ejs and toggleSvg() js script here. Hope you can help me.
ejs snippet:
(look for "svg here")
<div class="max-w-5xl mt-14 mx-auto sm:max">
<% posts.forEach(post=> { %>
<div class="my-20">
<div class=" px-2 mb-2 flex items-center justify-between">
<div class="flex items-center">
<div class="border border-gray-300 p-1 rounded-full w-10 h-10 flex items-center bg-white">
<img
src="<%= post.merchant.image %>"
alt="..."
class="w-10"
loading="lazy"
/>
</div>
<p class="pl-5"><%= post.merchant.name %></p>
</div>
<div>
<!--svg here!-->
<svg id="test" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 cursor-pointer" fill="none" viewBox="0 0 24 24" stroke="currentColor" onclick="toggleSvg()" >
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"/>
</svg>
</div>
</div>
<!--image carousell-->
<div class="swiper mySwiper">
<div class="swiper-wrapper">
<div class="swiper-slide w-10 h-20 bg-black ">
<div class="justify-center flex ">
<img
src="<%= post.imageUrl[0] %>"
alt="..."
class="h-72"
loading="lazy"
/>
</div>
</div>
<div class="swiper-slide bg-black">
<div class="justify-center flex bg-black">
<img
src="<%= post.imageUrl[1] %>"
alt="..."
class="h-72"
loading="lazy"
/>
</div>
</div>
<div class="swiper-slide bg-black">
<div class="justify-center flex bg-black">
<img
src="<%= post.imageUrl[2] %>"
alt="..."
class="h-72"
loading="lazy"
/>
</div>
</div>
<div class="swiper-slide bg-black">
<div class="justify-center flex bg-black">
<img
src="<%= post.imageUrl[3] %>"
alt="..."
class="h-72"
loading="lazy"
/>
</div>
</div>
</div>
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
<div class="swiper-pagination"></div>
</div>
<div class="">
<p><span class="font-bold pr-3"><%= post.merchant.name %></span><%= post.description %></p>
</div>
</div>
<% }) %>
</div>`enter code here`
toggleSvg() js:
<script>
function toggleSvg() {
svgElem = document.getElementById("test");
if(svgElem.style.fill === 'red'){
svgElem.style.fill = 'none';
}else{
svgElem.style.fill = 'red';
}
}
</script>
you're using a id in a loop
the can only select one element, if you want to color all svg you can use a class, if you want to color a specific svg you can do it like this
onclick="toggleSvg(this)"
this way you pass the current element when you click
<script>
function toggleSvg(svgElem ) {
if(svgElem.style.fill === 'red'){
svgElem.style.fill = 'none';
}else{
svgElem.style.fill = 'red';
}
}
</script>

I can't dispatch event in Alpinejs

I am using Laravel 8, Alpinejs and Livewire and having this problem:
This is my index file:
#extends('dashboard')
#section('content')
<header class="max-w-7xl mx-auto bg-white flex items-center justify-between">
<div class="mx-9 py-6 mt-4">
<h1 class="text-3xl font-bold text-gray-900">
Boards
</h1>
</div>
<div class="mx-9 py-6 mt-4">
<a href="#" #click="
$dispatch('custom-event')
"
class="w-28 text-base text-white bg-blue hover:text-gray-50 hover:bg-blue-hover rounded-xl py-2 px-3 leading-none transition ease-in duration-150 text-center">
Create new board
</a>
</div>
</header>
<livewire:boards-table
:boards="$boards"
/>
<livewire:create-board />
#endsection
When I click the "Create new board" button in the header tag, I want the create-board livewire component to be displayed. So I used #click="$dispatch('custom-event').
And here is my create-board file:
<div
x-cloak
x-data="{ isOpen: false }"
x-show="isOpen"
#keydown.escape.window="isOpen = false"
#custom-event.window="isOpen = true"
class="fixed z-20 inset-0 overflow-y-auto"
aria-labelledby="modal-title"
role="dialog"
aria-modal="true"
>
<div class="flex items-end justify-center min-h-screen">
<div x-show.transition.opacity="isOpen" class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity"
aria-hidden="true">
</div>
<div x-show.transition.origin.bottom.duration.300ms="isOpen"
class="modal bg-white rounded-tl-xl rounded-tr-xl overflow-hidden transform transition-all sm:max-w-lg sm:w-full">
<div class="absolute top-0 right-0 pt-6 pr-6">
<button #click="isOpen = false" class="text-gray-400 hover:text-gray-500">
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd"
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
clip-rule="evenodd" />
</svg>
</button>
</div>
<div class="bg-white sm:p-6 my-3">
<h3 class="text-center text-xl font-bold text-gray-900">Create a new board</h3>
<form wire:submit.prevent="createBoard" action="#" method="POST" class="space-y-4 px-4 pt-6">
<div>
<input wire:model.defer="boardName" type="text"
class="w-full bg-gray-100 rounded-xl placeholder-gray-900 border-none font-semibold px-4 text-sm"
placeholder="Board name">
</div>
<div>
<input wire:model.defer="urlName" type="text"
class="w-full bg-gray-100 rounded-xl placeholder-gray-900 border-none font-semibold px-4 py-2 text-sm"
placeholder="Short name (used in board URL)">
</div>
<div class="flex items-center justify-end">
<button type="submit"
class="text-center w-44 bg-blue font-bold h-11 text-sm text-white rounded-xl border border-blue hover:bg-blue-hover transition duration-150 ease-in px-6 py-3 mr-4 mt-2">Create new board</button>
</div>
</form>
</div>
</div>
</div>
</div>
But when I click on "Create new board" button, nothing happens.
Create-board component is still rendered in the browser.

Q: how to make use of Alpinejs and tailwindcss within Laravel?

I am trying to make use of Alpinejs using Adam Wathan's responsive navbar using vuejs, but i am experimenting if i can get it to work with Alpinejs.
app.blade.php
<head>
[...]
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine#v2.x.x/dist/alpine.min.js" defer></script>
[...]
</head>
In case you are wondering if Alpine is already loaded, it is working trying a simple dropdown toggle, but with this approach i find it hard to get it working.
Navbar.blade.php
#guest('applicant')
#else
<header class="bg-gray-900 sm:flex sm:items-center sm:justify-between xl:bg-white" x-data="dropdown()">
<div class="flex justify-between px-4 py-3 xl:w-72 xl:bg-gray-900 xl:justify-center xl:py-5">
<div>
[...]
</div>
<div class="flex sm:hidden">
<button x-on:click="open" type="button"
class="px-2 text-gray-500 hover:text-white focus:outline-none focus:text-white">
<svg class="h-6 w-6 fill-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path x-if="isOpen" fill-rule="evenodd" clip-rule="evenodd"
d="M18.278 16.864a1 1 0 0 1-1.414 1.414l-4.829-4.828-4.828 4.828a1 1 0 0 1-1.414-1.414l4.828-4.829-4.828-4.828a1 1 0 0 1 1.414-1.414l4.829 4.828 4.828-4.828a1 1 0 1 1 1.414 1.414l-4.828 4.829 4.828 4.828z" />
<path x-if="!isOpen" fill-rule="evenodd"
d="M4 5h16a1 1 0 0 1 0 2H4a1 1 0 1 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2z" />
</svg>
</button>
</div>
</div>
<nav class="sm:flex sm:items-center sm:px-4 xl:flex-1 xl:justify-between"
:class="{ 'hidden': !isOpen, 'block': isOpen }" x-show="open" x-on:click.away="close">
<div class="hidden xl:block xl:relative xl:max-w-xs xl:w-full">
[...]
</div>
<div class="sm:flex sm:items-center">
[...]
<div class="relative px-5 py-5 sm:py-0 sm:ml-4 sm:px-0">
[...]
<Dropdown class="hidden sm:block">
<template #trigger="{ hasFocus, isOpen }">
<span class="block h-8 w-8 overflow-hidden rounded-full border-2 "
:class="[(hasFocus || isOpen) ? 'border-white xl:border-indigo-500' : 'border-gray-600 xl:border-gray-300']">
<img class="h-full w-full object-cover"
src="https://images.unsplash.com/photo-1487412720507-e7ab37603c6f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=256&q=80"
alt="">
</span>
</template>
<template #dropdown>
<div class="mt-3 bg-white xl:border rounded-lg w-48 py-2 shadow-xl">
<a href="#account" class="block hover:text-white text-gray-800 px-4 py-2 hover:bg-indigo-500">Account
settings</a>
<a href="#support"
class="block hover:text-white text-gray-800 mt-0 px-4 py-2 hover:bg-indigo-500">Support</a>
<a href="#sign-out" class="block hover:text-white text-gray-800 mt-0 px-4 py-2 hover:bg-indigo-500">Sign
out</a>
</div>
</template>
</Dropdown>
</div>
</div>
</nav>
</header>
<script>
function dropdown() {
return {
open: false,
open() {
this.show = true
},
close() {
this.show = false
},
toggle() {
this.isOpen = !this.isOpen
},
}
}
</script>
#endguest
You do not need to add the scripts to make a dropdown open and close.
You need to have x-data defined in a parent (to both button and dropdown) div. Then reference it in the button and/or dropdown elements.
A simple example:
<div x-data="{isOpen : false}">
<button x-on:click="isOpen = !isOpen" class="button">Menu</button>
<!-- you need to toggle isOpen state on click. You can also use #click just like in vue -->
<div x-show="isOpen" class="dropdown"> <!-- x-show to show and hide -->
Account settings
Support
</div>
</div>
That is all there is to make a dropdown using alpine js.
In my case i didn't my javascript nor installed it, i just used the cdn
{{-- scrip --}}
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine#v2.x.x/dist/alpine.min.js" defer></script>
and had installed tailwind css. my code is..
<div x-data="{dropdownMenu: false}" class="lg:inline-block relative">
<!-- Dropdown toggle button -->
<button #click="dropdownMenu = ! dropdownMenu"
class="text-base no-underline hover:bg-indigo-300 hover:text-cool-gray-900 rounded-3xl py-1 px-2 ">
<span class="sr-only">{{ Auth::user()->name }}</span>
<img class="h-8 w-8 rounded-full"
src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=4&w=256&h=256&q=60"
alt="avatar">
</button>
<!-- Dropdown list -->
<div x-show="dropdownMenu"
class="absolute right-0 py-2 mt-2 bg-white bg-gray-100 rounded-md shadow-xl w-44">
<a href="#"
class="block px-4 py-2 text-sm text-gray-300 text-gray-700 hover:bg-gray-400 hover:text-white">
Your Profile
</a>
<a href="#"
class="block px-4 py-2 text-sm text-gray-300 text-gray-700 hover:bg-gray-400 hover:text-white">
Settings
</a>
<a href="#"
class="block px-4 py-2 text-sm text-gray-300 text-gray-700 hover:bg-gray-400 hover:text-white">
Reports
</a>
<a href="{{ route('logout') }}"
class="block px-4 py-2 text-sm text-gray-300 text-gray-700 hover:bg-gray-400 hover:text-white"
onclick="event.preventDefault();document.getElementById('logout-form').submit();">{{ __('Logout') }}</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST"
class="hidden">
{{ csrf_field() }}
</form>
</div>
</div>
this was my result when i click the avatar..
i hope this will assist you solve your problem

Rails Ajax Refresh Breaks Modal Upload Form Submit

I have a list of items that gets refreshed on create and update, I have a form that allows you to add elements, remove, adjust pricing inline. If you'd like to edit whom the task is assigned to, it pops up a modal which contains a partial with the form once again but to edit the object. Everything works fine and refreshes as it should.
The Problem
On the same line I have a paperclip and a camera that also open up modals that contain forms to upload a document or click camera to upload a picture. These work fine from the page if it's on load but after an ajax refresh the submit buttons will not work.
The Code
Index Partial:
<div class="row">
<div class="col-md-12">
<% if work_order.tasks.any? %>
<ul class="task-table">
<% work_order.tasks.each_with_index do |task, index| %>
<li class="row task-table-row">
<%= bootstrap_form_for(task, remote:true) do |f| %>
<%= render(partial:'tasks/task', locals:{task:task, f:f, index: index}) %>
<% end %>
</li>
<%= render(partial:'work_orders/modal_forms', locals:{task:task, index:index}) %>
<%= render(partial:'tasks/attachments', locals:{task:task, index: index}) %>
<%= render(partial:"tasks/edit", locals:{task:task, index:index})%>
<% end %>
<li class="row">
<div class="table-total">
<div class="col-md-6 col-md-push-6 column">
<div id="total-wrap">
<h3>Est. total: <span id="subTotal"></span></h3>
</div>
</div>
</div>
</li>
</ul>
<% else %>
<li class="row task-table-row">
No tasks currently exist.
</li>
<% end %>
</div>
</div>
<div class="button-margin">
<%= render(partial:'tasks/new', locals:{work_order:work_order})%>
</div>
<div id="placeHolder"></div>
<%= link_to "Mark as Complete", work_order_path(work_order, work_order:{completed: true}), class:"btn btn-block btn-danger btn-outline b-r-xs", method: :put, remote:true %>
Task partial:
<div class="col-md-4 column">
<div class="pull-right column inline">
<p class="assign inline"><small class="text-muted">
<% if task.assignable_id.present? %>
<%= truncate(task.assignable.name, length:7) %>
<% else %>
assign
<% end %>
</small></p>
<a href="#" class="text-muted inline" data-toggle="modal" data-target="#editModal<%= index %>">
<i class="fa fa-pencil"></i>
</a>
</div>
<p class="inline"><%= truncate(task.location, length:20) %></p>
</div>
<% if task.labor.present? && task.materials.present? %>
<!-- if labor or materials are both available -->
<div class="col-md-3 column">
<%= link_to work_order_task_path(task.work_order, task, task:{labor:nil}), method: :put, remote:true, class:" text-muted pull-right" do %><i class="fa fa-pencil"></i><% end%>
<p class="inline pull-right">
<span class="text-success currency"><%= number_to_currency(task.labor) %></span>
</p>
</div>
<div class="col-md-3 column">
<%= link_to work_order_task_path(task.work_order, task, task:{materials:nil}), method: :put, remote:true, class:" text-muted pull-right" do %><i class=" fa fa-pencil"></i><% end%>
<p class="inline pull-right">
<span class="text-success currency"><%= number_to_currency(task.materials) %></span>
</p>
</div>
<div class="col-md-2 column task" data-task="<%= task.id%>">
<a id="deleteTask">
<i class="fa fa-remove text-danger pull-right" > </i>
</a>
<a data-toggle="modal" data-target="#imageModal<%= index %>">
<i class="fa fa-camera text-success pull-right"></i>
</a>
<a class="text-primary" data-toggle="modal" data-target="#attachmentModal<%= index %>">
<i class="fa fa-paperclip pull-right"></i>
</a>
<% if task.task_photos.any? || task.attachments.any? %>
<a class="text-green" data-toggle="modal" data-target="#attachments<%= index %>" tooltip="View Attachments">
<i class="fa fa-eye pull-right" > </i>
</a>
<% end %>
</div>
<% elsif task.labor.blank? && task.materials.present? %>
<!-- Else if labor is blank and materials are present -->
<div class="col-md-3 column">
<%= f.text_field :labor, hide_label:true, prepend: "$", append: ".00", placeholder:"Est. Labor" %>
</div>
<div class="col-md-3 column">
<%= link_to work_order_task_path(task.work_order, task, task:{materials:nil}), method: :put, remote:true, class:" text-muted pull-right" do %><i class=" fa fa-pencil"></i><% end%>
<p class="inline pull-right">
<span class="text-success currency"><%= number_to_currency(task.materials) %></span>
</p>
</div>
<div class="col-md-2 column task" data-task="<%= task.id%>">
<%= f.submit "Save", class:"btn btn-outline btn-success b-r-xs submitTask pull-right" %>
</div>
<% elsif task.materials.blank? && task.labor.present? %>
<!-- Else if materials is blank and labor is present -->
<div class="col-md-3 column">
<%= link_to work_order_task_path(task.work_order, task, task:{labor:nil}), method: :put, remote:true, class:" text-muted pull-right" do %><i class=" fa fa-pencil"></i><% end%>
<p class="inline pull-right">
<span class="text-success currency"><%= number_to_currency(task.labor) %></span>
</p>
</div>
<div class="col-md-3 column">
<%= f.text_field :materials, hide_label:true, prepend: "$", append: ".00", placeholder:"Est. Material" %>
</div>
<div class="col-md-2 column task" data-task="<%= task.id%>">
<%= f.submit "Save", class:"btn btn-outline btn-success b-r-xs submitTask pull-right" %>
</div>
<% else %>
<!-- Else materials and labor are both blank -->
<div class="col-md-3 column">
<%= f.text_field :labor, hide_label:true, prepend: "$", append: ".00", placeholder:"Est. Labor" %>
</div>
<div class="col-md-3 column">
<%= f.text_field :materials, hide_label:true, prepend: "$", append: ".00", placeholder:"Est. Material" %>
</div>
<div class="col-md-2 column task" data-task="<%= task.id%>">
<%= f.submit "Save", class:"btn btn-outline btn-success b-r-xs submitTask pull-right" %>
</div>
<% end %>
The Modals That Wont Submit
<!-- attachments modal -->
<div class="modal inmodal fade" id="attachmentModal<%= index %>" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">Attach Documents</h4>
<small class="font-bold">Upload quotes, sales orders, receipts and invoices.</small>
</div>
<div class="modal-body">
<div class="row">
<%= bootstrap_form_for [task, Attachment.new] do |f| %>
<div class="col-md-4">
<%= f.text_field :name %>
</div>
<div class="col-md-4">
<%= f.text_field :amount, prepend: "$", append: ".00", label:"Total (optional)" %>
</div>
<div class="col-md-4">
<%= f.file_field :file %>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
<%= f.submit "Add Attachment", class:"btn btn-primary btn-outline b-r-xs" %>
<% end %>
</div>
</div>
</div>
</div>
<!-- end attachments modal -->
<!-- images modal -->
<div class="modal inmodal fade" id="imageModal<%= index %>" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">Attach Images</h4>
<small class="font-bold">Upload images and descriptions.</small>
</div>
<div class="modal-body">
<div id="target">
</div>
<%= bootstrap_form_for [task, TaskPhoto.new] do |f| %>
<div class="field">
<%= f.hidden_field :property_manager_id, value:current_manager.id %>
</div>
<div class="field">
<%= f.file_field :photo %>
</div>
<div class="field">
<%= f.text_field :description %>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-white btn-outline b-r-xs" data-dismiss="modal">Close</button>
<%= f.submit "Add Photo", class:"btn btn-primary btn-outline b-r-xs" %>
<% end %>
</div>
</div>
</div>
</div>
<!-- end images modal -->
Turns out that having the submit in my modal footer was causing the error.
Although it works just fine on initial page load, it was causing error when it was refreshed by ajax. Moving the submit button into the modal-body with the rest of my form fixed my problem.
Hope this helps someone in the future!

Resources