Select using "this" keyword using document.on(..) - Jquery - javascript

My html code ( which is fetched from a json file after the page is loaded ):
<div class="fooditem">
<select class="quan">
<option value="0">0</option>
</select>
</div>
My javascript/jquery code :
$(document).on("click", ".fooditem", function() {
$(this).find('.quan').click();
});
I want to to click the select option tag when i click the div.
I found that the this keyword, here, is representing the document not the particular class.
So how should I go about doing it?
Here is the link

First Problem:
You are getting an infinite loop by listening to click but then generating a click on a descendant element...
The only solution to that is:
Move the child element outside of the element catching the click.
Note: You cannot block the click handler of the select or it will stop working.
As an alternative you can however do one of the following:
Set focus on the select element
Change the value of the select element
Generate a change event on the select element (as if the element was chosen)
but you cannot get the select to simply pop open and select the item.
Examples below:
1) Set focus
$(document).on("click", ".fooditem", function(e) {
$(this).find('.quan').focus();
});
2) Change the selected value
$(document).on("click", ".fooditem", function(e) {
$(this).find('.quan').val(0); // or whatever value
});
3) Generate a change event on the select element
$(document).on("click", ".fooditem", function(e) {
$(this).find('.quan').trigger('change');
});
note: This can be done with or without a prior value change.
Note: You have said in comment "i just want the drop down to open and select the value when i click on div", but this will not happen. A click event will not trigger opening of a select. See this example which has the recursion avoided (the elements are not nested): jsfiddle.net/TrueBlueAussie/zgub3838/7

You are binding your onclick event to the document. Try changing your jQuery snippet to this:
$(".fooditem").on("click", function(e) {
e.preventDefault();
$(this).find('.quan').click();
});

Related

Uncaught TypeError: document.querySelector(...).click is not a function on automated process

Expected Behaviour: I am adding the value from a select element to a 3rd party API input element using the select element's onchange event. Once the text value has been added to the input element, the search button must be clicked to fully automate the process.
Returned Behaviour: Although the text value can be seen in the input, once it gets focus, it clears the text. When the text is visible and the search button is clicked, nothing happens. When I add the text value manually to the input and then click search it works fine. Not too sure what to do to make sure the text remains in the input.
Code for my select and the input as follow -
function vehicle_vin() {
var use_vehicle_vin = document.getElementById('get_vehicle_make');
use_vehicle_vin = use_vehicle_vin.options[use_vehicle_vin.selectedIndex].value;
var add_vehicle_vin = document.getElementById('id-vin-frame-search');
add_vehicle_vin.value = use_vehicle_vin;
alert(add_vehicle_vin.value);
//This works fine, but please see my notes above, when I put focus on the input, my value dissapears...
//I have tried, as per various search results the following QuerySelector, no luck in the search button being clicked.
//document.querySelector('.CLOYw6ixbVCoWy9pu904a ._2DcnCzqTJKrTWusHYHyHEf').click();
//I then changed to the svg element, the same error was returned...
var x_vin = document.querySelector('._15YY4Hl-2b6wr1smId9ZlA').click();
//I also tried to do a setTimeout, also did not work, then added the below, this returns nothing -.
if (x_vin && x_vin.length) {
alert("All true, click...");
setTimeout(() => { x_vin[0].click(); }, 750);
alert("clicked");
} else {
alert("not clicked");
}
}
<select id="get_vehicle_make" name="get_vehicle_make" title="Select a vehicle from your current car park. This V.I.N. will be added to the Search Input and will automatically load your search." onchange="vehicle_vin();">
<option value="" selected >Select Saved Vehicle</option>
<option value = "123456asdfgh09876" >Kia, Sportage, 2. CRDi</option>
</select>
<!--3rd party Api input and search button-->
<input type="text" id="id-vin-frame-search" name="vin-frame-search" placeholder="VIN or FRAME" class="_2UbmnxPVuhV1aqBHdE1oDO">
<button type="button" class="CLOYw6ixbVCoWy9pu904a _2DcnCzqTJKrTWusHYHyHEf">
<span class="_24-MeE_aY0KDledQMmmJAn">
<svg width="16" class="_15YY4Hl-2b6wr1smId9ZlA">
<use xlink:href="#search"></use>
</svg>
</span>
</button>
As above, I have tried many things with no success and will really appreciate any help available, javascript is not my strong point...
querySelector returns single element, to get multiple elements use
querySelectorAll
As you are trying to access single and first element, then you can use querySelector.
So the x_vin will contain element directly (not nodelist)
So you are trying to click element programmatically (From Javascript), Then you have .click() function
Just wrapped the click function in timeout (e.g., below)
setTimeout(() => {
console.log(document.querySelector('._15YY4Hl-2b6wr1smId9ZlA'));
document.querySelector('._15YY4Hl-2b6wr1smId9ZlA').click();
}, 1000) //1 second delay
Update
Hey I just found that svg does not have click function (I thought
every element does). Solution is to click parent element
programmatically, In your case either click span or button

