Checking input elements on Firefox with JavaScript - javascript

I'm developing an extension, which listens to click events on elements.
Now I have two questions:
Is there a convenient way to detect whether an element is an input element? Like input, textarea in HTML, and textbox in XUL.
If the user clicked on an input element, how to get the position where the user clicked?
For example, there's an <input> element, with its value set to blah, and the user clicked between 'l' and 'a', how can I get the index(in this case it's 2)?

Every event has some data that gets passed with it in the event param. You can do something like this to figure out what was clicked on:
function clickFun(event){
if (event.target.nodeName == "INPUT") {
var type = event.target.getAttribute('type').toLowerCase();
if (type == 'text') {
console.log('text input');
} else if (type == 'checkbox') {
console.log('checkbox');
}
} else if (event.target.nodeName == "TEXTAREA") {
console.log('text area');
}
}
thing.onclick = clickFun;
You can do this with jQuery which gives you some easy functions to check out information about elements. Up to you if you want to try out a javascript framework.
$(':input').click(function(event){
var $this = $(this);
if ($this.is(':text')) {
console.log('text input');
} else if ($this.is(':checkbox')) {
console.log('checkbox');
} else if ($this.is(':textarea')) {
console.log('textarea');
}
});
To get the position of the cursor when they click in a text box or area try checking out this article:
http://www.dedestruct.com/2008/03/22/howto-cross-browser-cursor-position-in-textareas/

For #1: it's convenient to use the jQuery ":input" selector like this:
if ($(node).is(":input"))
alert("It's an input element!");
But generally, I don't think there is an easy way to tell XUL elements. Enumerating node names would be the simplest solution I could think of.

Related

How to reference all <input> and <textarea> and do an action if they have :focus?

I am trying to use plain Javascript to set up a function that fires when the S key is pressed AND the search overlay is not already open AND the S is not pressed when inside an <input> or <textarea>. The issue is in the third argument and I can't seem to figure it out.
Can you please tell me how to set up the third argument in the IF statement?
I have been trying to get an equivent of the JQuery is() function in regular JS. Since I don't know much about JS I am avoiding JQuery until I get the basics down. I have created a class for OOP, so the this. is referencing that.
My Javascript:
keyPressControl(event) {
if (event.keyCode == 83 && !this.isOverlayOpen && !document.querySelectorAll('input, textarea').hasFocus()) {
this.staffSearchOpen();
}
}
The this.staffSearchOpen(); should function when all three arguments noted above are true, but I can only get the first two to work properly.
The wording of the question is a little confusing but it looks like you're trying to exclude event that happen when an input field is in focus, not the other way around.
Instead of "hasFocus()" you could just build the rule into the selector itself as input:focus, textarea:focus:
document.addEventListener('keypress', function() {
if (document.querySelector('input:focus, textarea:focus')) {
console.log("keypress event was inside an input")
} else {
console.log("No input in focus");
}
})
<input>
<textarea></textarea>
...so your function could be:
keyPressControl(event) {
if (
event.keyCode == 83 &&
!this.isOverlayOpen &&
!document.querySelector('input:focus, textarea:focus')
) {
this.staffSearchOpen();
}
}
Do it the other way around:
var elems = document.querySelectorAll('input, textarea');
elems.foreach(function (elem) {
this.addEventListener("keydown",keyPressControl);
});
keyPressControl(event) {
//you won't get a key event here unless the element is the focus owner
if (event.keyCode == ...) {
this.staffSearchOpen();
}
}

Hide buttons related to empty textareas (selecting issue)

I'm struggling with a jQuery selection: I have a table that contains these columns (more or less)
Name (input field)
Surname (input field)
Note (textarea)
Button (a button to submit the relative note)
I would like to hide all buttons whose textarea is empty (to avoid the submission). This is the table:
The DOM structure of the single row is quite simple (I think):
So, I would like to select something like "all buttons contained in a td that is a brother of a td that cointains an empty textarea"...anf anf...can I do that with a single jQuery selection or not? Thank you in advance.
Of course!
$("tr td textarea").each(function() {
if (this.value == "") {
$(this).closest("td").next("td").find("button").prop("disabled", true);
}
});
You could hide buttons onLoad with the next selector:
$('textarea:empty').parent().next('td').find('button').hide();
Or if you want to disable the buttons:
$('textarea:empty').parent().next('td').find('button').prop("disabled", true);
It would be useful to check if user has type something in the textarea while on the page, and enable or not the button:
$( $('textarea') ).blur(function() {
var button = $(this).parent().next('td').find('button');
if($(this).val() === ''){
button.prop("disabled", true);
}else{
button.prop("disabled", false);
}
});
You can check this fiddle with your table included:
http://jsfiddle.net/6B9XA/4/
try this
$('table textarea').change(function()
{
var thisval=$.trim($(this).html())
if(thisval=='')
{
$(this).parent().next().children('button').attr('disabled')
}
})
I think you should use it this way:
$("#yourtableid").find("textarea").each(function() {
if (this.value == "") {
$(this).closest("tr").find("button").prop("disabled", true);
}
});
"#yourtableid" this should be changed to your table id.
Selectors optimization for performance boost.
You can use filter() to get only the buttons who contains an empty textarea within that row
$('tr button').filter(function(){ // get all buttons
return $(this).closest('tr').find('textarea').val() == ''; // only return those that are empty
}).prop('disabled',true); // disable the buttons

X-Editable: stop propagation on "click to edit"

