Replace in variable a href address - javascript

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);
}
}

Related

Angular - Create component tree menu

I am creating a tree menu, visually it looks like this:
The tree has been created based on an array of objects obtained from a service, extracted from a date property.
Now, I have to get the tree menu to allow displaying and collapsing the: years, months and complete dates, in the style of this component:
https://angular2-tree.readme.io/
Ideally, I'd do this with typescript, but if it's hard for me, I'd try using an external component.
This is the html code:
<ul>
<li *ngFor="let y of tree | keyvalue">{{y.key}}
<ul>
<li *ngFor="let m of tree[y.key] | keyvalue">{{m.key}}
<ul>
<li *ngFor="let d of tree[y.key][m.key] | keyvalue">{{d.key}}
<ul>
<li *ngFor="let h of tree[y.key][m.key][d.key]"><a [ngClass]="{'hourSelected': (idSchedule === h.id || lastId === h.id),'hourUnSelected': idSchedule !== h.id}" (click)="loadMacroProcesses(h.id)">{{h.hour}}</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
This would be the solution, now I will refine it:
<ul>
<li id="year" *ngFor="let y of tree | keyvalue; let i=index" (click)="listClick($event, i)">{{y.key}}
<ul [hidden]="indexExpandedYear!=i?true:null">
<li id="month" *ngFor="let m of tree[y.key] | keyvalue; let j=index" (click)="listClick($event, j)">{{m.key}}
<ul [hidden]="indexExpandedMonth!=j?true:null">
<li id="day" *ngFor="let d of tree[y.key][m.key] | keyvalue; let k=index" (click)="listClick($event, k)">{{d.key}}
<ul [hidden]="indexExpandedDay!=k?true:null">
<li *ngFor="let h of tree[y.key][m.key][d.key]"><a [ngClass]="{'hourSelected': (idSchedule === h.id || lastId === h.id),'hourUnSelected': idSchedule !== h.id && lastId !== h.id}" (click)="loadMacroProcesses(h.id)">{{h.hour}}</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
This is the typescript method:
listClick(event, i) {
switch (event.srcElement.id) {
case "year":
this.indexExpandedYear = this.indexExpandedYear==i?-1:i;
event.stopPropagation();
break;
case "month":
this.indexExpandedMonth = this.indexExpandedMonth==i?-1:i;
event.stopPropagation();
break;
case "day":
this.indexExpandedDay = this.indexExpandedDay==i?-1:i;
event.stopPropagation();
break;
default:
break;
}
}
Can you recommend me a good one external component? Thanks.
NOTE: I am working with version 11 of Angular
NOTE: If you deploy one year, the rest of the years should be collpased back.
NOTE: Angular material is not valid for me
You could add a parameter for visibility and click event to the parent ul. How it would work is that they would have a boolean value on them for visibility that would change when you click the top ul element. You would have a method that would just switch between true/false and display if true hidden if false. Click event should be on the top li element and visibility on its child.
You should checkout the tree component provided by primeng. It has its own data format and can do your own customisation on top it.

How to click using query selector

