I've got Facebook style statuses working in my user profiles but if I set the quicktabs to 'ajax' = TRUE, the statuses don't appear. Here is what I've done so far ->

1. I created a node and put this php snippet in it

<?php  $account = user_load(array('uid' => arg(1)));
  $size = variable_get('facebook_status_size_long', 40);
  $view = 'facebook_status';
  echo theme('facebook_status_form_display', $account, $size, $view);
?>

This node basically prints the facebook style statuses so I use it as one of the tabs in part 2.

2. In mytheme_preprocess_user_profile() I put the following code

<?php
    $tabs['first'] = array(
        'title' => t('Profile'),
        'type' => 'node',
        'nid' => $nid,
        'hide_title' => FALSE,
    );
    $tabs['second'] = array(
        'title' => t('Status'),
        'type' => 'node',
        'nid' => '30', // This is the nid of the node I created above to hold the facebook statuses
        'hide_title' => TRUE,
    );

    $quicktabs['qtid'] = '1';
    $quicktabs['tabs'] = $tabs;
    $quicktabs['style'] = 'Zen';
    $quicktabs['ajax'] = FALSE;
    $quicktabs = theme('quicktabs', $quicktabs);
   
    $vars['user_profile'] = $quicktabs;
?>

If I set $quicktabs['ajax'] = TRUE, the FBSS don't appear. I plan on adding some more tabs so I would really like to use ajax so I can reduce the load times on user profile pages. Any idea why it's not working if I set quicktabs ajax=TRUE? Any ideas on how I could get this working?

Comments

icecreamyou’s picture

Status: Active » Fixed

Yeah, when you put FBSS in an AJAX quicktab, the tab is loaded via AHAH, so your call to arg(1) which is supposed to set the User ID for the status update form returns something that is not a UID and then the form fails.

I don't know if there is a good way around this. There's nothing FBSS can do about it; any workaround would involve you being able to pass variables to the AJAX tab so that the node is aware of the User ID context. One hack would be to use a $_SESSION variable but that will fail if you visit another user page before switching to the FBSS tab. The best way would be if QuickTabs passed the information in its AJAX callback -- if it doesn't already do that, you should open an issue for it in the QuickTabs queue.

Of course, you could always just make FBSS the first tab.

And also, if I were you I would build the QuickTab using the interface instead of manually using PHP, if possible.

ltwinner’s picture

Cheers for the quick reply mate. I can see with firebug/firephp that when using ajax quicktabs the arg(1) is 'ajax'. It's coming from this url - GET http://localhost/mytheme/quicktabs/ajax/node/30/undefined/true

I really need to have my profile info on the first tab so I can't use that workaround.

icecreamyou’s picture

Well then take a look at the QT documentation and issue queue and see if there is a way to pass variables to AJAX tabs. If not you should open an issue for it. If you do open an issue or find a solution, please post the link or explanation here, as other people will probably want to know this in the future.

ltwinner’s picture

Hi mate, I went ahead and created a special 'fbss' type for quicktabs and the fbss are now loading with ajax quicktabs. There is an issue though....

This code is for programatically creating quicktabs of they new type 'fbss'.

<?php
$tabs['second'] = array(
  'title' => t('Status'),
  'type' => 'fbss',
  'hide_title' => TRUE,
  );
?>

I've added the following 3 bits of code to quicktabs.module

<?php
//This is in quicktabs_menu()
  $items['quicktabs/ajax/fbss'] = array(
    'page callback' => 'quicktabs_ajax_fbss',
    'access callback' => 'user_access',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
  );
?>
<?php
/**
 * Ajax callback for fbss tabpage.
 */
function quicktabs_ajax_fbss($uid, $hide_title) {
  $tabpage = array(
    'type' => 'fbss',
    'uid' => $uid,
    'hide_title' => $hide_title,
  );

  $output = quicktabs_render_tabpage($tabpage);
  drupal_json(array('status' => TRUE, 'data' => $output));
}
?>
<?php
//This is in quicktabs_render_tabpage($tab, $hide_empty = FALSE)
case 'fbss':
  if (isset($tab['uid'])) {
    $account = user_load($tab['uid']);
    $size = variable_get('facebook_status_size_long', 40);
    $view = 'facebook_status';
    $output = theme('facebook_status_form_display', $account, $size, $view);
  }
  break;
?>

Then in quicktabs.js I added the following

// This is in the quicktabsClick function
	    case 'fbss':
              path = window.location.pathname;
              uid = path.split('/').slice(-1);
              qtAjaxPath +=  uid + '/' + tab.tabObj.hide_title;
              break;

FBSS load up now with ajax enabled quicktabs and the ajax pager at the bottom of the FBSS also works fine. The problem is when you submit a new status the whole thing disappears. The status does actually get submitted though as you can see it when you refresh the page. So the issue is the FBSS dissappearing on submission of the FBSS form. Any ideas what could be causing this and how to fix it?