I have an editable element inside a div which itself is clickable. Whenever I click the x-editable anchor element, the click bubbles up the DOM and triggers a click on the parent div. How can I prevent that? I know it's possible to stop this with jQuery's stopPropagation() but where would I call this method?
Here's the JSFiddle with the problem: http://jsfiddle.net/4RZvV/ . To replicate click on the editable values and you'll see that the containing div will catch a click event. This also happens when I click anywhere on the x-editable popup and I'd like to prevent that as well.
EDIT after lightswitch05 answer
I have multiple dynamic DIVs which should be selectable so I couldn't use a global variable. I added an attribute to the .editable-click anchors which get's changed instead.
editable-active is used to know if the popup is open or not
editable-activateable is used instead to know if that .editable-click anchor should be treated like it is
$(document).on('shown', "a.editable-click[editable-activateable]", function(e, reason) {
return $(this).attr("editable-active", true);
});
$(document).on('hidden', "a.editable-click[editable-activateable]", function(e, reason) {
return $(this).removeAttr("editable-active");
});
The check is pretty much like you've described it
$(document).on("click", ".version", function() {
$this = $(this)
// Check that the xeditable popup is not open
if($this.find("a[editable-active]").length === 0) { // means that editable popup is not open so we can do the stuff
// ... do stuff ...
}
})
For the click on the links, simply catch the click event and stop it:
$("a.editable-click").click(function(e){
e.stopPropagation();
});
The clicks within X-editable are a bit trickier. One way is to save a flag on weather the X-editable window is open or not, and only take action if X-editable is closed
var editableActive = false;
$("a.editable-click").on('shown', function(e, reason) {
editableActive = true;
});
$("a.editable-click").on('hidden', function(e, reason) {
editableActive = false;
});
$("div.version").click(function(e) {
var $this;
$this = $(this);
if(editableActive === false){
if ($this.hasClass("selected")) {
$(this).removeClass("selected");
} else {
$(this).addClass("selected");
}
}
});
Fixed Fiddle
It's not pretty, but we solved this problem with something like:
$('.some-class').click(function(event) {
if(event.target.tagName === "A" || event.target.tagName === "INPUT" || event.target.tagName === "BUTTON"){
return;
}
We're still looking for a solution that doesn't require a specific list of tagNames that are okay to click on.

Why doesn't jQuery function properly on keydown?

I have this external jQuery code:
jQuery(document).one('keydown', 'g',function (evt){
if ($("#tb").html() == "0")
{
$("#tb").html("Testing the chicken.")
} else {$("#tb").html("Chickens fart too.")}
return false;});
There are no errors in console.
I know it's rather silly, but never mind the text in .html(). Anyways, whenever I go to the webpage it just replaces the default 0 in the page with nothing. Then, when I press any key nothing happens. Ultimately, what I want this script to do in the end is display the letter or number that the user types in the tb div.
P.S. I'm new to stackoverflow so please tell me if my formatting is wrong or if I broke a rule.
Okay, so I edited the code and here is what I have:
$('#tb').on("keydown", function(event) {
if ($("#tb").html() == "0")
{
$("#tb").html("Testing the chicken.")
} else {$("#tb").html("Chickens fart too.")}
});
It still doesn't work.
A div element does not have a keydown event. Only element that have focus property can have it.
So I think you are referring to a input inside the div..
HTML
<div id="tb">
<span class="output"></span>
<input type="text" />
</div>
JS
// Delegating the event on input to it's container
$('#tb').on("keydown", 'input', function (event) {
// $(this).val() - Gets the value of the input on keydown
if ($(this).val() === "") {
// Set the html for span inside div
$(".output").html("Testing the chicken.");
} else {
$(".output").html("Chickens fart too.");
}
});
Check Fiddle
// Bind event to the document which fires when document is focussed and
// a key is pressed
$(document).on('keydown', function(event) {
// Key code for g
if(event.keyCode === 71) {
// Bind the event to the input when g is pressed
$('#tb input').on('keyup', inputKeydown);
// unbind the event on document as no longet necessary
$(document).off('keydown');
}
return;
});
function inputKeydown() {
// $(this).val() - Gets the value of the input on keydown
if ($(this).val() === "") {
// Set the html for span inside div
$(".output").html("Testing the chicken.");
} else {
$(".output").html("Chickens fart too.");
}
}
Another Fiddle

Set focus on textfield when un-focused

I want a text field to always be focused. When they click out of the textfield, I want the focus to go back into the textfield.
How would I accomplish this with jQuery?
$('input').focus();
$('input').**unfocused?**( function($) { $('input').focus();} );
You're looking for the blur event:
$(':text').blur(function() { this.focus(); });
The following code is an alternative solution which depends on periodically checking the control's state.
var controlFocus=false;
$("#txtName").focus(function(){
$(this).addClass("focused");
if(!controlFocus) {
controlFocus = true;
setInterval(function(){
var o = $("#txtName");
if(!o.hasClass("focused")) o.focus();
}), 200);
}
}).blur(function(){$(this).removeClass("focused");});
After the textbox (named txtName) gets its first focus, every 0.2 second, the code controls whether the textbox has focus. If it doesn't, it's focused. But this can be a really annoying thing.
Bind to get the change event, and check if focus must be forced to this input if so, insert some data in the document. $(document).data(‘_force_focus’, e.target)
$('input.force').bind('change', function(e) {
if( need_force_focus() ) {
$(document).data('_force_focus', e.target);
} else {
$(document).removeData('_force_focus');
}
});
Now on the document bind to the focusin event, testing if document have the “_force_focus” data. If so set the focus to the value. It’s important prevent the focusin retrigger by testing against e.target
$(document).bind('focusin', function (e) {
var t = $.data(document, '_force_focus');
if( t && e.target !== t ) {
$(t).trigger('focus');
return false;
}
return true;
});

Categories

Resources