jquery ui autocomplete - manipulating results - javascript

I'm returning multiple pieces of data for each result. In each result I have different link's that I am passing that I'd like to make selectable. Right now no matter where someone clicks on a result it just puts the title into the text box rather than processing the link.
$(function() {
function log(message) {
$("<div/>").text(message).prependTo("#log");
$("#log").attr("scrollTop", 0);
}
$.ajax({
url: "links2.xml",
dataType: "xml",
success: function(xmlResponse) {
var data = $("ROW", xmlResponse).map(function() {
return {
value: $("SC_DF_FIELD_1", this).text(),
url: $("SC_DF_FIELD_2", this).text(),
support_url: $("SC_DF_FIELD_3", this).text(),
description: $("SC_DF_FIELD_4", this).text(),
contact: $("SC_DF_PERSON_LINK", this).text()
};
}).get();
$("#birds").autocomplete({
source: data,
minLength: 0
}).data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.value + "<br>" + item.url + "<br>" + item.description + "<br>" + "Support URL: " + item.support_url + "<br>" + "Contact: " + "Test" + "</a>" )
.appendTo( ul );
};
}
})
});
So I'd like them to be able to click item.url and it goes there, or item.contact and it goes there.
EDIT:
This is the formatItem code I'm trying out. It doesn't seam to have any effect on what is returned.
function formatItem(item, foo, bar, term){
var temp = item.title + '<br /> ' + item.description + '<br />' + '<a href=' + item.url + '>test</a>';
return temp;
}
$.ajax({
url: "links2.xml",
dataType: "xml",
success: function(xmlResponse) {
var data = $("ROW", xmlResponse).map(function() {
return {
value: $("SC_DF_FIELD_1", this).text(),
url: $("SC_DF_FIELD_2", this).text(),
support_url: $("SC_DF_FIELD_3", this).text(),
description: $("SC_DF_FIELD_4", this).text(),
contact: $("SC_DF_PERSON_LINK", this).text()
};
}).get();
$("#birds").autocomplete({
source: data,
minLength: 0,
formatItem: formatItem
})
}
})
});

Disabling the click event handler was not difficult and solved the problem.

You should look at
http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions
, specifically the formatItem and
formatResult options.
Use the formatItem option in lieu of
your _renderItem hack. Having
multiple different links inside of the
auto-complete row is a little more
complicated. I'd suggest that maybe
you just make the formatResult
function do nothing and hook onto your
custom contact links and what not via
.delegate() handler.
Ehh....
The reason that you're having to work around this is because autocomplete isn't designed to have links in the formatted list items. If you look at the source, you'll see that there is a click event handler assigned to the list container, and it returns false on all clicks that happen inside of the list box. With that in mind, a simple .delegate() handler isn't going to fix the problem. You're going to have to first unbind the built-in .click() handler each time it is created. That's a messy hack though, and if you want to do it, I'll let someone else explain it. I'd recommend you just find a different plugin that's meant to work this way or rethink what you're doing.

Related

Javascript adding a variable to my anchor tag

There I am struggling here trying to find a resolution to my following ice of java script.
I have a tree view that I am constructing that will have clickable branches and I am struggling adding the parameter +ele.id+ to the href in the anchor tag inside the second span tag.
I have tried every combination I can think of to no avail and researching around the internet has not proved fruitful .
I am fairly new to both javascript and web/ front end design in general so am working my way up a pretty vertical learning curve. I would be very grateful in deed if any one out there can push me in the right direction to adding my parameter to my href URL or if there is a better way to tackle the problem.
Can anyone help me?
// load in the data
$.ajax({
url: "/InvalidAddressTreeView/GetSubMenue",
type: "GET" ,
data: data ,
dataType: "json",
success: function (d) {
$(this1).removeClass("loadingP");
if (d.length > 0) {
var $ul = $("<ul></ul>");
$.each(d, function (i, ele) {
$ul.append(
$("<li></li>").append(
"<span class = 'collapse collapsible' data-loaded = 'false' pid='" + ele.id + "' treelevel ='" + ele.tree_level + "'> </span>" +
"<span><a href='/SalesRepAddress/Modify?id='>" + ele.name + "</a></span>"
)
);
});
}
}
});
How about creating the elements like :
$('<a/>', {
id: 'foo',
href: 'http://example..com',
title: 'ABC',
text: 'XYZ'
}).appendTo('#mySelector');
You want to append the ele.id after the href link? Like this?
<span><a href='/SalesRepAddress/Modify?id="+ele.id+"'>"+ele.name+"</a></span>
→
$("a").attr("href", $("a").attr("href") + ele.id));

Issue filling select box via ajax call in Django

