I need a way to display the calendar, 1 month at a time, and be able to click/change without opening up the admin. Is this possible? Seems like it should be possible to load the edit view of the calendar, which is a form, into a block somehow and change up the styling. Any ideas are welcome. I really, really need to make this happen.

Comments

PeggyOCO’s picture

Issue summary: View changes
fietserwin’s picture

It should be possible. I see a few ways that could work:
- show the edit form, but set the #access property of all other fields to FALSE. Though this might give problems accessing the form at all (in D8 we will be able to define multiple forms, like we now already can with view modes on the view side).
- write some custom code to attach the edit controller (in availability_calendar.edit.js) to the calendar. But this will need a submit button as well, and some code to handle the submit or you would have to go the ajax way, making it probably more difficult.

PeggyOCO’s picture

How about using CSS to hide the enable checkbox and the name fields and anything above or below the actual editable mini-calendar and the radio buttons to choose state, only run this css when viewing the calendar in an iframe. I know iframes are never recommended, however, like tables, iframe sometimes serves a purpose. This is, of course, the chicken way out, but I think it might work. Do you see flaws in this approach?

To clarify my purpose:

User logs in.

Profile2 contains a reference field to Availability content type, which shows calendars for each user (I'm handling this in a module where, when a user logs in, if they don't have a calendar yet, one is created for them)

User, on login, is redirected to a views page which shows the user/profile2/calendar data for the logged in user.

User is able to click-set availability on the availability calendars mini-calendar.

fietserwin’s picture

Apparently you already have kind of detached the calendar field from the user, so just showing that referenced entity edit form brings you already a long way.
- Name fields on a calendar should normally not used. Normally, when only 1 calendar is attached to an entity, the name of that entity is better used. There is a field setting to enable/disable it
- The enable checkbox can also be removed/shown with a field widget setting. But if the checkbox should be shown on the user edit page, that is a problem.
- How can a user mark a day as available resp. unavailable without the radio buttons?

PeggyOCO’s picture

I've got it showing in an iframe in my view by using php in the view footer (I know, that's bad, should be a module. But I'm just looking at possibilities right now).

Since the calendar is set to enabled when it is programmatically created, no need to display to the logged in user. There are only 2 things they need: The editable calendar, and the radio buttons. All else gets hidden with css. Controlling css in an iframe is a real pain, even on the same server. I'm thinking I'll add the css within a conditional such that if the page path is /member-view, then add css file.:

Here's the dynamic generation code so far:

if($path == 'member-page'){
   $sql = "SELECT nid FROM node WHERE type = :type and uid = :uid";
  $result = db_query($sql, array(':type' => 'availability','uid' => $user->uid));

    while ($row = $result->fetchAssoc()) {
      // Do something with:
   $myvar = $row['nid'];
      //    $row['quantity']
  }
  
if(!$myvar){

$node = new stdClass();
$node->title = $user->name.$user->uid;
$node->type = 'availability';
$node->created = '';
$node->changed= '';
$node->status = 1;
$node->promote = 0;
$node->sticky = 0;
$node->tnid = 0;
$node->translate = 0;
$node->uid = $user->uid;
$node->language = 'en';
$node->timestamp = '';
$node->revision = 0;
$cid =availability_calendar_create_calendar();
$node->field_availability_calendar['und'][0]['enabled'] = 1;
$node->field_availability_calendar['und'][0]['cid'] = $cid;
$node->field_availability_calendar['und'][0]['name'] = $user->name . $user->uid;
$node=node_submit($node);
node_save($node);
drupal_set_message($path . 'New availability calendar with nid: ' . $node->nid);

//insert into the reference field (field_data_field_availability_ref) and set the target id to $node->nid and the cid to $cid
}else{drupal_set_message($myvar . ' ' . $user->uid);}

Here's the php in the Global:php field in the view footer:


<?php 
$thisid = $results[0]->field_field_availability_ref[0][raw][target_id]; ?>
<iframe id="calframe" src="/drupal/node/<?php echo $thisid;?>/edit" width='300' height='300' border='1'> </iframe>

Pretty clunky. I'd rather do it without a lot of css trickery. I'd rather be able to simply summon up the calendar and mark whether or not it should be editable.

PeggyOCO’s picture

Got it working. This, in hook_preprocess_page:

if($vars['theme_hook_suggestions'][3] == 'page__node__edit'){

$css = "#overlay-titlebar,#branding,div.vertical-tabs,#edit-actions,.form-item-title,.form-item-field-availability-calendar-und-0-name,#edit-field-availability-calendar-und-0-description,.form-type-checkbox{display:none; }";
$css2= "label,.fieldset-legend,.field-label{display:none;}";
$css3= ".fieldset-wrapper{margin-top:-50px;}";
$css4= ".availability-details{background-color:#efefef;margin:0px;width:320px;margin-left:-15px;}";
drupal_add_css($css, 'inline');
drupal_add_css($css2, 'inline');
drupal_add_css($css3, 'inline');
drupal_add_css($css4, 'inline');
}

That hides everything on the edit page except for the radio buttons and the calendar, shown 1x1, with next/previous scrolling.
It seems to work. I know it's kind of a weird way to handle this. The benefit is not having to monkey around with the really complex code -- just leave all the functionality in place, and use css to adjust the display. All browsers understand display:none.

If you can suggest a better, easier way to do this, please share. I might be missing something obvious, like writing a function to display the editable calendar and its radios.

fietserwin’s picture

As said before, you could try to attach the edit controller to the calendar view and add a submit button (and radio buttons) your self. Alternatively, just calling availability_calendar_field_widget_month_form() to get the form might even work better. That form does not include a submit button though, but that can be added afterwards (perhaps even automatically, as with system forms).

PeggyOCO’s picture

How would I call that? I tried this code and I got this error: Fatal error: Call-time pass-by-reference has been removed in /home/commxtra/public_html/drupal/testquery.php on line 28



define('DRUPAL_ROOT', getcwd());
include_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);



