I've run into a very strange problem.
I'm trying to create a search bar that has a dropdown button with many different search categories. Every link in the dropdown has the same id attribute each with a specific unique category attribute.
In my Javascript I used the querySelectorAll function to loop over all the elements and attach a click event listener which will execute my search function with one parameter (param):category attribute value.
However when the value is passed into the function I get [object MouseEvent] as the output. It's quite strange because the alert function that is called right before the function is called outputs the correct value. I'm not quite sure what is wrong
HTML Code:
<ul class="dropdown-menu dropdown-menu-right">
<li><a class="dropdown-item" id="search-users-btn" data-category="name" href="#">By First Name</a></li>
<li><a class="dropdown-item" id="search-users-btn" data-category="level" href="#">By Rank</a></li>
<li><a class="dropdown-item" id="search-users-btn" data-category="id" href="#">By ID</a></li>
</ul>
Javascript Code:
var searchBtn = document.querySelectorAll("[id=search-users-btn]");
for (var i = 0; i < searchBtn.length; i++) {
searchBtn[i].addEventListener("click", function (e) {
e.preventDefault();
e.stopPropagation();
alert(this.dataset.category); // This outputs the correct value.
searchQuery(this.dataset.category);//Everything goes wrong here
return false;
})
}
function searchQuery(param) {
var query = _("search-users-query-box");
if (!DN.value.empty(query.value)) {
window.location.href = encodeURI("/index/admin/search/param=" + param + "_" + query.value);
//Output looks like this: "/index/admin/search/param=[object%20MouseEvent]_somevaluehere"
} else {
query.style.borderColor = "red";
}
}
Try adjusting selector to className document.querySelectorAll(".search-users-btn") ; removing duplicate ids at search-users-btn , substituting adding search-users-btn as className at a elements
html
<ul class="dropdown-menu dropdown-menu-right">
<li><a class="dropdown-item search-users-btn" data-category="name" href="#">By First Name</a></li>
<li><a class="dropdown-item search-users-btn" data-category="level" href="#">By Rank</a></li>
<li><a class="dropdown-item search-users-btn" data-category="id" href="#">By ID</a></li>
</ul>
js
var searchBtn = document.querySelectorAll(".search-users-btn");
for (var i = 0; i < searchBtn.length; i++) {
searchBtn[i].addEventListener("click", function(e) {
e.preventDefault();
e.stopPropagation();
alert(e.target.dataset.category); // This outputs the correct value.
searchQuery(e.target.dataset.category); //Everything goes wrong here
})
}
Related
I am beginner web developer.
I have small problem with my code:
var nodes = document.querySelectorAll('.breadcrumb-item');
if(nodes != undefined && nodes !=''){
var first = nodes[0];
console.log('xxxxxx' , first);
}
It's return me:
[Log] xxxxxx
<li role="presentation" class="breadcrumb-item">
Home
</li>
I need check:
if a href is "Home" then replace href from "#/" to "/dashboard"
if a href is not "Home" then show console.log('not find').
How can I make it?
I have dynamic string. For example:
<li role="presentation" class="breadcrumb-item">
Home
</li>
<li role="presentation" class="breadcrumb-item">
Dogs
</li>
<li role="presentation" class="breadcrumb-item">
calls
</li>
<li role="presentation" class="breadcrumb-item">
cats
</li>
I need replace URL ONLY for Home
I've written assuming that Home will always be first in order. If you're going to change its order, you'll will have to change the index for nodes inside if block.
const nodes = document.querySelectorAll(".breadcrumb-item");
if (nodes.length > 0) {
const first = nodes[0].firstElementChild;
first.href = "/dashboard";
console.log(first);
}
Previous answer is correct. Maybe the following gives you a clearer understanding:
const nodes = document.querySelectorAll('.breadcrumb-item');
if (nodes.length > 0) {
const first = nodes[0].firstElementChild;
let currentUrlTitle = first.text.trim().toLowerCase();
if (currentUrlTitle == 'home') {
console.log(first.text);
first.href = '/dashboard';
console.log(first.href);
} else {
console.log(currentUrlTitle);
}
}
I want to rename CAR BUS to MY CAR, rename WATER to BREAKFAST, and delete the cocacola and fanta, to now be shown. People tell me it must be replaced with JS but I have no idea.
<li class="dropdown">
<a href="#" data-toggle="dropdown" data-hover="dropdown" aria-expanded="false">
CARS BUS<b class="caret"></b></a>
<ul class="dropdown-menu">
<li>WATER</li>
<li>COCA COLA</li>
<li>FANTA</li>
</ul>
</li>
If you have access to the underlying HTML, there's no need to use JavaScript at all. So if you have access, change it in the HTML.
In case you don't have access, you have to do these steps:
1) Grab elements to change with a DOM query (document.querySelector & document.querySelectorAll)
2) Change their innerHTML to the desired text
Based on the HTML you've shown, the most tricky part of it will be the DOM query. Mainly because there isn't much which allows to identify the correct elements (via id or class). To find out if you are working with the correct elements, you also have to compare their content.
This should work:
function queryAll(s, r) {
return Array.prototype.slice.call((r || document).querySelectorAll(s));
}
function isTarget(needle, element) {
var regex = new RegExp(needle);
return regex.test(element.innerHTML);
}
function changeText (needle, replacement, element) {
element.innerHTML = element.innerHTML.replace(needle, replacement);
}
var dropdowns = queryAll('a[data-toggle="dropdown"]');
dropdowns.forEach(function (anchor) {
if (isTarget('CARS BUS', anchor)) {
var subAnchors = queryAll('a', anchor.nextElementSibling);
changeText('CARS BUS', 'MY CAR', anchor);
subAnchors.forEach(function (sub) {
if (isTarget('WATER', sub)) {
changeText('WATER', 'BREAKFAST', sub);
} else {
sub.parentNode.style.display = 'none';
}
});
}
});
<li class="dropdown">
<a href="#" data-toggle="dropdown" data-hover="dropdown" aria-expanded="false">
CARS BUS<b class="caret"></b></a>
<ul class="dropdown-menu">
<li>WATER</li>
<li>COCA COLA</li>
<li>FANTA</li>
</ul>
</li>
// Plain JS
// `document.querySelector` will get the first element that matches
// inside selector `>` means that you want to get the direct child of --- in this case `.dropdown`
var $carbus = document.querySelector( 'li.dropdown > a' ), // element
$dropdownMenu = document.querySelector( '.dropdown-menu' ), // dropdown-menu
$firstLi = $dropdownMenu.querySelector( 'li > a' ), // element with water text
$notFirstLi = $dropdownMenu.querySelectorAll( 'li:not(:first-of-type)' ); // last two `li` items
replaceWord( $carbus, 'cars bus', 'my car' ); // replacing `cars bus` with `my car`
replaceWord( $firstLi, 'water', 'breakfast' ); // replacing `water` with `breakfast`
// removing last two items
$notFirstLi.forEach(function (item) {
item.remove();
});
/**
* #param {Element} el - target element
* #param {String} oldWord - Old word you want to change
* #param {String} newWord - New word you want to show
*/
function replaceWord(el, oldWord, newWord) {
var re = new RegExp( oldWord.toUpperCase(), 'i' ),
newTxt = el.innerText.replace(re, newWord.toUpperCase());
el.innerText = newTxt;
}
<li class="dropdown">
CARS BUS<b class="caret"></b>
<ul class="dropdown-menu">
<li>WATER</li>
<li>COCA COLA</li>
<li>FANTA</li>
</ul>
</li>
I'm using jQuery. I need to get the data-id of the clicked item and pass it to a webservice. How do I get the data-id attribute?
My HTML looks like this:
<ul class="nav nav-pills">
<li class="onselectedCategory" data-id="12">12</li>
<li class="onselectedCategory" data-id="23">23</li>
<li class="onselectedCategory" data-id="34">34</li>
<li class="onselectedCategory" data-id="45">45</li>
<li class="onselectedCategory" data-id="56">56</li>
</ul>
And my JavaScript looks like this:
events{
"click li.onselectedCategory": "selectCategory"
}
selectCategory: function(event){
event.preventDefault();
var _selectedValue = $(this).data('id');
alert("Selected Value : "+_selectedValue);
},
Try this:
$(".onselectedCategory").click(function(){
alert($(this).data("id"));
});
onselectedCategory is a class, therefor you need to reference it with a . and not with the # which is used for ids.
change #data-id to data-id
$(".onselectedCategory").click(function(){
alert($(this).attr("data-id"));
})
Edit for backbone
selectCategory: function(event){
event.preventDefault();
var selectedValue = "";
if($(e.target).is('li')) {
selectedValue =$(e.target).attr('data-id');
} else {
selectedValue =$(e.target).parent().attr('data-id');
}
alert("Selected Value : "+ selectedValue);
},
The onselectedCategory class must be within the label <a>
<li><a class="onselectedCategory" data-id="12" bla,bla,bla...</li>
$(".onselectedCategory").click(function(){ alert($(this).data("id")); });
I have this unordered list and would like to get the data-file attribute value of a link element inside the list element of the unordered list, then delete the whole list element in which it lies if it is not in array z.
<ul id="hithere"class="image-list">
<li class='image-list'>
<div class='controls'>
<a href='#' class='image-list' data-name='myname'><img src='stop.png' ></a>
</div>
<span class='name'>myname12</span
</li>
<li class='image-list'>
<div class='controls'>
<a href='#' class='image-list' data-name='myname2'><img src='stop.png' ></a>
</div>
<span class='name'>myname1312</span
</li>
</ul>
And this is my jQuery but it deletes all the list elements
var z = ["myname", "yourname"];
$("li.image-list a.image-list ").filter(function () {
if ($.inArray($(this).attr('data-name'), z) == -1) {
$(this).parent("li.image-list").empty().remove();
}
});
here is the code recieving from server:
var box = $('#drone');
box.f_drop({
url: 't_file.php',
check_data:function(i,file,response){
z=[];z.push(response.Oname);
$("li.image-list ").filter( function () {
return $.inArray($(this).find('a[data-name]').attr('data-name'), z) == -1
}).remove();
},
});
why is it that all the lists are now being removed instead of just one ie the one not in array?? Also, how can i rename the data-name attribute,to say "xyz" instead.
There are few problems in your script
The array is called z not _out
The anchor element does not have a class
the data property is called name, not filename
Try
var z = ["myname", "yourname"];
$("li.image-list").filter(function () {
return $.inArray($(this).find('a[data-name]').attr('data-name'), z) == -1
}).remove();
Demo: Fiddle
is it possible to amend the following html into the source linked at the bottom of this page? I have limited scripting access to the source page so I'm looking for a way to change the page using jquery or js.
Also the department id's will be completely random and there will be a different number of links relative to each group, therefore it will need to be dynamic. I've tried appending but I'm having trouble as inserting starting or closing tags only, so not sure how to go about this. Thanks in advance for any help offered.
Additions I need in the code are marked with **'s
Original source:
<ul class="menu">
<a id="group-car" href="#">Car</a>
<li><a id="department-2" href="link">Black</a></li>
<li><a id="department-4" href="link">Blue</a></li>
<a id="group-bike" href="#">Bike</a>
<li><a id="department-1" href="link">BMX</a></li>
<li><a id="department-6" href="link">Racing</a></li>
<li><a id="department-12" href="link">Mountain</a></li>
</ul>
What I need to end up with:
<ul class="menu">
**<li>**
<a id="group-car" href="#">CAR</a>
**<ul class="acitem">**
<li><a id="department-2" href="link">Black</a></li>
<li><a id="department-4" href="link">Blue</a></li>
**</ul>**
**</li>**
**<li>**
<a id="group-bike" href="#">BIKE</a>
**<ul class="acitem">**
<li><a id="department-1" href="link">BMX</a></li>
<li><a id="department-6" href="link">Racing</a></li>
<li><a id="department-12" href="link">Mountain</a></li>
**</ul>**
**</li>**
</ul>
jQuery(".menu").children("a").each(function()
{
jQuery(this).nextUntil("a").add(this).wrapAll("<li></li>");
jQuery(this).nextUntil("a").wrapAll("<ul></ul>");
});
jsfiddle
Does this need some explanation?
EDIT oops! I didn't see the classes on them:
jQuery(".menu").children("a").each(function()
{
jQuery(this).nextUntil("a").add(this).wrapAll("<li></li>");
var jUL = jQuery("<ul></ul>").addClass("acitem");
jQuery(this).nextUntil("a").wrapAll(jUL);
});
jsFiddle
What a beautiful challenge!!
Here you have. Tested in FF 3.6 and works!
function fixMarkup(){
var liFamilies = [];
var iFamily = 0;
$(".menu li").each(function(){
if($(this).prev().is("a"))
liFamilies[iFamily] = [this]; //Start a family
else
liFamilies[iFamily].push(this); //Append to family
if($(this).next().is("a")) iFamily++; //A new family begins
});
//console.log(liFamilies);
for(var i = 0; i< liFamilies.length; i++){
var family = liFamilies[i];
$(family).wrapAll('<ul class="acitem" />');
var ulNew = $(family[0]).parent()[0];
var aElem = $(ulNew).prev()[0];
$([aElem, ulNew]).wrapAll("<li/>");
}
}
$(document).ready(function(){
fixMarkup();
});