var not always set when clicking link in JQuery - javascript

In my index.html i have a JQuery var which i need to set when the user clicks an option from the left hand menu and its needed to show/hide fields depending on the selection made as the page is shared between 3 pages but displays different fields depending on the option.
But i have an issue when sometimes when the option is selected, its not setting the var as expected then after a few other clicks, it then decides to play ball and set it, then when ever it wants, it will stop again.
There no errors what so ever so not sure how to track or stop it.
JQuery
$('li').on('click', function (event) {
selectedLinkId = event.target.id.toLowerCase();
// Admin menu option clicked
if ($(this).is($("li[name*='admin']"))) {
selectedLink = 'adminMenuOption';
}
// Reseller menu option clicked
else if ($(this).is($("li[name*='reseller']"))) {
selectedLink = 'resellerMenuOption';
}
// Channel menu option clicked
else if ($(this).is($("li[name*='channel']"))) {
selectedLink = 'channelMenuOption';
}
// Customer menu option clicked
else if ($(this).is($("li[name*='customer']"))) {
selectedLink = 'customerMenuOption';
}
// Any other menu option clickedf
else {
selectedLink = 'generalMenuOption';
}
$('#mainSearchSection').show();
})
Part of HTML
<ul class="nav nav-tabs nav-pills flex-column" role="tablist">
<li class="nav-item" id="adminSearchLink" name="adminOptions">
<div class="nav-link d-flex align-items-center option pl-6">
Search for
<i id="adminSearchMenuIcon" class="material-icons ml-auto mr-0">arrow_drop_up</i>
</div>
</li>
<li class="nav-item" name="adminSearchOptions">
<a id="adminSearchCustomerLink" class="nav-link d-flex align-items-center option" href="#" data-toggle="tab" role="tab" aria-selected="false">
<span class="ml-5 pl-4">Customer</span>
</a>
</li>
<li class="nav-item" name="adminSearchOptions">
<a id="adminSearchNumberLink" class="nav-link d-flex align-items-center option" href="#" data-toggle="tab" role="tab" aria-selected="false">
<span class="ml-5 pl-4">Number</span>
</a>
</li>
<li class="nav-item" name="adminSearchOptions">
<a id="adminSearchResellerLink" class="nav-link d-flex align-items-center option" href="#" data-toggle="tab" role="tab" aria-selected="false">
<span class="ml-5 pl-4">Reseller</span>
</a>
</li>
</ul>
Console.Log Output
Other Page JQuery Which Reads The Var
var selectedLinkId;
if (selectedLinkId.includes('reseller')) {
$('#accStatusCol, #companyNameCol, #nameFieldCol').show();
$('#nameField').focus();
} else if (selectedLinkId.includes('channel')) {
$('#accStatusCol, #companyNameCol, #nameFieldCol').hide();
} else if (selectedLinkId.includes('customer')) {
$('#accStatusCol, #companyNameCol').show();
$('#companyNameField').focus();
}

You seems to want to get the id of the clicked <a> element. However the event is bound to the <li> element.
When you use event.target it will give you the element that you clicked. Because events are bubbling it is not always the same element but can be any of the children of the element that the event handler is bound to. So sometimes you get the <li> element, sometimes the <a> element and sometimes the <span> element. If you want to get the id of the first a element all the times you can do $(this).children('a').first().attr('id').

The problem is that you're sometimes clicking on the <span> and sometimes on the <a>, outside the text. Only the latter has an id.
Use $('li a').click(...) and
selectedLinkId = $(this).attr('id').toLowerCase();
This way, this always refers to the <a>, and getting the id from that never fails.
The non-jQuery variant is to use event.currentTarget.id.toLowerCase(), which always refers to the element that the listener was attached to as it bubbles up the tree.

Related

Select an specific option from Dropdown Menu without values using Puppeteer

