Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make <a> inside jQuery autocomplete clickable

I managed to add a link to the right of the jQuery autocomplete items, using the following code:

function onClientSelect(event, ui) {
    // My handling code goes here
    event.preventDefault();
}

$("#mypage input[name='client']").autocomplete({
    minLength: 1,
    appendTo: $(this).parent(),
    source: '/filter_client/',
    select: onClientSelect,
    focus: function (event, ui) {
        event.preventDefault();
    },
}).data("ui-autocomplete")._renderItem = function (ul, item) {
    return $("<li></li>")
        .data("item.autocomplete", item)
        .append("<a>" + item.label + "</a>")
        .appendTo(ul);
};

My server returns element label in this format:

<div class="ac-item-lb">My Item Label</div>
<a class="ac-item-a" href="/url_to_go_to/" target="_blank">View Detail</a>

What I want to do is to open the link in a new tab when I click on 'View Detail', which clicking any other area executes onClientSelect just like normal. However, currently left-clicking on the link also executes onClientSelect. The only way to open the link is to click the middle wheel or right mouse button and select 'open in new tab'.

I tried attaching a click event handler on the link with event.stopImmediatePropagation() but that doesn't seem to work. Does anyone have any idea how to fix this?

like image 457
pinghsien422 Avatar asked Jun 09 '15 08:06

pinghsien422


3 Answers

One way to do it is by defining a custom select function and by not using an <a> for the links

HTML:

<div class="ui-widget">
    <label for="tags">Tags:</label>
    <input id="tags">
</div>

JS:

 var availableTags = [
    "ActionScript",
    "AppleScript",
    "Asp",
    "BASIC",
    "C",
    "C++",
    "Clojure",
    "COBOL",
    "ColdFusion",
    "Erlang",
    "Fortran",
    "Groovy",
    "Haskell",
    "Java",
    "JavaScript",
    "Lisp",
    "Perl",
    "PHP",
    "Python",
    "Ruby",
    "Scala",
    "Scheme"];

$("#tags").autocomplete({
    source: availableTags,
    select: function (event, ui) {
        var elem = $(event.originalEvent.toElement);
        if (elem.hasClass('ac-item-a')) {
            var url = elem.attr('data-url');
            event.preventDefault();
            window.open(url, '_blank ');
        }
    }
}).data("ui-autocomplete")._renderItem = function (ul, item) {
    return $("<li></li>")
        .data("item.autocomplete", item)
        .append('<a>' + item.label + '<span class="ac-item-a" data-url="http://www.nba.com"> View Details</span></a>')
        .appendTo(ul);
};

JSFIDDLE.

like image 162
Amir Popovich Avatar answered Nov 06 '22 21:11

Amir Popovich


Have you thought about putting a conditional in your click handler to not preventDefault when it is that link? If you test if the element should function as normal then you can return early before the preventDefault and then the link should function as normal.

Here is an example (JSBin):

function clickHandler(e) {
  // If the target element has the class `test-clickable` then the
  // function will return early, before `preventDefault`.
  if (this.className.indexOf('test-clickable') !== -1) {
    return;
  }

  alert('That link is not clickable because of `preventDefault`');
  
  e.preventDefault();
}

$('a').click(clickHandler);
a {
  display: block;
}
a:after {
  content: ' [class=' attr(class)']';
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>Title</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>

<body>
  <a class='test-clickable' href='http://www.google.com' target='_blank'>Link</a>
  <a class='test-not-clickable' href='http://www.google.com' target='_blank'>Link</a>
</body>

</html>
like image 5
pseudosavant Avatar answered Nov 06 '22 19:11

pseudosavant


Amir, regarding to your answer, I think that opening window inside javascript function from select event can be blocked by PopupBlocker

pinghsien422 , your server side should return Json and not complete html , if you must return complete html, make the following changes:

1.Remove the clientSelect function

2.No 'a' tag is needed in renderData function

 $("#mypage input[name='client']").autocomplete({
   minLength: 1,
  appendTo: $(this).parent(),
   source: '/filter_client/',
  focus: function (event, ui) {
    event.preventDefault();
  },
}).data("ui-autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
    .data("item.autocomplete", item)
    .append( item.label )
    .appendTo(ul);
};
like image 3
Elisheva Wasserman Avatar answered Nov 06 '22 21:11

Elisheva Wasserman