I have (an array of) two inputs product and category.
The product one is an autocomplete.
I would like to fill in the category when a product is selected.
the problem that the event.target is not a jquery object, so it seems I can't apply the jQquery's .next("input")
Here is my code:
var addedProduct = $(".produit:last > input");
addedProduct.autocomplete( {
source: Object.keys(availableProducts),
select: function(event, ui){
var category = event.target.next("input"); // something like this ???
category.value = availableProducts[ui.item.value]; //{"product1":"category1",...}
}
})
The inputs location is like this:
You can create a new jQuery object from the event target with $(event.target). You'll be able to call .next on it afterwards
The other solution without jQuery is to use the native DOM API. You can select the next element with nextElementSibling. The only requirement is that the element you want to target must be immediately the next element.
EDIT: From the DOM structure provided you can use .parent().next() to select the next element at the parent level. Then on this new element use .find() to select the wanted input. Note that the code is highly tied to the DOM structure. You could use the id to directly select the element.
$(event.target).parent().next().find("input");
Related
I clone multiple select elements in the following manner. This work perfectly:
Demo: https://jsfiddle.net/DTcHh/36308/
// get all items of specific class
var $selectedClassDiv = $('.to-clone');
// find select eles and clone into div
$('#cloned-list').html($selectedClassDiv.find('select').clone());
// loop through cloned select eles to set the correct selected option
$selectedClassDiv.find("select").each(function(i) {
var select = this;
$('#cloned-list').find("select").eq(i).val($(select).val());
});
The problem I have is that I would like to wrap these select items in a div that has a custom class. I've tried multiple methods to no avail, my latest attempts below.
Has no effect
$('#cloned-list').html($selectedClassDiv.find('select').clone().wrap('<div class="customClass"></div>'));
Demo: https://jsfiddle.net/DTcHh/36309/
Causes error
$('#cloned-list').html($selectedClassDiv.find('select').clone().parent().wrap('<div class="customClass"></div>'));
Demo: https://jsfiddle.net/DTcHh/36310/
I am interested in a solution that wraps a div around the select items. Cloning the parent div and adding a class isn't an option.
You could add it within your current loop:
https://jsfiddle.net/DTcHh/36311/
$selectedClassDiv.find("select").each(function(i) {
var select = this;
$('#cloned-list').find("select").eq(i).val($(select).val()).wrap('<div class="customClass"></div>');
});
function appendToSelect_pick_loc1(select, value, content,pSize,i) {
var ulelement=$(select).siblings('.cs-options').children('ul');
$(ulelement).append("<li data-option=\"\" data-value=\""+value+"\"><span>"+content+"</span></li>");
}
The elements are added ,but i cannot select any from them.
To do operations on a dynamically generated element you do not use the simple $(selector).click(function(){}); approach.
To select the dynamically created elements you have to use:
$(document).on('click',selector,function(){
//console.log(this); //the selected item
});
In place of document you can take any element from the DOM that is static (not generated at runtime) and encloses your selector.
I am trying to select all elements with the "findme" class, and from those get the selects that are nearby them.
http://jsfiddle.net/R93md/1/
Specifically I have tried
$(".findme").parent().prev().first();
then once I have all selects I plan on doing a
.each(function (){doSomething(this);})
to each select. I am stuck getting the selects because it seems that I am never going down and retrieving the contents of the span.
$(".findme").closest("td").find("select").each(function() {
doSomething(this);
});
I think you should follow this:
$('.findme').each(function(){
var el = $(this).closest('td').find('select');
dosomething(el);
});
I would first grab the parent <td> element and then use find() like so
$('.findme').parents('td').find('select').each(function(){
...
});
http://jsfiddle.net/JYGK3/
Edit:
In review of the other answers here, I've concluded that you probably should use closest() rather than parents(). If the table is nested, it could produce unwanted results.
http://jsfiddle.net/JYGK3/1
You can use .closest() to go up to the common <td> and then .find() to go down from there to find the neighboring <select>:
$(".findme").each(function() {
var select = $(this).closest("td").find("select");
// now do what you want to with the neighboring select object
// here you have access to both this which is the findme object
// and select which is the select object
});
I have a couple of drop down boxes with ids country1, country2, ... When the country is changed in a drop down the value of the country shoudl be displayed in an alert box.
if I add the onchange handler for one box like this it works fine:
$('#country1') .live('change', function(e){
var selectedCountry = e.target.options[e.target.selectedIndex].value;
alert(selectedCountry);
});
But I need to do this dynamically for all drop down boxes so I tried:
$(document).ready(function() {
$('[id^=country]') .each(function(key,element){
$(this).live('change', function(e){
var selectedCountry = e.target.options[e.target.selectedIndex].value;
alert(selectedCountry);
});
});
});
This doesn't work. No syntax error but just nothing happens when the seleted country is changed. I am sure that the each loop is performed a couple of times and the array contains the select boxes.
Any idea on that?
Thanks,
Paul
The reason .live() existed was to account for elements not present when you call the selector.
$('[id^=country]') .each(function(key,element){ iterates over elements that have an id that starts with country, but only those that exist when you run the selector. It won't work for elements that you create after you call .each(), so using .live() wouldn't do you much good.
Use the new style event delegation syntax with that selector and it should work:
$(document).on('change', '[id^=country]', function(e) {
// ...
});
Replace document with the closest parent that doesn't get dynamically generated.
Also, consider adding a class to those elements along with the id attribute.
Instead of incremental ids I'd use a class. Then the live method is deprecated but you may use on with delegation on the closest static parent or on document otherwise.
$('#closestStaticParent').on('change', '.country', function() {
// this applies to all current and future .country elements
});
You don't need an each loop this way; plus events are attached to all the elements in the jQuery collection, in this case all .country elements.
What I am trying to do is populate data in a select element. I'm using the following code, where a user selects a SubjectCategory from one drop down, which then should populate the next select element's html. The handler itself is working just fine, it returns the correct html I need to place inside the select element.
Also, keep in mind that I eventually clone both of these select elements and will need to populate them accordingly.
The problem is that $elem is always returning null.
I'm guessing that it's a problem with this line of code, however not quite sure (keeping in mind that I'm also cloning these two select elements):
var $elem = $this.closest('div').prev().find('select');
$(".SubjectCategory").live("click", function () {
var $this = $(this);
var $elem = $this.closest('div').next().find('select');
var a = $this.val();
$.get("/userControls/BookSubjectHandler.ashx?category=" + a, {}, function (data) {
$elem.html(data);
});
});
<div class="singleField subjectField">
<label id="Category" class="fieldSml">Subject Matter</label>
<div class="bookDetails ddl"><select id="ddlSubjectMatter" class="fieldSml SubjectCategory"></select></div>
<label id="Subjects" class="fieldSml">Category</label>
<div class="bookDetails ddl" id="subjectMatter"><select id="ddlSubjects" class="fieldSml Subjects"></select></div>
</div>
You're searching inside the <label>, not the next <div> as you want. next only gets one element after the current one.
Try this: It searches for the first div next to your parent element.
var $elem = $this.closest('div').nextAll('div').first().find('select');
Given that the source element has an id of ddlSubjectMatter and the target select element has an id of subjectMatter, it may be a lot simpler to capitalise the first letter of the second id (i.e. make SubjectMatter) then you get the second element by:
var elem = document.getElementById(this.id.replace(/^ddl/,''));
It makes the element relationship independent of the document layout.
Incidentally, it is invalid HTML to have select elements with no options, not that it is a big issue.
Why are you creating an extraneous $this variable? Unless you've omitted code that requires it for a different scope, just call $(this). That might be causing the problem, too.