Alter granularity in date exposed filter from Y-m to Y if only year is selected I am trying desperately to get the following working:
Goal:
I have a views that displays a list of events. To this views is a date exposed filter attached, with granularity Y-m(year month). I want this filter to filter with Y granularity if only the year is selected, and by Y-m if both are selected.
In addition to that, the view is set so that: when no date filter is selected, then filter by upcoming events, else, use the exposed filter value
Issue:
The month is required, even if I alter the form
I am suprised by the fact that exposed_form_alter as well as the validation fct are called multiple times, before the view is pre-build and before it is pre-executed, but this might be normal behavior.
See here: http://cl.ly/image/1C0t3Z3O0D3W (hook_views_*** dpms the function's name)
Draft:
The solution was inspired by this thread
function lezoo_form_views_exposed_form_alter(&amp;$form, &amp;$form_state) {
  if($form['#id'] == 'views-exposed-form-teaser-list-panel-pane-1')
  {
   $form['#validate'][] = 'lezoo_views_exposed_form_validate';

  }
}

function lezoo_views_exposed_form_validate(&amp;$form, &amp;$form_state) {

  $handlers = &amp;$form_state['input'];
  foreach ($handlers as $key =&gt; $handler) {
    if (
      isset($form[$key]['value']['#type'])
      &amp;&amp; $form[$key]['value']['#type'] == 'date_select'
      &amp;&amp; $form[$key]['value']['#date_format'] == 'Y-m'
      &amp;&amp; $form_state['input'][$key]['value']['month'] == '') {
      $form[$key]['value']['#date_format'] == 'Y';
    unset($form[$key]['value']['#granularity'][2]);
    unset($form_state['input'][$key]['value']['month']);
  }
}
dpm('form validation');
   // dpm($form);
   // dpm('form_state');
   // dpm($form_state);
}


function lezoo_views_query_alter(&amp;$view, &amp;$query) {
  //If a date was selected in the exposed filter, ignore the default date filter '&gt; today'
  $conditions = $view-&gt;query-&gt;where['1']['conditions'];
  $date_index = 3;
  if(isset($view-&gt;query-&gt;where['1']['conditions'][$date_index]) &amp;&amp;
    //if a date exposed filter was set
   $view-&gt;query-&gt;where['1']['conditions'][$date_index]['field'] != 'node.nid')
  {
    unset($view-&gt;query-&gt;where['1']['conditions'][2]);
  }
} 

I am really stuck here, IRC is not helping unfortunately, and i would really appreciate more insights on this!
Thanks in advance!
So, I ended up going the very ugly way.

First, my module is now reduced to:

    function lezoo_views_query_alter(&amp;$view, &amp;$query) {
  //If a date was selected in the exposed filter, ignore the default date filter '&gt; today'
  $conditions = $view-&gt;query-&gt;where['1']['conditions'];
  $date_index = 3;
  dpm($conditions);
  if(isset($view-&gt;query-&gt;where['1']['conditions'][$date_index]) &amp;&amp;
    //if a date exposed filter was set
   $view-&gt;query-&gt;where['1']['conditions'][$date_index]['field'] != 'node.nid')
  {
    unset($view-&gt;query-&gt;where['1']['conditions'][2]);
  }
} 


which is needed because the default filter on dates(not exposed) is after today, but if you select a date, then ignore that filter.

And I added a second date_exposed_filter, so that I now have date1->granularity:Y, and date2->granularity:Y-m. I then use css to hide the Y of Y-m, and js to mirror both Year fields. if anyone is interested, here is the code I use:

            var year = $('.views-widget-filter-field_date_value_2 select.date-year');
            var ymonth = $('.views-widget-filter-field_date_value_1 select.date-month');
            var yearm = $('.views-widget-filter-field_date_value_1 select.date-year');

            ymonth.change(function(e){
                var value = $(this).val();
                //var value = e.target.value;
                var empty = value == "";
                if(!empty)
                {
                    yearm.val(year.val()).trigger("chosen:updated");
                }
                else
                {
                    yearm.val("");
                }
            });

            year.change(function(e){
                if(ymonth.val() != '')
                {
                    yearm.val(year.val()).trigger('chosen:updated');
                }
                else
                {
                    month.val('');
                }
            })