I am trying to add links eg <a> to the code from here, it is a treeview using JS and JSON.
It fully works and the children are already <a></a> with href="#", I have replaced the following code, to grab a href : "example.com" attribute from the JSON and set it to the href, which works. I have also made a change to the onclick, but that only does something if you click twice :/
I would like for it to instantly href, and not when you click twice on the child.
class SimpleTree extends Emitter {
constructor(parent, properties = {}) {
super();
// do not toggle with click
parent.addEventListener('click', e => {
// e.clientX to prevent stopping Enter key
// e.detail to prevent dbl-click
// e.offsetX to allow plus and minus clicking
if (e && e.clientX && e.detail === 1 && e.offsetX >= 0) {
if (parent.href != null) {
window.location.href = parent.href;
}
return e.preventDefault();
}
const active = this.active();
if (active && active.dataset.type === SimpleTree.FILE) {
e.preventDefault();
this.emit('action', active);
if (properties['no-focus-on-action'] === true) {
window.clearTimeout(this.id);
}
}
});
[...]
class SelectTree extends AsyncTree {
constructor(parent, options = {}) {
super(parent, options);
/* multiple clicks outside of elements */
parent.addEventListener('click', e => {
if (e.target.href !== '#' || e.target.href !== 'javascript:void(0)' || e.target.href !== undefined || e.target.href !== '' || e.target.href !== null) {
window.open(href, '_blank');
}
if (e.detail > 1) {
const active = this.active();
if (active && active !== e.target) {
if (e.target.tagName === 'A' || e.target.tagName === 'SUMMARY') {
return this.select(e.target, 'click');
}
}
if (active) {
this.focus(active);
}
}
});
The simplest answer to this, add an eventlistener for the <a> element and navigate if it's not empty, null, etc.
Solution below is using Jquery.
$("a").click(function(e) {
e.preventDefault();
var href = $(this).attr("href");
if (href !== '#' || href !== 'javascript:void(0)' || href !== undefined || href !== '' || href !== null) {
window.open(href, '_blank');
}
});
Related
Hi all i am simply trying to remove this keyup event from the window and it is not working.
toggle(forceClose = false) {
const shouldClose = forceClose || this.isOpen()
const action = shouldClose ? 'remove' : 'add'
const expanded = !shouldClose
var escape = function(e) {
if (e.key === "Escape" || e.which === 27) {
console.log("Escape")
}
}
if (shouldClose && this.targetEl) {
window.removeEventListener('keyup', escape, true)
this.targetEl.classList.remove(this.options.menuActiveClass)
setTimeout(() => !this.targetEl.classList.contains(this.options.menuActiveClass) && this.targetEl.classList.remove(this.options.menuOpenClass), 300)
} else if (this.targetEl) {
window.addEventListener('keyup', escape, true)
this.targetEl.classList.add(this.options.menuOpenClass)
setTimeout(() => this.targetEl.classList.contains(this.options.menuOpenClass) && this.targetEl.classList.add(this.options.menuActiveClass), 10)
}
}
You are creating a new escape function on every call. So removeEventListener will try to remove something that never been added.
Move the declaration to the outer scope
toggle(forceClose = false) {
const shouldClose = forceClose || this.isOpen()
const action = shouldClose ? 'remove' : 'add'
const expanded = !shouldClose
if (shouldClose && this.targetEl) {
window.removeEventListener('keyup', escape, true)
this.targetEl.classList.remove(this.options.menuActiveClass)
setTimeout(() => !this.targetEl.classList.contains(this.options.menuActiveClass) && this.targetEl.classList.remove(this.options.menuOpenClass), 300)
} else if (this.targetEl) {
window.addEventListener('keyup', escape, true)
this.targetEl.classList.add(this.options.menuOpenClass)
setTimeout(() => this.targetEl.classList.contains(this.options.menuOpenClass) && this.targetEl.classList.add(this.options.menuActiveClass), 10)
}
}
function escape(e) {
if (e.key === "Escape" || e.which === 27) {
console.log("Escape")
}
}
When you call removeEventListener you have to pass as function the same instance passing on addEventListener.
So in your case you have to define escape ouside toggle
Okay - so for some reason or another, the jQuery UI Selectmenu-button messes with both focus() and blur()-events - they do not trigger. Is there a way to get these events to trigger, without having to use a function in the selectmenu()-assignment?
Reason I ask is that I have a overall function which is used for focus and blur-events on input, textarea and the like, which would be nice to also be able to use on selectmenu - but since it doesn't accept blur and focus, that makes it a bit more difficult.
Currently, I have the following code:
$('input,textarea,select').on('blur focus',function(event) {
var $this = $(this),
thisID = $this.attr('id'),
thisType = $this.attr('type'),
thisContent = $this.val(),
thisForm = $this.parents('form').attr('id'),
isRequired = $this.attr('required'),
getMessage = '',
elementPosition = $this.position(),
elementWidth = $this.width(),
elementHeight = $this.height(),
checkmarkPosition = (elementPosition != undefined) ? elementPosition.left + (elementWidth-10) : '',
topPosition = (elementPosition != undefined) ? Math.floor(elementPosition.top) : '';
if ($(this).hasClass('required')) {
thisContent = $this.text();
}
if (event.type == 'blur') {
if (isRequired == 'required' && (thisContent == '' || thisContent == 'Can\'t be empty')) {
getMessage = 'requiredField';
} else if (thisType == 'email') {
if (validateEmail(thisContent) == false) {
getMessage = 'notValidEmail';
} else {
getMessage = 'checkMark';
}
} else {
getMessage = 'checkMark';
}
}
if (getMessage != '' && getMessage != undefined) {
$.post('/returnmessages.php', {getmessage:getMessage}, function(data) {
data = $.parseJSON(data),
message = data.returnmessage,
infoState = data.infostate;
if (infoState != '' && infoState != undefined && thisType != 'submit') {
if (infoState == 'success') {
$this.addClass(infoState).after('<span style="position: absolute; left: '+(checkmarkPosition)+'px; top: '+(topPosition+10)+'px;" class="fa fa-check"></span>');
} else if (infoState == 'error' && (thisContent == '' || thisContent == undefined)) {
$this.addClass(infoState).prop('placeholder',message).next('span').remove();
}
}
})
}
})
Which works fine for regular events on regular inputs, but not on selectmenu-elements. It is a function to return "ok" (checkmarks) and different error-messages and such in the elements themselves, so no need to attach error-messages in separate elements.
Anyone have an idea as to how to make this work?
If you mean that select won't trigger your own function,you can use
$( "#selectionSomething" ).selectmenu({
change: function(){
$(this).trigger('blur')
}
});
hope it's useful
I need to pop-up alert when I use Middle Click and it must don't pop-up if I click it on a link but on any other element of page (or just on empty space).
var test = {
pageMiddleClickListener : function(e) {
if(e.which === 2) {
//if (!gContextMenu.onLink) {
alert('ok');
//}
}
}
window.addEventListener("click",test.pageMiddleClickListener,false);
Alert show-ups when I use Middle Click on a link, but I need to prevent this behavior to links
I need something like "!gContextMenu.onLink" but not for context menu (without)
There are multiple ways that you can test for the target of the click being a link. One way would be to check to see if the Element.tagName is A, another would be to test for the href property. As it turns out is is also necessary to test to see if any of the target's parentNodes are links.
var test = {
pageMiddleClickListener : function(e) {
if(e.button === 1) {
if (!test.isLinkOrAParentIsLink(e.target)) {
e.view.alert('ok');
}
}
},
isLinkOrAParentIsLink : function(el) {
if (el.tagName === "A") {
return true;
} //else
let parent= el.parentNode;
while (parent !== null && typeof parent.tagName !== "undefined") {
if (parent.tagName === "A") {
return true;
} //else
parent= parent.parentNode;
}
return false;
}
}
window.addEventListener("click",test.pageMiddleClickListener,false);
or
isLinkOrAParentIsLink : function(el) {
if (el.hasAttribute("href")) {
return true;
} //else
let parent= el.parentNode;
while (parent !== null && typeof parent.tagName !== "undefined") {
if (parent.hasAttribute("href")) {
return true;
} //else
parent= parent.parentNode;
}
return false;
}
Note: I changed e.which to e.button as that is what is in the specification for click events and MouseEvent.which is non-standard. Note this also required testing for e.button === 1 instead of 2.
You can check if you have clicked an <a> with the prop method.
$(this).prop("tagName") == "A"
In your event listener:
var test = {
pageMiddleClickListener : function(e) {
if(e.which === 2) {
// not an <a> ?
if ($(this).prop("tagName") !== "A") {
alert('ok');
}
}
}
window.addEventListener("click",test.pageMiddleClickListener,false);
I call
element.focus();
Where element is HTMLInputElement of type=button.
But then the browser clicks the button! That's in mozilla and chrome.
How do i highlight the button with selection, but not initiate the click event?
No .focus() doesn't click the button or submits the form: http://jsbin.com/onirac/1/edit
It does exactly what you want it to.
Well, i've identified the reason.
I was handling the onkeydown event for Enter key.
The solution is to use
e.preventDefault();
function ConvertEnterToTab(s, e, numSkipElements) {
var keyCode = e.keyCode || e.htmlEvent.keyCode;
if (keyCode === 13) {
var tabIndex = s.tabIndex || s.inputElement.tabIndex;
if (numSkipElements == undefined) {
numSkipElements = 0;
}
var nextElement = FindNextElementByTabIndex(tabIndex + numSkipElements);
if (nextElement != undefined) {
nextElement.focus();
return e.preventDefault ? e.preventDefault() : e.htmlEvent.preventDefault(); // this is the solution
}
}
}
function FindNextElementByTabIndex(currentTabIndex, maxTabIndex) {
if (maxTabIndex == undefined) {
maxTabIndex = 100;
}
var tempIndex = currentTabIndex + 1;
while (!$('[tabindex='+ tempIndex+ ']')[0] || tempIndex === maxTabIndex) {
tempIndex++;
}
return $('[tabindex=' + tempIndex + ']')[0];
}
I have to the following function that I would like to modify so that it only binds the click event to all href's that = /ShoppingCart.asp?ProductCode="whatever" (whatever = whatever is in there") but not if it is specifically /ShoppingCart.asp?ProductCode="GFT". It must also check or convert a gft or Gft to upper case to check for those as well. So basically it has to check for any variation of the case of GFT.
If it finds a "GFT" do not bind the click event.
function sacsoftaddtocart() {
if (location.pathname == "/SearchResults.asp" || location.pathname == "/Articles.asp" || location.pathname.indexOf("-s/") != -1 || location.pathname.indexOf("_s/") != -1) {
$("a[href^='/ShoppingCart.asp?ProductCode']").click(function () {
var href = $(this).attr('href');
addToCart3(href);
return false;
});
}
}
You can do it using .toUpperCase() and .filter(), like this:
function sacsoftaddtocart (){
if (location.pathname == "/SearchResults.asp" || location.pathname == "/Articles.asp" || location.pathname.indexOf("-s/") != -1 || location.pathname.indexOf("_s/") != -1) {
$("a[href^='/ShoppingCart.asp?ProductCode']").filter(function() {
return this.href.length - this.href.toUpperCase().indexOf('PRODUCTCODE=GFT') != 15;
}).click(function () {
var href = $(this).attr('href');
addToCart3(href);
return false;
});
}
}
You cant test it in a demo here. The this.href.length - matchPosition == 15 is checking that the ProductCode=GFT is both matched and there's nothing after the "GFT", so a product code like "GFT5" won't match.
using the filter in this post link text
function sacsoftaddtocart() {
if (location.pathname == "/SearchResults.asp" || location.pathname == "/Articles.asp" || location.pathname.indexOf("-s/") != -1 || location.pathname.indexOf("_s/") != -1) {
$("a:regex('href','*/ShoppingCart.asp\?ProductCode=(!?=GFT)*)").click(function () {
var href = $(this).attr('href');
addToCart3(href);
return false;
});
}
}
or if you don't want to use an exrat plugin:
function sacsoftaddtocart() {
if (location.pathname == "/SearchResults.asp" || location.pathname == "/Articles.asp" || location.pathname.indexOf("-s/") != -1 || location.pathname.indexOf("_s/") != -1) {
$("a['href^='/ShoppingCart.asp?ProductCode']")
.filter(function(){ return !/ProductCode=GTF/.test($(this).attr('href')) };
.click(function () {
var href = $(this).attr('href');
addToCart3(href);
return false;
});
}
}
Try them and see what happens ;)