Offering small 20 USD bounty to come up with a fix for a bug with the jquery_autocomplete module that occurs in Google Chrome. The jquery_autocomplete module is a simple module that uses JavaScript to remove the [nid:X] text when you select an item in a Node Reference field. jquery_autocomplete is located here (it does not yet have a project page):
http://drupal.org/node/640832#comment-4112374

For example, if you have
My Node Title [nid:384]
jquery_autocomplete changes it to just
My Node Title

Unfortunately this does not work in Chrome. I suspect it might be a simple fix, but I am not skilled with jQuery or JavaScript. The fix should not break the module for IE and Firefox. Payment is via PayPal only, payable once the fix is complete.

I want to open up this bounty to anyone, so please just post here if you are working on it so others can be aware it is already being worked on.

Comments

arpeggio’s picture

Please try this:

Drupal.behaviors.jqueryAutocomplete = function (context) {
	$('.form-autocomplete').each(function() {
		var ac = $(this);
		ac.data('changed', false);
		ac.data('alias', 'ac-real-');
		ac.data('rx',  /\s*\[nid:\d+\]\s*/i);
		ac.data('name', ac.attr('name'));
		ac.data('id', ac.attr('id'));
		ac.data('value', ac.val());
		ac.before('<input name="'+ac.data('alias')+ac.data('name')+'" type="hidden" id="'+ac.data('alias')+ac.data('id')+'" value="'+ac.data('value')+'" />');
		ac.data('real', '#'+ac.data('alias')+ac.data('id'));
	});
	$('.form-autocomplete').blur(function() {
		var ac = $(this);
		var real = $(ac.data('real'));
		if ($.browser.msie && !ac.data('changed')) {
			ac.change();
		}
		if (ac.val().match(ac.data('rx'))) {
			real.val(ac.val());
		}
		ac.val(ac.val().replace(ac.data('rx'), ''));
		ac.attr('name', ac.data('alias')+ac.data('name'));
		real.attr('name', ac.data('name'));
		ac.data('changed', false);
	});
	$('.form-autocomplete').change(function() {
		var ac = $(this);
		if ($.browser.msie) {
			ac.data('changed', true);
		}
		ac.blur();
	});
  if ($.browser.safari) {
    $('input.form-autocomplete[type="text"]').change(function() {
      var ac = $(this);
      ac.data('changed', true);
      ac.blur();
    });
  }
	$('.form-autocomplete').focus(function() {
		var ac = $(this);
		var real = $(ac.data('real'));
		ac.attr('name', ac.data('name'));
		real.attr('name', ac.data('alias')+ac.data('name'));
	});
	$('.form-autocomplete').each(function() {
		var ac = $(this);
		ac.blur();
	});
};

I have added this code to jquery_autocomplete.js of http://drupal.org/node/640832#comment-4112374 attachment:

  if ($.browser.safari) {
    $('input.form-autocomplete[type="text"]').change(function() {
      var ac = $(this);
      ac.data('changed', true);
      ac.blur();
    });
  }

This works for if you selected an item via arrow keys (up/down). We still need to add event when we use the click event on its dropdown selection items.

Arpeggio
(o-)===#~
Web developer

threexk’s picture

Thanks for taking a look at this bug. And sorry for the delayed response, I did not realize that I was not receiving notifications for new posts on this thread.

Your patched code indeed works if you use the arrow keys, but not if you click an item. The common use case is clicking an item (most users do not use arrow keys), and the module works when clicking an item in Firefox/IE, so it would need to work by click in Chrome.

For what it's worth, I consider the up/down arrow keys to be a separate problem outside the scope of this bounty. The up/down arrow keys do not currently work for Firefox/IE.

Drave Robber’s picture

Hack nodereference.module and save twenty bucks. :)

No, seriously. Hacking modules of course has certain implications (you will have to repeat if CCK 6.x-2.x ever gets a serious update that cannot be skipped, which doesn't seem very likely), but I doubt whether indiscriminately adding a lump of js to bloody _every_ page that happens to contain a form is any better.

Those [nid:666] are contained only in displayed labels, the stored value is plain NID all along.

Comment out line 570 of cck/modules/nodereference/nodereference.module:
$value .= ' [nid:'. $nid .']';
=>
// $value .= ' [nid:'. $nid .']';

and modify line 978:
$matches[$row['title'] ." [nid:$id]"] = '<div class="reference-autocomplete">'. $row['rendered'] . '</div>';
=>
$matches[$row['title']] = '<div class="reference-autocomplete">'. $row['rendered'] . '</div>';

Tested to have no immediate ill effects in Chromium/Ubuntu and Firefox/Ubuntu.

Edit: tested also to work in Konqueror, while that javascript thingy there prevents the form from working altogether (edits are not saved).

threexk’s picture

Appreciate the hack, and you're probably right that that's the easiest way, but our policy where I work is not to modify the code of contributed modules. Reason is that the maintenance of sites often gets transferred to inexperienced developers who are likely to unwittingly obliterate the modifications. If it's its own module, less chance the modifications will be lost in the course of maintenance. I don't like that the JavaScript goes everywhere, but I think the scope eventually be changed to only target forms of interest. Nevertheless, I think your post should be helpful to those who are not so concerned about this maintenance issue.

Drave Robber’s picture

Well, I'll look into politically more correct solutions... :)

Do you need this on node edit forms only, or are nodereference fields present elsewhere, too?

Update: I seem to have successfully overridden all [nid:1234] using another approach (not JavaScript, but hook_form_alter_with_a_big_hammer()); will test a bit more and upload somewhere.

Drave Robber’s picture

Micromodules: Need No NID!

Browser-independent – works even in Konqueror! :)

