1

On an index page, I'd have a form to create a new object. On submitting the form, I'd like to update the page with the new object without the page refreshing. The form submits and the object is created but the page is not updated. The form is hidden which is the desired affect but the new object does not display. The logs show the stack trace as

Started POST "/products" for ::1 at 2015-06-27 18:38:14 +0100
Processing by ProductsController#create as JS
Parameters: {"utf8"=>"✓", "product"=>{"name"=>"Pets"}, "button"=>""}
User Load (1.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1  [["id", 2]]
(0.2ms)  BEGIN
SQL (0.4ms)  INSERT INTO products" ("name", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["name", "Pets"], ["created_at", "2015-06-27 17:38:14.418558"], ["updated_at", "2015-06-27 17:38:14.418558"]]  
(6.1ms)  COMMIT
(0.4ms)  SELECT COUNT(*) FROM "items" WHERE "items"."product_id" = $1    [["product_id", 83]]
Rendered products/_product.haml (1.4ms)
Rendered products/create.js.erb within layouts/admin (2.7ms)
Rendered products/index.haml within layouts/admin (12.8ms)
Rendered layouts/_shim.html.erb (0.1ms)
Rendered layouts/_header.haml (0.6ms)
Rendered layouts/_footer.haml (0.1ms)
Completed 200 OK in 139ms (Views: 134.7ms | ActiveRecord: 2.1ms)

the form is in index.haml

%div{class: "col-md-4 col-md-offset-2 product-list"}
  - @products.each do |product|
    = render 'product', product: product

%div{class: "col-md-4"}
  .btn.btn-success.btn-sm.add-product
  Add a product

.add-product-form
  = form_for @product, remote: true, html: {class: "product disabled"} do |f|

  .product-add
    .form-group
      = f.label :name 
      = f.text_field :name, class: "form-control"
    .form-group
      .controls
        = f.button '+ Add', class: 'btn btn-success save-product'
        .btn.btn-warning.product-cancel
          Cancel

products.js.coffee

$ ->
  $(document).on "click", ".save-product", ->
    $('.add-product-form').hide()

products_controller.rb

def create
  @product = Product.new(product_params)
  if @product.save
    respond_to do |format|
      format.html
      format.js
    end
  end
end

create.js.erb

$(".product-list").append("<%= j render 'product', product: @product} %>");

_product.haml

%h4
  = link_to product_url(product.id) do
    = product.name.capitalize

I'm fairly new to js/coffeescript. How do I get the view to update with the new item, which I can see has been saved?

3
  • At which line the error shows up? Commented Jun 27, 2015 at 16:19
  • line 2 of _product.haml Commented Jun 27, 2015 at 16:27
  • Hard to tell for sure, but I think when you call this line $(".product-list").append("<%= j render 'product', locals: {product: @product} %>"); what your'e doing is passing a Product Class instead of an instance, into the template. Commented Jun 27, 2015 at 18:10

1 Answer 1

1

Your render line in the js is wrong, either write

render 'product', product: @product

Or write

render partial: 'product', locals: { product: @product }
Sign up to request clarification or add additional context in comments.

6 Comments

good spot, I just spotted that too. So now I'm not getting any 500 error or any error at all. But the new product is not being shown.
Alternative method, instead of doing your submit via rails, submit via an AJAX request from the page, and then on the rails side do render :json => { results => (render_to_string partial: "product", locals: {product: @product}) } and have your JavaScript interpret append that response to the page. Perhaps a personal preference, but makes tracking bits much easier.
Margo: from the code you show everything seems ok. Things to look for: 1) the jquery selector does not return anything (but it seems ok), 2) there is an error in the javascript code. The easy way to test this: open the console in the browser, open the network tab, do the ajax, click the request, copy the response and run the response in the javascript console: then you will see the error. Good luck!
@Kirill: which means rendering views in the js side, which is a completely different approach, and not an easy switch. Imho a simple case like this is still easier like Margo is handling it now.
thx @nathanvda, the response is $('.category-list').append("<h4>\n <a href=\"localhost:3000/categories/118\">Cats\n <span class=\'category_count\'>\n (0)\n <\/span>\n <\/a>\n<\/h4>\n") which throws a syntax error, unterminated string literal, which I don't know how to fix
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.