I am trying to use puppeteer to select and click an option in a dropdown menu in a navbar.
I already searched. There is always a page.select with the ID of the dropdown menu, but the thing is, there is no value option.
How can i, for example, make puppeteer click on the Tools2 dropdown item?
Or, in a case of a dropdown menu with options that changes if you are a different user, how can i make puppeteer always click on the second option of a dropdown? Can i use CSS to make this work?
Here is the dropdown menu:
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="home.html">Home<span class="sr-only">(current)</span></a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
Tools
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="#">Tools1</a>
<a class="dropdown-item" href="#">Tools2</a>
<a class="dropdown-item" href="#">Tools3</a>
</div>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
User
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
Create users
<a method="get" class="dropdown-item" href="/usuario">Manage users</a>
<a class="dropdown-item" href="#">Profile</a>
<a method="get" action="/usuario/logout" class="dropdown-item" href="/">Logout</a>
</div>
</li>
</ul>
CSS selector
If the dropdown items are already in the DOM you can use the nth-child CSS pseudo-class to select a specific one:
await page.click('ul > li:nth-child(2) > div > a:nth-child(2)')
li:nth-child(2) => the "Tools" menu (1 would be the "Home", while 3 would be the "User" nav-item)
a:nth-child(2) => the second <a> element within the dropdown, "Tools2"
In case these list items are dynamically generated then you first need to open the dropdown:
await page.click('ul > li:nth-child(2)')
Then proceed with selecting the 2nd <a> element.
XPath selector
If the text content is more reliable than the (second) position within the dropdown then you can also use XPath's contains() function to detect the element, return it as an element handle then click it :
const [item] = await page.$x('//a[contains(text(), "Tools2")]')
await item.click()
Note: $x returns an array of matched items, hence you either need to use an index of the item or use ES6 destructuring as in my example.
$$eval approach
You can also use page.$$eval to click the item based on its index ([1] will be the second element within the array of dropdown elements):
await page.$$eval('ul > li:nth-child(2) > div > a', (elems) => elems[1].click())

Laravel: Click event on tab pane

I have tables called: 1) purchase_requisitions; 2) liquidations. Assuming that I have 100 data for both purchase requisitions and liquidations.
In our application, we have all the lists of users and when the client clicked a certain user, there will be a modal that will pop-up.
In this modal you can see all the records for that user and also there's 2 tab. 1) Purchase Requisition tab; 2) Liquidations tab.
Purchase Requisition is the active tab once the client clicked the certain user and this is where I'm fetching the data of purchase requisitions.
Now what I want is, I dont want to load the 100 data of purchase requisitions and liquidations at the same time.
I want to load the liquidations, for example when I clicked the liquidations tab.
Question: Why does my click event is not working?
Tab pane
<ul class="nav nav-pills">
<li class="nav-item" style="width: 10%">
<a class="nav-link active" data-toggle="pill" href="#purchases-payments-tab">Purchases/Payments</a>
</li>
<li class="nav-item" style="width: 10%">
<a class="nav-link" data-toggle="pill" href="#liquidations-tab">Liquidations</a>
</li>
Javascript
<script type="text/javascript">
function getPurchasesPayments(vendor_id,start_date,end_date){
// .... code
}
$(document).ready(function(){
var vendor_id = "<?= $vendor->id; ?>";
var start_date = "<?= $start_date;?>";
var end_date = "<?= $end_date;?>";
if ($('.purchases-payments').length > 0) {
$('div').click('.purchases-payments',function(e){
// $('.purchases-payments').click(function(e){
$('.purchases-payments-details').html('');
getPurchasesPayments(vendor_id,start_date,end_date);
e.preventDefault();
return false;
})
}
if ($('.liquidations').length > 0) {
$('div').click('.liquidations',function(e){
// $('.liquidations').click(function(e){
alert('test');
e.preventDefault();
return false;
})
}
// if ($('.liquidations').hasClass('active')) {
// alert('liquidations active');
// }
})
You're targeting "div" in your jQuery click code, but you want to target your a elements, you should also add classes or ids to this elements which you will be targeting.
Add ids to your a elements
<ul class="nav nav-pills">
<li class="nav-item" style="width: 10%">
<a id="purchases" class="nav-link active" data-toggle="pill" href="#purchases-payments-tab">Purchases/Payments</a>
</li>
<li id="liquidations" class="nav-item" style="width: 10%">
<a class="nav-link" data-toggle="pill" href="#liquidations-tab">Liquidations</a>
</li>
</ul>
and in your javascript:
$(document).ready(function(){
$('#purchases').click(function(e){
// your code
});
$('#liquidations').click(function(e){
// your code
});
})

How to override or redefine vue router?

