JS, Highlight content between comments - javascript

I have few comments in my code, like this:
<!-- DebugDataTemplateBegin {"template":"one"} -->
<div class="row notices" id="admin">
comment One content
</div>
<!-- DebugDataTemplateEnd {"template":"one"} -->
<!-- DebugDataTemplateBegin {"template":"two"} -->
<div class="row notices" id="admin">
comment Two content
</div>
<!-- DebugDataTemplateEnd {"template":"two"} -->
and I have anchors like this:
one <br/>
two
These links content corresponds to the comments 'template' element, what I want to achieve is that when the user hover over any of these links it's correspondence content (between the comment) will be highlighted.
I started a simple jsfiddle example http://jsfiddle.net/Banzay/md79aaby/ , but not sure if this is even possible.
Sorry if I didn't explain this very well.
Youssef

Cleaned up my answer above and removed it.
You might have to change the parent you are looking for comments in. And the regex could use some love but this is the general idea.
HTML:
<!-- DebugDataTemplateBegin {"template":"one"} -->
<div class="row notices" id="admin">comment One content</div>
<!-- DebugDataTemplateEnd {"template":"one"} -->
<!-- DebugDataTemplateBegin {"template":"two"} -->
<div class="row notices" id="admin">comment Two content</div>
<!-- DebugDataTemplateEnd {"template":"two"} -->
one
<br/>
two
JS:
var getComment = function (templateName) {
return $("body").contents().filter(function () {
return this.nodeType == 8 && this.nodeValue.match(RegExp('DebugDataTemplateBegin.*'+templateName));
})
}
$('a').hover(function () {
var templateName = this.href.split('#')[1];
var comment = getComment(templateName);
var element = $(comment).next();
element.toggleClass('highlight');
})
http://jsfiddle.net/md79aaby/18/

Related

Add and remove class on multiple element when clicked

I have the below as an example of what I'm working on; I'm trying to add a class to two elements when one of the elements is clicked.
<div id="main">
<div id="section1">
- contents here -
</div>
<div id="section2">
- contents here -
</div>
<div id="section3">
- contents here -
</div>
<div class="plans-group">
<div class="plans-columns plans-type-1">
<div class="plans-col plans-left plans-heading">Heading</div>
<div class="plans-col plans-right">
<div class="select-plan select-gold">Gold</div>
</div>
<!-- end plans-right -->
</div>
<!-- end plans-columns -->
<div class="plans-columns plans-type-2">
<div class="plans-col plans-left plans-heading">Heading</div>
<div class="plans-col plans-right">
<div class="select-plan select-silver">Silver</div>
</div>
<!-- end plans-right -->
</div>
<!-- end plans-columns -->
<div class="plans-columns plans-type-3">
<div class="plans-col plans-left plans-heading">Heading</div>
<div class="plans-col plans-right">
<div class="select-plan select-bronze">Bronze</div>
</div>
<!-- end plans-right -->
</div>
<!-- end plans-columns -->
</div>
<!-- end plans-group -->
</div>
<!-- end main -->
#1): DIV with class "select-plan"
When div with class "select-plan" is clicked, add class "clicked" to that div. When it's clicked again, remove the added class.
#2): DIV with id "main"
When "select-plan" is clicked (as explained above) also add class to the container div with id "main". And remove the added class when "select-plan" is clicked again.
This is where I have a problem because different classes have to be added to "main". For example:
When "select-gold" is clicked, add class "gold-selected" to "main"
When "select-silver" is clicked, add class "silver-selected" to "main"
When "select-bronze" is clicked, add class "bronze-selected" to "main"
I don't want previously clicked div to have its added class removed because another div is clicked. The added class should only be removed when that same div is clicked for the second time and so on...
Also, I might have up to 8 or more plans. The solution should not be limited to the 3 plans (Gold, Silver, and Bronze). I should have the ability to create more plans.
I really appreciate everyone's help with this.
Thanks in advance.
let selectPlan = document.querySelectorAll('.select-plan');
let mainDiv = document.getElementById('main');
selectPlan.forEach(el =>{
el.addEventListener('click',function(e){
if(e.target.classList.contains('select-plan')){
e.target.classList.toggle('clicked');
}
if(e.target.classList.contains('select-gold')){
mainDiv.classList.add('gold-selected');
mainDiv.classList.remove('silver-selected');
mainDiv.classList.remove('bronze-selected');
}else if(e.target.classList.contains('select-silver')){
mainDiv.classList.add('silver-selected');
mainDiv.classList.remove('gold-selected');
mainDiv.classList.remove('bronze-selected');
}else{
mainDiv.classList.add('bronze-selected');
mainDiv.classList.remove('silver-selected');
mainDiv.classList.remove('gold-selected');
}
});
});
let main = document.getElementById("main");
let select = document.querySelector(".select-plan");
let selectG = document.getElementsByName("gold");
let selectS = document.getElementsByName("silver");
let selectB = document.getElementsByName("bronze");
function toggleGold() {
if (main.classList.contains('gold-select')) {
main.classList.remove('gold-select');
} else {
main.classList.add('gold-select');
}
selectG[0].classList.toggle('cliqué')
}
//You can add same function for silver and bronze
document.querySelector(".select-gold").addEventListener("click", toggleGold);
document.querySelector(".select-silver").addEventListener("click", toggleSilver);
document.querySelector(".select-bronze").addEventListener("click", toggleBronze)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div name="gold" class="select-plan select-gold">Gold</div>
<div name="silver" class="select-plan select-silver">Silver</div>
<div name="bronze" class="select-plan select-bronze">Bronze</div>

