Confused by data_rapid in 1.4

58 views
Skip to first unread message

devcurmudgeon

unread,
Jul 1, 2012, 5:08:49 PM7/1/12
to hobo...@googlegroups.com
I'm trying to understand the new data_rapid mechanism. Currently we've got a a single popup edit dialog for "items" which is populated dynamically for a selected "item" using a Hobo.ajaxRequest in JavaScript. I'm guessing there's a more elegant way to do this in 1.4 -  am I on the right track with the following in dryml, where the context is the "item" i want to create an edit dialog for?

 <dialog-open-button data-rapid='{"dialog-box":{"item_id": #{this.id}}}'><this.title/></dialog-open-button>

It gives the following:

NoMethodError: private method `status_code' called for #<ActionDispatch::ExceptionWrapper:0x000001054b5d38>

ActionView::Template::Error (757: unexpected token at '{"dialog-box":{"item_id": #{this.id}}}'):










 

Bryan Larsen

unread,
Jul 3, 2012, 10:19:08 AM7/3/12
to hobo...@googlegroups.com
You shouldn't need to play with the data-rapid attribute if you're
using an existing tag. You may need to understand it if you're
creating a new jQuery tag, so more documentation is probably
warranted, but if you're just using an existing tag, you shouldn't
need to play with it directly.

In this case, try:

<dialog-box id="dialog-for-item-#{this.id}" ...>...</dialog-box>

<dialog-open-button dialog="#dialog-for-item-#{this.id}"/>

Note the two different uses for hash. #{...} is for embedded ruby,
but "#dialog-..." is a CSS selector.

Also note the two different meanings of ID. There's the ActiveRecord
ID (this.id), and there's the CSS ID (dialog-for-item-17). We're
using one to build the other but they are distinct.

Bryan
> --
> You received this message because you are subscribed to the Google Groups
> "Hobo Users" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/hobousers/-/tDyuKfRW4mMJ.
> To post to this group, send email to hobo...@googlegroups.com.
> To unsubscribe from this group, send email to
> hobousers+...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/hobousers?hl=en.

devcurmudgeon

unread,
Jul 3, 2012, 4:31:28 PM7/3/12
to hobo...@googlegroups.com
Hi Bryan
On Tuesday, July 3, 2012 3:19:08 PM UTC+1, Bryan Larsen wrote:
You shouldn't need to play with the data-rapid attribute if you're
using an existing tag.   You may need to understand it if you're
creating a new jQuery tag, so more documentation is probably
warranted, but if you're just using an existing tag, you shouldn't
need to play with it directly.

In this case, try:

<dialog-box id="dialog-for-item-#{this.id}" ...>...</dialog-box>

<dialog-open-button dialog="#dialog-for-item-#{this.id}"/>

Note the two different uses for hash.   #{...} is for embedded ruby,
but "#dialog-..." is a CSS selector.

Also note the two different meanings of ID.  There's the ActiveRecord
ID (this.id), and there's the CSS ID (dialog-for-item-17).   We're
using one to build the other but they are distinct.

thank you for explaining this. Your suggestion works, but unless I'm missing something this approach pre-populates a dialog for every item. 

In our use-case we create a kanban board with a card for each "item" - so we can have maybe several hundred "items" on a single show page. The current design is that we only load titles+ids to populate the board, then if the user clicks on a specific card we pull the full item record into a popup dialog. Creating dialogs for all of the items is too big and slow, hence the current Hobo.ajaxRequest call. I noticed in the 1.4 changes guide that you've rationalized the various AJAX mechanisms so that's why I started fiddling with data-rapid. 

br
Paul
 

Bryan Larsen

unread,
Jul 3, 2012, 5:15:12 PM7/3/12
to hobo...@googlegroups.com
That's actually the approach I use on a couple of different web pages.
I never have "several hundred" dialog boxes, but I do often have
most of a hundred. It really doesn't seem to slow things down a lot,
although none of the pages I use that technique on are important
enough that it matters.

It should be simple to use a little bit of Javascript to change the
content of the dialog box when the button is clicked so that you can
use a single dialog box rather than several hundred. However, I don't
think there's an easy way at the moment of adding that javascript
hook. Let me get back to you on that with either an example or a fix
to make it easy.

Bryan

Bryan Larsen

unread,
Jul 4, 2012, 12:18:29 PM7/4/12
to hobo...@googlegroups.com
Here's the promised example:

<dialog-box id="mydialog">
<div id="message"/>
</dialog-box>

<dialog-open-button dialog="#mydialog" onclick="$('#message').text('hello')"/>

Replace .text('hello') with whatever DOM manipulation is required to
get the desired results.

Bryan

devcurmudgeon

unread,
Jul 7, 2012, 8:55:00 AM7/7/12
to hobo...@googlegroups.com
Thanks Bryan.

Sorry to go around again, but assuming we have the dialog plumbing working, what would be the recommended Hobo 1.4 way to retrieve the data from the server-side db?

In 1.3 we've used Hobo.ajaxRequest as follows, but it's always seemed like hard work to me, and CHANGES-1.4.txt note suggests you've dropped this for 1.4 anyway

  Hobo.ajaxRequest( "/items/" + item_id + "/ajax_item",
                    [],
                    { params: { item_id: item_id },
                      action: 'ajax_item',
                      controller: 'items',
                      method: 'get',
                      message: "Please wait",

                      onSuccess: function(transport) {
                        jQuery("#edit-item-dialog").empty();
                        jQuery("#edit-item-dialog").append(transport.responseText);

                        jQuery("#edit-item-dialog").find('.hjq-annotated').each(function() {
                          var annotations = hjq.getAnnotations.call(this);
                          if (annotations.init) {
                            hjq.util.createFunction(annotations.init).call(this, annotations);
                          };
                        });

                        hjq.dialog_opener.click(this, jQuery('#item-dialog-s' + item_id));
                      },

                      onFailure: function(transport) {
                        jQuery("#edit-item-dialog").empty();
                      }
                    } );

Bryan Larsen

unread,
Jul 7, 2012, 11:16:58 AM7/7/12
to hobo...@googlegroups.com
You can probably do something similar with v1.4 using the buildRequest
function in hjq.js. There are comments explaining its usage and you
can look through hjq.js for examples. If you start down this path and
want some help, I'll be glad to help.

However, what I would recommend instead would be to add a hidden form
to your HTML

<div style="display: none;">
<form update="myresponse" action="&some_path" success="my_function">
<inputs that can be manipulated/>
<div part="myresponse"><% #code that calculates the response to
the ajax %></div>
<submit id="#mysubmit"/>
</form>
</div>

Then you can manipulate this form via jQuery DOM manipulation to
change the action and manipulate inputs, and then use jQuery to click
on the submit button. Your success function can then pull the answer
out of myresponse and put it where you want it. Alternatively you
can use a larger part and then you won't have to move the response.

Hopefully this also means you don't have to call init() again,
depending on how well the items you move deal with being moved.

This method should work with both 1.3 & 1.4 and future versions is
easier to debug because you can unhide it and play with it manually.

The above approach is probably your best option if you want to return
HTML in your Ajax. If your Ajax returns something other than HTML,
you're probably best off just using jQuery.ajax and rolling your own
controller code.

Bryan
> --
> You received this message because you are subscribed to the Google Groups
> "Hobo Users" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/hobousers/-/J07D5x7fDj0J.
Reply all
Reply to author
Forward
0 new messages