html5 data attributes

18 views
Skip to first unread message

nathan

unread,
Feb 25, 2012, 9:27:19 AM2/25/12
to Pakyow
At the risk of venturing into the earlier view discussion, I have a
couple of questions about populating a data attributes.

I have a "main" view

<div class='small_index_card yellow_card todo_display ui-widget-
content draggable'>
<div class='todo_name'><p name="todo[name]">Test todo</p></div>
<div class='todo_content'><p name="todo[content]">SOme long content</
p></div>
<div class='todo_tags'><p name="todo[tag_collection]">tag1, tag2,
tag3</p></div>
<div class='todo_due_date'><p name="todo[due_date]">12-12-12</p></
div>
</div>

and in the controller...

if(user.todos.count > 0)
presenter.view.find('.small_index_card').repeat_for(user.todos)
end

As you can see it uses the pre 0.8 name attribute instead of scoping,
etc.

I need to track the todo.id so I can delete, update, etc. I would like
to keep it in an attribute "data-card_id" and not expose it to the
user. So my questions.

1) Is keeping this kind of data in the data attribute field wrong?
2) How can I fill out this data-attribute? Via the binder? Or in the
controller's index action? How can I accomplish this with repeats?

p.s. if you prefer to see the full up code check out http://github.com/nclaburn/curator

bryanp

unread,
Feb 25, 2012, 1:17:40 PM2/25/12
to pak...@googlegroups.com
If you expose the id of the record to the front-end, you then have to construct URLs for deleting and updating the resource inside of your Javascript code. It's typically best practice to not do URL construction on the front-end so if/when things change, you only have to update the URLs in one place. Sometimes there isn't a way around doing URL construction on the front-end, fortunately delete isn't one of those times.

In the example above, there would be some UI object that the user would interact with to delete the todo. We can add this to the view in the form of a link, then populate the href from the binder. Here's the updated view:

    <div class='small_index_card yellow_card todo_display ui-widget-content draggable'>
      <a href="#" class='delete' itemprop="todo[delete_link]">Del</a>

  
      <div class='todo_name'>
        <p name="todo[name]">Test todo</p>
      </div>
  
      <div class='todo_content'>
        <p name="todo[content]">SOme long content</p>
      </div>
  
      <div class='todo_tags'>
        <p name="todo[tag_collection]">tag1, tag2, tag3</p>
      </div>
  
      <div class='todo_due_date'>
        <p name="todo[due_date]">12-12-12</p>
      </div>
    </div>

A "delete_link" method would then be added to the todo binder:

    def delete_link
      { :href => "/todos/#{bindable.id}" }
    end

Now, for delete to work properly we have to make the link send a delete request. Using the approach above, we'd need to do this with Javascript:

    $('.delete').bind('click', function() {
      $.post(this.href, {_method:'delete'});
    });

Another approach is possible, and doesn't require Javascript. It involves using a form with a submit button instead of a link. Here's the view:

    <div class='small_index_card yellow_card todo_display ui-widget-content draggable'>
      <form itemprop='todo[delete_action]'>
        <input type='hidden' name='_method' value='delete'>
        <input type='submit' value='Del'>
      </form>

      <div class='todo_name'>
        <p name="todo[name]">Test todo</p>
      </div>
      <div class='todo_content'>
        <p name="todo[content]">SOme long content</p>
      </div>
      <div class='todo_tags'>
        <p name="todo[tag_collection]">tag1, tag2, tag3</p>
      </div>
      <div class='todo_due_date'>
        <p name="todo[due_date]">12-12-12</p>
      </div>
    </div>

The "delete_action" method in the todo binder would look something like this:

    def delete_action
      {
        :action => "/todos/#{bindable.id}",
        :method => "post"
      }
    end

Hope this helps! For updating, do you mean changing the status of a todo or updating other attributes?

Bryan

nathan claburn

unread,
Feb 25, 2012, 4:01:26 PM2/25/12
to pak...@googlegroups.com
My problem comes in that I'm using drag & drop to delete. So, instead of clicking link, etc. I drag a "card" to a location to remove it. I like your solution for updating the data on the card.

Instead of creating the url I suppose I may be able to implement your solution for deleting by "clicking" a hidden "link" on the drop event.

Bryan Powell

unread,
Feb 25, 2012, 4:34:58 PM2/25/12
to pak...@googlegroups.com
Yeah, clicking a hidden anchor tag is really the only option if you want to avoid constructing the URL on the front-end. This is the kind of problem we hope to solve with pakyow-ui, but that's a long way off.

nathan claburn

unread,
Feb 25, 2012, 5:46:26 PM2/25/12
to pak...@googlegroups.com
I'm trying the hidden link method and it successfully calls the "delete" method in the TodoController. Then it errors out because "params" is null.

def delete
 43     if user = User.get(request.session[:user])
 44       todo = Todo.get(params[:id])
 45       todo.destroy
 46     end
 47   end

[500] undefined local variable or method `params' for #<TodosController:0x00000001db1c20>

I used the $.post method you described above. Maybe the ajax call does not fill out the "params"?

Bryan Powell

unread,
Feb 25, 2012, 5:52:13 PM2/25/12
to pak...@googlegroups.com
Try request.params instead.

nathan claburn

unread,
Feb 25, 2012, 5:54:34 PM2/25/12
to pak...@googlegroups.com
Sorry.

"I am not in rails..."
"I am not in rails..."
"I am not in rails..."
"I am not in rails..."
"I am not in rails..."
"I am not in rails..."
"I am not in rails..."
Reply all
Reply to author
Forward
0 new messages