-1

Is it possible to create a custom href based on data attribute such as data-schemaid="my-id-name"

All examples I have seen use an id.

For eg:https://www.w3schools.com/bootstrap/tryit.asp?filename=trybs_scrollspy&stacked=h

My html is dynamically generated and does not have a class or id, but rather looks like this:

<div data-schemaid="my-id-name"></div>

I tried using the same logic as the example, but that does not work.

Micheal
  • 2,272
  • 10
  • 49
  • 93
  • 1
    Do you mean if you have an anchor tag with `href="my-id-name"` it will take you to an element with attribute `data-schemaid="my-id-name"`? – Patrick Evans Sep 05 '17 at 20:59

2 Answers2

1

Yes, you can set any aspect of an element based on any aspect of any other element. You do need to choose a point in time when that should happen (on page load, on the click of another element, etc.).

Here's an example that sets up an <a> element with an href that matches the data-schemaid attribute value of the div upon page load and appends that a element into the document (by the way, you do understand that the value of the div you have shown isn't a valid URL by itself and would need to be adjusted to be valid to navigate to, right? If you just want the clicking of the <a> to navigate (scroll) to the <div>, you'd just need to prepend a "#" to it, as shown below.):

// Set up an event handler for when the document is parsed and ready to be interacted with:
window.addEventListener("DOMContentLoaded", function(){
   // Scan the document for the dynamically generated div that has a `data-schemaid` attribute
   var theDiv = document.querySelector("div[data-schemaid]");
   
   var newA = document.createElement("a");      // Create a new <a> element
   newA.href = "#" + theDiv.dataset.schemaid;         // Set the href to the div's attribute value
   newA.textContent = "Click Me";               // Give the new <a> some text to click on
   document.body.appendChild(newA);             // Append the new <a> to the end of the body
});
<div data-schemaid="my-id-name">
</div>

Or, if the <a> element already exists in the document (and doesn't need to be appended), then the solution is a bit simpler:

// Set up an event handler for when the document is parsed and ready to be interacted with:
window.addEventListener("DOMContentLoaded", function(){
   // Scan the document for the dynamically generated div that has a `data-schemaid` attribute
   var theDiv = document.querySelector("div[data-schemaid]");
   
   var speicalA = document.getElementById("specialA");   // Get a reference to the <a> element
   speicalA.href = "#" + theDiv.dataset.schemaid;         // Set the href to the div's attribute value

});
<div data-schemaid="my-id-name">
</div>

<a id="specialA">Click Me</a>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
1

If I am assuming correctly that you want an anchor tag that has href="my-id-name" to take you to an element with attribute data-schemaid="my-id-name", then it is just a matter of locating the element and calling scrollIntoView(true) on it. If wanting to animate the scroll see this answer (uses jQuery)

//use getAttribute("href") instead of this.href as 
//this.href will get a url based on the actual href attribute
var schemaid = this.getAttribute("href");

//use css attribute selector to find the target element
var target = document.querySelector(`[data-schemaid="${schemaid}"]`);
if(target){
  target.scrollIntoView(true);
}

Demo

document.querySelector('#anchor').addEventListener("click",function(event){
   event.preventDefault();
   var schemaid = this.getAttribute("href");
   var target = document.querySelector(`[data-schemaid="${schemaid}"]`);
   if(target){
     target.scrollIntoView(true);
   }
});
.spacer {
  height:1440px;
}
<a id="anchor" href="my-schemaid">Click me</a>
<div class="spacer"></div>
<div data-schemaid="my-schemaid">The target div</div>
<div class="spacer"></div>
Patrick Evans
  • 41,991
  • 6
  • 74
  • 87
  • I'm trying to understand why you provided this solution. First, using `querySelector` when searching for an `id` is slower than `getElementById`. Next, you've provided a JQuery answer when the question was not tagged with JQuery. Third, what is this syntax: `${schemaid}`? Next, why not just use the `element.dataset` property (which is specifically for gettting `data-*` attributes).... – Scott Marcus Sep 05 '17 at 22:17
  • ...Lastly, why not just set the actual `href` property as the OP asks instead of cancelling the native click event and then calling a method that does exactly what the native click event would do if the `href` property were set? – Scott Marcus Sep 05 '17 at 22:17
  • @ScottMarcus, the demo's performance doesn't matter, but querySelector is just what happened to use for the demo. As for the jQuery linked answer it was just a side note, which is why I specifically mentioned it was jQuery based, in case they wanted to try having a smooth scroll. As for `${schemaid}` it is an expression for [template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals). Why would I use `element.dataset`? I am not retrieving that value from the div, as it is the element we are trying to find. – Patrick Evans Sep 05 '17 at 22:25
  • As for using the href property, the property will return a url, so if the attribute is `my-id` it is going to use that to create a url like: `http://example.com/my-id`, which is not the value of the div's `data-schemaid`. The native click would do a page navigation away from the current page. The href is not using a hashtag, eg `#someanchor`, so it wouldn't do a native action like goto that anchor point, which is why we cancel the event and bring the element into view ourselves – Patrick Evans Sep 05 '17 at 22:28
  • I guess my overarching comment is that your solution is needlessly complex. There's no need to cancel the anchor's native event if the `href` simply gets a `#` prepended to it. Also, you would use the `dataset` property because you are retrieving that value from the `div`. That actually was the entire point of the question. Template literals, ok, but why? This answer just seems like an attempt to cram as much unneeded code into what should be a very simple solution. – Scott Marcus Sep 05 '17 at 23:34
  • @ScottMarcus, prepending a "#" would only work if the div has an id that matched, it doesn't. As for the template literals it is just a preference over using `"+variable+"` for concatenation. Not sure how it is complex though, the only thing it does is get's the value, uses it to find the element and then scrolls it into view... how is that complex? – Patrick Evans Sep 05 '17 at 23:39