I am having a list of navigation items that on load click the first element from the list
<li class="nav-item" v-for="(checkoutplan, index) in checkoutplans" :key="checkoutplan.id">
<a class="nav-link" :class="{ 'active show' : index === 0 }" href="#settings" data-toggle="tab" #click="editModal(checkoutplan)">Checkout Plan {{index +1}}</a>
</li>
What i am trying
document.querySelector("li[class='nav-item']").click()
nor
document.querySelector("li.nav-item:first-child").click()
It is not working
created() {
axios.get("api/checkoutplan")
.then(({ data }) => {this.checkoutplans = data;document.querySelector("a.nav-link:first-child").click();});
}
First add refs to your HTML (at a tag) as
<li class="nav-item" v-for="(checkoutplan, index) in checkoutplans" :key="checkoutplan.id">
<a :id="'nav' + index" :ref="'nav' + index" class="nav-link" :class="{ 'active show' : index === 0 }" href="#settings" data-toggle="tab" #click="editModal(checkoutplan)">Checkout Plan {{index +1}}</a>
</li>
Now in vuejs
$(this.$refs.nav0).click(function(){
//nav0 is beacuse you want first element & first element index is 0
});
as your comment , I tried like below in mounted method (not created) .Beware nextTick is required when vue element is modify by data
new Vue({
el: "#app",
data: {
checkoutplans : []
},
methods: {
editModal : function(param) {
console.log(param);
}
},
mounted: function() {
this.checkoutplans = [{id:1},{id:2}];
this.$nextTick(() => {
this.$el.querySelector("li.nav-item:first-child a").click();
});
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<ul>
<li class="nav-item" v-for="(checkoutplan, index) in checkoutplans" :key="checkoutplan.id">
<a class="nav-link" :class="{ 'active show' : index === 0 }" href="#settings" data-toggle="tab" #click="editModal(checkoutplan)">Checkout Plan {{index +1}}</a>
</li>
</ul>
</div>
Your code seem to click first li after api called ! So the method you will call is editModal({firstItem}) . How about calling the method directly without clicking like
axios.get("api/checkoutplan")
.then(({ data }) => {this.checkoutplans = data;this.editModal(this.checkoutplans[0]) // direct call });
Created method is not ready state for document element so you can't call document element in that method
var button = document.querySelector("input[type=button]");
button.addEventListener("click", function() {
alert("button was clicked");
})
document.querySelector('.nav-link');
please try this code.
You binded click event in href a.nav-link tag. not in so try
document.querySelector("a.nav-link:first-child").click()

How i can replace these words with JavaScript?

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>

Javascript, if URL then item

As the title suggests I am looking for a script command for "if url", then "item." I am working on a wordpress theme that I am translating. All of the content has been translated except for 1 item that is essentially a tile menu item.
I figure the best/only way to translate it since the theme does not support multilungual sites is to give it a javascript condition.
Perhaps I am wrong in my approach but I have been trying something like the following:
if(window.location.pathname == "example.com")
{
<li class="b1">
<a href="http://example.com/?page_id=69">
<h5>Example</h5>
<span>Thank you!.</span>
</a>
</li>
}
else
{
<li class="b1">
<a href="http://example.com/?page_id=69">
<h5>Example</h5>
<span>Merci beaucoup!.</span>
</a>
</li>
If anyone could tell me what im doing wrong that would be pretty cool
Thanks
You can't embed HTML into the middle of your javascript like that - everything in a script has to be actual javscript. You can use javascript to insert HTML into the DOM, either at the current position or in other positions in the document. For example, you could do this in your HTML:
<li class="b1">
<a href="http://example.com/?page_id=69">
<h5>Example</h5>
<span><script>
if(window.location.hostname == "example.com") {
document.write("Thank you!.")
} else {
document.write("Merci beaucoup!.")
}
</script></span>
</a>
</li>
You will also have to fix your javascript logic because location.pathname does not contain the domain - perhaps you meant to use .hostname instead.
your if statement is wrong because you are checking your domain against the path.
you should replace
window.location.pathname
with
window.location.hostname
put the javascript only where you need the text replaced: no need to write all the html twice.
if(window.location.hostname == "example.com") {
document.write("Thank you!.")
} else {
document.write("Merci beaucoup!.")
}
Something like this works.
<ul>
<li class="b1"> </li>
</ul>
<script language="javascript">
if(window.location.hostname == "example.com") {
document.querySelector('.b1').innerHTML = "<a href='http://example.com/?page_id=69'><h5>Example</h5><span>Thank you!.</span></a>";
}
else
{
document.querySelector('.b1').innerHTML = "<a href='http://example.com/?page_id=69'><h5>Example</h5><span>Merci beaucoup!.</span></a>";
}
You maybe should use a regular expression to catch the url, did you already tried?
<li class="b1">
<a href="http://example.com/?page_id=69">
<h5>Example</h5>
<span><script>
var expression = /[-a-zA-Z0-9#:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9#:%_\+.~#?&//=]*)?/gi;
var regex = new RegExp(expression);
if (window.location.hostname.match(regex) ){
<span>Thank you!.</span>
}
else{
<span>Merci beaucoup!.</span>
}
</script></span>
</a>
</li>

Javascript create recursive unordered list from ordered lists

I have the following HTML
<ol data-level="0">
<li class="active">This is the data1</li>
</ol>
<ol data-level="1">
<li class="active">This is the data2</li>
</ol>
<ol data-level="2">
<li class="active">This is the data3</li>
</ol>
<ol data-level="3">
<li class="active">This is the data4</li>
</ol>
<ol data-level="2">
<li class="active">This is the data5</li>
</ol>
<ol data-level="2">
<li class="active">This is the data6</li>
</ol>
<ol data-level="0">
<li class="active">This is the data7</li>
</ol>
Below you can see the outcome of the above HTML (I stripped out some html tags for better readability!).
I have to create a valid unordered list from this outcome. I've searched around stackoverflow and I came across multiple solutions. E.g. making use of a recursive function. The problem with this is that I don't know how to pass in the objects that belong to the 'root' object (see: How can I recursively create a UL/LI's from JSON data - multiple layers deep).
At the moment I'm stuck with this code:
var $root = $items.first();
var rootLvl = $root.data('level');
var prevLvl = rootLvl;
function recursiveCheck($next) {
prevLvl = $next.data('level');
var nextItem = $next.next();
if (nextItem.data('level') > prevLvl) {
console.log('check');
recursiveCheck(nextItem);
} else {
console.log('break');
}
}
recursiveCheck($root);
At the 'break' I don't know how to go back to the previous root element.. Can someone pull me in the right direction?
Thanks in advance!
Edit: My desired outcome is like this:
<ul>
<li>Data 1
<ul>
<li> Data 2
<ul>
<li> Data 3
<ul>
<li>
Data 4
</li>
</ul>
</li>
<li>Data 5
</li>
<li>Data 6
</li>
</ul>
</li>
</ul>
</li>
<li>Data 7
</li>
</ul>
More information
- level 1
- - level 2 // this belongs to the first level 1
- - - level 3 // this belongs to level 2
- - - level 3 // this belongs to level 2
- - - level 3 // this belongs to level 2
- - level 2 // this belongs to the first level 1
- level 1
- - level 2 // this belongs to the second level 1
in this example the first level 1 has two level 2 subitems, but one of them also has three level 3 subitems. So I have to find out how to get the next items with a higher level. I'm able to produce above string with '- - -'. I just can't convert this to an unordered list.
Solved, final code:
edu.saveSummary = function() {
var dataLevel = 'edu-draggable-level';
var node = $('[data-edu-draggable]').first();
function parseUL() {
var level = node.data(dataLevel);
var ul = document.createElement("ul");
while (node && node.data(dataLevel) === level) {
var li = document.createElement("li");
li.textContent = node.text();
ul.appendChild(li);
node = node.next();
if (node && +node.data(dataLevel) > level) {
li.appendChild(parseUL());
}
}
return ul;
}
return parseUL();
};
Something along these lines should work:
var node = first_ol_node;
function parseUL() {
var level = +node.children().first().data('level');
var ul = document.createElement("ul");
while (node && +node.children().first().data('level') === level) {
var li = document.createElement("li");
li.textContent = node.text();
ul.appendChild(li);
node = node.next();
if (node && +node.children().first().data(level) > level) {
li.appendChild(parseUL());
}
}
return ul;
}
var ul = parseUL();
One problem is that you need both to return the parsed ul node from the function and you also need to advance the parsing pointer over the source items (and in Javascript there's no way to pass a variable by reference, you can only pass by value).
In this solution I'm using an external variable instead of a parameter to keep the current pointer in the source items (advanced in node = node.next()) and the return value is the parsed UL.

Categories

Resources