brobert
brobert

Reputation: 43

Save content of a <div contenteditable="true"> to my db through a form in Rails

I'm trying to make the contents of a <div contenteditable="true"> saved to the db in my Rails app through a form, so it can be saved and updated by the user.

Here is the setup:

The user gets a view (i.e /posts/1) that includes a <div> with contenteditable= "true". I added the javacript to give me a 'Save' button and a hidden field that will capture the content of the div for saving, as suggested in Can div with contenteditable=true be passed through form?. Then changed it to follow the suggestions in this same question.

<%= form_for @post do |form| %>                                                    
        <%= form.hidden_field :content %>
        <%= form.submit "Save" %>
    <% end %>
<div id="content" contenteditable="true">
    <p>Hello</p>
</div>
<script>
        document.getElementById('content').addEventListener('input', function(ev){
  document.getElementById('post_content').value = ev.target.innerHTML;
})
</script>

The behavior I'm looking for is for this form to, once I press 'Save', save all the contents of <div id="content"> to @post.content

I've added :content to my post_params in posts_controller.rb

def post_params
      params.require(:post).permit(:user_id, :content)
end

But it doesn't work. @post.content stays as nil as ever.

Server logs shows that the param :content is being sent, but empty!

Started PATCH "/posts/3" for ::1 at 2019-10-01 19:36:24 +0200
Processing by PostsController#update as HTML
  Parameters: {"authenticity_token"=>"SRzcfcrBWOCdaWeJkp6rCRw94Ex2XLuVvnc3Bt1dFP1JFz36NCNTcxcuOVqzymlIGq9sveaE/+OkDnaHv3kJNQ==", "post"=>{"content"=>""}, "commit"=>"Save", "id"=>"3"}

Any guesses of what am I doing wrong? Thanks in advance

Upvotes: 0

Views: 1235

Answers (2)

arieljuod
arieljuod

Reputation: 15838

You are setting the value the wrong way. You want to set the "post_content" value to the "content" innerHTML.

document.getElemenetById('post_content') = document.getElementById('content').innerHTML;

Also, you should use a hidden input instead of a textarea with display:none.

And lastly, make sure the function is being triggered. I don't think the "onsubmit" callback is properly fireing since form_with intercepts the form submission and does an ajax request.

Personally I'd listen to the input event on the contenteditable element so you don't depend on the form submission:

document.getElementById('content').addEventListener('input', function(ev){
  document.getElementById('post_content').value = ev.target.innerHTML;
})

Now everytime you change the contenteditable content you get the input updated instantly.

Upvotes: 1

Jay Kariesch
Jay Kariesch

Reputation: 1482

It looks like your form is refreshing the page before your submit handler is fired. You'll want to prevent this default behavior from happening, which you can do with the onsubmit event, like this:

    function getContent(event){
        event.preventDefault()
        document.getElementById("content").value = document.getElementById("post_content").innerHTML;
    }

Upvotes: 0

Related Questions