I've a page with about 10 short articles.
Each of them as a "Read More" button which when pressed displays hidden text
The issues I have at the moment is when I press the "Read More" on any of the 10 button it shows the 1st articles hidden content and not the selected one.
I think I need to set a unique ID to each article.. and the read more button be linked to it.. But I don't know how to set it.
I looked at this but couldn't get it working how to give a div tag a unique id using javascript
var WidgetContentHideDisplay = {
init:function() {
if ($('#content-display-hide').size() == 0) return;
$('.triggerable').click(function(e){
var element_id = $(this).attr('rel');
var element = $('#'+element_id);
element.toggle();
if (element.is(':visible')) {
$('.readmore').hide();
} else {
$('.readmore').show();
}
return false;
});
}
}
var div = documentElemnt("div");
div.id = "div_" + new Date().gettime().toString;
$(document).ready(function(){ WidgetContentHideDisplay.init(); });
OP Edit: Sorry, the original code wasn't in caps. I kept getting errors when trying to post, so I copied the code into Dreamweaver and it made it all caps for some reason.
Instead of selecting the element to toggle with an ID (i.e. $('#'+ELEMENT_ID)) you could setup a class for your item and use the class selection (e.g. $('.DETAILED-ARTICLE)') to select the child (or the brother, etc. depending how you built the HTML page).
In theory each ID should point to a single element but each class can be put to as many elements as you want.
If you're getting errors, read the errors and see what they are. Off of a quick read of your code, here are a couple things I noticed that will probably cause issues:
"documentElemnt" is misspelled, which will render it useless. Also, documentElement is a read-only property, not a function like you're using it.
toString is a function, not a property, without the parentheses (.toString()) it isn't going to function like you want it to.
Run the code, look at the errors in the console, and fix them. That's where you start.
Related
I'm trying to change the value of an element on a third-party web page using a JavaScript Add-on to display a hyperlink
I already have the link on the page i would like to be able to click it
I think I'm on the right track using document.getElementById although I'm not sure how to then change the id into a "a href" and then how to pass it back into the value.
Sorry, this is a bit of a tricky situation so I'll try my best to explain it. On a third-party web-page which we use for our HR related tasks, there is a section titled "File Link" although this isn't a link. When you copy and paste the address into a browser it displays the file. What i am trying to do is create a hyperlink on the "File Link" section to remove the need to copy and paste the link. Because this is a third party website. We have access to the JavaScript on the website and need to change the address into a hyperlink. I'm not entirely sure this is possible.The element id is "__C_cb_file_link" and i would like to insert the link address into the element using a variable then add the link parameters into the variable then reinsert it into the element/value.
function linkIt() {
var intoLink = document.getElementById("__C_cb_file_link");
var hLink = "<a href="+intoLink+"</a>;
intoLink.value = hLink;
}
window.onload = linkIt();
<td><div class="sui-disabled" title="">m-files://view/37FF751C-A23F-4233-BD8B-243834E67731/0-46524?object=C46A7624-D24B-45F3-A301-5117EFC1F674</div>
<input type="hidden" name="__C_cb_file_link" id="__C_cb_file_link" value="m-files://view/37FF751C-A23F-4233-BD8B-243834E67731/0-46524?object=C46A7624-D24B-45F3-A301-5117EFC1F674"/></td></tr>
In below code first we read input value with new link (however we can read this value from other html tags), then we remove this element (and button) and add to parent element (of removed input) the new link
function linkIt() {
let intoLink = __C_cb_file_link.value;
let parent = __C_cb_file_link.parentNode;
__C_cb_file_link.remove();
btn.remove();
parent.innerHTML += `${intoLink}`;
}
<input id="__C_cb_file_link" value="https://example.com">
<button id="btn" onclick="linkIt()">Link It</button>
There are a number of issues with your code:
1) The code snippet in your question doesn't run because of a missing " at the end of the second line of the linkIt() function.
2) intoLink is a hidden field so anything you add to it will not be visible in the page
3) Even if point 2 were not true, setting the value of a form field will not cause HTML to appear on the page (at best you might get some plain text in a textbox).
4) "<a href="+intoLink+"</a>" doesn't work because intoLink is a complex object which represents the entire hidden field element (not just its value property). You can't convert a whole object into a string directly. You need to extract the value of the field.
A better way to do this is by creating a new element for the hyperlink and appending it to the page in a suitable place. Also I recommend not adding your event via onload - when written using this syntax only one onload event can exist in a page at once. Since you're amending another page which isn't under your control you don't want to disable any other load events which might be defined. Use addEventListener instead, which allows multiple handlers to be specified for the same event.
Demo:
function linkIt() {
var intoLink = document.getElementById("__C_cb_file_link");
var hLink = document.createElement("a");
hLink.setAttribute("href", intoLink.value);
hLink.innerHTML = "Click here";
intoLink.insertAdjacentElement('beforebegin', hLink);
}
window.addEventListener('load', linkIt);
<td>
<div class="sui-disabled" title="">m-files://view/37FF751C-A23F-4233-BD8B-243834E67731/0-46524?object=C46A7624-D24B-45F3-A301-5117EFC1F674</div>
<input type="hidden" name="__C_cb_file_link" id="__C_cb_file_link" value="m-files://view/37FF751C-A23F-4233-BD8B-243834E67731/0-46524?object=C46A7624-D24B-45F3-A301-5117EFC1F674" /></td>
</tr>
P.S. m-files:// is not a standard protocol in most browsers, unless some kind of extension has been installed, so even when you turn it into a hyperlink it may not work for everyone.
[UPDATE] I supose that your "__C_cb_file_link" was a paragraph so I get the previous text http://mylink.com and create a link with, is it what you want, right?
function linkIt() {
let fileLink = document.getElementById("__C_cb_file_link");
let hLink = fileLink.textContent;
fileLink.innerHTML = ""+hLink+"";
}
linkIt();
<div>
<p id="__C_cb_file_link">http://myLink.com</p>
</div>
I have a script that gives me the following error: 'TypeError: clickables[ic] is undefined' when I'm checking it with Firebug/in browser consoles. I'm a javascript beginner, who is trying to learn how to do things in vanilla javascript, and so I'm looking specifically for a solution that is just that.
The question: How do I get rid of/silence the undefined TypeError?
What the script should be doing:
I'm using this to reveal hidden elements, whose display attribute is set to none. The script should be getting all the instances of a particular class in a document, .item-reveal, joining that with a unique ID that each item having that class is given, to form a new class to search for via getElementsByClassName. The items with the .item-reveal class are items that are clicked on, the item that is unhidden/revealed has the .ID-reveal-item class (the unique ID of the clickable element followed by the .item-reveal class name reversed, for a simple convention). The ID isn't used for stying at all, it's merely to create a unique class based on a naming convention that can be applied to any pair of elements: one that is clicked on, one that is unhidden/hidden via creating/changing a style for the display attribute.
What the script does:
Currently, the script actually reveals the items onclick, and hides them again on subsequent clicks, and it works with multiple items. So, it kind of, basically, works. I just can't figure out the 'TypeError: clickables[ic] is undefined' issue and how to get rid of it. I get it in several browsers when using developer tools.
The script is an attempt at a self-executing anonymous function sort of thing, so I know the convention is a bit different, but I'm wanting to stick with it so I can apply it to other uses down the road. The article that inspired it is found here:
http://esbueno.noahstokes.com/post/77292606977/self-executing-anonymous-functions-or-how-to-write
EXAMPLE:
HTML
<!-- Item to be clicked, with unique ID -->
<h3 class="item-reveal" id="plan-1">Click for special pricing!</h3>
<p>An introductory paragraph...</p>
<!-- Hidden item to be revealed, will always have a unique class -->
<p class="plan-1-reveal-item">Special, this month only: $49.99</p>
<h3 class="item-reveal" id="plan-b">Click for special pricing!</h3>
<p>An introductory paragraph...</p>
<p class="plan-b-reveal-item">Special, this month only: $29.99</p>
CSS
/* Init - hide/unhide onclicks */
.item-reveal {cursor:pointer;}
[class$="-reveal-item"] {display:none;}
/* Halt - hide/unhide onclicks */
javascript:
var clickables = document.querySelectorAll('.item-reveal');
var clickCount = clickables.length;
(function () {
var Reveal = {
swapThis: function () {
for (var ic = 0; ic <= clickCount; ic += 1) {
// Next line seems to create the error message.
clickables[ic].onclick = function (unhideHide) {
var hidden = this.id;
var findClass = hidden += '-reveal-item';
var revealSwap = document.getElementsByClassName(findClass);
for (rn = 0; rn < revealSwap.length; rn++) {
revealSwap[rn].style.display = (revealSwap[rn].style.display == 'block') ? 'none' : 'block';
}
}
}
}
}
Reveal.swapThis();
}) ();
The script is linked via a SCRIPT tag, just prior to the closing BODY tag. I have tried it with both Async and Defer attributes, with and without other scripts in an HTML document, and the result is the same. I tried adding an event handler to ensure it wasn't something with the DOM loading still ongoing, but I'm not sure how to really test for that to see if it was actually doing anything. Unit testing is something that I'm just starting to attempt familiarizing myself with.
I'm trying to knock the dust off skills after several years in a completely unrelated industry, so the last year has been all about catching up on web development technologies, learning responsive design and HTML5 data stuff, and trying to learn javascript. I've searched, read, and bought several ebooks/books, and this is one of the few times I've run into something I just can't figure out. I imagine it's probably something simple and obvious to someone with formal programming/scripting knowledge, but I was an eBusiness major and networking, marketing, server/systems support, cabling, HTML/CSS, etc., are where I'm comfortable. Any help is greatly appreciated, but keep in mind that I'm trying to implement this in an environment/project that will have no jQuery, by choice. Thanks!
You are going off the end of the list with this:
for (var ic = 0; ic <= clickCount; ic += 1)
Change it to this:
for (var ic = 0; ic < clickCount; ic += 1)
clickCount is the length of the list so since it's 0 based indexing, clickables[clickCount - 1] is the last element in the list. You were trying to access clickables[clickCount] which does not exist.
I have li blocks which onclick will change class ID as follows:
onclick = "document.getElementById('procblock1').id = 'procblock1Clicked';"
"document.getElementById('procblock2Clicked').id = 'procblock2';"
"document.getElementById('procblock3Clicked').id = 'procblock3';"
"document.getElementById('procblock4Clicked').id = 'procblock4';"
The line document.getElementById('procblock2Clicked').id = 'procblock2'; should revert any clicked elements (blocks) back to their original ID names.
The code works for changing the original id to the clicked id but doesn't have any effect in reverting previously clicked to the original as per lines 2,3 & 4.
I have searched hard for similar questions but can find nothing that covers this specific issue.
#Matthias - I acted upon your advice and came up with a very simplified jquery solution :
`$(function() {
$(".showinfo").click(function() { //using class instead of ID
$(".showinfo").removeClass("clicked"); //Remove all existing clicks
$(this).addClass("clicked"); //add the class to the clicked element });
});`
Posted solution in case anyone else has same query. Your help was appreciated.
If this really is part of the code you're using lines 2-4 won't work; onclick will only handle the first line. You should wrap it as a function to be called onclick, like onclick = "doStuff()" and add a function doStuff () {/* your code here */}. But that's just guessing as you only provide some part of the code in question.
In addition would be good to know what you want to achieve - in case you want to mark clicked elements, it would be a cleaner approach to add a class, e.g. "clicked" or "active", that you simply remove later on instead of changing ids.
This question comes very closely to what I'm after: Replace an Attribute in the Tweet Button with Jquery
However, the suggested solution works just once. That is, I cannot use it in my switch statement like this:
switch(element.id)
{
case "t1":
$(document).ready(function(){
$('a[data-text]').each(function(){
$(this).attr('data-text', Text_Variant_1);
});
$.getScript('http://platform.twitter.com/widgets.js');
});
break;
case "t2":
$(document).ready(function(){
$('a[data-text]').each(function(){
$(this).attr('data-text', Text_Variant_2);
});
$.getScript('http://platform.twitter.com/widgets.js');
});
...
}
What happens is that the data-text attribute is set according to whichever case happens first and doesn't change afterwards.
How can I change data-text attribute of a Tweet Button as many times as I need?
Update: here's the page I'm working on: http://zhilkin.com/socio/en/
The Traits table can be safely ignored. What I want to do with the Sociotypes table is that when you click on a type, the data-text of the Tweet Button below the description on the right should be changed accordingly.
Right now it works like this: if I hover on or click "Don Quixote", then data-text is set to "... Don Quixote ...", and it stays the same if I click "Dumas" later. And vice versa: if I hover on or click "Dumas", then data-text is set to "... Dumas ..." and doesn't change if I click "Don Quixote". (Other types are empty at the moment.)
So, the Tweet Button is only changed the first time I run the script, but I need it to be updated as many times as the type changes.
I struggled with this for a couple of hours this morning, but finally got it working! The problem is essentially that you can only include the twitter widgets.js script once in the page, and that script evaluates the data-text attribute on load. Therefore, in your example, you dynamically set the data-text attribute before loading the script, which will work as expected. However, you can then make no further updates as the script has already run.
I saw this article suggesting you can call twttr.widgets.load() again at runtime to re-evaluate and re-render the buttons, however that didn't work for me. This is because that function re-evaluates <a> tags, not <iframe> tags!
So the solution, as pointed out here, is to completely remove the rendered <iframe> from the DOM, then make a new <a> element with all the appropriate attributes before calling twttr.widgets.load() to finally re-evaluate it and turn it into an <iframe>.
Please see this fiddle for a working example!
You can also use Twitter's createShareButton API call:
function callAsRequired(){
var nodeID = 'YourTwitterNodeID'
//Remove existing share button, if it exists.
var myNode = document.getElementById(nodeID);
while (myNode.firstChild) {
myNode.removeChild(myNode.firstChild);
}
//Create button and customise
twttr.widgets.createShareButton(
'http://your.custom.url.here/',
document.getElementById(nodeID),
{
count: 'none',
text: 'Your custom tweet here'
});
}
since you are using each loop you can use if statements instead:
$(document).ready(function(){
$('a[data-text]').each(function(){
if (theCase == 1) {
$(this).attr('data-text', Text_Variant_1);
}
else if (theCase == 2) { ... }
})
});
I have an application in which the user needs to see the changes that have been made during the latest edit.
By changes I mean, the changes made in all inputs like a textarea, dropdowns.
I am trying to implement this by showing a background image on the right top and then when the user clicks this background image, a popup is shown which shows the difference.
I am using prototype 1.7.0.
My First question would be:-
1. What would be the best approach to implement this functionality?
2. Can I put a onClick on the background image?
There some functions in the jQuery library that I believe would be helpful to you. If you are using prototype, I would guess that there is some similar functionality you may utilize.
I would suggest writing some code like this:
var $input = $('input').add('textarea').add('select');
$input.each(function() {
var id = $(this).attr('id');
var value = $(this).val();
var hiddenId = 'hidden' + id;
var newHiddenInput = $("<input type='hidden'").val(value).attr('id',hiddenId);
$(this).after(newHiddenInput);
});
The above code will create a new hidden input for each input, textarea, and select on your page. It will have the same value as the input it duplicates. It will have an id equivalent to prepending the id with the word 'hidden'.
I don't know if you can attach a click handler to a background image. If your inputs are enclosed inside a <div>, you may be able to get the result you want by attaching the click handler to your div.
In any case, you should now have the old values where you can easily compare them to the user's input so that you can prepare a summary of the difference.
Prototype gives us the Hash class which is almost perfect for this but lacks a way of calculating the difference with another hash, so let's add that...
Hash.prototype.difference = function(hash)
{
var result = this.clone();
hash.each(function(pair) {
if (result.get(pair.key) === undefined)
// exists in hash but not in this
result.set(pair.key, pair.value);
else if (result.get(pair.key) == pair.value)
// no difference so remove from result
result.unset(pair.key);
// else exists in this but not in hash
});
return result;
};
This is no way to tell if an element was clicked on just it's background image - you can find out the coordinates where it was clicked but that is not foolproof, especially since CSS3 adds complications like multiple backgrounds and transitions. It is better to have an absolutely positioned element to act as a button.
$('button-element').observe('click', function() {
var form_values = $H($('form-id').serialize(true));
if (old_values) {
var differences = old_values.difference(form_values);
if (differences.size()) {
showDiffPopup(differences);
}
}
window.old_values = form_values;
});
// preset current values in advance
window.old_values = $H($('form-id').serialize(true));
All that remains is to implement showDiffPopup to show the calculated differences.