I'm trying to imitate the function of the datepicker on how the focus, blur, and click works.
focus: when the cursor is at the text field the datebox appear
blur: when the cursor is not in the text field the datebox disappear
click: when the user clicks the datebox disappear and new value in textfield
I'm trying to create a similar concept:
focus: when cursor is at the text field, a div with an icon will appear
blur: icon will disappear
click: when the icon is clicked, a certain logic code will be executed.
PROBLEM:
WHEN I TRY TO CLICK THE ICON, THE BLUR EVENT IS FIRST BEING CALLED, SO THE CLICK EVENT NEVER FIRES,
here is my code:
$(document).ready(function(){
$(".test").searchHelp();
$(".test2").searchHelp();
});
(function($){
$.fn.extend({
searchHelp: function(options){
return this.each(function(){
var $this = $(this);
var searchIcon = newSearchIcon();
var helpTable = newSearchHelpTable();
jQuery("body").prepend(searchIcon);
jQuery("body").prepend(helpTable);
var x = $this.position().left + $this.width();
var y = $this.position().top;
var once = false;
jQuery(searchIcon).css({position:'absolute',left:x,top:y});
$this.bind("focus",function(){
searchIcon.show();
});
$this.bind("blur",function(){
searchIcon.hide();
});
/*$(document).bind('mousedown',function(ev){
if(ev.target != searchIcon){
searchIcon.hide();
}
});*/
searchIcon.click(function(){
/*helpTable.show();
if(!once){
jQuery("tr",helpTable).dblclick(function(){
$this.val($(this).children("td._key").text());
helpTable.hide();
searchIcon.hide();
});
once = true;
}*/
alert("DO SOMETHING!");
});
});
function newSearchIcon(){
var icon = jQuery('');
icon.append("[#]");
icon.hide();
return icon;
}
function newSearchHelpTable(){
var helpSHTable = jQuery('');
helpSHTable.load("from.htm");
helpSHTable.hide();
return helpSHTable;
}
}
});
})(jQuery);
div.searchHelp table tbody tr:hover{
background:orange;
}
div.searchHelp table tbody tr:active{
background:red;
}
div.searchHelp table tbody tr td._key{
background:green;
}
I hope to get help from you guys, thanks
If you change your
searchIcon.click(function(){
to
searchIcon.mousedown(function(){
mousedown fires before focus is lost on the input. This will however still hide the icon after your mousedown runs. If you do not want the icon to disappear after it is clicked, have your mousedown set a flag, then have your blur check that flag. Something like this:
var iconClicked=false;
searchIcon.mousedown(function(){
...
iconClicked=true;
}
$this.bind("blur",function(){
if(iconClicked){
iconCLicked=false;
}else{
searchIcon.hide();
}
});
The only drawback is that this is on mousedown and not on click, but depending on what you're trying to do this may be acceptable.
EDIT: Found this, the first suggestion is an interesting one. jQuery Blur Fires Before href
Related
I am having a problem with my code, I have a hidden a href link that the href value is added once a click is detected in a image and the link is pass as a value the the hidden href. So once it clicks on the image in Javascript I am making the manually .click() to the hidden href tag but it is not working in mobiles. My code is below:
processGridClick : function(obj){
var objIndex = obj.getAttribute('data-item-number');
var docType = obj.getAttribute('data-doc-type');
if(obj.className.indexOf('single') > -1){
var documentURL = "";
var documentsJsonRoot = DocumentsMgr.documentationData.documents[objIndex];
if(docType == 'reportsList'){
documentURL = documentsJsonRoot.reportsList[0].url;
}else if(docType == 'attachmentList'){
documentURL = documentsJsonRoot.attachmentList[0].url;
}
dojo.attr('linkDocumentsSingle', "href", documentURL);
document.getElementById('linkDocumentsSingle').click();
}
}
The view is a table that is generated in base of a JSON object and it can have more than one row, the value of the href is passed in base of the image that they clicked. This works good for desktop but in mobile the .click is not working, I even tried to add manually the touchstart event to all the clickable elements with the code below but stills not working.
**(function(window){
// check for touch
if (Modernizr.touch) {
// run the forEach on each figure element
[].slice.call(document.querySelectorAll("figure")).forEach(function(el,i){
// check if the user moves a finger
var fingerMove = false;
el.addEventListener("touchmove",function(e){
e.stopPropagation();
fingerMove = true;
});
// always reset fingerMove to false on touch start
el.addEventListener("touchstart",function(e){
e.stopPropagation();
fingerMove = false;
});
// add hover class if figure touchend and fingerMove is false
el.addEventListener("touchend",function(e){
e.stopPropagation();
if (fingerMove == false) {
classie.toggle(el,"hover");
}
});
});
}
})(window);**
Will this work for mobile? Try simulating a mouse click...?
var ele = document.getElementById('linkDocumentsSingle');
ele.dispatchEvent(new MouseEvent('mousedown'));
ele.dispatchEvent(new MouseEvent('mouseup'));
Try to use this
In i phones there is a click event only for anchor tag or buttons. So for image, div or span you have to use tap event.
// listen for a touchstart event
$('img').on('touchstart.tap',function (e) {
// listen for a touchend event
$(e.target).one('touchend.tap',function() {
$(e.target).trigger('tap');
});
// cancel it in 150ms
setTimeout(function () {
$(e.target).off('touchend.tap');
},150);
});
This will trigger a tap event if a touchend follows a touchstart within 150ms (which you can adjust, of course). You could try using this in lieu of including jQuery mobile if a tap event is all you're after.
Note: For this i have examined you have included bootstrap js library
I have this jQuery code. I make first lines here as comment, because they are not important in my question, just for structure. I have click event, after click on td I have input field with text in it. I set focus at end of text. But when I have made click, I want to remove focus , so that I can click in middle position of name, and cursor will be there. It works when it is one.('click'), but i need to do it multiple times, so one click works just for one time.
$('td').on('click', function() {
//val = $(this).text();
//console.log(val);
//rowid = $(this).parents('tr').attr('id');
//realclass = $(this).attr('class');
//$("tr").filter("#" + rowid).find("td").filter("." + realclass).find("span").hide(); //hide td->span field..
//$("tr").filter("#" + rowid).find("td").filter("." + realclass).find("input").show();//..and show input field
//get focus on end of input val
SearchInput = $("tr").filter("#" + rowid).find("td").filter("." + realclass).find("input");
strLength = SearchInput.val().length;
SearchInput.focus();
SearchInput[0].setSelectionRange(strLength, strLength);
});
The problem is that clicking on the input itself also triggers the click event on the encompassing <td> element (due to event propagation or "bubbling"), which you don't want to happen. To prevent that you want to call the event.stopPropagation() function when handling click events on the input:
$('td input').on('click', function(e) {
e.stopPropagation();
});
I'm writing a simple jQuery plugin that will dynamically place a div under a text box whenever it has focus. I've been able to get the position just about right in all the browsers.
I have to attach two event handlers as well on the focus and blur events of the textbox. And it works okay, but the problem is that the div that has been placed under the textbox closes even when we click on it. Now it makes sense why it would so happen, it's because the textbox loses focus, but is there a way I can stop it from happening?
I tried attaching this to the blur event handler -
if($(mainElem).is(":focus")) return;
where mainElem is the div that is shown below the textbox.
Here is a jsFiddle to illustrate the problem.
You are not going to be able to use the blur event if you want to place "clickable" elements in the div that shows. One way to solve this is to bind your event listener to a more global element like the document and then filter out the targets.
Here is a code sample:
$(document).on('click', function (e) {
var targetEl = e.target,
parent = $(e.target).parents()[0];
if (relElem[0] === targetEl || self[0] === targetEl || self[0] === parent) {
$(mainElem).show();
} else {
$(mainElem).hide();
}
});
Here is an update to your fiddle: http://jsfiddle.net/9YHKW/6/
This is a fiddle that I threw together for a project a while back: http://jsfiddle.net/MYcZx/4/
While it is not based off of your fiddle (and I do apologize) I believe that the functionality is much the same as what you're looking for. My example does not include input fields, but rather spans that hold the values. And while I'm not managing focus/blur, you could add a tabIndex attribute to the spans and then add a trigger on focus that would open the menu.
var $sub = $('.subscription');
$sub
.on('click', '.remove', function() {
$(this).parent().remove();
})
.on('click', 'li', function(e) {
var $this = $(this),
$parent = $this.parent(),
$options = $parent.children('li'),
$value = $parent.siblings('.value'),
isMulti = $parent.hasClass('multi'),
values = [];
if(!isMulti) {
$options.removeClass('active');
}
$this.toggleClass('active');
$options.filter('.active').each(function() {
values.push($(this).text());
});
$value.text(values.join(', ') || 'select');
$value[(values.length ? 'add' : 'remove') + 'Class']('set');
});
var $clone = $sub.clone(true);
$('.new')
.on('click', function() {
$(this).before($clone.clone(true));
});
I'm using the following for a dropdown:
/* recurse through dropdown menus */
$('.dropdown').each(function() {
/* track elements: menu, parent */
var dropdown = $(this);
var menu = dropdown.next('div.dropdown-menu'), parent = dropdown.parent();
/* function that shows THIS menu */
var showMenu = function() {
hideMenu();
showingDropdown = dropdown.addClass('dropdown-active');
showingMenu = menu.show();
showingParent = parent;
};
/* function to show menu when clicked */
dropdown.bind('click',function(e) {
if(e) e.stopPropagation();
if(e) e.preventDefault();
showMenu();
});
/* function to show menu when someone tabs to the box */
dropdown.bind('focus',function() {
showMenu();
});
});
/* hide when clicked outside */
$(document.body).bind('click',function(e) {
if(showingParent) {
var parentElement = showingParent[0];
if(!$.contains(parentElement,e.target) || !parentElement == e.target) {
hideMenu();
}
}
});
Notice:
$(document.body).bind('click',function(e) {
The problem is that the dropdown opens on click or when you tab to it. But it only closes on click, not when you tab out.
How can I bind an event to mean "tabbing out" ,losing focus, so the dropdown closes?
Thanks
You could trigger a click outside when you press the tab key. Like this:
$('#your_dropdown').bind('keydown', function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) { //If it's the tab key
$("body").click(); //Force a click outside the dropdown, so it forces a close
}
});
Hope this helps. Cheers
Try the blur event, which will be triggered when the control loses focus (i.e., when the user clicks outside the control or uses the keyboard to tab to the next control).
Put something like this just after your existing focus binding:
dropdown.bind('blur',function() {
// whatever tests you want
hideMenu();
});
(You shouldn't then need the separate click binding that you're currently using to hide the menu.)
P.S. You might also consider focusout, which is similar to blur except that it bubbles.
Seems like you're looking for the onblur event?
I'm trying to write a web app which replaces the context menu (right-click menu) with my own customized ones. I want it so that when the user clicks on a table row, they get one certain context menu and when they click on the background of the page, they get a different one.
I have already written the menus and gotten them working. The problem comes in when trying to figure out how to get the background's menu to show ONLY when clicking on the background and how to get the table row's menu to show when that is clicked.
I tried using document.body.oncontextmenu for the body and and setting the oncontextmenu function for each table row, but the body's oncontextmenu function overrides the row's so I get the wrong menu. The menu for the table rows DOES work if I stop using the body's menu, so that's not the issue.
I could be using the wrong events, so is there a different event for just the background (and not the elements on top of the background)? Or a way to "prioritize" the events so the table row's function takes precedence?
This is how the code looks:
var tableMenu;
var bodyMenu;
window.onload = function()
{
bodyMenu = new rightClickMenu("bodyMenu");
document.body.oncontextmenu = function() { bodyMenu.show(); tableMenu.hide(); }
bodyMenu.add("Add Entry", function()
{
alert("ADD");
});
tableMenu = new rightClickMenu("tableMenu", "tblSims");
simRows = getElementsByClassName("trSimRow");
for (var i in simRows)
simRows[i].oncontextmenu = function() { tableMenu.show(this.id.substring(2)); bodyMenu.hide(); }
tableMenu.add("Delete Entry", function(mac)
{
alert("DELETE");
});
document.body.onclick = function()
{
bodyMenu.hide();
tableMenu.hide();
};
}
You can capture the target element, e.g.:
$('*').click(function(e) {
alert(e.target);
alert(e.target.tagName);
if(e.target.tagName == 'html') {
// show background menu
}
});
You have to work with the Javascript Event Propagation model. What happens is that your click event is automatically passed down the layers of objects on a page that have been registered as event listeners, unless you explicitly tell it to stop, try something like this:
function setupClickHandlers()
{
document.getElementsByTagName('body')[0].onclick = doBodyMenu;
document.getElementById('tableID').onclick = doTableMenu;
}
function doBodyMenu()
{
//do whatever it does
}
function doTableMenu(e)
{
//do whatever it does
//stop the event propagating to the body element
var evt = e ? e : window.event;
if (evt.stopPropagation) {evt.stopPropagation();}
else {evt.cancelBubble=true;}
return false;
}
This should deal with the way each browser handles events.
$( document ).ready(function() {
var childClicked = false;
// myContainer is the nearest container div to the clickable elements
$("#myContainer").children().click(function(e) {
console.log('in element');
childClicked = true;
});
$("#myContainer").click(function(e){
if(!childClicked) {
console.log('in background');
e.preventDefault();
e.stopPropagation();
}
childClicked = false;
});
});
#myContainer {
width:200px;
height:200px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myContainer" style="">
link
<div style="width:50px;height:50px;background-color: white;">
another link
</div>
</div>