Comments (17)
The README file is outdated, I have to fix that. Forms used to have methods to render all the form fields in one call, but thats not supported anymore. The preferred way of doing it now is to just use some templating system (ERB, HAML, or anything) and iterate over the fields.
For example:
<% form.each do |field| %>
<tr><td><%= field.label_tag %></td><td><%= field %></td></tr>
<% end %>
from bureaucrat.
Gotya - I agree with the deprecation. Makes more sense to have people define their own templates.
I do wish there was a way to access the fields individually however. On many forms the flow of the fields are interrupted by other types of random dom elements. Sometimes fields are grouped together differently. More flexibility is needed
I suppose in an ideal world I would be able to do this
<% form = MyForm.new %>
<tr><td><%= form[:title].label_tag %></td><td><%= form[:title] %></td></tr>
</div>
from bureaucrat.
That works, and is how I render fields 99% of the time. Sorry, I know the documentation is really lacking, but the documentation for Django forms is a good place to start, most of the stuff there applies to Bureaucrat too.
There are some docs here too: http://rubydoc.info/github/tizoc/bureaucrat/frames
from bureaucrat.
Ok, rubydoc.info is a bit broken right now, it doesn't show the documentation for the Form class, but in Form you have this:
# Iterates over the fields
def each
@fields.each do |name, field|
yield BoundField.new(self, field, name)
end
end
# Access a named field
def [](name)
field = @fields[name] or return nil
BoundField.new(self, field, name)
end
from bureaucrat.
There we go!
% form = SiteForm.new
{{ form[:domain_name].label_tag }}
{{ form[:domain_name].to_s }}
This is really beautiful man. I've also enjoyed picking at your code as it's a lovely example of pure, compositional OO
The last question I have is how to deal with existing models. Right now I am playing with the Cuba framework so my new route looks like this:
on "new" do
res.write view("sites/new", title: "New Site", site: Site.new, form: SiteForm.new)
end
What is the recommended way to set this up with an edit action? SiteForm.new(site.put_atts_here)
Overall I am curious to see how you integrate this with a working, RESTful app. Perhaps in addition to cleaning up the docs a sample app would be a welcome addition. I can sort out the docs myself if you like and shoot you a pull request. Let me know
In the meantime I'm closing this issue as its been resolved. Thanks for the prompt replies! :)
from bureaucrat.
Oh one more thing - the widgets are outputting flat name attributes:
<input type="text" name="title" id="id_realname" />
Is there a convention for namespacing the attributes? I'm looking for name="post[title]"
No biggie if there isn't I can hack something up myself. Just trying not to reinvent the wheel here
from bureaucrat.
Untested example (based on actual code I wrote for an application):
class Base < Bureaucrat::Forms::Form
extend Bureaucrat::Quickfields
attr_accessor :edited_object # So that we can access it
# This method calculates the hash of "initial" values for the form
# it is useful for forms that "edit" an already existing object.
def self.initial(object)
o = Bureaucrat::Utils::StringAccessHash.new
base_fields.keys.inject(o) do |h, field|
if object.respond_to?(field)
value = object.send(field)
value = value.to_s if value.is_a?(Numeric)
h[field] = value
end
h
end
end
# This method will be used instead of new when we want to "edit"
# an already existing object. e.g. Forms::User.new_for(Models::User)
def self.new_for(object, options={})
options[:initial] = initial(object)
new(nil, options).tap do |f|
f.edited_object = object
f.initialize_formsets(nil)
end
end
# Alternatively, you can override initialize so that it accepts
# an :object option
def initialize(data = nil, options = {})
if self.edited_object = options.fetch(:object, nil)
options = {
initial: self.class.initial(self.edited_object)
}.merge(options)
end
super(data, options)
end
# On POST routes, we will use this to save changes to the object:
# if form.valid?
# user = form.save(user)
# redirect
# else
# .. handle error
# end
#
# or for new records
#
# user = form.save(User.new)
#
def save(record)
DB.transaction do # this example assumes Sequel
populate_object(record) # See Form#populate_object and Field#populate_object
record.save
end
record
end
end
As for namespacing, there is no convention, and right now Bureaucrat doesn't take advantage of how Rack interprets nested attributes (I don't think it is likely to happen, at least not by default).
from bureaucrat.
Btw, forms support a "prefix" option, thats something you can use to differentiate fields that belong to one form or another (thats the intended use).
from bureaucrat.
Sorry, one correction:
Forms::User.new_for(Models::User)
should have been
Forms::User.new_for(Models::User[params[:id]])
What new_for expects is an instance.
from bureaucrat.
Thanks a bunch, the example is very helpful. I can see myself taking a lot of that above code and factoring into a module for re-use.
I will definitely be kicking the tires a bit more on this as its a lot more robust than I originally thought. If I run into any gotchas I will post em here. Hopefully my questions will help drive your reboot of documentation :)
BTW you really could use a proper promotional page for this once the docs are somewhat sorted. If you need a hand I got some design skillz. You can see my handiwork on the Slim site http://www.slim-lang.com, Merb http://www.merbivore.com (holy crap they really butchered my design :)) I can help you with logos/icons / layout if you need it
Cheers
from bureaucrat.
Awesome, the slim site in particular looks great.
And yes, I would say Bureaucrat is pretty robust by now, I have been using it in every project as a very-core component. I don't use 100% of the implemented features, but for the stuff I use, it is pretty well battle-tested.
Regarding promotion, I don't promote it because it lacks documentation. It lacks documentation because there are some things I want to change (so I don't want to document things that I will not support in the future), and a few missing components. Then I haven't done those things because I'm lazy, and also spent time on other stuff, oh well. With Fiasco it is the opposite, I focused on documenting things first, made a homepage, etc, but then I decided I wanted to change things and never got to finishing it. I have been slowly leaving Ruby behind for doing work, so, that also affects my motivation.
from bureaucrat.
Leaving Ruby?? Blasphemy!
Don't tell me the community has lost yet another decent programmer to nodejs :p
from bureaucrat.
Btw, you may also be interested in Scrivener: http://github.com/soveran/scrivener
It was made by a coworker (the same guy behind cuba, ohm, etc) and is a more lightweight version of the concept behind Bureaucrat (but it focuses only on validation, anything related to HTML is left out).
from bureaucrat.
No, no nodejs here. For web stuff I have always been a Python guy. The only reason I do Ruby is that it is the main language being used at my Job. And well, Ruby isn't bad, just not my tool of choice.
from bureaucrat.
I like Python - a lot actually. It's the closest thing to Ruby I have worked with.
I dig Ruby because it's so flexible. The features I like from other languages (like Python decorators) are actually pretty easy to implement. for example http://yehudakatz.com/2009/07/11/python-decorators-in-ruby/
Thanks a lot for the scrivener link. Looks nice and lightweight. Since you plan on migrating I may just dig up the guts of this gem and put together a stripped down version for html rendering
from bureaucrat.
I really don't like Yehuda's implementation of decorators (both in terms of implementation, interface, performance, etc they are also global).
Ruby is flexible, but I think a lot of its flexibility is wrong-headed, thats why I try to write Ruby code in the most plain way possible. Anyway, it just came to me that this is a github issue and not my inbox, so, not the place for rants :)
re: migrating, thats not what is happening, I don't belong to tribes! I just learn and use tools to do my work.
from bureaucrat.
Not the place for rants? Have you seen this? :p
That's about all the geekery I'm good for today. Time to enjoy the weekend.
from bureaucrat.
Related Issues (1)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bureaucrat.