icecreamyou’s picture

My guess is you still probably have the same issue as before. The $uid is still probably not passed correctly, because you're still getting it from the URL in your JavaScript -- but the JavaScript isn't running for the user page, it's running for the AJAX callback.

ltwinner’s picture

That issue of the incorrect url being passed is fixed now with the code I posted above. I am setting the correct url now in the javascript by making a special - case 'fbss': - statement. And then in quicktabs.module I am handling that url in a special quicktabs_ajax_fbss($uid, $hide_title) function.

And FBSS are now working fine with ajax enabled quicktabs, and submitting fine. The only issue now is the fbss disappear after the submisssion. I'm wondering would yourself or anybody else with more ajax experience than me have an idea why this might be happening?

icecreamyou’s picture

Possibly the form #action gets screwed up when it's loaded via AJAX; you might try writing some JavaScript to rewrite it dynamically when the tab is loaded.

ltwinner’s picture

Hi mate, Ive been stepping through quicktabs.module and facebook_status.module to try and figure this issue out and I've tried out a good few different things but to no avail. Can you explain to me the process that takes place when a user submits a new message?

I know there are two requests made, a POST to /facebook_status/js that saves the new status and then a GET to /user/1?ts=127abcdefg. I take it the refreshing of the fbss area takes place during the GET request and the POST request is purely for saving the status? How come the GET request goes to /user/1?ts=127abcdefg....is it because there is no redirect set on the form so it defaults to the page the request was made from? The main thing I need to know is where/how the view facebook_status gets called to show the updated statues once the form is submitted.

Any info you can give me on how the fbss stuff is refreshed is appreciated.

Btw, I just want to clarify the issue as I mistakenly said the whole fbss area disappears on submission -

FBSS work with ajax enabled quicktabs when you use the code I posted above. I can submit new statues fine and the form refreshes showing the new default value in the textarea and showing the new status in the <span class="facebook_status_slider"></span> section. The sole remaining issue is the statuses view disappears when the form is submitted.

icecreamyou’s picture

Title: Facebook style statuses in Quicktabs » Content loaded on the page via AJAX can't be automatically refreshed when a status is submitted
Category: support » bug
Priority: Normal » Minor
Status: Fixed » Active

Submitting the form is handled mostly by core, that's the POST request and it saves and updates the form itself. The GET request is handled by FBSS, it basically reloads the current page in the background and looks for the div where the view should be. So that's your problem: it can't find that div because it's not there until the QuickTabs AJAX loads it.

There is no easy solution for this. In the mean time you can work around it by adding your view to the page in a normal block and hiding it using CSS. That reduces the performance benefit of loading the tab via AJAX, but it should allow the FBSS JavaScript to correctly update the attached view at least.

Probably what will need to happen to fix this is FBSS will need to check whether the view is actually attached to the form via a setting before deciding how to update it. That way we can use a special callback that will load only the attached view instead of trying to find it by silently reloading the current page.

dimitriz1’s picture

I have also been tryin to get this working as using ajax for tabs is the future for social networks.... This is must have feature for user profiles in 2010...without it a site feels, hmmmm...'old-fashioned'. look at facebook, all ajax tabs that go to info, wall, photos, etc.
I have tried the code posted in comment #4 above and I got the same issue - messages vanish when a new status is submitted. Is it really a tough problem to fix..seems like it is very close to working already as the new status gets saved and the form gets updated. Any idea when this feature could be fixed?

Also thanks for the great work on facebook style status module so far!

icecreamyou’s picture

@dimitriz1: Glad you're enjoying the module. I don't know when I'll have time to fix it. For me it's not a super difficult problem because I know the module and the technologies well, but it does require knowing a lot about FBSS, Drupal, jQuery, and AJAX. So it's not something I can do quickly. The best thing I can tell you is that I'm pretty sure I will have it fixed by August 22nd just because I'm hoping to have an alpha of the 3.x branch out by the end of August and I will address any outstanding bugs like this one before that happens. It may very well get fixed before then, we'll see.

ltwinner’s picture

I've got this working now. It's just hardcoded in for the uid 1 but should be simple to make it work for all users. It needs to be tidied up a little bit but it's working fine. I'll try and post it up tomorrow once I've figured out how you make patches as I haven't submitted one yet. There will also be a patch to quicktabs.

icecreamyou’s picture

Cool. I'd still like to take the path I explained in #9 above for performance reasons. It's great if you have a patch that does that, or even if you have one that just provides a workaround for now.

WRT patching, please see http://drupal.org/patch

ltwinner’s picture

I have it working for all users and tidied up a bit now. It checks to see if the fbss is in a quicktab with $('.quicktabs_wrapper .view-facebook-status') and if it is it calls the quicktab module's special fbss path instead of the normal path.

