我正在寻找一些有关如何使用 JQuery 在 Rails 3 应用程序中实现 类似 Wufoo 的构建器 的指导在客户端。基本上允许用户在“离线”模式下构建某些内容(Wufoo 中的表单),然后通过单击“保存”按钮或类似按钮将所有用户编辑批量保存到服务器(例如,可以是由每 30 秒左右浏览一次)。
目前我倾向于使用 HTML5 本地存储。 “构建器”本质上将以 JSON 格式将用户编辑本地存储在浏览器本地存储中。单击“保存”按钮会将本地存储的内容通过 HTTP 发布到 Rails 应用程序,同样以 JSON 格式。这听起来正确吗?有什么意见、建议吗?
一些额外的注意事项/问题:
- 不支持 HTML5 的旧版浏览器怎么办?是否应该有一个使用 cookie 存储的后备计划?
- 有什么 JQuery 插件可以帮助解决这个问题吗?例如,将 HTML5 本地存储抽象为主要存储,将 cookie 存储抽象为辅助/后备存储。
- 有哪些特定于 Rails 需要注意的注意事项?
注意:以下问题专门针对所见即所得表单生成器,并没有真正提供任何好的解决方案。
在 Rails 中创建 WYSIWYG 表单构建器(á la Wufoo)
谢谢!
I'm looking for some guidance on how to implement a Wufoo-like builder in a Rails 3 application with JQuery on the client side. Basically allow a user to build something (a form in the case of Wufoo) in "offline" mode then save all user edits to the server in one batch by clicking a Save button or similar (e.g. could be an auto-save triggered by the browser every 30s or so).
I'm leaning towards using the HTML5 local storage at this point. The "builder" would essentially store user edits locally in the browser local storage in JSON format. A click on the Save button would then HTTP Post the content of the local storage to the Rails app, again in JSON format. Does this sound about right? Any advice, suggestions?
Some additional considerations/questions:
- What about older browsers that do not support HTML5? Should there be a fallback plan that uses cookie storage?
- Any JQuery plugin that can help with some of this? e.g. abstract HTML5 local storage as primary storage and cookie storage as secondary/fallback storage.
- Any Rails-specific considerations to be aware of?
Note: The following question addresses WYSIWYG form builder specifically and doesn't really provide any good solution.
Creating WYSIWYG form builder (á la Wufoo) in Rails
Thanks!
发布评论
评论(2)
我在工作中对此进行了一些尝试,我认为它可以让您在知道如何序列化和反序列化自身的 jquery 表单构建器上取得领先。我认为它将表单序列化为字符串而不是 JSON,但这是一个开始。 http://www.botsko.net/blog/ 2009/04/07/jquery-form-builder-plugin/
谷歌搜索找到了我sites.google.com/site/daveschindler/jquery-html5-storage-plugin,它说它将东西存储在HTML 5存储中如果浏览器不支持,则使用 cookie。
另一个想法:如果使用本地存储的目标是让用户不丢失他们还不想发布的工作,另一个选择可能是实现单独的“保存”和“发布”按钮,这样您仍然可以保存用户的工作服务器端,但让他们保留“草稿”直到他们准备好发布为止,这样他们使用哪种浏览器或PC就无关紧要了。
希望这有帮助。
I have been playing around with this a bit at work and I think it could give you a head start on a jquery form builder that knows how to serialize and deserialize itself. I think it serializes the form to a string rather than JSON, but it's a start. http://www.botsko.net/blog/2009/04/07/jquery-form-builder-plugin/
A google search found me sites.google.com/site/daveschindler/jquery-html5-storage-plugin which says that it stores things in HTML 5 storage with a fallback to cookies if the browser does not support it.
Another thought: If the goal in using local storage is for users not to lose work that they don't yet want to publish, another option could be to implement seperate "save" and "publish" buttons so you still save the user's work on the server side but let them retain "drafts" till they're ready to publish, and this way it wouldn't matter which browser or PC they use.
Hope this helps.
这是我最终实现的设计。我距离完整的解决方案还很远,但我认为这是一个好的开始。
数据模型
在我的例子中,用户需要能够构建一个任务列表,其中任务可以具有不同的类型和属性。任务还可以嵌入其他对象。在某种意义上类似于表单生成器,尽管我正在处理更深层次的嵌套对象。这里的关键是确保您的后端应用程序仅公开属于您的应用程序域的对象(在 域驱动设计),这样您的客户端代码就不会在从服务器调用反序列化数据之后以及在准备保存之前序列化数据之前花费时间重构数据。在某种程度上,我必须对服务器端表示层进行一些更改,但结果我认为我的客户端代码更干净,更专注于处理实际的用户事件。
数据序列化
我选择 JSON 作为数据交换格式。在客户端,我有两个处理数据序列化和反序列化的函数。实现非常简单(部分归功于我为公开域模型对象所做的一些更改)。我在下面粘贴了一个简化版本。唯一的挑战是 Rails 用于处理 PUT 请求的 _method 参数似乎不适用于 JSON Content-Type。请参阅 使用 HTTP PUT 通过 Jquery 发送 JSON 和Rails 3
在服务器端,Rails 也可以轻松处理 JSON(JSON 的序列化和反序列化由框架自动且透明地执行)。我只是重写了 TodoList 模型上的 to_json() 方法,以避免来回传递无用的数据(例如 create_at、modified_at 属性)。还必须确保在获取顶级对象(即 TodoList)时包含所有嵌套对象。
客户端持久性
这里的目标是避免意外丢失尚未保存的用户编辑。到目前为止,我直接使用 HTML5 本地存储(localStorage 变量),但最终会寻找一个 jQuery 插件,如果不支持 HTML5,它会自动处理回退到 cookie 存储。
动态 HTML 生成
我依靠 jQuery 模板 来生成HTML。构建器的主要功能是动态生成 HTML,因此这个插件非常方便。我已经为待办事项列表模型的所有构建块定义了模板(例如任务、注释……)。每当创建这些对象的新实例并需要呈现时,就会调用模板。
我认为这奠定了大部分基础。其余部分主要是核心 Javascript,用于处理与表单/todoList 构建器的所有用户交互。
Here's the design I ended up implementing. I'm far from having a complete solution but I think it's a good start.
Data Model
In my case users need to be able to build a list of tasks where tasks can have different types and therefore attributes. Tasks can also embed additional objects. Similar to a form builder in a sense although I'm dealing with a deeper hierarchy of nested objects. The key here is to make sure that your back-end application only exposes objects that pertain to your application domain (in the sense of Domain Driven Design) so that your client-side code doesn't spend time refactoring data after deserializing it from a server call and before serializing it in preparation for a Save. To that extent I had to make a few changes to my server-side presentation layer but as a result I think my client-side code is cleaner and more focused on processing actual user events.
Data Serialization
I chose JSON as the data-interchange format. On the client-side I have two functions that handle the data serialization and deserialization. The implementation is pretty straight forward (in part thanks to some of the changes I made to expose domain model objects). I pasted a simplified version below. Only challenge was that the _method parameter used by Rails to handle PUT requests does not seem to work with a JSON Content-Type. See Using HTTP PUT to send JSON with Jquery and Rails 3
On the server-side, Rails makes it easy to handle JSON too (serialization and deserialization of JSON is performed automatically and transparently by the framework). I just overrode the to_json() method on my TodoList model to avoid passing back and forth useless data (e.g. create_at, modified_at attributes). Also had to make sure to include all nested objects when fetching my top-level object (i.e. TodoList).
Client-side persistence
The goal here is to avoid accidentally losing user edits that haven't been saved. So far I'm directly using the HTML5 local storage (localStorage variable) but ultimately will be looking for a jQuery plugin that automatically handles falling back on cookie storage if HTML5 is not supported.
Dynamic HTML Generation
I'm relying on jQuery Template to generate HTML. The primary function of the builder is to dynamically generate HTML so this plugin comes in very handy. I've defined templates for all building blocks of my todo list model (e.g. tasks, notes, ...). The templates are invoked whenever new instances of these objects are created and need to be rendered.
I think this lays out most of the foundation. The rest is mostly hardcore Javascript to handle all user interactions with the form/todoList builder.