问题
I am using jquery-ui's autocomplete on two input fields of an HTML form in a Sinatra app. They work on my local machine but not on Heroku. Jquery-ui's datepicker works on this same page, so I know the jquery and jquery-ui javascript files are being loaded correctly. Also, I can see that the variable that I am using as the source for the autocomplete is actually getting populated from the database. There are no console errors as well.
Here's the HTML:
<form action="/add-event" method="post">
Date: <input id="datepicker" class="required" type="text" maxlength="50" name="date" /><br />
Headliner: <input id="headliner" class="required" type="text" maxlength="50" name="headliner" /><br />
Venue: <input id="venue" class="required" type="text" maxlength="50" name="venue_name" /><br />
</form>
There are some other fields in the form, but they don't play a part in any of this.
Here's the Jquery:
<script type="text/javascript">
var artist_names = [<%= @artist_names %>];
var venue_names = [<%= @venue_names %>];
$(document).ready(function() {
//Set button disabled
$("input[type=submit]").attr("disabled", "disabled");
var submitForm = function(date, headliner, venue) {
//If form is validated enable form
if ((date != "") && ($.inArray(headliner, artist_names) != -1) && ($.inArray(venue, venue_names) != -1))
{
$("input:submit#event").removeAttr("disabled");
}
else
{
$("input:submit#event").attr("disabled", true);
}
$('#typing').html(date+headliner + venue);
}
$("#datepicker").datepicker({
onSelect: function(dateText, inst) { submitForm(this.value, $('#headliner').val(), $('#venue').val()) }
});
$("#headliner").autocomplete({
source: artist_names,
select: function(event, ui) {
submitForm($('#datepicker').val(), ui.item.value, $('#venue').val());
$('#add-artist').empty();
}
});
$("#venue").autocomplete({
source: venue_names,
select: function(event, ui) {
submitForm($('#datepicker').val(), $('#headliner').val(), ui.item.value);
$('#add-venue').empty();
}
});
//Append a change event listener to you inputs
$('#headliner').keyup(function() {
var val = $('#headliner').val();
if ($.inArray(val, artist_names) == -1)
{
if (val=="")
{
$('#add-artist').empty();
}
else
{
$('#add-artist').html("<strong>" + val + "</strong> isn't in our database. you must first add a profile for them to add this event!<br /><form action='/add-artist-event' method='post'><br />Artist Name: <input type='text' maxlength='50' name='artist_name' value='" + val +"' /><br /> Website: <input type='text' maxlength='50' name='artist_website' /><br /> Facebook: <input type='text' maxlength='50' name='artist_facebook' /><br />Twitter: <input type='text' maxlength='50' name='artist_twitter' /><br />Soundcloud: <input type='text' maxlength='50' name='artist_soundcloud' /><br />Bandcamp: <input type='text' maxlength='50' name='artist_bandcamp' /><br /><button type='button' id='add-artist-button' onclick='addNewArtist();'>Add New Artist!</button></form><br /><br />" );
}
$("input:submit#event").attr("disabled", true);
}
else
{
$('#add-artist').empty();
submitForm($('#datepicker').val(), $('#headliner').val(), $('#venue').val());
}
});
$('#venue').keyup(function() {
var val = $('#venue').val();
if ($.inArray(val, venue_names) == -1)
{
if (val=="")
{
$('#add-venue').empty();
}
else
{
$('#add-venue').html("<strong>" + val + "</strong>" + " is not in our database. you must first add a profile for this venue to add this event!<br /><form action='/add-venue-event' method='post'><br />Venue Name: <input type='text' maxlength='50' name='venue_name' value='" + val +"'/><br />Address: <input type='text' maxlength='50' name='venue_address' /><br />City: <input type='text' maxlength='50' name='venue_city' /><br />State: <input type='text' maxlength='50' name='venue_state' /><br />Zip: <input type='text' maxlength='50' name='venue_zip' /><br />Phone: <input type='text' maxlength='50' name='venue_phone' /><br /> Website: <input type='text' maxlength='50' name='venue_website' /><br /> Facebook: <input type='text' maxlength='50' name='venue_facebook' /><br />Twitter: <input type='text' maxlength='50' name='venue_twitter' /><br /><button type='button' id='add-venue-button' onclick='addNewVenue();'>Add New Venue!</button> </form><br /><br />");
}
$("input:submit#event").attr("disabled", true);
}
else
{
$('#add-venue').empty();
submitForm($('#datepicker').val(), $('#headliner').val(), $('#venue').val());
}
});
});
var addNewArtist = function() {
$.post('/add-event/new-artist', {
artist_name: $(':input[name="artist_name"]').val(),
website: $(':input[name="artist_website"]').val(),
facebook: $(':input[name="artist_facebook"]').val(),
twitter: $(':input[name="artist_twitter"]').val(),
soundcloud: $(':input[name="artist_soundcloud"]').val(),
bandcamp: $(':input[name="artist_bandcamp"]').val()
},
function(output) {
artist_names = output.split(',');
$('#add-artist').html(output);
$('#headliner').autocomplete("option", { source: artist_names });
});
};
var addNewVenue = function() {
$.post('/add-event/new-venue', {
venue_name: $(':input[name="venue_name"]').val(),
street_address: $(':input[name="venue_address"]').val(),
city: $(':input[name="venue_city"]').val(),
state: $(':input[name="venue_state"]').val(),
zip: $(':input[name="venue_zip"]').val(),
phone: $(':input[name="venue_phone"]').val(),
email: $(':input[name="venue_email"]').val(),
website: $(':input[name="venue_website"]').val(),
facebook: $(':input[name="venue_facebook"]').val(),
twitter: $(':input[name="venue_twitter"]').val()
},
function(output) {
venue_names = output.split(',');
$('#add-venue').html(output);
$('#venue').autocomplete("option", { source: venue_names });
});
};
</script>
I was hoping to avoid including all the javascript in the question, but I think it's best that I do. The only other piece is that when I "view source" in chrome I see the two variables are indeed getting populated with data:
var artist_names = [["'Bubonic Bear', "]];
var venue_names = [["'Electric Factory', "]];
UPDATE
If I hardcode a list for the "headliner" field's autocomplete function, the autocomplete works.
$("#headliner").autocomplete({
//source: artist_names,
source: ["band1", "band2", "band3"],
select: function(event, ui) {
submitForm($('#datepicker').val(), ui.item.value, $('#venue').val());
$('#add-artist').empty();
}
});
I'm still not sure of the solution, it seems odd that a variable would be accessible in a local instance of the app and not on heroku. Anyway, I will add more if I figure out more.
回答1:
I don't see how that would work anywhere. Your data sources:
var artist_names = [<%= @artist_names %>];
var venue_names = [<%= @venue_names %>];
come out as:
var artist_names = [["'Bubonic Bear', "]];
var venue_names = [["'Electric Factory', "]];
and that's not the right format for the jQuery-UI Autocomplete widget. The source
option should be a simple array of strings when you're using an inlined source.
You should be inlining your arrays in JSON format:
var artist_names = <%= @artist_names.to_json %>;
var venue_names = <%= @venue_names.to_json %>;
and that should produce things like this:
var artist_names = ["Bubonic Bear"];
var venue_names = ["Electric Factory"];
and the autocomplete widget will be happy with that.
You can play with this demo to see the difference:
http://jsfiddle.net/ambiguous/Brb9p/
来源:https://stackoverflow.com/questions/8827186/jquery-ui-autocomplete-works-locally-not-on-heroku