So I have two autocomplete containers. Instead of writing code twice, I will use the same autocomplete call.
But in order to triger correct autocomplete (read: populate correct result list), I need to assign it to a variable. I've done this a long time ago, but I have forgotten how I did it.
So I have the following:
autocomplete: function () {
var autocompleteInput = null;
var autocompleteResultList = null;
$('.autocomplete').on("input", function (e) { // I have 2 of these
autocompleteInput = $(this); // This is the input i'm working with
autocompleteResultList = autocompleteInput.closest('.autocomplete-result');
resourcesData(autocompleteInput.val());
}).on('focus', function (e) {
autocompleteInput.val(''); //Cannot read property 'val' of null
}).on('blur', function (e) {
autocompleteResultList.removeClass('is-active');
});
}
My HTML x 2 (short version)
<div class="autocomplete-wrapper">
<input class="autocomplete" type="text" >
<input class="resource-id" type="hidden">
<div class="autocomplete-result"></div>
</div>
I'm pretty sure it' some basic jQuery knowledge in regards of setting a variable = a jQuery object (autocompleteInput = $(this);) and how it all works that I've forgotten.
Any help appreciated :)
PS. I'm not using jQuery autocomplete - I've made my own.
You have to abandon the variables that you share across the different event callbacks. But since they are easy to derive, just do that in each event handler itself.
Some things to note:
The closest method only looks to parents, not to siblings, so use the siblings method instead (or if your structure is slightly different than in your question, maybe .closest(".autocomplete-wrapper").find(".autocomplete-result")).
resourcesData is currently not provided with any information about where it should populate the data, so you should pass it an extra argument for it to know where to populate, and deal with that argument in that function.
Suggested code would then be:
autocomplete: function () {
$('.autocomplete').on("input", function (e) {
// extra argument
resourcesData($(this).val(), $(this).siblings('.autocomplete-result'));
}).on('focus', function (e) {
$(this).val('');
}).on('blur', function (e) {
$(this).siblings('.autocomplete-result').removeClass('is-active');
});
}
So after good help from Patric, Baao and Trincot (and others), I got it working. So just want to share my working solution just incase others are facing similar issues. It's probably not the most elegant solution, but it's working :)
let resources = {
init: function () {
this.searchResources();
},
searchResources: function () {
var self = this;
$('.autocomplete').on("input", function (e) {
let term = $(this).val();
if(term.length > 1){
self.autocomplete($(this));
}
}).on('focus', function (e) {
$(this).val('');
}).on('blur', function (e) {
$(this).closest('.autocomplete-result').removeClass('is-active');
});
},
autocomplete: function(obj){
let url = 'http://localhost.no:8080/resources%TERM';
url = url.replace('%TERM', '/' + $(obj).val() );
var resultList = $(obj).siblings('.autocomplete-result');
let source = $('#autocomplete-list').html();
let template = Handlebars.compile (source);
$.ajax({
method: "GET",
url: url,
dataType: "json",
success: function(result) {
let content = template({resources: result.data});
$(resultList).html(content);
$('.autocomplete-list-item').on('click', function (e) {
$(obj).siblings('input.resource-id').val($(this).data('resource-id'));
$(obj).val($(this).data('resource-name'));
$(resultList).removeClass('is-active');
console.log($(this).data('resource-id'));
console.log($(this).data('resource-name'));
});
},
error: function(err){console.log(err);}
}).done(function () {
var resultList = $(obj).siblings('.autocomplete-result');
if(!$(resultList).hasClass('is-active')){
$(resultList).addClass('is-active')
}
});
}
};
One of my input fields looks like this:
<div class="input-field column is-6 autocomplete-wrapper">
<input id="autocomplete-owner" class="autocomplete" autocomplete="off" type="text" >
<label for="autocomplete-owen">Prosjektleder</label>
<input id="resource-id-owner" class="resource-id" type="hidden" name="resource-id-owner">
<div class="autocomplete-result"></div>
</div>
Related
I have a download button set up on a web page that is iteratively assigned an ID based on the how many questions are posted.
Here is the button:
<input data-bind="attr: { id: $index() }" type="button" value="Download" class="download" />
Here is the the JS function that finds the number assigned and does the onclick:
#Scripts.Render("~/bundles/knockout")
<script type="text/javascript">
var SDNo = 0;
$(document).ready(function () {
SystemJS.import('sd/questions').then(function (modules) {
//Code here for another section that fills out the questions not relevant apart from assigning SDNo
});
SystemJS.import('sd/download').then(function (modules2) {
var attachVM = new modules2.Attachment();
//$("#download").click(function () {
$("input[class^='download'], input[class*=' download']").each(function () {
$(this).click(function () {
var id = $(this).attr('id');
let passedValue = id.concat("-" + SDNo);
attachVM.download(passedValue);
});
});
});
The above function allows me to go off to a typescript file and handle the required API call to GET a file
that code is here:
typescript
export class Attachment {
async download(ID: Number) {
window.open(await WebApi.getJSON('SD', 'Download', Number));
}
}
So yeah it'll work then it'll randomly stop working for no reason that I can find and obviously no errors thrown, via debugging it doesn't even get into the typescript file at all nothing happens. But then sometimes it goes all the way through into the controller doing what it needs to do.
As per #LouysPatriceBessette
$("input[class^='download'], input[class*=' download']").each(function () {
$(this).click(function () {
var id = $(this).attr('id');
let passedValue = id.concat("-" + SDNo);
attachVM.download(passedValue);
});
to
$("input.download").on("click", function() {
var id = $(this).attr('id');
let passedValue = id.concat("-" + SDNo);
attachVM.download(passedValue);
});
And it works consistently now thank you again.
I couldn't find any solutions for my problem yet. Maybe I used wrong keywords.
I'm trying to update the value of an input field onchange after a .load() action has been performed.
Here is my script:
$(document).on("change",".myInput",function() {
var value = $(this).val();
$('#actionDiv').load("someAction.php?value="+value, function() {
$(this).val('OK');
});
});
So, after someAction.php has been loaded into #actionDiv successfully, I'd like to change the value of that input field, that has been changed.
I have several input fileds, which take this kind of action...
It seems "$(this)" is unknown in the function after load() has been completed.
Can anyone please help?
Thanks
You need to store a reference to the element, or use an arrow method which doesn't change the value of this
$(document).on("change",".myInput",function() {
var that = this;
var value = $(that).val();
$('#actionDiv').load("someAction.php?value="+value, function() {
$(that).val('OK');
});
});
OR
$(document).on("change",".myInput",function(e) {
var value = $(e.target).val();
$('#actionDiv').load("someAction.php?value="+value, function() {
$(e.target).val('OK');
});
});
OR
$(document).on("change",".myInput",function() {
var value = $(this).val();
$('#actionDiv').load("someAction.php?value="+value, () =>{
$(this).val('OK');
});
});
I have the following function, I want to get called everytime, user types something in the typeahead input field.
function getAllActiveUsers() {
var userList = $('#usersTable').jqGrid('getGridParam').userData;
var userNames = {};
if(userList) {
// Return the list of all active users
$(userList).each(function() {
if(this.userStatus != 1) {
// If the user is verified
// Could be active/inactive
userNames.user = this.username;
}
});
}
return JSON.stringify(userNames);
}
HTML:
<div id="the-basics">
<input class="typeahead" type="text" data-provide="typeahead" placeholder="User List">
</div>
I have been browsing through, the examples, but do not understand how to implement this functionality.
Edit:
Why it doesn't work when I initialize as :
$('.typeahead').typeahead({
source : getAllActiveUsers
});
Try this
$(document).ready(function(){
$('.typeahead').keyup(function(){
getAllActiveUsers();
});
});
You can use .keyup jquery function
$( ".typeahead" ).keyup(function() {
getAllActiveUsers();
});
Taken from the reference you gave you can specify the class .typeahead inside the id #the-basics:
$(document).ready(function(){
$('#the-basics .typeahead').typeahead({
//code here;
}
}
Since the page can't be manipulated safely until the document is ready you should be using $(document).ready.
Also, try to use your browser console and check if you can reach $('#the-basics .typeahead')
You can use Jquery Keyup which gets triggered when a key is released.
$( ".typeahead" ).on('keyup',function() {
getAllActiveUsers();
});
if your text box coming dynamically then you should try
$(document).on("keyup", ".typeahead" , function() {
getAllActiveUsers();
});
try this and let us know if its works or not.
It should be possible
var getAllActiveUsers = function(q, cb, cb2) {
// cb for sync, cb2 for async
var userList = $('#usersTable').jqGrid('getGridParam').userData;
var filterted = /* whatever you want to do with q */;
cb(filtered);
};
$('.typeahead').typeahead({
/* Options */
},
{
source : getAllActiveUsers
});
When I use this code it bind my $.post() to a form and prevent a page reload for submitting it:
$("#analyze_audio").submit(function (e) {
debugger;
e.preventDefault();
var url = "/analyze_audio";
var dataToSend = {"analyze_audio": "analyze_audio"};
var callback = function (data) {
debugger;
document.getElementById("audioresponse").innerHTML = (data);
};
$.post(url, dataToSend, callback, 'html');
});
But it doesn't trigger the debuggers I used in it, so it doesn't bind the event to my function correctly, but when I use this code fragment, it works perfectly:
$(function() {
$("#analyze_audio").submit(function (e) {
debugger;
e.preventDefault();
var url = "/analyze_audio";
var dataToSend = {"analyze_audio": "analyze_audio"};
var callback = function (data) {
debugger;
document.getElementById("audioresponse").innerHTML = (data);
};
$.post(url, dataToSend, callback, 'html');
});
});
I really don't understand why?
When you're working with jQuery (which you clearly are), wrapping a function in $( ) makes it a function that's called by the library when the "DOM ready" event is received from the browser. It thereby defers execution of your code until the DOM is fully built. That makes your code work because it ensures that the element with id "analyze_audio" is present.
There's nothing syntactically special about $( ) — it's just a simple function call, to a function named $ (which is the main entry point to the jQuery library).
You may see code that does something similar:
$(document).ready(function() { ... });
That does precisely the same thing (and is also a jQuery idiom). There's no reason to use that form unless you enjoy typing in extra characters.
$(function() {}); is just a shortcut for document.ready. It would work the same like this:
<script type="text/javascript">
$(document).ready(function() {
$("#analyze_audio").submit(function (e) {
debugger;
e.preventDefault();
var url = "/analyze_audio";
var dataToSend = {"analyze_audio": "analyze_audio"};
var callback = function (data) {
debugger;
document.getElementById("audioresponse").innerHTML = (data);
};
$.post(url, dataToSend, callback, 'html');
});
});
</script>
When you bind event to the form #analyze_audio it not present in DOM yet. If you put your script after the html with form, then it will work. Or you can use $(document).ready() to add your binding or just $(function(){}) both this functions will be executed when whole page will be loaded.
I got an problem with dynamically added DOM objects in jQuery. First of all I use this:
var $input = $('#search-input');
var $usersList = $('#ulist');
$input.on('input', function () {
$.ajax({
type: 'get',
url: '/userlist',
data: {query: $input.val()},
success: function (response) {
var json = JSON.parse(response);
$usersList.empty();
$.each(json, function (index, val) {
$usersList.append("<div id=\"listelem\">" + val + "</div>");
});
}
});
});
<div id="ulist"></div>
<input id="search-input" type="text">
to insert divs into usersList. This works well, but now I want to get val from this div when I click on it to process it further. I wrote this piece of code:
$usersList.on('click','#listelem', function(){
alert("clicked");
});
When I click on div I got proper alert, but now I have no idea how could I took data from inside of this element.
I don't know the proper engineering but I have dealt with similar issue while I was developing some requirements. basically as I understood you want to find out the target of the event and drag a value from there? if so you can do something like this:
jQuery(document).on('click', '#listelem', function(event){
var x = event.target.val();// event.target.value; depending on your situation and availability of the method.
});
Hope this helps.
try this
$(document).on('click','#listelem', function(event) {
alert($(event.target).text());
});
jsfiddle
Thanks you for help. for me proper option was to call
var mem =event.target.innerText;
you can do that with the regular javascript, you don't need Jquery.
document.addEventListener("click", function(e) {
if(e.target) {
console.log("item clicked ", e.target.textContent);
}
});
This should do the job to get the value of current target.