Using Javascript to edit HTML elements created by a content management system - javascript

Our small business signed a year long contract with Web.com to design and host a website, as well as make unlimited changes for the duration of the year. Unfortunately their content management system is extremely limiting, and their "experts" have little to no actual technical knowledge. Right now we're trying to add a page (Promotions) to the navigation bar, but the CMS does not allow us to edit it, the web.com design staff says they cannot access it for fear that they might break it, and they refuse to give us any kind of direct access to the files, so I cannot make the changes myself.
For reference, the website is www.icfloors.com
You can see if you inspect the navigation bar that it's serving up content for the promotions page, but it's set to not display
<li class="primary-webcomMenuItem" style="height: 72px; text-indent: 0px; display: none;">
<a href="promotions.html">
<div class="primary-webcomMenuItem-bottom" style="height: 72px;">
<div class="primary-webcomMenuItem-top" style="height: 72px;">
<div class="primary-webcomMenuItem-right" style="height: 72px;">
<div class="primary-webcomMenuItem-left" style="height: 72px;">
<div class="primary-webcomMenuItem-middle" style="padding-top: 25.5px; padding-bottom: 25.5px; height: 72px;">
Promotions
</div>
</div>
</div>
</div>
</div>
</a>
</li>
If you change the display attribute to "display: block;" as I do below, then the link appears exactly as intended and everything looks great.
<li class="primary-webcomMenuItem" style="height: 72px; text-indent: 0px; display: block;">
We've been on the phone with their designers, customer service, and/or tech support for hours and everyone is either incapable or unwilling to fix the issue/give us access to the actual code. We are however, able to directly edit the html of text boxes. So at this point, my hope is that I can write a short script in one of the boxes lower on the page that will go back and make the necessary change to the display attribute on the user's end. Unfortunately I have no ability to add a name or id to the element, so I have no idea how to find or address it.
Is there any way for me to do this?

If the href of that anchor tag can be relied on to be unique and consistent you can start there then go up one level and edit the display of its parent.
$('a[href="promotions.html"]').parent().css('display', 'block');
If you do not have access to jQuery, the process is a little more involved:
var element = getElementByHref('promotions.html');
if(element) element.parentElement.style.display = "block";
function getElementByHref(href) {
var anchors = document.getElementsByTagName("a");
for (var i = 0;i < anchors.length; i++) {
if (anchors[i].getAttribute("href") === href) return anchors[i];
}
}

Yes, it's possible. Using JQuery (that's what the $ he has means) as the other answer has posted, it would be a little easier, but here is the code without raw JS, because it doesn't seem like you have JQuery loaded on your site.
--Edited response to account for HREF and LI parent...
ADD at the bottom :
<script>
document.querySelector("[href='promotions.html']").parentNode.style.display = "block";
</script>
This may also help...
How to get all elements with a specified href attribute
Then just get down to .style.display.

Related

Trying to build a content locker using jQuery