I am running into an issue creating cascading select boxes (backend Django-though I think this portion is mostly worked out). I have the following javascript code adapted from this stackoverflow response.
$(document).ready(function(){
$('select[name=experiment]').change(function(){
experiment_id = $(this).val();
request_url = '/admin/get_measurements/' + experiment_id + '/';
$.ajax({
url: request_url,
success: function(data){
$.each(data, function(){
$('select[name=measurement_a]').append('<option value="' + this.key + '">' + this.value +'</option>');
// $('select[name=measurement_a]').append($("<option />").val(this.key).text(this.value))
});
},
return: false
})
})
});
In my project I select an experiment which triggers a call to "get_measurements" function and receive a list of "measurements" which should populate the measurement select box. Currently when I select the experiment I see the json response as expected:
{1: "MyFirstMeasurment", 2: "MySecondMeasurement"}
The measurement select box received 2 new selections however, both of them have the text "undefined" as opposed to "MyFirstMeasurement" and "MySecondMeasurement". I am guessing this is something simple in my code, Thank you for the help, let me know if you need more information.
It turns out I needed to do a couple of things to fix this, thanks for the help and hints. Here is the final code.
$(document).ready(function(){
$('select[name=experiment]').change(function(){
experiment_id = $(this).val();
request_url = '/admin/get_measurements/' + experiment_id + '/';
$.ajax({
url: request_url,
success: function(data){
$.each(data, function(key, value){
$('select[name=measurement_a]').append("<option value='" + value + "'>" + value +</option>");
});
},
return: false
})
})
});

Jquery remote completion, li's are not selectable

I'm trying to create a text input with text completion using a remote host.
I've been trying to use the example in the following URL: http://demos.jquerymobile.com/1.4.0/listview-autocomplete-remote/
this is the javascript code from the example:
$( document ).on( "pageinit", "#myPage", function() {
$( "#autocomplete" ).on( "filterablebeforefilter", function ( e, data ) {
var $ul = $( this ),
$input = $( data.input ),
value = $input.val(),
html = "";
$ul.html( "" );
if ( value && value.length > 2 ) {
$ul.html( "<li><div class='ui-loader'><span class='ui-icon ui-icon-loading'></span></div></li>" );
$ul.listview( "refresh" );
$.ajax({
url: "http://gd.geobytes.com/AutoCompleteCity",
dataType: "jsonp",
crossDomain: true,
data: {
q: $input.val()
}
})
.then( function ( response ) {
$.each( response, function ( i, val ) {
html += "<li>" + val + "</li>";
});
$ul.html( html );
$ul.listview( "refresh" );
$ul.trigger( "updatelayout");
});
}
});
});
so first of all I changed dataType from jsonp to json which makes the ajax call
return a proper json object and the unordered list is filled properly.
the problem that I encounter is that once I see the text completion (the li elements), I can't select any of the elements.
I tried browsing this example on my Galaxy Note 2 and I encountered the same problem, the elements are not selectable.
any ideas how to resolve the issue?
thanks
update
as to #Omar comment i changed the following line:
html += "<li>" + val + "</li>";
to
html += "<li><a href='#'>" + val + "</a></li>";
now i can click on an item but it doesn't do anything. it supposed to close the list and add to the text field the selected item.
You need to delegate an event to generated list items and then update input with the value.
$("#autocomplete").on("click", "li", function () {
/* text of clicked element */
var value = $(this).text();
/* update value of input */
$("#autocomplete-input").val(value);
/* optional - remove autocomplete result(s) */
$(this).parent().empty();
});
Demo

Jquery autocomplete images in the returned data

I've gotten jquery autocomplete working on my site, and now I'm trying to get it to display an image from the data that I am pulling from my database.
However I've run into a problem as while it is pulling through my image data and product name, it's displaying the html as text in the autocomplete drop down.
Hopefully someone can see where I'm going wrong and point me in the right direction!
$(document).ready(function() {
$(function() {
$( "#autocomplete" ).autocomplete({
source: function(request, response) {
$.ajax({ url: "<?php echo site_url('homepage_products/suggestions'); ?>",
data: { term: $("#autocomplete").val()},
dataType: "json",
type: "POST",
success: function(data){
var data_to_return = new Array();
for (var i = 0; i < data.length; ++i) {
data_to_return.push("<li><a>" + "<img src='" + data[i].image + "' />" + data[i].prodid+ " - " + data[i].product_name+ "</a></li>");
}
response(data_to_return);
}
});
},
minLength: 4
});
});
});
Thanks!
-------------EDIT-------------
Ok after the suggestion of Spokey I've now altered my code as follows and I've managed to get my results to display in html rather than just text:
$(function() {
$( "#autocomplete" ).autocomplete({
source: function(request, response) {
$.ajax({ url: "<?php echo site_url('homepage_products/suggestions'); ?>",
data: { term: $("#autocomplete").val()},
dataType: "json",
type: "POST",
success: function(data){
var data_to_return = new Array();
for (var i = 0; i < data.length; ++i) {
data_to_return.push("<li><a href = '/shop/products/id/" + (data[i].image).toLowerCase() + ".htm'>" + "<img src='/shop/images/product_thumbs/" + (data[i].image).toLowerCase() + ".jpg' />" + data[i].id + " - " + data[i].name+ "</a></li>");
}
response(data_to_return);
}
});
},
select: function( event, ui ) {
alert(ui.item.value);
window.location.href = ui.item.value;
},
minLength: 2
}).data("autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + item.image + "</a>")
.appendTo(ul);
};
});
However now I'm not getting any specific javascript errors, but the images aren't appearing. I've tried absolute paths, and I've checked that they do exist on the server - but all I get is a grey box when I roll my mouse over where the image should be appearing on the drop down list.
Hopefully someone can spot my mistake!
I also found this for links which I found quite useful and thought I'd recommend for anyone else trying to achieve something similar:
JQuery Autocomplete Where the Results are Links
-------------FINAL FIX-------------
Oops - it was me being an idiot in the end - I was calling
item.image
When I should have been calling
item.label
Thanks for the help!

Using Ajax callback variable values in JQuery dynamic click handlers

I'm doing a simple ajax query which retrieves a variable-length list of values as JSON data. I'm trying to make a list based on this data which has click-functions based on the values I got from the JSON query. I can make this work just fine by writing the onClick-methods into the HTML like this:
function loadFooList() {
var list_area = $("#sidebar");
list_area.html("<ul>")
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
$.each(json, function(i, item) {
var link_id = "choosesfoo" + item.id;
list_area.html(list_area.html()
+ "<li> <a href='#' onClick='alert(\"" +
link_id + "\");'>" +
item.name + "</a></li>");
});
list_area.html(list_area.html() + "</ul>");
}
});
}
I don't like writing the onClick-function into the HTML and I also want to learn how to create this same functionality via JQuery click-function.
So the problem is obviously variable-scoping. My naive attempt here obviously won't work because the variables are no longer there when the click happens:
function loadFooList2() {
var list_area = $("#sidebar");
var link_ids = Array();
list_area.html("<ul>")
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
$.each(json, function(i, item) {
var link_id = "choosefoo" + item.id;
list_area.html(list_area.html()
+ "<li> <a href='#' id='" + link_id + "'>"+item.name+"</a></li>");
link_ids.push(link_id);
});
list_area.html(list_area.html() + "</ul>");
for (link_index=0; link_index<link_ids.length; link_index++) {
$("#" + link_ids[link_index]).click(function() {
alert(link_ids[i]);
});
}
}
});
}
Obviously I'd like to do something else than just alert the value, but the alert-call is there as long as I can get that working and move forward.
I understand that I'll have to make some kind of handler-function to which I pass a state-variable. This works for a single value (I can store the whole link_ids array just fine, but then I don't know which of them is the right value for this link), but how would I do this for arbitrary-length lists?
Here is an example from JQuery docs which I'm trying to copy:
// get some data
var foobar = ...;
// specify handler, it needs data as a paramter
function handler(data) {
//...
}
// add click handler and pass foobar!
$('a').click(function(){
handler(foobar);
});
// if you need the context of the original handler, use apply:
$('a').click(function(){
handler.apply(this, [foobar]);
});
And I quess the last example here, "if you need the context of the original handler..." would probably be what I want but I don't know exactly how to get there. I tried to store the current link_id value into this, use it from this in the applied function (using apply()) but I didn't succeed. The necessary values were still undefined according to FireFox. I'm using JQuery 1.3.2.
So what's the right solution for this relatively basic problem?
Use append instead of html():
function loadFooList() {
var ul = $('<ul>');
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
$.each(json, function(i, item) {
var link_id = "choosesfoo" + item.id;
var a = $('<a>').attr('href','#').bind('click', function(e) {
alert(link_id,item_name);
e.preventDefault();
});
$('<li>').append(a).appendTo(ul);
});
ul.appendTo('#sidebar'); // this is where the DOM injection happens
}
});
}
So the problem appears to be getting the link id associated with the link so that your click handler has access to it. Note that if it's alphanumeric it will qualify for the id attribute and you can extract it from there. If it is purely numeric, it will be an illegal id attribute. In that case, you can either use an attribute, like rel, or the jQuery.data() method to store the link id with the link. You can also simplify by using append. I'll show both examples.
var link = $("<li><a href='#' id='" + link_id + "'>" + item.name + "</a></li>";
link.click( function() {
alert( $(this).attr('id') );
});
list_area.append(link);
or (if numeric)
var link = $("<li><a href='#'>" + item.name + "</a></li>";
link.data('identifier', link_id )
.click( function() {
alert( $(this).data('identifier') );
});
list_area.append(link);
Try this:
function loadFooList() {
var list_area = $("#sidebar");
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
var out = '<ul>';
$.each(json, function(i, item) {
var link_id = "choosefoo" + item.id;
out +="<li><a href='#' id='" + link_id + "'>"+item.name+"</a></li>";
});
out +="</ul>"
var $out = $(out);
$out.find('a').click(function(){
var link_id = this.id;
var item_name = $(this).text();
alert(link_id);
alert(link_name);
})
list_area.html($out);
}
});
}
Using multiple appends causing the browser to redraw multiple times in a row. You only want to modify the dom once.

Categories

Resources