我正在使用Jquery Steps插件为User创建一个向导来创建一个对象。起初,它没有保存到数据库中,我被告知我必须使用AJAX将数据从JavaScript保存到Rails数据库。在与对等方交谈之后,我们认为这可能是一个真实性令牌问题,但已经解决了,它仍然无法在数据库中保存和创建对象。
TLDR Jquery Steps Wizard Form不会使用AJAX保存到DB中。
建筑形式视图
<%= form_for(building, html: {id: 'form', class: 'wizard-big'}, remote: true, :authentictiy_token => true) do |f| %>
<% if building.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(building.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% building.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<h1>Location Information</h1>
<fieldset>
...
</fieldset>
<h1>General Information</h1>
<fieldset>
<h2>General Information</h2>
...
</fieldset>
<h1>Remarks</h1>
<fieldset>
<h2>Remarks</h2>
...
</fieldset>
<h1>Additional Information</h1>
<fieldset>
<h2>Additional Information</h2>
<%= f.collection_check_boxes :pet_restriction_ids, PetRestriction.all, :id, :options do |b| %>
<%= b.label do %>
<%= b.check_box %>
<%= b.object.options %>
<% end %>
<% end %>
</div>
...
</fieldset>
<h1>Rental Information</h1>
<fieldset>
<h2>Rental Information</h2>
...
</fieldset>
<h1>Office Information</h1>
<fieldset>
<h2>Office Information</h2>
...
</fieldset>
<% end %>
building.js
//= require iCheck/icheck.min.js
//= require steps/jquery.steps.min.js
//= require validate/jquery.validate.min.js
//= require dropzone/dropzone.js
//= require summernote/summernote.min.js
//= require colorpicker/bootstrap-colorpicker.min.js
//= require cropper/cropper.min.js
//= require datapicker/bootstrap-datepicker.js
//= require ionRangeSlider/ion.rangeSlider.min.js
//= require jasny/jasny-bootstrap.min.js
//= require jsKnob/jquery.knob.js
//= require nouslider/jquery.nouislider.min.js
//= require switchery/switchery.js
//= require chosen/chosen.jquery.js
//= require fullcalendar/moment.min.js
//= require clockpicker/clockpicker.js
//= require daterangepicker/daterangepicker.js
//= require select2/select2.full.min.js
//= require touchspin/jquery.bootstrap-touchspin.min.js
//= require bootstrap-markdown/bootstrap-markdown.js
//= require bootstrap-markdown/markdown.js
//= require bootstrap-tagsinput/bootstrap-tagsinput.js
//= require dualListbox/jquery.bootstrap-duallistbox.js
//= require typehead/bootstrap3-typeahead.min.js
//= require codemirror/codemirror.js
//= require codemirror/mode/javascript/javascript.js
// datepicker formating for Ruby
$('.datepicker').datepicker(
{format: 'yy-mm-dd'}
);
// wizard initialization
$(function(){
$("#wizard").steps();
$("#form").steps({
bodyTag: "fieldset",
onStepChanging: function (event, currentIndex, newIndex) {
// Always allow going backward even if the current step contains invalid fields!
if (currentIndex > newIndex) {
return true;
}
// Forbid suppressing "Warning" step if the user is to young
if (newIndex === 3 && Number($("#age").val()) < 18) {
return false;
}
var form = $(this);
// Clean up if user went backward before
if (currentIndex < newIndex) {
// To remove error styles
$(".body:eq(" + newIndex + ") label.error", form).remove();
$(".body:eq(" + newIndex + ") .error", form).removeClass("error");
}
// Disable validation on fields that are disabled or hidden.
form.validate().settings.ignore = ":disabled,:hidden";
// Start validation; Prevent going forward if false
return form.valid();
},
onStepChanged: function (event, currentIndex, priorIndex) {
// Suppress (skip) "Warning" step if the user is old enough.
if (currentIndex === 2 && Number($("#age").val()) >= 18) {
$(this).steps("next");
}
// Suppress (skip) "Warning" step if the user is old enough and wants to the previous step.
if (currentIndex === 2 && priorIndex === 3) {
$(this).steps("previous");
}
},
onFinishing: function (event, currentIndex) {
var form = $(this);
// Disable validation on fields that are disabled.
// At this point it's recommended to do an overall check (mean ignoring only disabled fields)
form.validate().settings.ignore = ":disabled";
// Start validation; Prevent form submission if false
return form.valid();
},
onFinished: function (event, currentIndex) {
var form = $(this);
// Submit form input
form.submit();
}
}).validate({
errorPlacement: function (error, element) {
element.before(error);
},
rules: {
confirm: {
equalTo: "#password"
}
}
});
});
AJAX
// Ajax call to submit data to DB
$("#finish").click(function() {
var submitData;
submitData = $.ajax({
type: "POST",
url: "buildings/new",
data: $([
'building_id',
'unit_no',
'floor_plan',
'num_fbaths',
'num_hbaths',
'advertising',
'move_in_special',
'commission',
'created_at',
'rent_price',
'rent_per_period',
'for_sale',
'beds',
'fbaths',
'hbaths',
'unit_floor_location',
'type_of_property',
'style',
'sqft',
'balcony',
'liv_area',
'efficiency',
'faces',
'additional_parking_info',
'furnished_information',
'available_date',
'view',
'floor',
'dinning',
'listing_type',
'list_date',
'expiration_date',
'convert_bed'
].join(', ')).serialize(),
success:
dataType:
})
post(url, function(data, textStatus, submitData) {
return console.log('i guess it worked');
});
return submitData.fail(function() {
return console.log(submitData.responseText);
});
});
建筑控制器
class BuildingsController < ApplicationController
before_action :set_building, only: [:show, :edit, :update, :destroy]
# GET /buildings
# GET /buildings.json
def index
@buildings = Building.where(user_id: current_user)
end
# GET /buildings/1
# GET /buildings/1.json
def show
end
# GET /buildings/new
def new
@building = Building.new
end
# GET /buildings/1/edit
def edit
end
# POST /buildings
# POST /buildings.json
def create
@building = Building.new(building_params)
respond_to do |format|
if @building.save
session[:building_id] = @building.id
redirect_to listing_wizards_path
format.html { redirect_to @building, notice: 'Building was successfully created.' }
format.json { render :show, status: :created, location: @building }
else
format.html { render :new }
format.json { render json: @building.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /buildings/1
# PATCH/PUT /buildings/1.json
def update
respond_to do |format|
if @building.update(building_params)
format.html { redirect_to @building, notice: 'Building was successfully updated.' }
format.json { render :show, status: :ok, location: @building }
else
format.html { render :edit }
format.json { render json: @building.errors, status: :unprocessable_entity }
end
end
end
# DELETE /buildings/1
# DELETE /buildings/1.json
def destroy
@building.destroy
respond_to do |format|
format.html { redirect_to buildings_url, notice: 'Building was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_building
@building = Building.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def building_params
params.require(:building).permit(:list_type, :county, :area, :city, :folio, :street, :compass_point, :street_name, :state, :zip, :zip4, :unit, :legal, :zoning, :geographical, :municip_code, :township, :section, :subdivision, :parcel, :map_coordinates, :elementary_school, :middle_school, :senior_high_school, :subdivision_name, :development_name, :model_name_in_mls, :user_id, additional_room_ids: [], amenity_ids: [], approval_ids: [], construction_ids: [], cooling_description_ids: [], design_ids: [], dining_area_ids: [], equipment_ids: [], exterior_feature_ids: [], floor_ids: [], heat_ids: [], interior_feature_ids: [], leasing_term_ids: [], lot_description_ids: [], misc_ids: [], parking_restriction_ids: [], pet_restriction_ids: [], pool_description_ids: [], rental_dep_incl_ids: [], rental_pay_inc_ids: [], rental_restriction_ids: [], security_ids: [], showing_instruction_ids: [], water_access_ids: [], waterfront_desc_ids: [], window_treatment_ids: [])
end
end