My problems
Hi guys,
I am building a website that uses vuejs (vue, vuex, vue-router). Besides, I have used another template which is material dashboard (this template uses bootrsap4 and a custom js file).
At first, everything was very convenient, my vue-router worked perfectly. But when I checked the interface on my phone, there was a problem:
In this interface, the user menu in the upper right corner works with the vue-router normally, my page does not reload every time the url changes.
But when I changed the browser size, made it smaller and the user menu bar will now show as above. The problem now is that the links act like a normal anchor tag, and my page re-loads every time the URL changes.
Found the cause
This is the code of the user menu bar.
<!-- language-all: lang-html -->
<div class="collapse navbar-collapse justify-content-end">
<div class="navbar-form"></div>
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link" href="javascript:;" id="navbarDropdownProfile" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">person</i>
<p class="d-lg-none d-md-block">
Account
</p>
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownProfile">
<router-link class="dropdown-item" to="/test">Profile</router-link>
<router-link class="dropdown-item" to="/another_one">Settings</router-link>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Log out</a>
</div>
</li>
</ul>
</div>
The problem is in the template's javascript custom file
They use a function that rewrites the menu bar whenever the window size gets smaller and
this may accidentally overwrite or disrupt the vue-router. The code is as follows:
initRightMenu: debounce(function() {
$sidebar_wrapper = $('.sidebar-wrapper');
if (!mobile_menu_initialized) {
$navbar = $('nav').find('.navbar-collapse').children('.navbar-nav');
mobile_menu_content = '';
nav_content = $navbar.html();
nav_content = '<ul class="nav navbar-nav nav-mobile-menu">' + nav_content + '</ul>';
navbar_form = $('nav').find('.navbar-form').get(0).outerHTML;
$sidebar_nav = $sidebar_wrapper.find(' > .nav');
// insert the navbar form before the sidebar list
$nav_content = $(nav_content);
$navbar_form = $(navbar_form);
$nav_content.insertBefore($sidebar_nav);
$navbar_form.insertBefore($nav_content);
$(".sidebar-wrapper .dropdown .dropdown-menu > li > a").click(function(event) {
event.stopPropagation();
});
// simulate resize so all the charts/maps will be redrawn
window.dispatchEvent(new Event('resize'));
mobile_menu_initialized = true;
} else {
if ($(window).width() > 991) {
// reset all the additions that we made for the sidebar wrapper only if the screen is bigger than 991px
$sidebar_wrapper.find('.navbar-form').remove();
$sidebar_wrapper.find('.nav-mobile-menu').remove();
mobile_menu_initialized = false;
}
}
}, 200),
What have I tried
I tried rewriting javascript in their js file as follows:
nav_content = $navbar.html(); // I turned this
// into this
nav_content = `<li class="nav-item dropdown">
<a class="nav-link" href="javascript:;" id="navbarDropdownProfile" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">person</i>
<p class="d-lg-none d-md-block">
Account
</p>
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownProfile">
<router-link class="dropdown-item" to="/test">Profile</router-link>
<router-link class="dropdown-item" to="another_one">Settings</router-link>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Log out</a>
</div>
</li>`
But it still does not work
To be more clear
I tried printing out nav_content, everything seems right. I think the problem is $nav_content = $(nav_content);
Is the problem I pointed out correct? If yes, I'd appreciate it if I got your advice, thank you.

How to get a link that do nothing

I have created a search engine using Angular and Bootstrap. I have created different results tab as shown in image Tabs . Right clicking on tab does not show the option of a link as we get on any link.
link on right click
Currently I am using <li> tag and bootstrap to create the tabs of different result section. Here is the code for that
<ul type="none" id="search-options">
<li [class.active_view]="Display('all')" (click)="docClick()">All</li>
<li [class.active_view]="Display('images')" (click)="imageClick()">Images</li>
<li [class.active_view]="Display('videos')" (click)="videoClick()">Videos</li>
<li [class.active_view]="Display('news')" (click)="newsClick()">News</li>
<li class="dropdown">
<a href="#" id="settings" class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Settings
</a>
<ul class="dropdown-menu" aria-labelledby="settings" id="setting-dropdown">
<li routerLink="/preferences">Search settings</li>
<li data-toggle="modal" data-target="#customization">Customization</li>
</ul>
</li>
<li class="dropdown">
<a href="#" id="tools" class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Tools
</a>
<ul class="dropdown-menu" aria-labelledby="tools" id="tool-dropdown">
<li (click)="filterByContext()">Context Ranking</li>
<li (click)="filterByDate()">Sort by Date</li>
<li data-toggle="modal" data-target="#myModal">Advanced Search</li>
</ul>
</li>
</ul>
After clicking on the link everything is handled by the functions which get executed on click event. All I want to do that is make that a link, so that user can open it in new tab and state of the app should not change at all. How that is possible? I have tried to do that using routing but things became more complicated. i also followed some answers from here Make a HTML link that does nothing (literally nothing) but they do not work. Please help. I have tried all the answers from there opening link in new tab just disturbs the state of URL.
Using will make the page scroll to the top.
Use javascript:void(0):
Clicking here does nothing
Or equivalently, use javascript:;:
Clicking here does nothing
Or, with HTML5, just omit the href attribute:
<a>Clicking here does nothing</a>
You can use event.preventDefault() to prevent the default action of the link from being taken.
Valid Link<br>
<button id='hitMe'>Disable link</button>
<br/>
<button id="enable">Enable link</button>
<script>
document.getElementById('hitMe').onclick = function() { // button click
document.querySelectorAll('a').forEach(a =>{
a.onclick = function(e){
e.preventDefault();
return false;
}
});
};
document.getElementById("enable").onclick = function(){
document.querySelectorAll('a').forEach(a =>{
a.onclick = null;
});
}
</script>
By clicking the button, no more links will be followed.
Like this you still have the hover destination preview. Like google.de etc...
document.getElementById('hitMe').onclick = function() { // button click
[...document.querySelectorAll('a')].forEach(function(el){
el.onclick = function( e ) { // all 'a'
return false;
}
});
};
Valid Link<br>
<button id='hitMe'>Disable link.</button>
use
javascript:;
as href attribute
and add
event.preventDefault()
onclick method.
Click me

