将带有表单数据的GeoJSON数据发布到Rails 4 app

时间:2015-09-06 01:37:11

标签: javascript ruby-on-rails ajax post geojson

我有一个创建“活动”的网页。使用简单形式,用户填写有关活动的一些基本信息:

#new.html.erb
<%= simple_form_for @activity do |f| %>
    <%= f.input :name, label: "Activity name", input_html: { id: "create_activity_name_field" }, hint: "At least 7 characters" %>
    <%= f.input :type, label: "Activity type", input_html: { id: "create_activity_type_field" }, as: :select, :include_blank => false, collection: Activity.types.keys.to_a %>
    <%= f.input :date_field, input_html: { id: "create_activity_date_field" }, as: :string %>
    <%= f.input :time_field, input_html: { id: "create_activity_time_field" }, as: :string %>
    <% f.button :submit, :class => "btn btn-primary" -%>
<% end %>

但是,我也在使用MapBox来显示地图。用户将单击地图上的点以为活动创建路线。当用户完成绘制路线后,我可以为此路线提取GeoJSON数据。

我想用javascript用表单数据发布GeoJSON数据。在后端,我将有轨道将GeoJSON转换为KML文件,并使用Paperclip将其上传到Amazon S3。其余数据可以保存,Paperclip会给我一个KML文件的URL,我可以将其与活动相关联。

我是一个Rails noob,我无法弄清楚如何做到这一点,也无法找到任何让我超越这个障碍的东西。我考虑过使用javascript的FormData。我非常喜欢这种方法,因为实现看起来很简单,但显然它只能真正处理键/值对,而不是复杂的嵌套JSON数据。

任何建议或策略都非常感谢。非常感谢++,如果有人可以提供详细的答案,因为,就像我说的那样,我已经有几个星期的时间对轨道和网络开发感兴趣了。

2 个答案:

答案 0 :(得分:1)

您可能想要做的是在JS中阻止表单的默认行为:

$('form').submit(function(e) { 
 e.preventDefault();
 var form = $('form');
 var form_data_json = JSON.stringify(form.serializeArray());
 form_plus_geojson = form_data_json.concat(Geojson);

在JS中抓取你的数据(这应该很容易,但你真的不知道如何从mapbox中提取数据)。

然后通过AJAX发回数据(不要忘记两端的验证)

if (my_data_is_not_good/empty/whatever) { 
    console.log('nop')
 } else {
         $.ajax({ 
         type: 'post',
         url: Yourcontrollerpostaction, 
         data: form_plus_geojson,
         dataType: "JSON",

数据发送完毕后,您希望恢复正常表单提交后的行为并提交表单。

         complete: function() { 
            this.off('submit');
            this.submit();
         }
     });
 }

});

然后您只需解析控制器中的数据。

def post_controller
  if request.xhr?
    my_hash = JSON.parse(params[:mydata]) 
  else 
    normal post behavior 
  end
end

所有内容都是快速伪代码,你可能需要修复一些东西,因为我没有测试它但它应该可以工作。 显然现在我们在ajax中做了所有事情,你不需要回调complet函数,可以删除那部分。

答案 1 :(得分:1)

感谢@jDay指出我正确的方向 - 特别是连接JSON数据。但是,我无法使用他的特定解决方案来处理我的应用程序,我尝试了另一种方法,在我看来,这种方法更直接。

我使用Rails simple_form_for gem制作表单,指定远程帖子调用:

#new.html.erb
<%= simple_form_for @activity, :url => '/activities', :method => :post, :remote => true, html: {id: :activity_create_form, "data-type" => :json} do |f| %>
    <%= f.input :name, label: "Activity name", input_html: { id: "create_activity_name_field" }, hint: "At least 7 characters" %>
    <%= f.input :type, label: "Activity type", input_html: { id: "create_activity_type_field" }, as: :select, :include_blank => false, collection: Activity.types.keys.to_a %>
    <%= f.input :date_field, input_html: { id: "create_activity_date_field" }, as: :string %>
    <%= f.input :time_field, input_html: { id: "create_activity_time_field" }, as: :string %>
    <%= f.button :submit, :class => "btn btn-primary", input_html: {id: "create_activity_submit_btn"} -%>
<% end %>

然后我使用jQuery来劫持表单提交按钮并附加一个带有GeoJSON数据的不可见表单元素。但是,数据必须按字母顺序排列,以便发送:

#activity_new.js
$("form").submit( function (e) {
        e.preventDefault();

        $('<input />')
                    .attr('type', 'hidden')
                    .attr('name', 'routeGeoJson')
                    .attr('value', JSON.stringify(polyline.toGeoJSON()))
                    .appendTo(this);
        return true;
});

(这里,&#34;折线&#34;是我以前在地图上绘制的Leaflet L.polyline对象。)

在控制器中,你会得到这样的参数:

  

{&#34; utf8&#34; =&gt;&#34;✓&#34;,&#34;活动&#34; =&gt; {&#34;名称&#34; =&gt;&# 34;在树林里短途旅行&#34;,&#34;键入&#34; =&gt;&#34;步行&#34;,   &#34; date_field&#34; =&gt;&#34; 2015-09-08&#34;,&#34; time_field&#34; =&gt;&#34; 07:00&#34;},   &#34; routeGeoJson&#34; =&GT;&#34; {\&#34;类型\&#34;:\&#34;特征\&#34; \&#34;特性\&#34 ;:{},\&#34;几何\&#34;:{\&#34;类型\&#34;:\&#34;线段形式\&#34; \&#34;坐标\& #34;:[[ - 118.38855654001236,33.95361274499209],[ - 118.36624056100845,33.97681937760982]]}}&#34 ;,   &#34;提交&#34; =&gt;&#34;创建活动&#34;,&#34;控制器&#34; =&gt;&#34;活动&#34;,   &#34;动作&#34; = GT;&#34;创建&#34;}

自&#34; routeGeoJson&#34;数据仍然是字符串形式,我通过使用JSON gem解析它来重新组装GeoJSON数据(我认为默认包含在Rails 4中):

def create
   geojson = JSON.parse(params[:routeGeoJson])
   # do something...
end

你得到你的GeoJSON哈希:

  

{&#34;输入&#34; =&gt;&#34;功能&#34;,&#34;属性&#34; =&gt; {},   &#34;几何&#34; = GT; {&#34;类型&#34; = GT;&#34;线段形式&#34 ;,   &#34; coordinates&#34; =&gt; [[ - 118.42014223337173,33.98407904797006],   [-118.37825685739517,33.956175751601826]]}}