Anki Forums

(Not solved yet) Dear programers! How can i change this code?

Back in the day i copied and pasted this code in my card’s template:

<div id="tags-container"></div>


<script>

//Vars
var tagsPresent = false;
var tags;
var tagContent = "{{Tags}}";
// Place all specified tag colors here
var tagMap = [
  // "fallback" should be set to desired default color
  fallback = {
    name: "",
    color: "#3F51B5"
  },
  Dependentes = {
    name: "Dependentes",
    color: "#f44336"
},
  Word = {
    name: "Word",
    color: "#13cfc8"
},
  Lei8112 = {
    name: "Lei8112",
    color: "#049177"
  },
  AtosAdministrativos = {
    name: "AtosAdministrativos",
    color: "#629104"
  }
];


//Calls
tags = searchTags();
checkTags(tags);

// Functions

//Find out if tags are there or not, and if so split at each word
function searchTags(){
  //Check if there are any tags
  if (tagContent == null || tagContent === ""){
    tagsPresent = false;
  } else {
    // Check if there is more than one tag
    if (tagContent.search(" ") >= 1){
      tagsPresent = true;
      tags = tagContent.split(" ");
    } else {
      tagsPresent = true;
      var tags = [tagContent];
    }
  }
  return tags;
}

// Loop through all tags in array and create a new div for each w/ respective color
function checkTags(tags){
  if (tagsPresent) {
    addTags(tags);
  } else {
    console.log("tags are not present");
  }
}


function addTags(tags){
  for (var i in tags) {
  var newDiv = document.createElement("div");
  newDiv.id = "tag";
  newDiv.innerHTML = tags[i];
  newDiv.style.display = "inline-block";

  // Choose background fill
  newDiv.style.backgroundColor = determineTagColor(tags[i]);

  //Choose outline
  newDiv.style.border = "1px solid" + determineTagColor(tags[i]);

  document.getElementById("tags-container").appendChild(newDiv);

  }
}

// Determine Tag Color by running through each tag
function determineTagColor(tag) {
  for (var i = 0; i < tagMap.length; i++){
    if (tagMap[i].name === tag){
      return tagMap[i].color;
    }
  }
  return tagMap[0].color;
}
</script>

#tag{
 font-size: 14px;
 border-radius: 3px;
 padding: 0.25rem;
 margin: 0.25rem;
}

Which basically show colored tags while reviewing cards and allows me to associate a color with a specific tag. If there’s no color associated, the default color will be blue.

image

But since i began to use hierarchical tags, this happens:

image

The code is considering that just one tag and then applying blue color because is the default color"

My question is: How can i change the code for it to ignore the :: for applying the color, but at the same time show the :: for me to know that is a hierarchical tag.

Something like this:

image

1 Like

I think if you change