Trying to pass variables to another function

Okay, I dont know why my codepen version and my real one act different, but they are. In my codepen both windows start off with all of them open. In my real version you only see 2 sets of 01-Postpone and 02-Approve, the way they should be. Here, in my code snippet, the first text box does not populate, but the values are logged in the console.
Okay, so now my problem. Clicking any 1 of these slides opens a box underneath it with 2 options. PROCEED and CANCEL. With my fun function, it gets the 3 variables perfectly when 1 of those options is clicked ( see them in my console).
When PROCEED is clicked, I need those 3 variables so that I can run an ajax post to an external file. How do I get the 3 fun variables into my proceed function? I thought with var, they would be global, but I have tried many possibilities without success to access them. I do not want to use cookies as I am sure this is possible without them.
I have another freaky issue, but that is for another day when I get this part to work. Any assistance would greatly be appreciated.
https://codepen.io/lepew/pen/agNBzo
// 00 - CANCEL
function cancel00() {
alert("Cancel");
}
// End CANCEL
// 02 - PROCEED
function proceed01() {
// Ajax will go here
alert("This works.");
}
// End of PROCEED
// 03 - Get the data-field variables
function fun(obj) {
var one = obj.dataset.self,
two = obj.dataset.record,
three = obj.dataset.selectedoption;
//
console.log(one, two, three);
//
}
//external file
$(document).ready(function() {
$(".dropdown-link").on("click", function() {
//
const tranSpeed = "slow";
//
//
// Get code variable and be able to access this value elsewhere.
var selectmycode = $(this).attr("data-selectedoption");
//
// Display the variable in CONSOLE.
console.log(selectmycode);
//
// Get clicked option.
var selOption = $(this).data("selectedoption");
//
// Out the value of selectedoption into text field thecode.
var thecoder = $(".thecode").attr("value", selOption);
//
//
//
// Get next "here".
var here = $(this).closest(".bind_Name").next(".here");
//
// Populate stuff.
$(here).find("legend").text(`Option ${selOption}`);
//
// TO DETECT IF DATA HAS CHANGED.
var dataChanged = $(here).data("seloption") !== selOption;
$(here).data("seloption", selOption);
console.log(dataChanged)
//
// Show the dropdown if data changed.
var target = $(here).find(".dropdown-container");
//
// This will close all other open options.
$(".dropdown-container").not(target).hide(tranSpeed);
//
if (dataChanged) {
$(target).show(tranSpeed);
} else {
// Or toggle it otherwise.
$(target).toggle(tranSpeed);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="bind_Area">
<div class="bind_Name">
<div class="dropdown">
<div class="dropdown-link" onclick="fun(this);" data-selectedoption="01" data-record="123456820" data-self="123456830">01-Postpone
</div>
<!-- end of #dropdown-link -->
</div>
<!-- end of #dropdown -->
<div class="dropdown">
<div class="dropdown-link" onclick="fun(this);" data-selectedoption="02" data-record="123456820" data-self="123456830">02-Approve
</div>
<!-- end of #dropdown-link -->
</div>
<!-- end of #dropdown -->
</div>
<!-- end of #bind_Name -->
<div class="here">
<div class="dropdown-container">
<fieldset>
<legend></legend>
<input type="text" class="thecode" data-code="">
<input type="text" class="peter" data-user="123456820" value="123456820">
<input type="text" id="mary" data-product="123456830" value="123456830">
<div>PROCEED</div>
<div>CANCEL</div>
</fieldset>
</div>
<!-- end of #dropdown-container -->
</div>
<!-- end of #here -->
<div class="bind_Note"></div>
</div>
<!-- end of #bind_Area -->
<br>
<br>
<br>
<div class="bind_Area">
<div class="bind_Name">
<div class="dropdown">
<div class="dropdown-link" onclick="fun(this);" data-selectedoption="01" data-record="123456820" data-self="123456831">01-Postpone
</div>
<!-- end of #dropdown-link -->
</div>
<!-- end of #dropdown -->
<div class="dropdown">
<div class="dropdown-link" onclick="fun(this);" data-selectedoption="02" data-record="123456820" data-self="123456831">02-Approve
</div>
<!-- end of #dropdown-link -->
</div>
<!-- end of #dropdown -->
</div>
<!-- end of #bind_Name -->
<div class="here">
<div class="dropdown-container">
<fieldset>
<legend>
<div class="fubar"></div>
</legend>
<div>
<input type="text" class="thecode" data-code="">
<input type="text" class="peter" data-user="123456820" value="123456820">
<input type="text" id="mary" data-product="123456831" value="123456831">
</div>
<!-- end of #blank div -->
<div>PROCEED</div>
<div>CANCEL</div>
</fieldset>
</div>
<!-- end of #dropdown-container -->
</div>
<!-- end of #here -->
<div class="bind_Note">
</div>
</div>
<!-- end of #bind_Area -->
<br>
<br>
<br>

Toggle only this item

i've a problem to toggle only (this) 1 'card'
$('a[rel="toggle_comments"]').click(function(){
var div = $('.comments');
$(div, this).slideToggle('slow');
});
<!-- This is a example code -->
<section>
<div class="mainclass">
[...]
<div class="select">
Test
</div>
</div>
<ul class="comments">
<!-- Content -->
</ul>
</section>
<section>
<div class="mainclass">
[...]
<div class="select">
Test
</div>
</div>
<ul class="comments">
<!-- Content -->
</ul>
</section>
[...]
When I clicked at 'toggle_comments', toggle all '.comments' classes, not only that, I have clicked. Anyone have any ideas?
Sorry for my bad english.
I hope you understand what I mean - Thanks :-)
If you want to toggle only the .comments under the <section> tag your link is in, do this:
$('a[rel="toggle_comments"]').click(function(){
// find the closest section tag (parent) and find all child `.comments`
var $comments = $(this).closest('section').find('.comments');
$comments.slideToggle('slow');
});
If you want to toggle all .comments:
$('a[rel="toggle_comments"]').click(function(){
$('.comments').slideToggle('slow');
});

Referencing HTML elements

I am looking that if certain element could be referenced so, If I make any change to the one it also makes change in the other. For example,
<div id="trigger" data-referencedID="meter voltmeter ammeter vmeter">Trigger</div>
...
...
<div id="meter">
<!-- Its children goes here -->
</div>
...
...
<div id="voltmeter">
<!-- Its children goes here -->
</div>
...
...
<div id="ammeter">
<!-- Its children goes here -->
</div>
...
...
<div id="vmeter">
<!-- Its children goes here -->
</div>
Now in jQuery or JS:
$("#trigger").click( function() {
$(this).addClass("animated"); // The same class will be also added to the elements defined in attribute.
});
I could do it like this:
$("#trigger").click( function() {
var a = $(this).data("referenced").split(" ");
for(var i = 0; i < a.length; i++) {
$("#"+a).addClass("animated");
}
$(this).addClass("animated");
});
But it is not good looking and convenient plus I can have more main elements with referenced attribute.
How can I easily add referencing in my document?
You can use a class for all referenced elements like:
<div id="trigger" data-reference="reference_1">Trigger</div>
<div id="meter" class="reference_1"></div>
<div id="voltmeter" class="reference_1"></div>
And in your jQuery part:
$("#trigger").click( function() {
var e = $(this);
e.addClass("animated");
$('.' + e.data('reference')).addClass("animated");
});
How about a reverse referring? Add classes in the meters which points to the trigger. This way you may add any number of meters which referring the trigger:
<div id="trigger">Trigger</div>
...
...
<div id="meter" class="ref-trigger">
<!-- Its children goes here -->
</div>
...
...
<div id="voltmeter" class="ref-trigger">
<!-- Its children goes here -->
</div>
...
...
<div id="ammeter" class="ref-trigger">
<!-- Its children goes here -->
</div>
...
...
<div id="vmeter" class="ref-trigger">
<!-- Its children goes here -->
</div>
And change the click handler for trigger as follows:
$("#trigger").click( function() {
$('.ref-trigger').addClass("animated");
});
How about this?
You can use an attribute on referenced elements:
<div id="trigger">Trigger</div>
...
...
<div id="meter" data-reference="trigger">
<!-- Its children goes here -->
</div>
...
...
<div id="voltmeter" data-reference="trigger">
<!-- Its children goes here -->
</div>
...
...
<div id="ammeter" data-reference="trigger">
<!-- Its children goes here -->
</div>
...
...
<div id="vmeter" data-reference="trigger">
<!-- Its children goes here -->
</div>
And then you access all referencing elements this way:
$("#trigger").click( function() {
$("#trigger, [data-reference=trigger]").addClass("animated");
});
The [data-reference=trigger] parts of the query match all elements that has an attribute reference with a value of trigger.

I have DIV and its child DIV , i want to select last DIV using jQuery . Parent DIVS have id

Here is the description of problem . I have parent div(allcomments_4) and than inside it , i have few child divs(oneEntry) with their own children inside but i just need to find the last child of the parent node(allComments_4). I want to read the content inside of div(lastComment) it than add it above this div which will be similar like above div (oneEntry) using jquery. I want to do this manipulation using ids not class. As i calculate the id of allComments_4 div . I tried like this.
<script>
var allcommentsId =allcomments_4
var right = "div#lastComment"
var left = '#'+allcommentsId
var message = $(left>right ).html()
alert(message)
</script>
<div id="allcomments_4">
<div class="oneEntry">
<div class="commentImage">
</div>
<div class="commentEntry">
<div class="commentText">
</div>
<div class="commentDate">
Commented On -"Thu Jan 26 16:44:16 EST 2012"/>
</div>
</div>
<div class="oneEntry">
<div class="commentImage">
</div>
<div class="commentEntry">
<div class="commentText">
</div>
<div class="commentDate">
Commented On -"Thu Jan 26 16:44:16 EST 2012"/>
</div>
</div>
</div><!-- One Comment Entry Ends here -->
<div id ="lastComment">
</div><!-- last Comment ends here -->
</div><!-- All Comments Ends here -->
I think missing something and i am sorry for asking such lame question as i am beginner in jquery and this whole javascript thing.
As mentioned, IDs must be unique. That being said, here is a way to accomplish what you asked (using classes where appropriate):
function displayContent(IdNum) {
var Id = '#allcomments_' + IdNum;
var $lastComment = $(Id).find('.lastComment');
var message = $lastComment.html();
alert(message);
}
displayContent(4);
HTML w/ classes (for reference):
<div id="allcomments_4">
<div class="oneEntry">
<div class="commentImage">
</div>
<div class="commentEntry">
<div class="commentText">
</div>
<div class="commentDate">
Commented On - "Thu Jan 26 16:44:16 EST 2012"
</div>
</div>
</div>
<div class="oneEntry">
<div class="commentImage">
</div>
<div class="commentEntry">
<div class="commentText">
</div>
<div class="commentDate">
Commented On - "Thu Jan 26 16:44:16 EST 2012"
</div>
</div>
</div><!-- One Comment Entry Ends here -->
<div class="lastComment">
Body of lastComment
</div><!-- last Comment ends here -->
</div><!-- All Comments Ends here -->
jsFiddle: http://jsfiddle.net/yT8Fc/
var message = $(left>right ).html()
This does not work as it gives the result of the bigger than comparison as parameter. It has to look like this:
var message = $(left + ' > ' + right).html()

Categories

Resources