I've a simple input for which I use jquery autocomplete. I want to manage the display myself so I use the _renderItem method. Then when navigating with the up and down arrows, this raises error Uncaught TypeError: Cannot read property 'value' of undefined Even stranger, this error is triggered once every two key strokes...
html:
<input type="text" id="input" placeholder="Name"/>
<ul id='ul'></ul>
js:
var data = ['bob', 'alice', 'rob'];
var my_ul = $('#ul');
var $input = $('#input').autocomplete({
search: function(event, ui) {
my_ul.empty();
},
source: data,
});
$input.data('ui-autocomplete')._renderItem = function(ul, item) {
var el = $('<li>');
el.append('<div>'+item.label+'</div>');
el.appendTo(my_ul);
return el;
};
here is a jsfiddle http://jsfiddle.net/4dw2aa75/ (open your console to see errors)
Related
I have a working UI Auto complete with jQuery. I wanted to change the way it worked. Instead of a new browser tab opening with the user selects a value from the list I wanted the user to first pick a value then click a search button to trigger the event.
It works but if you perform a search and then a second search it will trigger the previous URL and new URL at the same time. Also if you perform a search then click the search button without typing anything into the search input it triggers the previous search. Weird right? I'll add my code but I think a codepen example will help clarify what I mean.
The other issue I was having is I am trying to set up a custom alert if the value typed is not in the array but I get the invalid error message no matter what I type. I added that as well in the code. It is one of the if statements.
JS
var mySource = [
{
value: "Google",
url: "http://www.google.com"
},
{
value: "Yahoo",
url: "https://www.yahoo.com"
},
{
value: "Hotmail",
url: "https://hotmail.com"
},
{
value: "Reddit",
url: "https://www.reddit.com"
}
];
//Logic for ui-autocomplete
$(document).ready(function() {
$("input.autocomplete").autocomplete({
minLength: 2,
source: function(req, resp) {
var q = req.term;
var myResponse = [];
$.each(mySource, function(key, item) {
if (item.value.toLowerCase().indexOf(q) === 0) {
myResponse.push(item);
}
if (item.value.toUpperCase().indexOf(q) === 0) {
myResponse.push(item);
}
//Add if statement here to determine if what the user inputs is in the
// array
//and if not in the array give an error to #textAlert.
//Example
if (item.value.indexOf(q) != myResponse) {
$('#alertText').text("Invalid Search");
} else {
return false;
}
});
resp(myResponse);
},
select: function(event, ui) {
$('#appSearchBtn').one("click", function() {
window.open(ui.item.url);
$('#appsearch').val('');
return false;
});
}
});
});
//Input and ui text clears when clicked into
$(document).ready(function() {
var input = document.querySelector('#appsearch');
var ui = document.querySelector(".ui-helper-hidden-accessible");
input.onclick = function() {
input.value = '';
ui.textContent = '';
};
});
HTML
<p id="alertText"></p>
<div class="input-group">
<input type="text" id="appsearch" class="form-control autocomplete" placeholder="Application Search" />
<span class="input-group-btn">
<button class="btn btn-primary inputBtn" id="appSearchBtn" type="button">Search</button>
</span>
</div>
Here is a Code pen https://codepen.io/FrontN_Dev/pen/MEmMRz so you can see how it works. I also added how it should work and what the bugs are.
9/29/17 #0732
I resolved the issue with the event firing the same URL over and over but I still need help with the custom invalid search message that appears for every search even if the value is in the array.
I am quite new to MVC, I had a function that I wrote to override the default event on a submit button and I would update a partial view based on the submit form. It was working great. Then it just stopped working. The only thing I've changed is that I've added a few webshim things for a datepicker (IE 9). I tried commenting this out and nothing. I placed an error function in the ajax call, and sure enough, the call is failing for some reason. Below is my ajax call:
<script>
$(document).ready(function () {
$("#DropDownForm").on("submit", function (event) {
//Prevent default action on the drop down submit form
event.preventDefault();
var form = $(this);
var Project = $('#ProjectDropDown').val();
var Release = $('#ReleaseDropDown').val();
//Instead run this function - find Release and update table
$.ajax({
url: form.attr("action"),
//async: false,
method: form.attr("method"),
data: form.serialize(),
error: function (exception) { alert(exception + "\n" + form.serialize() + "\n" + form.attr("action") + "\n" + form.attr("method")) }
})
.done(function (result) {
$("#ReleaseTableBodyForm").empty();
$("#ReleaseTableBodyForm").html(result +
'<br/><div><button style=\"text-align:center\">Submit</button></div>');
});
});
});
</script>
The form it is referencing:
#using (Html.BeginForm("LoadRelease", "Home", FormMethod.Post, new { id = "DropDownForm", style = "" }))
{
#*Dropdowns*#
<select id="BusinessAreaDropDown" name="BusinessArea" onchange="javascript: FillGenericProject(); FillProject(); FillReleases();" style="width: 11em;">
#Html.Partial(#"Dropdowns\_BusinessArea", Model.ProjectViewModels);
</select>
<select id="GenericProjectDropDown" name="GenericProject" onchange="javascript: FillProject(); FillReleases();" style="width: 11em;"></select>
<select id="ProjectDropDown" name="Project" style="width: 18em;" onchange="javascript: FillReleases();"></select>
<select id="ReleaseDropDown" name="Release" style="width: 11em;"></select>
<button type="submit" id="GoButton" style="visibility:hidden;">Go</button>
}
And the controller that it was calling very happily until recently (In HomeController.cs)
[HttpPost]
public ActionResult LoadRelease(string Project, string Release)
{
var ProjectID = _ProblemReportsDB.ProjectMaps
.Where(r => r.Project == Project)
.Select(r => r.ID).FirstOrDefault();
ViewBag.Project = Project;
var Releases = from row in _ProblemReportsDB.PlannedOpenCloses
where (row.Project == ProjectID && (Release == null || row.Release == Release))
select row;
return PartialView("_TableBody", Releases.ToList());
}
I just have no idea how to debug the ajax call.
The error call is outputting this:
[object Object]
BusinessArea=Test1&GenericProject=Test2&Project=Test3&Release=Create+New+Release
/Home/LoadRelease
post
All of which is correct. Just simply fails. Is there some way I can get more information from the ajax error parameters? [object Object] is kind of useless to me.
Is there some way I can get more information from the ajax error
parameters? [object Object] is kind of useless to me.
As per the documentation for $.ajax
error Type: Function( jqXHR jqXHR, String textStatus, String
errorThrown )
Function receives three arguments: The jqXHR (in jQuery 1.4.x,
XMLHttpRequest) object, a string describing the type of error that
occurred and an optional exception object, if one occurred. Possible
values for the second argument (besides null) are "timeout", "error",
"abort", and "parsererror".
When an HTTP error occurs, errorThrown
receives the textual portion of the HTTP status, such as "Not Found"
or "Internal Server Error." As of jQuery 1.5, the error setting can
accept an array of functions. Each function will be called in turn.
Note: This handler is not called for cross-domain script and
cross-domain JSONP requests. This is an Ajax Event.
So the [object] you're getting is the jpXHR which is the jquery wrapper for the underlying XMLHttpRequest. If you want status text and error message, then add the additional parameters to your error callback:
error: function (xhr, textStatus, errorThrown) {
console.error(textStatus + "\n" + errorThrown);
}
Javascript is not like C# in this respect. All arguments are essentially optional and you can also pass more arguments than a function signature requires.
I have a jQueryUI autocomplete that pulls from a list of customers and is attached based on the selector [input data-role="customer-search"]. Once a customer is selected, I make a AJAX call to get the full customer detail. This part I have working fine. The issue is that I am having trouble figuring out a way to incorporate knockout into this. My ideal situation is a custom binding like "onSelect: customerSelected", which would take in the selected Customer JSON and integrate it into the overall model, which would then cause updates to a bunch of fields on the page with bingings such as model.Customer.Address, model.Customer.Type.
The place I am butting my head against is that connection point after I've gotten the Customer JSON back from the AJAX call, how to send it to the "customerSelected" method on the viewmodel tied to the same input I attached the jQuery autocomplete.
Here is a simplified version of a bindinghandler my team wrote for handling autocomplete. When an item is selected, the item is inserted into an observable array in the view model. It is bound in the following manner:
<input type="text" data-bind="autoComplete:myObservableArray, source:'myUrl'" />
You can customize what happens when an item is selected in the 'select:' area.
ko.bindingHandlers.autoComplete = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var postUrl = allBindingsAccessor().source; // url to post to is read here
var selectedObservableArrayInViewModel = valueAccessor();
$(element).autocomplete({
minLength: 2,
autoFocus: true,
source: function (request, response) {
$.ajax({
url: postUrl,
data: { term: request.term },
dataType: "json",
type: "POST",
success: function (data) {
response(data);
}
});
},
select: function (event, ui) {
var selectedItem = ui.item;
if (!_.any(selectedObservableArrayInViewModel(), function (item) { return item.id == selectedItem.id; })) { //ensure items with the same id cannot be added twice.
selectedObservableArrayInViewModel.push(selectedItem);
}
}
});
}
};
Hopefully, it's something like this that you're looking for. If you need something clarified, let me know.
Note Besides jquery and knockout, this example uses underscore.js ( the _.any() function)
valueUpdate: blur
data-bind="value: textbox, valueUpdate: blur" binding fixed the problem for me:
$(function() {
$(".autocomplete").autocomplete({
source: [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Scheme"]
});
});
var viewModel = {
textbox: ko.observable()
};
ko.applyBindings(viewModel);
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
<input type="text" class="autocomplete" data-bind="value: textbox, valueUpdate: blur"/>
im working on this jquery data entry form in which i need a specific field to be autocompleted with data from mysql
i got everything working, autocomplete retrieves data from the sql through php matching is great in english/latin and utf8 characters
the values get retrieved from the sql as "'number' => 'name'"
right now the autocomplete has 3 values in the output, value, label and id.
as id and value it uses the 'name'
and the label is the 'number' of my sql string (which is posted to the next page when the form is submited)
so everyting works ok, my 'number' is posted correctly, there is a minor annoyance tho
when i select something from the autocomplete list, the field is populated with the 'number'
is there any way to fill it with the 'name'?
ie: search for 'name', get dropdown with 'names', click and get the 'name' in the field, and when i submit i get the 'number' posted?
any help would be greatly appreciated.
if you need to take a look at my code, it's posted on a previous question: Jquery ui - Autocomplete - UTF8 charset
thanx in advance :)
The usual way to do this is:
Use a hidden input to hold the value you'd like to POST, then autocomplete a separate field.
Populate the hidden input on select
Populate the visible, autocompleted input with the label property of the item that was selected.
So, for example:
HTML:
<input type="hidden" name="name" />
<input type="text" id="name_auto" />
JavaScript:
$(function () {
var cache = {},
lastXhr;
$( ".name" ).autocomplete({
minLength: 1,
source: function( request, response ) {
var term = request.term;
if ( term in cache ) {
response( cache[ term ] );
return;
}
lastXhr = $.getJSON( "search.php", request, function( data, status, xhr ) {
cache[ term ] = data;
if ( xhr === lastXhr ) {
response( data );
}
});
},
select: function (event, ui) {
event.preventDefault();
this.value = ui.item.label;
},
change: function (event, ui) {
if (ui.item) {
$("input[name='name']").val(ui.item.value);
} else {
$("input[name='name']").val('');
}
}
});
});
You can use the result (handler) from u'r autocomplete
where the variable data such as arrays and you can return two data at once
Expl:
in javascript
$().ready(function()
{
var url = "<?=base_url()?>index.php/master/agen";
var width_val = 308;
$("#name_auto").autocomplete(url,
{
width: width_val,
selectFirst: false,
});
$("name_auto").result(function(event, data, format)
{
$("#name_auto").val(data[0]);
$("#id").val(data[1]);
});
});
in HTML :
<input type="hidden" name="number" id="id" />
<input type="text" id="name_auto" name="name" />
in PHP :
foreach ($source->result() as $row)
{
echo "$row->nama|$row->id\n";
}
note : here I use PHP CodeIgniter in its
I'm trying to get an autocomplete field firing in my asp.net mvc website. Basically the user types in their location and i go out to my db and pre-populate with country and postcodes that match.
The problem im having is that when the view load an error throws saying "Microsoft JScript runtime error: Exception thrown and not caught". It is throwing in the jquery.Ui.widget.js file at the following line:
throw "cannot call methods on " + name + " prior to initialization; " +
"attempted to call method '" + options + "'";
Following is my script:
<script type="text/javascript" language="javascript">
$(function () {
$.ajaxSetup({ type: "POST" });
$('#Location').autocomplete('<%= Url.Action("Find") %>', {
dataType: 'json',
parse: function (data) {
var rows = new Array();
for (var i = 0; i < data.length; i++) {
rows[i] = { data: data[i], value: data[i].PlaceName, result: data[i].PlaceName, id: data[i].LocationID };
}
return rows;
},
formatItem: function (row) {
return row.PlaceName;
},
delay: 300,
autofill: true,
selectFirst: true,
highlight: false
}).result(function (event, row) {
$("input[id$='LocationID']").val(row.LocationID);
});
});
</script>
I've made sure all the needed jquery files are attached but still cant get it to fire. Ive got the simple default functionality of the autocomplete control to fire (showing a prepopulated list), but as soon as i try to pull from a Json datatype it gives me grief.
Any ideas?
You can check out my answer to Ben here, hopefully it will help you too.