Use with caution.

threexk’s picture

If two nodes have the same title, one of them will be arbitrarily selected.

See: http://drupal.org/node/157545
And googletorp's answer here: http://stackoverflow.com/questions/1515722/removing-nidn-in-nodereferenc....

The advantage of the jquery_autocomplete module is it still submits the [nid:X] part via hidden element, only hiding it from display. We are using the Node Reference autocomplete widget to select the names of people, and people can have the same name, so duplicate node titles is a problem for us.

I appreciate the effort--and I would settle for another solution if one worked as well as jquery_autocomplete--but with this bounty I was really hoping to find a fix for the jquery_autocomplete Chrome bug.

arpeggio’s picture

I've got working solution for your AC Chrome problem. Please try this:


Drupal.behaviors.jqueryAutocomplete = function (context) {
	$('.form-autocomplete').each(function() {
		var ac = $(this);
		ac.data('changed', false);
		ac.data('alias', 'ac-real-');
		ac.data('rx',  /\s*\[nid:\d+\]\s*/i);
		ac.data('name', ac.attr('name'));
		ac.data('id', ac.attr('id'));
		ac.data('value', ac.val());
		ac.before('<input name="'+ac.data('alias')+ac.data('name')+'" type="hidden" id="'+ac.data('alias')+ac.data('id')+'" value="'+ac.data('value')+'" />');
		ac.data('real', '#'+ac.data('alias')+ac.data('id'));
	});
	$('.form-autocomplete').blur(function() {
		var ac = $(this);
		var real = $(ac.data('real'));
		if ($.browser.msie && !ac.data('changed')) {
			ac.change();
		}
		if (ac.val().match(ac.data('rx'))) {
			real.val(ac.val());
		}
		ac.val(ac.val().replace(ac.data('rx'), ''));
		ac.attr('name', ac.data('alias')+ac.data('name'));
		real.attr('name', ac.data('name'));
		ac.data('changed', false);
	});
	$('.form-autocomplete').change(function() {
		var ac = $(this);
		if ($.browser.msie) {
			ac.data('changed', true);
		}
		ac.blur();
	});
  if ($.browser.safari || $.browser.mozilla) {
    jsACOriginal = Drupal.jsAC.prototype.hidePopup;
    Drupal.jsAC.prototype.hidePopup = function (keycode) {
      jsACOriginal.call(this, keycode);
      var ac = $('input.form-autocomplete[type="text"]');
      var real = $(ac.data('real'));
      if (ac.val().match(ac.data('rx'))) {
        real.val(ac.val());
      }
      ac.val(ac.val().replace(ac.data('rx'), ''));
      ac.attr('name', ac.data('alias')+ac.data('name'));
      real.attr('name', ac.data('name'));
    };
  }
	$('.form-autocomplete').focus(function() {
		var ac = $(this);
		var real = $(ac.data('real'));
		ac.attr('name', ac.data('name'));
		real.attr('name', ac.data('alias')+ac.data('name'));
	});
	$('.form-autocomplete').each(function() {
		var ac = $(this);
		ac.blur();
	});
};

My modification at jquery_autocomplete.js of http://drupal.org/node/640832#comment-4112374 attachment is:

  if ($.browser.safari || $.browser.mozilla) {
    jsACOriginal = Drupal.jsAC.prototype.hidePopup;
    Drupal.jsAC.prototype.hidePopup = function (keycode) {
      jsACOriginal.call(this, keycode);
      var ac = $('input.form-autocomplete[type="text"]');
      var real = $(ac.data('real'));
      if (ac.val().match(ac.data('rx'))) {
        real.val(ac.val());
      }
      ac.val(ac.val().replace(ac.data('rx'), ''));
      ac.attr('name', ac.data('alias')+ac.data('name'));
      real.attr('name', ac.data('name'));
    };
  }

That code works for both click and arrow keys events.

Arpeggio
(o-)===#~
Web developer

threexk’s picture

I tested it out and it works precisely as desired. Thank you. Now users will not have to ask what "nid" means.

threexk’s picture

Bounty paid, thanks again.

Drave Robber’s picture

Umm, people can indeed have the same name, but then I don't quite get why you wanted to remove [nid:xxx] at all. I would rather be looking to replace it with some other information from the node in question, like (b. 12 Jun 1966) or whatever is in there.

The bounty is pretty much irrelevant anyway, but the challenge is interesting.

threexk’s picture

That's a good point. If you have multiple nodes with the same title you would want the user to have some way to disambiguate them when selecting a node. To do this, you would make the title unique, in which case the hook_form_alter() approach would work.

So the JavaScript approach might be flawed. I will think on it. You could have Node Reference fields that only show a subset of nodes. There may be no duplicate titles in that subset. However, there may be duplicate titles across all nodes of the type. In this particular case the JavaScript approach may work where the hook_form_alter() approach would not.