Your Community is getting an upgrade!
Read about our partnership with Higher Logic and how we will build the next generation of the Instructure Community.
Found this content helpful? Log in or sign up to leave a like!
carroll-ccsd Nice Work has already done a Global Nav Menu - Custom Tray but with the new nav popping up tomorrow I didn't see any info about how to address those changes. So here is mine. @James
Thank You for the initial nudge to utilize mutation observers a lot more. (depicted in screenshot is the library the only custom nav we use for are school). Feel free to make the script better and share those changes as well
function LibraryResNav() {
const checkIfNull = async selector => {
while (document.querySelector(selector) === null) {
await new Promise(resolve => requestAnimationFrame(resolve));
}
return document.querySelector(selector);
};
checkIfNull("#application").then(() => {
// watching children && tree
const navR = document.querySelector("#application");
let uL;
const config = {
attributes: true,
attributeFilter: ["aria-hidden"],
subtree: false
};
const liConfig = {
"link reference": "#",
"name of SVG": "Library",
"view box dimensions": "0 0 500 500",
"name next to svg": `Library`,
"the g and path": `
<g role="presentation">
<path d="M459.91 192.02c-.7 0-1.39.02-2.06.05-49.8 2.84-140.51 13-201.84 47.57-61.33-34.57-152.05-44.73-201.84-47.57-.67-.04-1.36-.05-2.06-.05C31.71 192.01 0 206.36 0 242.22v178.05c0 26.69 21.25 48.7 48.34 50.12 34.41 1.81 120.56 9.08 177 37.47 4.68 2.37 9.66 3.5 14.66 3.84v.27h2.27c.09 0 .18.03.26.03h26.94c.09 0 .18-.03.26-.03H272v-.27c5-.34 9.98-1.48 14.66-3.84 56.44-28.39 142.59-35.65 177-37.47 27.09-1.42 48.34-23.44 48.34-50.12V242.22c0-35.86-31.71-50.2-52.09-50.2zM240 479.35c-.09-.04-.18-.02-.28-.07-59.59-29.97-144.43-38.45-189.7-40.84-10.1-.53-18.02-8.51-18.02-18.17V242.22c0-6.05 1.77-10 5.93-13.2 4.47-3.44 10.47-5.01 14.4-5.01 37.01 2.11 129.27 10.58 187.67 43.36v211.98zm240-59.08c0 9.66-7.92 17.64-18.03 18.17-45.27 2.38-130.11 10.86-189.76 40.87-.07.04-.14.02-.22.05V267.37c58.39-32.79 150.66-41.25 187.51-43.35l.39-.01c.2 0 20.09.49 20.09 18.21v178.05zM256 191.99c53.02 0 96-42.98 96-95.99S309.02 0 256 0s-96 42.98-96 95.99 42.98 96 96 96zM256 32c35.29 0 64 28.71 64 64s-28.71 64-64 64-64-28.71-64-64 28.71-64 64-64z" fill-rule="evenodd" stroke="none" stroke-width="1">
</path>
</g>
`
};
// Callback to execute when mutations are observed
const theOoze = mutationsList => {
for (let mutation of mutationsList) {
//console.log(mutation.target.hasAttribute("aria-hidden"));
if (mutation.target.hasAttribute("aria-hidden")) {
{
const notNull = async selector => {
while (document.querySelector(selector) === null) {
await new Promise(resolve => requestAnimationFrame(resolve));
}
return document.querySelector(selector);
};
notNull('div[role="dialog"][aria-label="Global Navigation"] ul')
.then(() => {
uL = document.querySelector(
'div[role="dialog"][aria-label="Global Navigation"] ul'
);
})
.then(() => {
let cloneLi = uL.querySelectorAll("li")[0].cloneNode(true);
cloneLi
.querySelectorAll("a")[0]
.setAttribute("href", liConfig["link reference"]);
cloneLi
.querySelectorAll("svg")[0]
.setAttribute("name", liConfig["name of SVG"]);
cloneLi
.querySelectorAll("svg")[0]
.setAttribute("viewBox", liConfig["view box dimensions"]);
cloneLi.querySelectorAll("svg")[0].innerHTML =
liConfig["the g and path"];
cloneLi.querySelectorAll("span:nth-last-of-type(1)")[3].innerHTML = liConfig["name next to svg"];
uL.appendChild(cloneLi);
});
}
}
}
};
// observer instance linked to the callback
const observer = new MutationObserver(theOoze);
// Start observing body since responsive nav is housed only in the body at end under <!-- #application -->
observer.observe(navR, config);
});
}
LibraryResNav();
@jsimon3 ,
Thanks for the shout-out and you're welcome. It's good to see MutationObservers catching hold.
I would try to rethink your selectors, though. As far as I know, those random-looking ReactJS classes are open to change as Canvas makes updates and might break with any code change. I would look for a different way to find the element you want, then find an existing item in the list and clone the element, then change the items that need changed before appending. This kind of bullet-proofs it against trivial updates (major updates may still break it).
I also don't get the purpose of your checkIfNull requesting an animationFrame. Was this a carry-over from the observer code that had the animation in it?
You may also find it quicker to re-check for the existence of the item you want rather than checking every modification that's made. You're watching a mutation on body with childList and subtree and that's going to be a lot of mutations. Using a CSS selector at least gets to use compiled code of the browser rather than JavaScript.
I know the selectors are a bit goofy but I thought it was just the JSS naming schema like: bgbk - background-break, etc
The checkIfNull promise won't start the observer and allow it to run constantly if nothing is found but I am glad you pointed it out because the selector that it is searching for is incorrect it should be: #application not the original nav
&& thanks for the tips I have implemented.
Done
.fOyUs_bGBk.tTloz_bGBk.tTloz_fLbg
These classes are built by webpack and are recompiled with each release, so this script would need to be updated with each release. It's why Global Nav Menu - Custom Tray comes with a CSS file.
Does this work for you?
document.querySelector('div[role="dialog"][aria-label="Global Navigation"] ul')
.cjUyb_bGBk.cjUyb_ycrn.cjUyb_eQnG
For this one. The trick I found was to set the class to those found in the LI next to the one I just added.
ccsd-canvas/admintray-subaccmenu.js at master · robert-carroll/ccsd-canvas · GitHub
Or try @James suggestion and clone one and then change what you need to.
OK, I thought the names were a part of JSS not webpack. I have not noticed those names to change but thanks for the heads up I will check the rest of my scripts for this as well. As far as that second class
```
.cjUyb_bGBk.cjUyb_ycrn.cjUyb_eQnG
```
goes I will probably just find it based on a count like
```
.querySelectorAll("span:nth-last-of-type(1)")[n]
```
But again thank you both
Between the 2 options, you can declare
var target_sel = 'div[role="dialog"][aria-label="Global Navigation"] ul'
and reuse it
// target UL
document.querySelector(target_sel)
// get this before placing the cloned item with the copied classNames
document.querySelector(`${target_sel} li:last-child`)
With the help of @James & carroll-ccsd I think that this is now acceptable .
I have been referred to this article after previously using and following Global Nav Menu - Custom Tray and Adding custom menu items.
Has the code in the original post been updated to reflect the discussion that has taken place?
Is this code, CSS code that would be used as a part of a theme?
Thank you.
Has the code in the original post been updated to reflect the discussion that has taken place?
---yes it has
Is this code, CSS code that would be used as a part of a theme?
---this is javaScript but you can embed it into the JS portion of your themes correct.
---the config for your icon is as follows
--- so if you changed the references like so "link reference": "https://google.com", and so on your icon will be added to the responsive navigation
const liConfig = {
"link reference": "#", //this is the name of an external link example https://google.com
"name of SVG": "Library", // the name of the SVG
"view box dimensions": "0 0 500 500", // each SVG comes with a viewbox this can be tweaked
"name next to svg": `Library`, //this is the link title in my case Library
"the g and path": ` //this is the SVG begining with the g and ending with /g
<g role="presentation">
<path d="M459.91 192.02c-.7 0-1.39.02-2.06.05-49.8 2.84-140.51 13-201.84 47.57-61.33-34.57-152.05-44.73-201.84-47.57-.67-.04-1.36-.05-2.06-.05C31.71 192.01 0 206.36 0 242.22v178.05c0 26.69 21.25 48.7 48.34 50.12 34.41 1.81 120.56 9.08 177 37.47 4.68 2.37 9.66 3.5 14.66 3.84v.27h2.27c.09 0 .18.03.26.03h26.94c.09 0 .18-.03.26-.03H272v-.27c5-.34 9.98-1.48 14.66-3.84 56.44-28.39 142.59-35.65 177-37.47 27.09-1.42 48.34-23.44 48.34-50.12V242.22c0-35.86-31.71-50.2-52.09-50.2zM240 479.35c-.09-.04-.18-.02-.28-.07-59.59-29.97-144.43-38.45-189.7-40.84-10.1-.53-18.02-8.51-18.02-18.17V242.22c0-6.05 1.77-10 5.93-13.2 4.47-3.44 10.47-5.01 14.4-5.01 37.01 2.11 129.27 10.58 187.67 43.36v211.98zm240-59.08c0 9.66-7.92 17.64-18.03 18.17-45.27 2.38-130.11 10.86-189.76 40.87-.07.04-.14.02-.22.05V267.37c58.39-32.79 150.66-41.25 187.51-43.35l.39-.01c.2 0 20.09.49 20.09 18.21v178.05zM256 191.99c53.02 0 96-42.98 96-95.99S309.02 0 256 0s-96 42.98-96 95.99 42.98 96 96 96zM256 32c35.29 0 64 28.71 64 64s-28.71 64-64 64-64-28.71-64-64 28.71-64 64-64z" fill-rule="evenodd" stroke="none" stroke-width="1">
</path>
</g>
`
};
Thank you for your reply, @jsimon3 , and additional guidance. It should help others if they decide to use it too.
I did actually mean JS (not CSS) and I apologize for the confusion and appreciate you correcting me. Not sure what I was thinking, probably just too early and should have thought more before posting the comment.
I will let you know if I need anything else.
Thanks again.
it's no problem at all, let me know if you need anything. Also the pattern I use here is also reflected in my modification for @r_carroll s Global Nav Menu - Custom Tray https://community.canvaslms.com/message/101582-global-nav-menu-custom-tray#comment-168252
To interact with Panda Bot, our automated chatbot, you need to sign up or log in:
Sign InTo interact with Panda Bot, our automated chatbot, you need to sign up or log in:
Sign In