Javascript code for Bootstrap Sidebar menu not working

I have a Sidebar / Menu that I am working with. It has been created with Bootstrap, DJango, and Javascript.
Basically, I am trying to write Javascript so that when on clicks on a menu-item, the background changes color (dark blue), the icon change color (light green / turquoise) and it gets a type of "wedge"
Below is an example of a menu-item that has been chosen (Dashboard) along with menu-items that have not been chosen (Security and Messages). The "wedge" has a red arrow pointing to it.
Here is the HTML code that is being used:
[... snip ...]
<div class="page-container">
<div class="page-sidebar-wrapper">
<div class="page-sidebar navbar-collapse collapse">
<ul class="page-sidebar-menu page-header-fixed page-sidebar-menu-hover-submenu "
data-keep-expanded="false" data-auto-scroll="true" data-slide-speed="200">
<li class="nav-item start active open">
<a href="{% url 'mainadmin:dashboard' %}" class="nav-link nav-toggle">
<i class="fa fa-tachometer"></i>
<span class="title">Dashboard</span>
<span class="selected"></span>
<span class="arrow open"></span>
</a>
</li>
<li class="nav-item ">
<a href="{% url 'mainadmin:security' %}" class="nav-link nav-toggle">
<i class="fa fa-users"></i>
<span class="title">Security</span>
<span class="arrow"></span>
</a>
</li>
<li class="nav-item ">
<a href="{% url 'mainadmin:in_progress' %}" class="nav-link nav-toggle">
<i class="fa fa-comment"></i>
<span class="title">Messages</span>
<span class="arrow"></span>
</a>
<ul class="sub-menu">
<li class="nav-item ">
<a href="{% url 'mainadmin:in_progress' %}" class="nav-link ">
<span class="title">List All Messages</span>
</a>
</li>
<li class="nav-item ">
<a href="{% url 'mainadmin:in_progress' %}" class="nav-link ">
<span class="title">List My Messages</span>
<span class="badge badge-danger"></span>
</a>
</li>
</ul>
</li>
[... snip ...]
Here is the Javascript code:
<script>
$(document).ready(function () {
$('.nav-item a').click(function(e) {
$('.nav-item a').removeClass('selected');
$('.nav-item a').removeClass('arrow');
$('.nav-item a').removeClass('open');
$('.nav-item a').removeClass('active');
alert("I have gotten in");
var $parent = $(this).parent();
$parent.addClass('selected');
$parent.addClass('arrow');
$parent.addClass('open');
$parent.addClass('active');
e.preventDefault();
});
});
</script>
I do get the alert message - but - what happens is :
-> the background of the chosen menu-item does change color - which is correct
--> The icon of the chosen menu-item changes color (to light blue / turquoise) - which is correct
-> the tick of the arrow does not take place for the chosen menu-item :(
-> the old chosen menu item does not "de-select"
What am I doing wrong?
TIA
Hi #Joe Lissner
Thanks so much for the response!
I had to add the following to get the "wedge" portion to work. It required span tags
// REFERENCE: https://stackoverflow.com/questions/2013710/add-span-tag-within-anchor-in-jquery
$(this).append('<span class="selected"></span>');
$(this).append('<span class="arrow open"></span>');
While this works when clicking on the main-menu item, I'm not so lucky when it comes to clicking on sub-menu items. As of now, I am pretty much new to Javascript.
How would one get the sub-menu items to work?
Also, when clicking on an item, it does not go to the page specified in "href="
How would can one make changes to the code so that when the menu-item is clicked, it would go to the page specified in "href="
Again, thanks for the response :-)
You are removing the classes from the a tags, not the .nav-item elements.
Try this:
$(document).ready(function () {
$('.nav-item a').click(function(e) {
e.preventDefault(); // best practice to have this first, if you remove this line then the link will function as expected.
var $parent = $(this).parent();
var $arrow = $parent.find('.arrow');
$('.nav-item').removeClass('selected arrow open active'); // simplified
$('.nav-item .arrow').removeClass('open');
$('.nav-item .selected').detach(); // remove the span that was there before
alert("I have gotten in");
$parent.addClass('open active'); // simplified
$arrow.addClass('open').before('<span class="selected" />')
});
});
Edit - Fixed the issue with the arrow

Categories

Resources