module_load_include('inc', 'availability_calendar', 'availability_calendar');


 availability_calendar_field_widget_month_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element);


This code gets me the calendar, but without any jquery or editability or anything usable:


$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
 ->entityCondition('bundle', 'availability')
 ->propertyCondition('status', 1)
->propertyOrderBy('created', 'DESC');
$result = $query->execute();
$nids = array_keys($result['node']);
echo $nids[0];

$node = node_load($nids[0]);


print render(node_view($node, $view_mode = 'full', $langcode = NULL));

fietserwin’s picture

Well,the exception is self-explaining: remove the & from your calling code. But that won't help you in the end. In Drupal, you can get a form using drupal_get_form() and passing that the id/function name and additional parameters. Drupal will initialize a form for you (save against session hijacking and other form related security problems).

PeggyOCO’s picture

I was able to show the form with drupal_get_form, but only partially -- the calendar didn't show up at all. I can't see any way to deliver just the calendar and the radios in a workable way using drupal_get_form. It returns everything except what I want -- the calendar, and the radio buttons.

For now, until I can understand this better, I'm sticking with the css hacks. If you could point me to some resources to study (I'm sure I'm just not understanding how to do this) I would appreciate that.

fietserwin’s picture

I guess that this is due to the parameters being passed in. As it is a field theme function, it expects quite some parameters containing field settings and such. A bit of debugging (dpm() from the devel module would be perfect here) could give you some insights in what is needed.

PeggyOCO’s picture

Would it be possible to submit the form and save when a user clicks on a day to indicate he is available or not? Without the submit button? Just a javascript thing that would automatically submit when clicked?

fietserwin’s picture

ctools offers an auto-submit.js, mainly used by Views to auto-submit exposed forms. By adding that script to your page and adding a class to either the form (ctools-auto-submit-full-form) or to the individual elements (ctools-auto-submit) you will get auto-submit behavior. If you need more flexibility you can use this js as starting point.

markdc’s picture

I got the calendar form to show up in a custom view using the Editable Views module. All the buttons are there and the calendar is editable, but when I click Save the changes aren't kept.

I have the calendar field attached to user accounts, so I created a Views page based on Users. The Views Format should be set to Editable table. Then add the (editable) availability calendar field.

Additionally, I'm using a UID contextual filter to set the default value based on the logged in user. I created a menu tab that shows up on user account pages. Ajax is enabled. But I can't get the changes to save upon submitting the form.

I know this is an old issue, but if anyone every found another solution, or has experience with editable views, I'd be grateful if you could tell me if this module could be used to Edit the calendar in place. Thanks.

fietserwin’s picture

To find out what is going on start by checking if these functions get called (e.g. by using a debugger):
- availability_calendar_field_widget_month_form_validate
- availability_calendar_field_attach_submit_inc