D7: When using editablefields ( http://drupal.org/project/editablefields ) the current table highlighter D7 dev version shows only the right color when the page is refreshed. But, the idea behind the editablefields is that no page refresh is needed.
Might be a bit early to come with such a use case for a not yet released D7 dev version of table highlighter, but people working with tables will use the editablefields module very soon...page refreshes are used less and less in web tables these days.

Comments

smokris’s picture

Title: Drupal 7: Table Highlighter only working after page refresh when editablefields is used » Refresh View after an editablefield is saved
Project: Views Table Highlighter » Editable Fields
Version: 6.x-1.x-dev » 7.x-1.x-dev
Category: bug » feature

Changing this to an editablefields feature request: editablefields would need to refresh the view after the field is saved.

ironbuilt’s picture

Can I add a bounty for this? $100?

When using editable fields in a View editable fields needs to update the entire single row in the view upon save. Anyone interested?

johnv’s picture

There has been some developments.
Is this still a problem with latest -dev from february with the following patches?
#1206656: Error on Node view page: Argument 1 passed to drupal_array_get_nested_value()
#1405854: Multiple fields not saved

zdean’s picture

Although the "save" feature is working, the "refresh" page feature provides slightly different functionality. For my case, I have a view that is grouped by one of the fields. When an editable field is edited, it affects which group the row belongs to. So, on changing the editable field, I have to refresh the page in order for the new grouping to be displayed. Is this something that could be done automatically so that on edit of the field the page refreshes to show the new grouping of rows?

Thanks!

JorgenSandstrom’s picture

bradjones1’s picture

The use case in the ticket summary mentions another module, table highlighter, though I think the real request here is for the view to refresh, and if it's got additional functionality provided by another module, so be it.

Views does have the option to refresh its results with Ajax after an exposed field is selected submitted. I think the best course of action here would be to replicate/borrow from that event in views during the editablefields Ajax response. Or, do I have the requirements wrong? Seems pretty straightforward.

charlie-s’s picture

I've been tinkering with this a bit today.

In views/includes/ajax.inc we have the views_ajax() function, which, given a view name and display ID will return the markup for a view. You can even throw something like this together and return the view's markup yourself:

<?php
function mymodule_ajax_a_view() {
  $view_dom_id = $_GET['view_dom_id'];
  $view_name = $_GET['view_name'];
  $view_display_id = $_GET['view_display_id'];
  $view_args = $_GET['view_args'];
  $view_path = $_GET['view_path'];

  $view = views_get_view($view_name);
  if ($view && $view->access($view_display_id)) {
    // Fix 'q' for paging.
    if (!empty($view_path)) { $_GET['q'] = $view_path; }

    // Add all $_POST data, because AJAX is always a post and many things,
    // such as tablesorts, exposed filters and paging assume $_GET.
    $_GET = $_POST + $_GET;

    // Reuse the same DOM id so it matches that in Drupal.settings.
    $view->dom_id = $view_dom_id;

    // Ensure args are an array.
    $view_args = explode('/', $view_args);

    // Build the array.
    exit($view->preview($view_display_id, $view_args));
  }
}

?>

and then get it via $.ajax really easily:

(function ($) {

  Drupal.behaviors.editablefieldsViewsRefresh = {
    attach: function (context, settings) {

        // Get the View that an editable field is inside.
        var classesString = $('.editablefields-item', context).closest('[class*=" view-dom-id-"]').attr('class');
        var regex = /view-dom-id-(.*)/; // Extract their dom IDs.
        match = regex.exec(classesString);

        // Get the object that describes this View.
        viewObj = Drupal.settings.views.ajaxViews['views_dom_id:' + match[1]];

        $.get(Drupal.settings.basePath + 'custom/ajax/views-update', {
            view_name: viewObj.view_name,
            view_display_id: viewObj.view_display_id,
            view_args: viewObj.view_args,
            view_path: viewObj.view_path
            }, function(data) {
            $('.view.view-dom-id-' + match[1]).replaceWith(data)
        });

  };
})(jQuery);

but I can't get this to only fire for my editablefields' ajaxComplete() function. I'm getting my hands dirty to make this happen but would really appreciate any direction anyone can share!

miccelito’s picture

Refreshing a views page (that may have 100+ rows) with editable fields in scope that you want i.e. to highlight various background colors for certain field depending on earlier choice of a field's select option, is maybe not good idea since it would be annoying if you edit a select field i.e. at row #50 and if page is refreshed you get back to row #1...

Maybe the solution should be another without having to refresh page. I would like to have an editable field with list select with options - i.e. to make an schoolar example - red, green and blue. Choosing 'blue', module Editablefields would add class 'blue' to the select tag's classes. And with that we could use css to background-color field or even row.

Modules related...
http://drupal.org/project/views_table_highlighter
http://drupal.org/project/field_formatter_class
http://drupal.org/project/select_with_style - adds classes to select options tags and even selected option tag with no need of refreshing page, select field needs to be added via taxonomy with terms as options (content type level) and in that way select options (terms) will have classes when adding the field in Views

WorldFallz’s picture

I just stumbled across this need myself recently-- has anyone figured out how to get an editablfield to refresh a view?

WorldFallz’s picture

I finally managed to work it out myself: http://drupal.org/node/1988484 (for d6 however).

vaccinemedia’s picture

Has anybody figured this out for Drupal 7?

Yuri’s picture

Issue summary: View changes

Seems like a very common need..

RaceCorp’s picture

Here is a hack to update a view based on an editable field ajaxcall being completed. It's a complete hack and there is probably a much easier way, but this may inspire someone to do it the right way.

Some PHP to refresh the order (If you need).

/**
 * Implements hook_commerce_cart_form_alter()
 */
function mymodule_form_alter(&$form, &$form_state, $form_id) {
  if($form['#entity_type'] == 'commerce_option') {
    $form['#attached']['js'][] = drupal_get_path('module', 'mymodule') . '/mymodule.js';
  }
}

function mymodule_views_pre_view(&$view, &$display_id, &$args) {
  if($view->name == 'commerce_cart_form') {
    $order_id = $view->args[0];
    commerce_cart_order_refresh($order_id);
  }
}

JS: mymodule.js

//On an editablefield completion, update the view
(function ($) {
  Drupal.behaviors.igd_commerce_attributes_form = { 
    attach: function(context, settings) {
      if (Drupal.views !== undefined) {
        jQuery.each(Drupal.views.instances, function(i, view) {
          if (view.settings.view_name == "commerce_cart_form") {
            jQuery(document).ajaxComplete(function(event, xhr, element_settings){
              jQuery('input[type="submit"][value="Save"][name="submit-"]').hide();
              //Check to make sure it's a an editable field ajax callback as well as make sure it's not a views ajax
              if(context[0].className == 'editablefield-item editablefield-processed' && !element_settings.url.match(/^\/views\/ajax/)) {
                var base = 'igd_commerce_attributes_form';
                var uri = Drupal.settings.views.ajax_path;
                var element_sett = {'url': uri, 'event':'click'};
                var element = $("<a href='"+uri+"' class='use-ajax' style='display:none'></a>");

                Drupal.ajax[base] = new Drupal.ajax(base, element, element_sett);
                // merge settings object into views object
                $.extend(Drupal.ajax[base].options.data, view.settings);
                //Trigger it
                Drupal.ajax[base].eventResponse(element, 'click');
              }
            });
            return false;
          }
        });
      }
    }
  }
})(jQuery);
train’s picture

If I may add to the conversation...

Based upon the code above, this is what I use to update any AJAX enabled View when an editable field is changed:

(function ($) {
 Drupal.behaviors.ksc = {
  attach: function(context, settings) {
                //refresh view after status change
		if (context[0] !== undefined && context[0].className == 'editablefield-item editablefield-processed') {
			var parentViewClasses = $('#' + context[0].id).closest('.view').attr('class').split(' ');
			$.each(parentViewClasses, function(index, value){
				 if (value.indexOf('view-dom-id-') > -1) {
					 $('.' + value).triggerHandler('RefreshView');
				 }
			     }
			 );
		}
  }
 };
})(jQuery);
johnkareoke’s picture

StatusFileSize
new75.94 KB

@Train

Quick question: Is this an ajax view that contains an editable field that is being updated, or are all ajax views on a page being updated? My use case is as follows: I have a panel that has a ajax enabled view in a pane (without any editable fields), and an editable field in another pane. The above code doesn't seem to work. Is it naive of me to think it would?

johnkareoke’s picture

johnkareoke’s picture

I've been having some trouble with this. I'm able to refresh my view, so I know that part is working, but I seem unable to limit it to editable field ajaxcall completing.

I'm using the following code:

(function ($) {
    Drupal.behaviors.camapaignRefresh = {
        attach: function (context, settings) {

         
        //Check to make sure it's a an editable field ajax callback as well as make sure it's not a views ajax

	//		if(context[0] !== undefined && context[0].className == 'editablefield-item editablefield-processed') {

				jQuery.each(Drupal.views.instances, function (i, view) {
                    var selector = '.view-dom-id-' + view.settings.view_dom_id;
                        
                        if (view.settings.view_name == "campaign_summary_and_widgets"){
                            console.log('1');
                            jQuery(selector).triggerHandler('RefreshView');
                        }
                    jQuery(selector).unbind();
                });
   //        }
        }
    }
}(jQuery));

I've tried to isolate the ajax call unsuccessfully as follows:

if(context[0] !== undefined && context[0].className == 'editablefield-item editablefield-processed') { ....

Any suggestions would be appreciated.

hondaman900’s picture

@Train #14

I also need this functionality. My editable field saves the change to the database field but calculations in views using that field do not update with the new value without a page refresh. I'm hoping your code will automate that by forcing a page refresh on clicking SAVE for edited fields.

My question is, where does your code in #16 go? How do I implement it. I'm finding my way around programming Drupal, so forgive me if this seems obvious to you.

Thanks in advance

delacosta456’s picture

Pleas has any one one found a workarround

thanks

hondaman900’s picture

Yes, I found a kludgie workaround. I added a button to the View footer, in a Global Text Area field, for the user to "accept changes". The button refreshes the page which commits the changes. Here's the code:

<center><button onclick="myFunction()">Accept Changes</button></center>

<script>
function myFunction() {
    location.reload();
}
</script>

It's not pretty, but it works for me. Hope this helps.

PS: I should add that this only works if the user allows the ""Please wait'''" ajax updater to complete after the field loses focus. In a case where the user makes the edit and then clicks on the "Accept Changes" button next (the intuitive thing for the user to do) then it's a crap shoot as to whether the ajax update to the database has completed before the page reloads.

shevgeny’s picture

how can you not update the whole View, but only the edited Row?

pinueve’s picture

Comment on #20, I followed your suggestion, but i placed an A anchor to muy button like:
<a href="/same/path/page" class="btn btn-success">Refresh page</a>