By the way I noticed when going through this that when a fbss is submitted the entire user page is called again so that new fbss is printed out. The jquery then finds the .view-id-facebook_status in the new content and uses that to replace the existing view on the page. Would it be possible to improve performance by calling a special path that only returns the output from theme('facebook_status_form_display', $account, $size, $view) as opposed to calling /user/%? That's basically all the quicktab special case fbss path I made does. Could this be applied to facebook_status in general so redundant information isn't called when refreshing the fbss?

Should have the patch up later.

ltwinner’s picture

nvm

ltwinner’s picture

Status: Active » Needs review
StatusFileSize
new1.75 KB
new1.74 KB
new714 bytes

I haven't added anything to the quicktabs admin interface so the way to see it working is to add the quicktabs programatically. Here's the most basic way -

<?php
function mytheme_preprocess_user_profile(&$vars) {

	$tabs['first'] = array(
		'title' => t('Info'),
		'type' => 'node',
		'nid' => 1,
		'hide_title' => FALSE,
	);	

	$tabs['second'] = array(
		'title' => t('Status'),
		'type' => 'fbss',
	);


	$quicktabs['qtid'] = '1';
	$quicktabs['tabs'] = $tabs;
	$quicktabs['style'] = 'Zen';
	$quicktabs['ajax'] = TRUE;
	$quicktabs = theme('quicktabs', $quicktabs);
	
	$vars['user_profile'] = $quicktabs;
?>
icecreamyou’s picture

Status: Needs review » Needs work

Thanks ltwinner. Hopefully this will help other people until I can get a more generic solution in place.

Would it be possible to improve performance by calling a special path that only returns the output from theme('facebook_status_form_display', $account, $size, $view) as opposed to calling /user/%?

The short answer is yes, that's what I explained I was going to do in the last paragraph of comment #9.

The long answer is -- sort of. The current model allows refreshing any part of the page, not just a view that's attached directly to the status update box. This lets you for example put the status update box in one region and a view in another and still have the view update when a status is submitted. In order for that to work, we have to download the whole page again (the current page, not just the user page -- the status update box could be placed on other pages on the site as well) because we can't know ahead of time what the code is that generates any given part of the page. However it should be possible to detect if the only thing we're updating is a view that is attached directly to the status update form, since that is the most common case and we do actually know what code we need to use there. So if we detect that, we can then use a different, special callback that gets just the required information instead of downloading the whole current page again. That should improve performance significantly for most sites. I just have to get some time.

While I'm at it, might add a way to specify custom callback pages, so that if you need to have a certain part of the page refreshed that is not attached directly to the status update box, you can create your own callback that just runs the code you need instead of only specifying the DOM path. This will also make it easier handle situations like the one that is the topic of this issue because it won't be affected by whether the content that is supposed to be refreshed is loaded onto the page via AJAX any more. (However I will have to make it so using those custom callbacks only happens if there are 1 or 2 of them because if you're making multiple requests and Drupal is doing a full bootstrap for each one it will be worse for performance than just downloading the current page again with a single request.)

ltwinner’s picture

Thanks ltwinner. Hopefully this will help other people until I can get a more generic solution in place.

Cool, I realise this is just the bare essentials for getting this to work, I'm sure you'll do a much more thorough job when it comes adding this feature properly.

I imagine the enhancements for refreshing the page with the special callback for the most common case, a view attached to status form, would yield big performance benefits - it would mean very quick refreshes no matter how complicated the user profiles are.

Michsk’s picture

Im using fbss in the first tab, but still got an issue. The view shows but when i post a status and try to update the view it hides and doesnt show anymore.

Michsk’s picture

The dom selector i use is: #quicktabs_tabpage_6_0 .view-facebook-status-stream

icecreamyou’s picture

Version: 6.x-2.3 » 6.x-3.x-dev
Category: bug » feature

Still intending to work on this

icecreamyou’s picture

Project: Facebook-style Statuses (Microblog) » Statuses (Social Microblog)
Version: 6.x-3.x-dev » 7.x-1.x-dev
Component: Miscellaneous » Code (API)
Status: Needs work » Postponed

Postponing until the 7.x-2.x branch.

mathankumarc’s picture

icecreamyou’s picture

Not currently. This issue deals specifically with refreshing content that is loaded on the page via AJAX after the page is loaded. Currently Statuses' AJAX refresh system loads a copy of the page in the background, which means it doesn't include content that would normally be loaded on the page later. The resolution to this issue will either involve an API for modules to specify a callback page or function used to specifically update the content in question, or it will reach the conclusion that we already have a JavaScript API for that and modules should handle whatever else they need on their own.

However, if we decide to change Statuses' AJAX refresh system to only work with Views, then another way to think about this issue might be "how do we update everything else"?

raulmuroc’s picture

Some advance?