if (tagContent.search(" ") >= 1){

and

tags = tagContent.split(" ");

to

if (tagContent.search("::") >= 1){

and

tags = tagContent.split("::");

in the searchTags function it should work.

It worked, but i can’t differentiate weather is on an hierarchy or not.

anki_GSulkt9o4x

You know a way i can put :: between de test1 and teste2?

Like this?

function addTags(tags){
  var numberOfTags =  tags.length - 1
  for (var i in tags) {
    var newDiv = document.createElement("div");
    newDiv.id = "tag";
    newDiv.innerHTML = tags[i];
    newDiv.style.display = "inline-block";

    // Choose background fill
    newDiv.style.backgroundColor = determineTagColor(tags[i]);

    //Choose outline
    newDiv.style.border = "1px solid" + determineTagColor(tags[i]);

    document.getElementById("tags-container").appendChild(newDiv);
    if (i < numberOfTags){
      var colonDiv = document.createElement("div")
      colonDiv.innerHTML = "::"
      colonDiv.style.display = "inline-block";
      document.getElementById("tags-container").appendChild(colonDiv);
    }
  }
}

I think i got it

anki_oJU5A91EMB

But there’s one problem

If i add a non-hierarchical tag, this happens:
anki_vCLhHyvsmh

anki_PFsshlzMqx

anki_siPt0FUTWf

anki_LezzzsIACE

Sorry bother you, but can you fix it?

If hierarchical tags and non-hierarchical tags are mixed it’s more difficult. Could you tell me what your tags look like? Are the non-hierarchical always before the hierarchical tags, or sometimes also after, or in between?

It should be easy since tags are separated by " " and hierarchical tags are separated by "::". Can I have a copy of the entire card template which you currently have?

After playing with it for a while, I got this solution.

// Get all the tags
const tagContent = "{{Tags}}";

// Place all specified tag colors here
const tagMap = {
  // "fallback" should be set to desired default color
  fallback: {
    name: "",
    color: "#3F51B5",
  },
  Dependentes: {
    name: "Dependentes",
    color: "#f44336",
  },
  Word: {
    name: "Word",
    color: "#13cfc8",
  },
  Lei8112: {
    name: "Lei8112",
    color: "#049177",
  },
  AtosAdministrativos: {
    name: "AtosAdministrativos",
    color: "#629104",
  },
};

// Find out if there are tags;
const tagsPresent = tagContent.length > 0;

// If there are tags present, continue.
if (tagsPresent) {
  // Assume that every tag is split by a whitespace.
  const tagGroups = tagContent.split(" ");

  for (const tagGroup of tagGroups) {
    // If the tag is a hierarchical tag, this would return an array of sub-tags. Else, it would be an array of a single tag.
    const hierarchy = tagGroup.split("::");

    // A container for each sub-tags.
    const groupElement = document.createElement("span");

    for (const [index, tag] of hierarchy.entries()) {
      // Create an element for the sub-tag
      const newDiv = document.createElement("div");
      newDiv.id = "tag";
      newDiv.innerHTML = tag;
      newDiv.style["display"] = "inline-block";

      // Assign the color to a variable.
      const color = (tagMap[tag] || tagMap["fallback"]).color;

      // Choose background fill
      newDiv.style["background-color"] = color;

      //Choose outline
      newDiv.style["border"] = "1px solid " + color;

      // Add the subtag to the sub-tag container.
      groupElement.appendChild(newDiv);

      // If the current sub-tag is not the final sub-tag, then a text node with '::' will be added.
      if (index != hierarchy.length - 1) {
        const textNode = document.createTextNode("::");

        groupElement.appendChild(textNode);
      }
    }

    // Add the sub-tag container to the tags-container element.
    document.getElementById("tags-container").appendChild(groupElement);
  }
}

image

This is my current template.

<div id="tags-container"></div>

&nbsp

{{edit:cloze:Text}}

<script>

//Vars
var tagsPresent = false;
var tags;
var tagContent = "{{Tags}}";
// Place all specified tag colors here
var tagMap = [
  // "fallback" should be set to desired default color
  fallback = {
    name: "",
    color: "#3F51B5"
  },
  Dependentes = {
    name: "Dependentes",
    color: "#f44336"
},
  Word = {
    name: "Word",
    color: "#13cfc8"
},
  Lei8112 = {
    name: "Lei8112",
    color: "#049177"
  },
  AtosAdministrativos = {
    name: "AtosAdministrativos",
    color: "#629104"
  }
];


//Calls
tags = searchTags();
checkTags(tags);

// Functions

//Find out if tags are there or not, and if so split at each word
function searchTags(){
  //Check if there are any tags
  if (tagContent == null || tagContent === ""){
    tagsPresent = false;
  } else {
    // Check if there is more than one tag
    if (tagContent.search("::") >= 1){
      tagsPresent = true;
      tags = tagContent.split("::");
    } else {
      tagsPresent = true;
      var tags = [tagContent];
    }
  }
  return tags;
}

// Loop through all tags in array and create a new div for each w/ respective color
function checkTags(tags){
  if (tagsPresent) {
    addTags(tags);
  } else {
    console.log("tags are not present");
  }
}


function addTags(tags){
  var numberOfTags =  tags.length - 1
  for (var i in tags) {
    var newDiv = document.createElement("div");
    newDiv.id = "tag";
    newDiv.innerHTML = tags[i];
    newDiv.style.display = "inline-block";

    // Choose background fill
    newDiv.style.backgroundColor = determineTagColor(tags[i]);

    //Choose outline
    newDiv.style.border = "1px solid" + determineTagColor(tags[i]);

    document.getElementById("tags-container").appendChild(newDiv);
    if (i < numberOfTags){
      var colonDiv = document.createElement("div")
      colonDiv.innerHTML = "::"
      colonDiv.style.display = "inline-block";
      document.getElementById("tags-container").appendChild(colonDiv);
    }

  }
}

// Determine Tag Color by running through each tag
function determineTagColor(tag) {
  for (var i = 0; i < tagMap.length; i++){
    if (tagMap[i].name === tag){
      return tagMap[i].color;
    }
  }
  return tagMap[0].color;
}
</script>

This is the result:

anki_00Fb2hATzV

anki_FsGR5aCJ3X

I tried to paste your code, but the tags disappeared, maybe i pasted in the wrong spot. Can you paste the whole code with your solution?

Obs: I’m pretty noob about programing.

Have you tried using the code that I have sent before this reply?

This : After playing with it for a while, I got this solution?

Yep. So if I modified your current template, it should look like this:

<div id="tags-container"></div>

&nbsp

{{edit:cloze:Text}}

<script>
{
// Get all the tags
const tagContent = "{{Tags}}";

// Place all specified tag colors here
const tagMap = {
  // "fallback" should be set to desired default color
  fallback: {
    name: "",
    color: "#3F51B5",
  },
  Dependentes: {
    name: "Dependentes",
    color: "#f44336",
  },
  Word: {
    name: "Word",
    color: "#13cfc8",
  },
  Lei8112: {
    name: "Lei8112",
    color: "#049177",
  },
  AtosAdministrativos: {
    name: "AtosAdministrativos",
    color: "#629104",
  },
};

// Find out if there are tags;
const tagsPresent = tagContent.length > 0;

// If there are tags present, continue.
if (tagsPresent) {
  // Assume that every tag is split by a whitespace.
  const tagGroups = tagContent.split(" ");

  for (const tagGroup of tagGroups) {
    // If the tag is a hierarchical tag, this would return an array of sub-tags. Else, it would be an array of a single tag.
    const hierarchy = tagGroup.split("::");

    // A container for each sub-tags.
    const groupElement = document.createElement("span");

    for (const [index, tag] of hierarchy.entries()) {
      // Create an element for the sub-tag
      const newDiv = document.createElement("div");
      newDiv.id = "tag";
      newDiv.innerHTML = tag;
      newDiv.style["display"] = "inline-block";

      // Assign the color to a variable.
      const color = (tagMap[tag] || tagMap["fallback"]).color;

      // Choose background fill
      newDiv.style["background-color"] = color;

      //Choose outline
      newDiv.style["border"] = "1px solid " + color;

      // Add the subtag to the sub-tag container.
      groupElement.appendChild(newDiv);

      // If the current sub-tag is not the final sub-tag, then a text node with '::' will be added.
      if (index != hierarchy.length - 1) {
        const textNode = document.createTextNode("::");

        groupElement.appendChild(textNode);
      }
    }

    // Add the sub-tag container to the tags-container element.
    document.getElementById("tags-container").appendChild(groupElement);
  }
}
}
</script>

It worked!

Man, thank you very much for your help and patience. :+1:

1 Like

Hi,
I wonder if there a way to hide hierarchical tags that seperated by :: and keep the tags that seperated by space " " , I would appreciate that if you can show me the way to do that, thanks