cancel
Showing results for 
Search instead for 
Did you mean: 
Adventurer

New Responsive Nav Custom Icons

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@richland.edu 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

339935_pastedImage_9.png

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();
10 Replies
Navigator

jsimon@uview.academy,

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@richland.edu 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`)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Adventurer

With the help of james@richland.edu‌ & carroll-ccsd‌ I think that this is now acceptable .

Explorer III

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, jsimon@uview.academy, 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.