2

I'm trying to find and replace URL's for each a element.

Each wrap has data-folder with a path to a file. Each <a> element inside each wrap links to a file. The problem is that each <a> can be linked with folder up, like '../' or multiple- '../../../'. I have to check how many '../' each has and for each '../' remove one folder. like '/folder/'

This is my HTML:

<div class="wrap" data-folder="data_folder_1/data_folder_2/data_folder_3/">
  <a href="/folder1/folder1/_WAS_Modeller_DNK1.htm">Link</a>
  <a href="../folder1/folder2/Modeller.htm">Link</a>
  <a href="../../folder1/folder2/Modeller.htm">Link</a>
</div>

<div class="wrap" data-folder="data_folder_1/data_folder_2/data_folder_3/data_folder_4">
  <a href="../folder1/folder2/folder3/Specifikationer.htm">Link</a>
</div>

And jQuery:

console.clear();

var wrap = $(".wrap");

$.each(wrap, function(index, value) {
  var file = $(this).attr("data-folder");
  var fileArray = file.split("/");
  var links = $(this).find("a");

  // loop for link elements (a), it looops 4 times in this case
  $.each( links, function( ind, val ){
    var $this = $(this);
    var aHref = $(this).attr('href');
    var hrToArr = aHref.split("/");
    console.log(hrToArr);

    $.each(hrToArr, function( indx, va ){
      if( va == '..' ){
        fileArray.pop();
        $this.addClass( fileArray );
        console.log(va);
      }
    });
  })
});

The results should be:

<div class="wrap" data-folder="data_folder_1/data_folder_2/data_folder_3">
  <a href="data_folder_1/data_folder_2/data_folder_3/folder1/folder1/_WAS_Modeller_DNK1.htm">Link</a>
  <a href="data_folder_1/data_folder_2/folder1/folder2/Modeller.htm">Link</a>
  <a href="data_folder_1/folder1/folder2/Modeller.htm">Link</a>
</div>

<div class="wrap" data-folder="data_folder_1/data_folder_2/data_folder_3/data_folder_4">
  <a href="data_folder_1/data_folder_2/data_folder_3/folder1/folder2/folder3/Specifikationer.htm">Link</a>
</div>

Codepen here: https://codepen.io/rolandas/pen/XLEXPR?editors=1010

3
  • You know that browsers are able to handle relative URLs, right? If you want that third link with href="../../folder1/folder2/Modeller.htm" to actually point to data_folder_1/folder1/folder2/Modeller.htm - then all you need to do, is add that prefix into the href attribute content, href="data_folder_1/data_folder_2/data_folder_3/../../folder1/folder2/Modeller.htm" - no need to manually replace any ../ and keep count how many, etc. Commented Jul 1, 2019 at 13:41
  • @04FS yes, I know, but I'll have to check for ID by that generated URL Commented Jul 1, 2019 at 13:50
  • Don’t know what you mean by that. Commented Jul 1, 2019 at 13:57

2 Answers 2

2
var wrap = $(".wrap");

$.each(wrap, function(index, value) {
  var file = $(this).attr("data-folder");
  var fileArray = file.split("/").filter(Boolean);
  var links = $(this).find("a");

  // loop for link elements (a), it looops 4 times in this case
  $.each( links, function( ind, val ){
    var $this = $(this);
    var aHref = $(this).attr('href');
    var hrToArr = aHref.split("/").filter(Boolean);
    /* console.log(hrToArr) */;
    let a = fileArray;
    let b = [];
    $.each(hrToArr, function( indx, va ){
        if(va === '..') {
        fileArray.pop();
      } else {
      b.push(va)
      }
    });
    $this.attr('href', a.concat(b).join('/'));
  })
});

Output:

<div class="wrap" data-folder="data_folder_1/data_folder_2/data_folder_3/">
  <a href="data_folder_1/data_folder_2/data_folder_3/folder1/folder1/_WAS_Modeller_DNK1.htm">Link</a>
  <a href="data_folder_1/data_folder_2/folder1/folder2/Modeller.htm">Link</a>
  <a href="folder1/folder2/Modeller.htm">Link</a>
</div>

<div class="wrap" data-folder="data_folder_1/data_folder_2/data_folder_3/data_folder_4">
  <a href="data_folder_1/data_folder_2/data_folder_3/folder1/folder2/folder3/Specifikationer.htm">Link</a>
</div>
Sign up to request clarification or add additional context in comments.

3 Comments

Can you offer a written explanation too, please? (As opposed to just replying with only code.)
@sreeram there is no written explanation, but I get the result I was expecting
Give me a moment while I refactor it and add explanation.
0

Probably you don't need to remove ../ because servers/browsers usually support finding subdirectory in url (e.g /a/b/../c will be interpret as /a/c). However I do it in below code

let w=[...document.querySelectorAll('.wrap')];

for(let v of w) {  
  let f = v.dataset.folder.split('/');
  for(let a of [...v.children]) {
    let n= a.outerHTML.match(/href="(.*)">/)[1].match(/\.\.\//g);
    n = n ? n.length : 0;
    let p= n==0 ? f : f.slice(0,-n||1);
    a.href = p.join('/') + a.pathname.replace(/\.\.\//g,'');
  }
}

let w=[...document.querySelectorAll('.wrap')];

for(let v of w) {  
  let f = v.dataset.folder.split('/');
  for(let a of [...v.children]) {
    let n= a.outerHTML.match(/href="(.*)">/)[1].match(/\.\.\//g);
    n = n ? n.length : 0;
    let p= n==0 ? f : f.slice(0,-n||1);
    a.href = p.join('/') + a.pathname.replace(/\.\.\//g,'');
  }
}
<div class="wrap" data-folder="data_folder_1/data_folder_2/data_folder_3">
  <a href="/folder1/folder1/_WAS_Modeller_DNK1.htm">Link</a>
  <a href="../folder1/folder2/Modeller.htm">Link</a>
  <a href="../../folder1/folder2/Modeller.htm">Link</a>
</div>

<div class="wrap" data-folder="data_folder_1/data_folder_2/data_folder_3/data_folder_4">
  <a href="../folder1/folder2/folder3/Specifikationer.htm">Link</a>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.