This is a follow up to updateFieldValue doesn't dispatch a change event.

I will preface by saying I'm not a JavaScript expert, and maybe there is a better way to achieve what I'm suggesting.

We have a client that needs to display messages if certain SHS dropdown options are selected. The problem is SHS doesn't provide an change event to access.

After doing some research, it seemed like the right approach was adding a change trigger, as patched in #2264795. However as far as I can tell, this won't work because it's a "change of a change"... SHS is changing the original select programmatically, and then .trigger is triggering a change from that change. JavaScript only recognizes change events when performed by the user.

So investigating further led to an approach using dispatchEvent and fireEvent, as detailed here: http://stackoverflow.com/a/2490876. This allows for an event listener to be set on the original field, and the selected value to be passed into JavaScript.

I'll post a patch in just a minute for review. As I said, there could be a much easier way to do this than I'm suggesting -- just haven't had any luck finding it. Thanks.

Comments

sgdev’s picture

Status: Active » Needs review
StatusFileSize
new1.81 KB

See attached. Also added some text to the README to describe how to use.

The function needs to have a custom event name (in this case, "shs-change") since dispatch options do not allow for reusing existing events.

I'd appreciate any feedback, thanks.

sgdev’s picture

Sorry, I realized the patch should also include the select's ID in cases where there are multiple SHS-enabled fields on the same page. See attached.

Mirkozzo’s picture

Patch don't have effect for me :/

For use i must something specific action in addition to patch shs.js?

sgdev’s picture

@Mirkozzo, did you read the update made to README.txt? It is necessary to use an event listener in your site's Javascript file to use the update.

Mirkozzo’s picture

sorry, I did not understand how to use the information in the file readme.txt :/

+  - Perform additional actions based on dropdown change. Include an event
+    listener in JavaScript for "shs-change" and access "id" and "value". Example:
+
+      document.addEventListener("shs-change", function(e) {
+        console.log(e.value);
+        alert("Current select ID is: " + e.id);
+        alert("Current select value is: " + e.value);
+      });

I am creating a custom module and I have to use #states with shs

sgdev’s picture

What exactly are you trying to do with #states and shs?

Mirkozzo’s picture

When term is select -> show field

function mymodule_form_alter (&$form, &$form_state, $form_id) {
$form['field_my_text_field']['#states'] = array(
		'visible' => array(
			':input[name="field_my_taxonomy_field[und]"]' => array('value' => (string) '168'),	//TID:168
			),
		);
	}
}

If i use default taxonomy drupal widget -> work
If i use shs widget -> not work (field_my_field_text is always shown)

sgdev’s picture

I don't think you have a full understanding of how this module works. SHS does not store the value in the input field until after the page is saved. Use Firebug and you can see this in action -- each time a value is selected, there is no change in the default input (which, by the way, is hidden from display). The only changes are to the SHS widget that is javascript-driven.

All steps are done via json. This is the reason why the hook_shs_json_callbacks_alter and hook_shs_json_get_children_alter functions exist. You need to intercept the value from JavaScript if you want to use it to control a change via #states.

Mirkozzo’s picture

Patch and code in readme.txt is good for my problem?

I need to: user select term -> action

sgdev’s picture

@Mirkozzo, yes that is the purpose of the patch. It provides a way to perform a secondary action based on a term event being selected.

Is there anyone else who has an opportunity to review this patch, or any feedback?

sgdev’s picture

Given the recent changes to the 7.x-1.x-dev version of SHS, I've created a new patch for review. See attached.

stborchert’s picture

SHS does not store the value in the input field until after the page is saved. ... each time a value is selected, there is no change in the default input

Sorry, but this is not correct.
Use Firebug (or Chrome dev tools, ...) to display the element and you will see, that the element value is updated as soon as you select an option within one of the widgets of SHS.

I've committed a change so other modules can listen to the change-event on the original element and get some additional information about what has happend.

  • stBorchert committed fa1e9f6 on 7.x-1.x
    Issue #2499279 by ron_s: updateFieldValue doesn't dispatch an accessible...
sgdev’s picture

@stBorchert, I think we might be referring to two different things. Yes, the element value is updated, but I'm referring to the default input value. This is not changed, and we verified this in both Firebug and Chrome dev tools.

The issue is SHS is changing the value programmatically, and .trigger is triggering a change from that change. My understanding is that JavaScript only recognizes change events when performed by the user. Therefore an accessible change event is necessary to hook into the process.

Thanks for making an update... we'll review and post our findings.

stborchert’s picture

but I'm referring to the default input value

Can you give a screenshot explaining, what you mean?

sgdev’s picture

Yes, I was just testing the patch right now. I'll post a few images and additional information in a few minutes. Thanks.

sgdev’s picture

Ok, before I add some screen shots, let me describe a test I've run. I want to capture the change event, so I have this simple code in my javascript file:

$('select').change(function() {
  console.dir('Handler for .change() called.');
});

(and to clarify, this is wrapped with a Drupal.behaviors, etc.)

There are two selects on the page I'm testing -- an Ajax-enabled select that shows/hides fields based on the option chosen, and the SHS-enabled select. When I change the Ajax-enabled select, the console message is displayed. When I change the SHS-enabled select, there is no message.

As a second test, I added an event listener breakpoint in Chrome Sources for the change event. When I change the SHS-enabled select, I do see the event displayed, and the field value matches what I would expect.

Am I missing how I'm supposed to access the event, or should I send screen shots with more details?

stborchert’s picture

Issue summary: View changes
StatusFileSize
new35.93 KB

Strange.
I have this javascript file https://gist.github.com/stborchert/ffbba33d6d3c8bc5e1ca and attach it to all forms:

<?php
/**
 * Implements hook_form_alter().
 */
function shs_alter_form_alter(&$form, &$form_state, $form_id) {
  if (empty($form['#attached']['js'])) {
    $form['#attached']['js'] = array();
  }
  $form['#attached']['js'][] = drupal_get_path('module', 'shs_alter') . '/shs_alter.js';
}
?>

If I now visit node/add/article and make a change to my shs-enabled select I get the following output in the console (2 times):

Seems to me its working ... ;)

sgdev’s picture

Status: Needs review » Reviewed & tested by the community

Ah! Such an unfortunate mistake. Now it makes sense why we weren't seeing any values and had to write our own event listener!

Javascript was copied from another part of the site for use on the registration form, and the code was wrapped with a jQuery .once:

$('body', context).once('registration', function () {
...
});

So it makes complete sense that a .change is rendered in the console for the Ajax-enabled select (the first step in the process), but not the SHS-enabled select. As soon as the .once was removed, it worked fine.

Thank you for helping us realize what was happening. The patch works well.

stborchert’s picture

Status: Reviewed & tested by the community » Fixed

Great to hear.
Setting to "fixed" then since it has been committed already.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

willabby’s picture

This is working on latest version dev version.