In firefox, I made a web page, there are two input text elements: input_text_1 and input_text_2. They behave like password verification: If the content of them is different, i.e. when onblur event of input_text_2 is activated, the onblur's handler will alert something and then select all text of input_text_1.
Actually, this is not easy to be implemented, as I think the events chain is not assured: Maybe, input_text_1 got text selected and then lost focus by some clicking. So, I just hack in the onblur's handler of input_text_1 as follows:
setTimeout("document.getElementById('input_text_1').select()", 100);
Is there a more elegant solution?
following code works fine in FireFox/IE/Opera/Safari/Chrome, but WebKit-based browsers not always take focus into input:
var blurHandler = function() {
var input1 = document.getElementById('input1');
if( this.value !== input1.value ) {
alert( 'Passwords are not equal' );
if( input1.selectionStart ) {
input1.selectionStart = 0;
input1.selectionEnd = input1.value.length;
}
input1.focus();
if( input1.select ) input1.select();
}
};
var input2 = document.getElementById('input2');
if( input2.addEventListener )
input2.addEventListener( 'blur', blurHandler, true );
else
input2.attachEvent( 'onblur', blurHandler );
you can try it http://jsfiddle.net/twilightfeel/3ggP6/3/
Related
I'm having this webpage
http://pocolocoadventures.be/reizen/
And it should filter (with isotope.js) the travelboxes on the page.It does in safari, chrome, firefox, opera, .. but in IE, the filter doesn't work. Even worse, JS doesn't react at all at a click event on te span.
This is the piece of js
// Travel Isotope
var container = $('#travel-wrap');
container.isotope({
animationEngine : 'best-available',
itemSelector: '.travel-box ',
animationOptions : {
duration : 200,
queue : false
},
});
$(".filters span").click(function(){
var elfilters = $(this).parents().eq(1);
if( (elfilters.attr("id") == "alleReizen") && elfilters.hasClass("non-active") )
{
$(".label").each(function(){
inActive( $(this) );
});
setActive(elfilters);
}
else{
//set label alleReizen inactive
inActive( $("#alleReizen") );
if( elfilters.hasClass("non-active") ){
setActive(elfilters);
}
else{
inActive(elfilters);
}
}
checkFilter();
var filters=[];
$(".search.filters").children().each(function(){
var filter = $(this).children().children().attr("data-filter");
if( $(this).hasClass("non-active") ){
filters = jQuery.grep(filters, function(value){
return value != filter;
});
}
else{
if(jQuery.inArray(filter,filters) == -1){
filters.push(filter);
}
}
});
filters = filters.join("");
filterItems(filters);
});
function filterItems(filters){
console.log("filter items with filters:" + filters);
container.isotope({
filter : filters,
}, function noResultsCheck(){
var numItems = $('.travel-box:not(.isotope-hidden)').length;
if (numItems == 0) {
$("#no-results").fadeIn();
$("#no-results").css("display", "block");
}
else{
$("#no-results").fadeOut();
$("#no-results").css("display", "none");
}
});
}
function setActive(el){
el.removeClass("non-active");
var span = el.find('i');
span.removeClass("fa-check-circle-o").addClass("fa-ban");
}
function inActive(el){
el.addClass("non-active");
var span = el.find('i');
span.removeClass("fa-ban").addClass("fa-check-circle-o")
}
function checkFilter(){
var filterdivs = $('.filters span').parent().parent();
if( filterdivs.not('.non-active').length == 0 ){
setActive( $("#alleReizen") );
}
var filterLabels = $(".filters .label");
if( filterLabels.not('.non-active').length == 0){
setActive( $("#alleReizen") );
}
}
function noResultsCheck() {
var numItems = $('.item:not(.isotope-hidden)').length;
if (numItems == 0) {
//do something here, like turn on a div, or insert a msg with jQuery's .html() function
alert("There are no results");
}
}
Probably something small and stupid; but I can't find it..
Thanks in advance!
On your website you've build the buttons like this:
<button>
<span>
</span>
</button>
Now the button element is designed to be a button. It differs from the input button. In the latter you'd set the caption using value. In the button element you set it as a text node. The button element can contain elements like a span. The spec isn't very clear about whether or not you should have event handlers on the children of the button element. It's a browser developers interpretation of allowing it or not.
This problem has been posted here before (a few times)
span inside button, is not clickable in ff
Missing click event for <span> inside <button> element on firefox
It seems that Firefox is allowing it, based upon your findings. IE isn't. So to be on the safe side: use the button the way it was intended.
Wrap the button inside a span (not really logical)
Put the click handler on the button.
$(".filters button").click(...);
played around in the console a bit, and this seemed to work well.
$(".filters").on('click', 'span', function(){
// foo here
console.log('foo');
});
Maybe the filters are manipulated by one of your js files after page load?
.on will allow you to select a container which listens on changes that happen inside it, passing the element you want the actual action to work on.
If it's ok for you, I'd suggest to use the <button> element, instead of the <span>.
Let me know if that works for you.
In Gmail, clicking on the checkbox shown below selects all messages and I'm making a userscript (for personal use and I need it to work in Chrome) that'll select the unread messages only (only the first 2 messages in the screenie below are unread) instead of the default behavior of that checkbox.
My first idea is to simulate click events and although I could access the "unread" menuitem fine using the code...
var unread_menuitem = document.getElementById('canvas_frame').contentWindow.document.getElementById(':s2');
$(unread_menuitem).css({'border':'thin red solid'});
and dispatch the click event to it using the code...
var clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent( 'click', true, true );
unread_menuitem.dispatchEvent(clickEvent); // Chrome's console returned 'true'
the unread messages don't get selected.
My second idea was to brute force the selection by checking the checkbox $('#canvas_frame').contents().find('tr.zE input').prop('checked', true) and apply the css styles that Gmail applies on a manual click event, but while I was able to match the manual click event both visually as well as DOM-wise (afaik)...
Gmail says "No conversations selected" while performing some action, in this case I did a "Mark as Read". I also want to note that manually clicking on the checkboxes that were put in this state using my brute force method did not "uncheck" them as you'd expect. They needed one additional manual click to get unchecked.
Both my ideas have bombed and I want to know if there are others ways to tackle this, or if there are ways to improve upon my ideas above that can solve the problem.
There's a script here that looks it does what you're trying to do. Is that the whole script you needed to create or was that just part of the functionality?
According to the discussions, they did create it for Firefox which it works in, some people have commented it doesn't work in Chrome, so you might be looking at a solution that needs to target different browsers (your question doesn't specify if it must work in Chrome, just that you were using it).
This is what they are using to select the unread messages, it looks like they are simulating the mousedown and mouseup events on each item:
var handler = function(type,e) {
e.preventDefault();
e.stopPropagation();
var e2 = document.createEvent('MouseEvents');
e2.initEvent('mousedown',true,false);
var el = anchor.wrappedJSObject;
el.dispatchEvent(e2);
setTimeout(function() {
var el = document.querySelectorAll('div[selector='+type+'] > div')[0].wrappedJSObject;
var e2 = document.createEvent('MouseEvents');
e2.initEvent('mouseup',true,false);
el.dispatchEvent(e2);
},100);
}
They are calling this by setting up a click event further down which calls handler('unread',e);
Solved it, easy as pie and now that I think about it, it's the solution listed in user PirateKitten's answer - instead of "checking off" the checkboxes besides the unread messages like my second idea, simulate clicks on those checkboxes instead. Works like a charm and here's the code, which you can run in Chrome's console while using Gmail (doesn't need jQuery btw):
var unreadMessages = document.getElementById('canvas_frame').contentWindow.document.querySelectorAll('tr.zE input');
var numMessages = unreadMessages.length;
while ( numMessages-- ) {
var clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent( 'click', true, true );
unreadMessages[numMessages].dispatchEvent(clickEvent);
}
Here's my full script that you can run inside your Chrome console (or turn it into an extension/userscript) to change the default behavior of the checkbox from selecting ALL messages to just the unread messages only:
var hasUILoaded = setInterval( function() {
if( document.getElementById('canvas_frame').contentDocument.getElementsByClassName('J-Zh-I J-J5-Ji J-Pm-I L3') ) {
clearInterval( hasUILoaded );
setTimeout( function() {
var content_frame = document.getElementById('canvas_frame').contentDocument;
var chkbox = content_frame.getElementsByClassName( 'J-Zh-I J-J5-Ji J-Pm-I L3' );
var chkbox = chkbox[0].childNodes[0];
var unreadMessages = content_frame.getElementsByClassName('zE'); // DOM structure: <tr class=zE> <td> <img><input> </td> </tr> so we add ".childNodes[0].childNodes[1]" whenever we want to access the check boxes of each message.
var allMessages = content_frame.getElementsByClassName('zA');
chkbox.onclick = function() {
if( chkbox.checked ) {
var numUnread = unreadMessages.length;;
var numAll = allMessages.length;
setTimeout(function () {
if( allMessages[0].childNodes[0].childNodes[1].checked ) {
while ( numAll-- ) {
var clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent( 'click', true, true );
allMessages[numAll].childNodes[0].childNodes[1].dispatchEvent(clickEvent);
}
}
}, 10);
setTimeout(function (){
if(!unreadMessages[0].childNodes[0].childNodes[1].checked) {
while ( numUnread-- ) {
var clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent( 'click', true, true );
unreadMessages[numUnread].childNodes[0].childNodes[1].dispatchEvent(clickEvent);
}
}
}, 30);
}
}
}, 100);
}
}, 300);
Anyone know of a good tutorial/method of using Javascript to, onSubmit, change the background color of all empty fields with class="required" ?
Something like this should do the trick, but it's difficult to know exactly what you're looking for without you posting more details:
document.getElementById("myForm").onsubmit = function() {
var fields = this.getElementsByClassName("required"),
sendForm = true;
for(var i = 0; i < fields.length; i++) {
if(!fields[i].value) {
fields[i].style.backgroundColor = "#ff0000";
sendForm = false;
}
else {
//Else block added due to comments about returning colour to normal
fields[i].style.backgroundColor = "#fff";
}
}
if(!sendForm) {
return false;
}
}
This attaches a listener to the onsubmit event of the form with id "myForm". It then gets all elements within that form with a class of "required" (note that getElementsByClassName is not supported in older versions of IE, so you may want to look into alternatives there), loops through that collection, checks the value of each, and changes the background colour if it finds any empty ones. If there are any empty ones, it prevents the form from being submitted.
Here's a working example.
Perhaps something like this:
$(document).ready(function () {
$('form').submit(function () {
$('input, textarea, select', this).foreach(function () {
if ($(this).val() == '') {
$(this).addClass('required');
}
});
});
});
I quickly became a fan of jQuery. The documentation is amazing.
http://docs.jquery.com/Downloading_jQuery
if You decide to give the library a try, then here is your code:
//on DOM ready event
$(document).ready(
// register a 'submit' event for your form
$("#formId").submit(function(event){
// clear the required fields if this is the second time the user is submitting the form
$('.required', this).removeClass("required");
// snag every field of type 'input'.
// filter them, keeping inputs with a '' value
// add the class 'required' to the blank inputs.
$('input', this).filter( function( index ){
var keepMe = false;
if(this.val() == ''){
keepMe = true;
}
return keepMe;
}).addClass("required");
if($(".required", this).length > 0){
event.preventDefault();
}
});
);
I have input-box. I'm looking for a way to fire-up alert() if first character of given string is equal to '/'...
var scream = $( '#screameria input' ).val();
if ( scream.charAt( 0 ) == '/' ) {
alert( 'Boom!' );
}
It's my code at the moment. It doesn't work and I think that it's because that browser doesn't know when to check that string... I need that alert whenever user inputs '/' as first character.
Try this out:
$( '#screameria input' ).keyup(function(){ //when a user types in input box
var scream = this.value;
if ( scream.charAt( 0 ) == '/' ) {
alert( 'Boom!' );
}
})
Fiddle: http://jsfiddle.net/maniator/FewgY/
You need to add a keypress (or similar) handler to tell the browser to run your function whenever a key is pressed on that input field:
var input = $('#screameria input');
input.keypress(function() {
var val = this.value;
if (val && val.charAt(0) == '/') {
alert('Boom!');
}
});
I am using jquery to keep the focus on a text box when you click on a specific div. It works well in Internet Explorer but not in Firefox. Any suggestions?
var clickedDiv = false;
$('input').blur(function() { if (clickedDiv) { $('input').focus(); } });
$('div').mousedown(function() { clickedDiv = true; })
.mouseup(function() { clickedDiv = false });
Point to note: the focus() method on a jquery object does not actually focus it: it just cases the focus handler to be invoked! to actually focus the item, you should do this:
var clickedDiv = false;
$('input').blur( function() {
if(clickeddiv) {
$('input').each(function(){this[0].focus()});
}
}
$('div').mousedown(function() { clickedDiv = true; })
.mouseup(function() { clickedDiv = false });
Note that I've used the focus() method on native DOM objects, not jquery objects.
This is a direct (brute force) change to your exact code. However, if I understand what you are trying to do correctly, you are trying to focus an input box when a particular div is clicked when that input is in focus.
Here's my take on how you would do it:
var inFocus = false;
$('#myinput').focus(function() { inFocus = true; })
.blur(function() { inFocus = false; });
$('#mydiv').mousedown(function() {
if( inFocus )
setTimeout( function(){ $('#myinput')[0].focus(); }, 100 );
}
Point to note: I've given a timeout to focussing the input in question, so that the input can actually go out of focus in the mean time. Otherwise we would be giving it focus just before it is about to lose it. As for the decision of 100 ms, its really a fluke here.
Cheers,
jrh
EDIT in response to #Jim's comment
The first method probably did not work because it was the wrong approach to start with.
As for the second question, we should use .focus() on the native DOM object and not on the jQuery wrapper around it because the native .focus() method causes the object to actually grab focus, while the jquery method just calls the event handler associated with the focus event.
So while the jquery method calls the focus event handler, the native method actually grants focus, hence causing the handler to be invoked. It is just unfortunate nomenclature that the name of this method overlaps.
I resolved it by simply replace on blur event by document.onclick and check clicked element if not input or div
var $con = null; //the input object
var $inp = null; // the div object
function bodyClick(eleId){
if (eleId == null || ($inp!= null && $con != null && eleId != $inp.attr('id') &&
eleId != $con.attr('id'))){
$con.hide();
}
}
function hideCon() {
if(clickedDiv){
$con.hide();
}
}
function getEl(){
var ev = arguments[0] || window.event,
origEl = ev.target || ev.srcElement;
eleId = origEl.id;
bodyClick(eleId);
}
document.onclick = getEl;
hope u find it useful