How to add event listener to an option inside a select box? [duplicate]

I want to alert an option when the mouse-cursor is over it. I use this code:
$("select > option").hover(function ()
{
alert($(this).attr("id"));
});
Unfortunately, this is neither working in IE nor in FF.
Can someone give me a hint please?
You can try this.
$("select").hover(function (e)
{
var $target = $(e.target);
if($target.is('option')){
alert($target.attr("id"));//Will alert id if it has id attribute
alert($target.text());//Will alert the text of the option
alert($target.val());//Will alert the value of the option
}
});
If you make a "listbox" type select box by adding a "size=x" attribute like this:
<select size="3">
<option>...</option>
<option>...</option>
</select>
The hover event will work on the option elements:
$('option').hover(function(){
//code here
});
Here's a workaround (quite decent I guess)-
Use mouseover event to set the size of the select box equal to the no. of its children
Use mouseenter event to get the options. mouseenter works on options perfectly when size attribute is there (we all know that now)
Use mouseout event to set the size of the select box back to 1, to get our normal select box back :)
JSFiddle

jQuery click event does not update ':last' when i add a new element that should become the new ":last"

So i am having a small issue,
I am working on a small effect on jquery that works this way.
The user is provided with one input button.
as soon as he types something into the input field, a new input is added below it.
Here is the HTML
<div class="container">
<div class="row">
<div class="col-md-4 data">
<input type="text" class="form-control" placehoder="some text"/>
</div>
</div>
<span><i class="fa fa-plus"></i></span>
</div>
Here is the jquery code
$(document).ready(function()
{
var input_button = '<div class="col-md-4 data"><input type="text" class="form-control" placeholder="some text"/></div>';
var last = 'div.data input[type="text"]';
$('div.data input[type="text"]:last').on("keyup",function(e)
{
value = $(this).val().trim();
if(value.length != 0)
{
$('.row').append(input_button);
}
});
});
Therefore, i use the $(div.data input[type="text"]:last) selector and the keyup event.
However, in my own thinking, when i Add a new input button, it should automatically become the ":last" input field. right?
But this is not the case. The last input field is, according to how the code is working, the first input field that originally existed?
Basically the first original input button is considered the "last" button even when more are added by the keyup event.
So my question is, how do i make the newly added input field (added using jquery) the last input field on the next keyup event?
The problem is that you bind to elements that are searched only once, not to a dynamic selector.
You should use
$('div.data').on("keyup", 'input[type="text"]:last', function(e)
so that the 'input[type="text"]:last' selector is checked each time there's a keyup event in a descendant of an element of $('div.data').
As your question isn't clear, in case you also dynamically add the div.data element, then you should do
$('.container').on("keyup", 'div.data input[type="text"]:last', function(e)
To read more about event delegation in jQuery, you can check this page.
When you dynamically create an element you have to select a parent element that is not being dynamically created then use the on function to trigger a function on an event.
So in your case you have to select a parent that is not being dynamically created which is .row and use the on function as follows:
$('.row').on("keyup", 'input[type="text"]:last', function (e)
http://jsfiddle.net/55SNt/
As the content are dynamically added on the fly , the event handler defined in your question points to the static field generated on page load. Instead you should do :
$(document).on("keyup", 'div.data input[type="text"]:last', function(e)
{
value = $(this).val().trim();
if(value.length != 0)
{
$('.row').append(input_button);
}
});
here is the example.
See More about Event Delegation.
To understand what's going on, you have to consider what jQuery is doing:
//Your code:
$('div.data input[type="text"]:last').on("keyup", function(e) {
//...
});
It looks like one thing is happening there, but there are actually two:
First you wrap the last element that matches div.data input[type="text"] in a jQuery object,
Then you add a handler to it.
Once $('div.data input[type="text"]:last') runs, the element it contains isn't going to change. It's already been found. The event handler is operating on that specific element, not the position it occupies.
To fix this, you have to tell jQuery to bind the handler dynamically every time the event fires. Fortunately, the on method is clever about that, and gives you the option to do it differently:
$(document).on("keyup", 'div.data input[type="text"]:last', function(e) {
//...
});
This will search the entire document for 'div.data input[type="text"]:last' before firing the event handler.

get Attribute of Hovered element that displayed menu

I have a menu that is displayed when a user hovers over an anchor tag with a certain class. The same menu is always displayed, but the anchor tags have a different "accNum" attribute. I want to get the value of the accNum attribute from the "parent" element that displayed the menu and append it to the click event of one of the menu items. Something like;
Actions
Actions
Actions
<div id="ActionsMenu" style="display:none;">
Show Account
</div>
Whichever 'ActionLink' is the one hovered over to display the menu, i want to take that AccNum value and create the onClick event of "ShowAccountValues" something like
onClick="showAccountValues('AccNum value of parent');"
any help would be great. Also, I assume I have to bind this to the document.ready() function for 'ActionLink' which makes sense, but i figured if i could get any of it through this that would be great.
Thank you
Firstly use jQuery to hook up your events, secondly accnum isn't a valid attribute, so use a data-* attribute like this:
Actions
Actions
Actions
<div id="ActionsMenu" style="display:none;">
Show Account
</div>
Then you can update the data attribute of the #showAccountValues link on hover of each a element:
$('.actionLink').on({
click: function(e) {
e.preventDefault();
$('#ActionsMenu').show();
},
mouseover: function() {
$('#showAccountValues').data('accnum', $(this).data('accnum'));
}
});
Then on the click of the a element in #ActionsMenu you can get the accnum:
$('#showAccountValues').click(function(e) {
e.preventDefault();
showAccountValues($(this).data('accnum'));
});
Example fiddle

Internet Explorer won't trigger click function if display: none;

The problem is mostly summed up in the title.
I am using the custom radio/checkbox code from accessible_custom_designed_checkbox_radio_button_inputs_styled_css_jquery/
This is the jist of their code (I modified it to allow defining different style depending on the label's title)
$(this).each(function(i){
if($(this).is('[type=radio]')){
var input = $(this);
// get the associated label using the input's id
var label = $('label[for='+input.attr('id')+']');
var labelTitle = label.attr('title');
// wrap the input + label in a div that has class "custom-radio-LabelTitle"
$('<div class="custom-radio-' + labelTitle + '"></div>').insertBefore(input).append(input, label);
// find all inputs in this set using the shared name attribute
var allInputs = $('input[name='+input.attr('name')+']');
//bind custom event, trigger it, bind click,focus,blur events
input.bind('updateState', function(){
if (input.is(':checked')) {
if (input.is(':radio')) {
allInputs.each(function(){
$('label[for='+$(this).attr('id')+']').removeClass('checked');
});
};
label.addClass('checked');
}
else { label.removeClass('checked checkedHover checkedFocus'); }
})
.trigger('updateState')
.click(function(){
$(this).trigger('updateState');
})
}
});
From my understanding, their code basically finds all the radio inputs and then defines a special trigger called updateState. Then they trigger it inside the input's click function.
So every time the input radiobutton is clicked, updateState is trigger, which in turn sets a class for that radiobutton's label. The changing of the class changes the CSS of the label.
When the label is clicked, The input that the label is for is also clicked (JQuery's .click() function is ran).
What I did was set all my input radiobuttons to display:none. That way the user only clicks the label, and secretly they clicked a radio button.
The .click() function won't run for the input if the input is hidden.
I assume there are two ways pass this:
instead of have the radio's .click() function trigger the handlestate, have the label's .click() function handle it instead. This may not work right though, because then the radio button may not actually be clicked (which messes up my form)
when the label is clicked, trigger the radio's click function manually. However, this may cause it to be triggered twice in every browser but IE. I don't know how to reference the label's radio nor to stop it from triggering twice.
a) instead of have the radio's
.click() function trigger the
handlestate, have the label's .click()
function handle it instead. This may
not work right though, because then
the radio button may not actually be
clicked (which messes up my form)
This may work right, on you label's .click() trigger also force the radio button to be checked like this,
$('#radiobutton').attr('checked', 'checked');
I got what I wanted with:
$("label[title='Plan']").click(function() {
var id = $(this).attr('for')
$("input[id='"+id+"']").trigger("click");
$("input[id='"+id+"']").trigger("updateState");
PlanChange();
});
Then removed all the onClicks.

Categories

Resources