I am very new to jQuery and not entirely sure what I'm doing. Will try my best to explain the problem I'm facing.
I'm trying to lock some content on a landing page until a user shares the link using FB, Twitter, LinkedIN or G+. The first version of the script I wrote (which worked fine) ran like this:
<head>
<script type="text/javascript">
...
$(document).ready(function()
{
$('.class').click(clearroadblock());
buildroadblock();
}
</script>
<style>
.class
{
[css stuff]
}
</style>
</head>
<body>
<div id="something">
<ul>
<li> Link1 </li>
<li> Link2 </li>
</ul>
</div>
</body>
The problem I'm now facing is changing out this code to replace the list elements with social share buttons. As they are no longer under .class, but classes like fb-share-button and twitter-share-button. Please help me understand what I need to modify to accommodate this? PS: This is not a Wordpress site.
function clearroadblock()
{
$('#roadblockdiv').css('display', 'none');
$('#roadblockBkg').css('display','none');
}
This is the way I'm clearing the overlay once a click is detected, BTW.
Can I wrap the social buttons in divs, assign them IDs and use those IDs to trigger the click like below?
<div id="Button">
Tweet
</div>
$('#Button').click(clearroadblock());
You can have multiple classes on an element by separating them with a space. Try the following:
class="class fb-share-button"
Your jquery will still work off the "class" class. I would recommend you change this name to something more meaningful though. Your css can target the "class" for general styles, but you can also target fb and twitter separately.
Update
I decided to create a quick JSFiddle for this.
Some of the styles etc won't be the same as what you're doing, but the problem is resolved. I've created a div with id main that contains the content that you want to hide. There's an absolutely positioned div over the top of this, this is the roadblock. The javascript is showing the roadblock (assuming that's what you wanted to do with buildroadblock()).
On click of a link in the ul with id socialMedia we call clearroadblock. Notice the lack of parenthesis. This hides the roadblock.
This isn't a great way of preventing someone from seeing information, you might want to think about pulling the content down from the server when the action is performed, however, I think this answers your question.

Formatting dynamically formed HTML elements created after Script is run

So this is actually a very tricky concept to portray so here is my attempt.
I am utilizing an HTML form template in LANDesk Service Desk - tool is irrelevant but important to note that there is back-end code that I cannot touch that is generating HTML.
So basically, the tool is pulling data from a back-end database containing a list of objects. It then inputs this data into an HTML form template that I have created using variables as placeholders for the objects. The HTML is then built on the fly with however many objects are in the database. Thus, I have no way of accessing the head - (which means native JS, and inline CSS).
My template looks like this...
<div class="my-template">
<a class="my-template my-link">My Link</a>
</div>
<script>
var myLinks = document.getElementsByClassName('my-link');
for (var i = 0 ; i < myLinks.length ; i++) {
myLinks[i].style.display = "none";
}
</script>
When I view the source on the loaded page it looks something like this...
<body>
<!--misc. page stuff-->
<!--First Item-->
<div class="auto-create">
<div class="my-template">
<a class="my-template my-link">My-Link</a>
</div>
</div>
<!--Second Item-->
<div class="auto-create">
<div class="my-template">
<a class="my-template my-link">My-Link</a>
</div>
</div>
</body>
All of the elements are formatted the way I want them to be...besides the last element on each page. I have determined that this is because each time the tool is running the object through the template, it is running the script. The issue is, there is a stupid default button that they place at the bottom of each object that is broken. (This is why I have the script changing the style to display: none..should have mentioned this earlier). Basically I want to delay the execution of the script until not only the object has been run through the template...but the entire page has loaded...but I can't seem to get the last button to go away.
I know that this is a lot of poorly written words trying to form an explanation, but I really think this is impossible...but I am convinced there has to be a way. (Also, the company isn't providing us with any help in finding a workaround, so I had to basically MacGyver this one

JS - Toggle all DIVs

My issue involves multiple DIVs that display:block or display:none each with their own anchor tag. The main problem is that I have recommissioned the JS code that runs this feature without completely understanding it. All I need is a way to toggle all of the DIVs with a single "Show All/Hide All" link. I cannot wrap my head around it.
I have tried absolutely everything that my exceptionally limited grasp will allow - which consists mostly of swinging my arms in the dark and hoping I accidently build a miracle. Since that hasn't worked I am shamefully seeking help.
The only thing that makes this question unique are all the variables with this specific issue -
An (almost) working example can be found at: www.robertmeans.com/menu.htm
The JS code:
imageX01='plus';
imageX02='plusEven';
function toggleOdd(ee){
imgX="imagePM"+ee;
divX="div"+ee;
imageX="imageX"+ee;
divLink="divHref"+ee;
imageXval=eval("imageX"+ee);
element = document.getElementById(divX).style;
if (element.display=='none') {element.display='block';}
else {element.display='none';}
if (imageXval=='plus') {document.getElementById(imgX).src='_images/minus.gif';eval("imageX"+ee+"='minus';");document.getElementById(divLink).title='Hide Content';}
else {document.getElementById(imgX).src='_images/plus.gif';eval("imageX"+ee+"='plus';");document.getElementById(divLink).title='Show Content';}
}
function toggleEven(ee){
imgX="imagePM"+ee;
divX="div"+ee;
imageX="imageX"+ee;
divLink="divHref"+ee;
imageXval=eval("imageX"+ee);
element = document.getElementById(divX).style;
if (element.display=='none') {element.display='block';}
else {element.display='none';}
if (imageXval=='plusEven') {document.getElementById(imgX).src='_images/minusEven.gif';eval("imageX"+ee+"='minusEven';");document.getElementById(divLink).title='Hide Content';}
else {document.getElementById(imgX).src='_images/plusEven.gif';eval("imageX"+ee+"='plusEven';");document.getElementById(divLink).title='Show Content';}
}
The HTML
<div id="task_item01">
<img src="_images/plus.gif" alt="" name="imagePM01" width="33" height="33" border="0" class="task_itemPlusImage" id="imagePM01" />
Div #1
</div>
<div style="display:none;" id="div01">
Content 1
</div>
<!-- ******************************** Item 1 End **************************** -->
<!-- ******************************** Item 2 Start ************************** -->
<div id="task_item02">
<img src="_images/plusEven.gif" alt="" name="imagePM01" width="33" height="33" border="0" class="task_itemPlusImage" id="imagePM02" />
Div #2
</div>
<div style="display:none;" id="div02">
Content 2
</div>
I have spent countless hours trying to work this out on my own. Any help is deeply appreciated.
Ok first of all, it seems like way too much code to me... you can do this very easily by using jQuery. I have made an example here: http://jsfiddle.net/Nr2f6/4/
Here is some simple html to help you better understand what is being done:
<div id="item-1"><span class="plus"></span>Open these items</div>
<div class="contents" data-rel="item-1">
I have superb items in this div... the world is about to understand just how awesome I am!
</div>
<div id="item-2"><span class="plus"></span>Open these other items</div>
<div class="contents" data-rel="item-2">
I have amazing contents in this div. I want to show them to the world!
</div>
as you can see above, there is no inline css. All the styling (display: none) should be placed separately, to not conflict with what you are trying to do. So simply place it in a separate css file.Then run this code:
$("div[id^=item]").click(function(){
var reference2open = $(this).attr("id");
//get the data-rel attribute associated
$("div[data-rel='"+reference2open+"']").slideToggle();
$("span",this).toggleClass('minus');
});
$("#all").click(function(){
if($(this).hasClass('close')){
$("div[data-rel^=item]").slideUp();
$("div[id^=item] span").removeClass('minus');
$("#all").removeClass('close');
$("#all").html('open them all');
}else{
//open and close them all by clicking
$("div[data-rel^=item]").each(function(){
if($(this).is(':hidden')){
$(this).slideDown();
$("div[id^=item] span").addClass('minus');
$("#all").html('close them all');
}
});
//change the button to close
$("#all").addClass('close');
}
//$("div[id^=item] span").toggleClass('minus');
});
****ADDED IN THE TOGGLE PLUS AND MINUS SIGNS USING CSS****
.plus{
background: url(http://www.robertmeans.com/offsite_files/code_help/_images/plus.gif);
width: 33px;
height: 33px;
display: inline-block;
}
.minus{
background: url(http://www.robertmeans.com/offsite_files/code_help/_images/minus.gif);
width: 33px;
height: 33px;
display: inline-block;
}
Do not forget to include your jQuery file! Hope this helps :)
Just wanted to add in some details for better understanding:
div[id^=item]: Is saying whenever a div is clicked that has an id that starts with (^=) item, run the code.
$("div[data-rel='"+reference2open+"']").slideToggle(): is saying take the id from the div that was clicked and find the content box where with the same name but in the data-rel attribute. The slide it down, if it is already down, slide it back up (toggle). You do not have to use a slide effect, I just thought it was more fun!
Then last but not least, the function you were looking for: How to open them all at once. Again we are using the (^=) to find all of the divs.
$("div[data-rel^=item").slideToggle();: So here we are saying to jQuery, hey toggle all the boxes that have a data-rel attribute that starts with (^=) item.
This last part is pretty neat, because you can create many instances of the item-? boxes and this code will work for any number of them. You can also add the same code to a different div, like even and odd, and toggle all the even and all the odd elements accordingly.
You could assign a specific class to all the things you want to toggle, then loop through all of them with a toggle function.

Displaying Hidden Javascript Divs if Java Enabled without Duplicate content

In short, I am trying to have an HREF menu with Javascript functions to display DIVs. However, my concern is that while I could have two seperate DIVs, one with Javascript if enabled, and one with No JAvascript enabled, I do not want to duplicate raw content on my page (as spiders will index Display: none html)
I am not familiar with functions of javascript, and best practices. My instinct is to string replace the DIVs for a specific id style tags when javascript is present..
Ie, logic that if javascript enabled, then replace text of style tags to to display=none (for specific ID's)
Also - is there a way to be nonspecific with javascript. Such as if i have contentid1,contentid2,contentid3,contentid4,contentid5,contentid6 I could use, via regular expression or equivalent for contentid 2-6
I will use this on multiple pages where contentids change. I do not know if i should create a javascript conditional style, as I am not sure how that style would be applied for multiple IDs (seen here)
Hide html only when Javascript is available
Heres my current code
<script type="text/javascript">
function showHide(d)
{
var onediv = document.getElementById(d);
var divs=['content1','content2','content3','content4'];
for (var i=0;i<divs.length;i++)
{
if (onediv != document.getElementById(divs[i]))
{
document.getElementById(divs[i]).style.display='none';
}
}
onediv.style.display = 'block';
}
</script>
then here is my menu
<ul>
<li>link1</li>
<li>link2</li>
<li>link3</li>
<li>link4</li>
</ul>
Then here is my content (note, i leave the content1 div visible by default
<div id="content1" >Content</div>
<div id="content2" style="display: none;">Stuff</div>
<div id="content3" style="display: none;">Things</div>`
I would like to avoid flickering if possible, and page refreshing if possible. Like could there be a condition so that content2+ have inlinestyle changed to hidden. If no javascript, my paeg just becomes really, really long.
?
Sorry-rambling. Tired, and have pneumonia :)

Updating the content of a div with javascript

Rather than trying to create tons of different pages on my website, I'm trying to update the content of a single div when different items in the navbar are click to update the maint div content. I tried to find a simple example using Javascript:
<script type="text/javascript">
function ReplaceContentInContainer(id,content) {
var container = document.getElementById(id);
container.innerHTML = content;
}
</script>
<div id="example1div" style="border-style:solid; padding:10px; text-align:center;">
I will be replaced when you click.
</div>
<a href="javascript:ReplaceContentInContainer('example1div', '<img src='2.jpg'>' )">
Click me to replace the content in the container.
</a>
This works just fine when I only try and update text, but when I put an img tag in there, as you can see, it stops working.
Either
1) what is the problem with how I am trying to do it?
or 2) What is a better/easier way to do it?
I'm not stuck on Javascript. jQuery would work too, as long as it is just as simple or easy. I want to create a function that will just let me pass in whatever HTML I want to update and insert it into the div tag and take out the 'old' HTML.
You just have some escaping issues:
ReplaceContentInContainer('example1div', '<img src='2.jpg'>')
^ ^
The inner ' need to be escaped, otherwise the JS engine will see ReplaceContentInContainer('example1div', '<img src=' plus some syntax errors resulting from the subsequent 2.jpg'>'). Change the call to (tip of the hat to cHao' answer concerning escaping the < and > in the HTML):
ReplaceContentInContainer('example1div', '<img src=\'2.jpg\'>')
A simple way to do this with jQuery would be to add an ID to your link (say, "idOfA"), then use the html() function (this is more cross-platform than using innerHTML):
<script type="text/javascript">
$('#idOfA').click(function() {
$('#example1div').html('<img src="2.jpg">');
});
</script>
First of all, don't put complex JavaScript code in href attributes. It's hard to read or to maintain. Use the <script> tag or put your JavaScript code in a separate file altogether.
Second, use jQuery. JavaScript is a strange beast: the principles underlying its patterns were not designed with modern-day web development in mind. jQuery gives you lots of power without miring you in JavaScript's oddities.
Third, if your goal is to avoid having to endlessly duplicate the same basic structure for all (or many) of your pages, consider using a templating system. Templating systems allow you to plug in specific content into scaffolds containing the common elements of your site. If it sounds complicated, it's because I haven't explained it well. Google it and you'll find lots of great resources.
Relying on JavaScript for navigation means your site won't be indexed properly by search engines and will be completely unusable to someone with JavaScript turned off. It is increasingly common--and acceptable--to rely on JavaScript for basic functionality. But your site should, at minimum, provide discrete pages with sensible and durable URLs.
Now, all that said, let's get to your question. Here's one way of implementing it in jQuery. It's not the snazziest, tightest implementation, but I tried to make something very readable:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery Example</title>
<style type="text/css" media="all">
/* all content divs should be hidden initially */
.content {
display: none;
}
/* make the navigation bar stand out a little */
#nav {
background: yellow;
padding: 10px;
}
</style>
</head>
<body>
<!-- navigation bar -->
<span id="nav">
about me |
copyright notice |
a story
</span>
<!-- content divs -->
<div class="content" id="about_me">
<p>I'm a <strong>web developer</strong>!</p>
</div>
<div class="content" id="copyright">
<p>This site is in the public domain.</p>
<p>You can do whatever you want with it!</p>
</div>
<div class="content" id="my_story">
<p>Once upon a time...</p>
</div>
<!-- jquery code -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script>
// Wait for the document to load
$(document).ready(function() {
// When one of our nav links is clicked on,
$('#nav a').click(function(e) {
div_to_activate = $(this).attr('href'); // Store its target
$('.content:visible').hide(); // Hide any visible div with the class "content"
$(div_to_activate).show(); // Show the target div
});
});
</script>
</body>
</html>
Ok, hope this helps! If jQuery looks attractive, consider starting with this tutorial.
Your main problem with your example (besides that innerHTML is not always supported) is that < and > can easily break HTML if they're not escaped. Use < and > instead. (Don't worry, they'll be decoded before the JS sees them.) You can use the same trick with quotes (use " instead of " to get around quote issues).

Categories

Resources