Closed christophermanning closed 13 years ago
This sounds good. But when the value is updated, you get to see the default-value again. Is it enough to only change the first text? Could you please explain the use-case? Is it to change the initial (empty) text?
My use case was for when I needed to parse and display markdown. Now I think I will just use showdown js to render that.
It could still be useful to add this to provide the end user the flexibility to display whatever initial text they want.
I'm trying to work with markdown, I'd rather use RedCarpet than a javascript callback, so far I have this:
budgets/show.html.haml
= on_the_spot_edit @budget, :description, type: 'textarea', display_text: markdown(@budget.description), loadurl: description_budget_path(@budget)
routes.rb
resources :budgets do
collection do
put :update_attribute_on_the_spot
end
member do
get 'description'
...
_budgetscontroller.rb
def description
@budget = Budget.find(params[:id])
render :text => @budget.description
end
_applicationhelper.rb
def markdown(text)
Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(hard_wrap: true),
autolink: true, lax_html_blocks: true, autolink: true, ).render(text).html_safe if text
end
Everything works as expected, the page loads with the markdown parsed into HTML. When edited, the user sees the raw markdown code but the problem is when it is then saved, the page then shows the raw markdown instead of the HTML. In JEditable the save action could then return the rendered markdown
"However save.php should return rendered html" - http://www.appelsiini.net/projects/jeditable
but as far as I can tell update_attribute_on_the_spot
returns the raw markdown (forgive me if I'm wrong). Is there a simple way to change this behaviour so that it can return anything, in this case the edited text via the markdown helper method?
Hi, definitely this is possible. I will provide some example code later today.
I have done that for a small side-project of mine (though I switched to using pagedown later).
In my view I had the following:
on_the_spot_edit note, :content, :type => :autogrow, :onblur => 'submit',
:url => {:controller => :notes, :action => :update },
:loadurl => note_content_url,
:display_text => display_note_content(note))
Let me explain this a bit: I specify a :loadurl
as you had and the :displaytext
, but also overwrite the :url
that will be used to save the data (and will return the new data in return).
In my helper I had:
def display_note_content(note)
note.content.blank? ? '' : BlueCloth.new(note.content).to_html.html_safe
end
In my controller my update
looked like:
def update
klass, field, id = params[:id].split('__')
@note = current_user.notes.find(id)
if @note.update_attributes(field => params[:value])
render :text => BlueCloth.new(@note.send(field)).to_html.html_safe, :status => 200
else
render :text => @note.errors.full_messages.join("\n"), :status => 422
end
end
Hope this helps.
Thanks Nathan! I've managed to implement something very similar now.
I might try and work on a feature so that models have a method like ots_FIELDNAME
which will return the value of FIELDNAME
formatted however you like. e.g.
def ots_description
BlueCloth.new(description).to_html.html_safe
end
Then the default update_attribute_on_the_spot
method can first check if the ots_FIELDNAME
property exists and return that, otherwise it'd return the raw FIELDNAME
property as it does currently.
This would remove the requirement for the extra controller methods. What do you think?
Something like this perhaps?
_lib/on_the_spot/controllerextension.rb
parsed_data = JSON.parse(select_data.gsub("'", '"'))
return_value = object.respond_to?("ots_#{field}") ? "ots_#{field}" : field
render :text => parsed_data[object.send(return_value).to_s]
Yeah, this sounds very reasonable. I would rather have the look-up method or attribute to be configurable. But a very good suggestion. I will try to implement something like that later today.
Indeed, it think it would be very good/easy to not have to implement the method yourself, because it is almost identical.
So I am thinking more along the lines of the following:
on_the_spot_edit note, :content, :type => :autogrow, :onblur => 'submit',
:loadurl => note_content_url,
:display_method => :display_content
And this will make sure it will always call the method display_content
for that instance.
So you do not have to specify the url
and the display_method
is also called when doing the first rendering.
What do you think?
Thank you!
That looks great. Actually, I just looked over best_in_place's documentation and it has a :display_as
property that behaves similarly to what you have just suggested. If something like the above could be implemented that would be brilliant. Thanks!
I just released a new version.
In your routes you will have to specify an extra option:
resources :posts do
collection do
put :update_attribute_on_the_spot
get :get_attribute_on_the_spot
end
end
and then you can just do something like
on_the_spot_edit @post, :some_field, :type => :textarea, :display_method => :some_formatted_method
Hope this helps!
This gem is now perfect for me.
Thanks so much.
:D :D :D
Right now there is now way to specify custom display text for a textarea.
Changing http://github.com/nathanvda/on_the_spot/blob/master/lib/on_the_spot/on_the_spot_helpers.rb#L28 to:
This would allow custom display text