Jquery select object by id dynamically using a string - javascript

I have an image gallery that uses modals. In the image modal or outside it, the user can click on a star and mark the image as favorite. Favorite images have a class that makes the star change color its to 'golden'. If a user marks a favorite in the modal, I need to change the color of the star of that image outside the modal as well.
To do this, I thought I could have a
<p id = "modal_counter" class = "hidden">number</p>
in the modal, so that I can get the image number. Then I use that image number as part of a jquery selector.
The images in the gallery have something like this:
<p id = "image_number" class = "hidden"></p>
<!-- for example: <p id = "image_2" class = "hidden"></p> -->
So, all I need is to successfully select the hidden p tag next to each image, then I could use jquery's next() or parent().find().
This is the relevant code:
...
var modal_counter = div_parent.find('#modal_counter').text();
var counter = "#image_"+String(modal_counter);
/* I would like the counter to be something like "#image_2" */
var $(counter).parent().find('.star').addClass('golden')
...
This doesn't work. Jquery tries to find an object using this selector:
"#image_\n 2"
and of course, it doesn't find one. I tried removing the \n with a regex, but it still doesn't work:
counter_processed = modal_counter.replace(/(<([^>]+)>)/ig,"");

It'll probably be better to use a data-attribute on your element rather than getting the text content. Do:
<p id = "modal_counter" class = "hidden" data-counter="number">number</p>
Then you can:
...
var modal_counter = div_parent.find('#modal_counter').data('counter');
var counter = "#image_" + modal_counter;
/* I would like the counter to be something like "#image_2" */
var $(counter).parent().find('.star').addClass('golden')
...
This way you don't bind your javascript to the text inside your elements.

jQuery has a handy trim function:
var modal_counter = div_parent.find('#modal_counter').text().trim();
Try this from your console:
$.trim("\n\nHello\r\nThere\n")
See how it removes the leading and trailing white-space?

Let's say you have:
<p id="modal_1" class="hidden">Img 1</p>
you can extract the number both using:
// If you need it from the text
var n = $("[id^=modal_]").text().match(/\d+/); // 1
or
// If you need it from the ID
var n = $("[id^=modal_]")[0].id.match(/\d+/); // 1
Than to target the image like:
<img id="image_1" src="someimage.jpg" alt="SEO">
you do:
$('#image_'+ n)
If you really just have:
<p id="modal_counter" class="hidden">3</p>
than you can do:
var n = $('#modal_counter').text(); // "3"
$("#image_"+ n) // .fadeIn() or whatever...
Just make sure you don't have duplicate modal_counter ID elements on your page. ID has to be unique.

Related

access DOM and change element font and colour

I want to access some character from string and change the style of them
for example "hello"
i want to change "h" character's color and font
how can i do this
i try this
var txt=document.getElementById('d1').getElementsByTagName('p')[0]
txt.innerHTML="H"
txt.style.color="red"
document.getElementById('di') selects a single element from the dom.
You don't need .getElementsByTagName('p')[0] after that.
The solution depends on the dom. If you have an element like
<span id='d1'>H</span>, then the following is correct
var txt = document.getElementById('d1');
txt.innerHTML="H";
txt.style.color="red";
If you want first character of the string and change its color and font (which i am getting from your question), you can do something like :
var text_array = document.getElementById('d1').getElementsByTagName('p')[0].textContent.split("");
text_array[0] = "<span style='color:green; font-family:Arial'>"+text_array[0]+"</span>";
document.getElementById('d1').getElementsByTagName('p')[0].innerHtml = text_array.join("");
<div id="d1">
<p>loading.....</p>
</div>
var txt=document.getElementById('d1').getElementsByTagName('p')[0] var edit=txt.innerHTML//ocnvertobject to string
var len=txt.innerHTML.length
var index=0 //container for scroll the string and change style each corrector
txt.innerHTML=edit[index].toUpperCase().fontsize(150).fontcolor("red")+edit.slice(index+1,len)
++index
i with this code edit corrector of my string

Attach event to a dynamically created dom element

In the code below I'm dynamically creating different posts.
Each post has its own image.
$(function () {
for(post in data){
//get from the data post details
var titleData = data[post]["title"];
var descriptionData = data[post]["description"];
var imageData = "images/"+data[post]["image"];
//create elements with jquery
var postHolder = $('<div class="post row"></div>');
var img = $('<img src="'+imageData+'" data-title="'+titleData+'" class="col-sm-3 img-post">');
var textHolder = $('<div class="col-sm-9"></div>');
var title = $('<h4 class="title-post"></h4>').append(titleData);
var description = $('<p class="explanation-post"></p>').append(descriptionData);
textHolder.append(title);
textHolder.append(description);
postHolder.append(img);
postHolder.append(textHolder);
$('.posts-container').append(postHolder);
img.on('click',function(){alert(this.data-title);});
}
});
I want that when I click the image, it will alert the title of the post (what's known as "titleData") and that the "textHolder" will change his background color to grey.
The limitation on this challenge are:
To pass a different parameter as the "titleData" each time.
To use minimum space in the memory.
data-title is invalid identifier in JavaScript. To access the data-* attributes, You can use HTMLElement.dataset
alert(this.dataset.title)
OR, As you are using jQuery .data() method.
alert($(this).data("title"));
What is in the alert is wrong.
You are saying
this.data MINUS title
You sould be using bracket notation if the name has a dash in it.
alert(this["data-title"]);
or better with getAttribute
alert(this.getAttribute("data-title"));
or jQuery
alert($(this).data("title"));
alert($(this).attr("data-title"));
so the final code with the bg color change should be
img.on('click', function() {
alert($(this).attr("data-title"));
textHolder.css("background-color","#CCC");
console.log(textHolder.css("background-color"))
});

Increment div class by +1 on click

I'm sure this is an easy question but I cannot figure it out.
I basically have a div with a number, 'div-1' for example, and need to +1 to the number every time another div is clicked. e.g. 'div-2' 'div-3' etc..
When you say a div with a number, It should be on id attribute.
<div class="your_div_selector" id="div-1">
so, in your javascript, using jquery and when the other div is clicked, just do this:
var div_id = $('.your_div_selector').attr("id")
var new_id = 1 + parseInt(div_id.split("-").pop());
Based on what you've described, it looks like you have an HTML div, which starts with a class of div-1. Every time the div is clicked, you want the div-n class to be replaced with a div-(n+1) class.
This is easily accomplished with an onclick listener.
<div id="mydiv" class="div-1"></div>
<script>
var mydiv = document.getElementById('mydiv');
mydiv.currentClass = 1;
mydiv.addEventListener('click', function() {
mydiv.classList.remove('div-' + mydiv.currentClass);
mydiv.classList.add('div-' + (++mydiv.currentClass));
});
</script>
Note that there should be a better solution, depending on your specific problem.
<div class="yourDivClass" id="myDiv"></div> <button id="incriment" onclick="incrementDivClass()">Click</button>
function incrementDivClass()
{
var divIncriment = ($('.yourDivClass').length);
$('#myDiv').append('<div class="yourDivClass" id="div-'+divIncriment+'">div-'+divIncriment+'</div>')
}
Demo

How to use arrays in javascript to match up divs when event fires?

I have a set of two divs - First set: when people mouse over these divs, it will fire an event, Second set: when the event is fired, these divs will be displayed.
When you mouse over a div in the first set, it should display its corresponding div in the second set. I thought an easy way to match the mouseover divs with the correct div to display would be using arrays. I've been able attach the event listeners properly, but I can't figure out how to set it up so that when you mouseover one object of an array, it displays the array object with the same index number. I think if I could figure out how to recoginze the index number of the object I am mousing over, I could get it to work. I've tried a lot of things, but haven't been able to create anything that works. Here's the code:
<script>
$(document).ready(function(){
//create array of divs to mouse over
var ar = new Array();
ar[0] = $("#home");
ar[1] = $("#doc");
var length = ar.length;
//create array of divs to display when event is fired
var des = new Array();
des[0] = $("#homeDes");
des[1] = $("#docDes");
// start for
for ( var i = 0; i< length; ++i )
{
ar[i].bind("mouseover",function(){$(des[i]).css("display","block");});
ar[i].bind("mouseout",function(){$(des[i]).css("display","none");});
}
//end for
});
//end
</script>
I would tend toward making a more flexible approach to this so that you don't need to change your javascript when you change your HTML. Consider classing your elements that need to have the bindings and providing data attribute to specify the target. Your HTML for divs to be bound might look like this:
<div id="home" class="mouseoverToggleTrigger" data-target="#homeDes">...</div>
And the jQuery might look like this:
$(document).ready(function(){
$('.mouseoverToggleTrigger').hover(function() {
var $target = $($(this).data('target'));
$target.toggle();
}
});
Note this is assuming you are using HTML5 for which jQuery, by default, converts data-* into values retrievable via data().
For pages that are not HTML5, this more generalized solution will work
$(document).ready(function(){
$('.mouseoverToggleTrigger').hover(function() {
var $target = $($(this).prop('data-target'));
$target.toggle();
}
});
One additional bit of flexibility this gives, is that you now don't have to limit yourself to a one-to-one trigger to target mapping. You could specify a class name or other jQuery selector for data-target values to get highly customized behavior, such as one trigger toggling all elements of a certain class that are children of another class.
$(document).ready(function(){
//create array of divs to mouse over
var ar = new Array();
ar[0] = $("#home");
ar[1] = $("#doc");
var length = ar.length;
//create array of divs to display when event is fired
var des = new Array();
des[0] = $("#homeDes");
des[1] = $("#docDes");
// start for
for ( var i = 0; i< length; ++i )
{
// WRAP THE BODY OF THE FOR LOOP IN A FUNCTION
function(index) {
ar[index].bind("mouseover",function() {
$(des[index]).css("display","block");}
);
ar[index].bind("mouseout",function() {
$(des[index]).css("display","none");
});
}(i);
}
//end for
});
When the events are fired the value of i is the length of the array, you have to pass the value of i to another function so that in each function scope the value of index will be the value of i when it was called.
A simpler approach code wise is to give the common elements common classes and then use jQuery index() and eq() to match pairings
HTML
<a id="home" class="hoverMe">
<a id="doc" class="hoverMe">
<div id="homeDes" class="content">
<div id="docDes" class="content">
JS
var $content=$('.content')
var $links=$('.hoverMe').hover(function(){
$content.eq( $links.index(this) ).show()
},function(){
$content.eq( $links.index(this) ).hide()
})
index() API Docs
eq() API Docs

Is there an easy way to add multiple javascript images together via `imgCounter.src =`

In photoshop I created images 0.png thru 9.png and know I can change each digit to simulate a counter by changing each picture of each digit as it counts down.
IDEA 1:
One way I thought would be to have multiple lines of
HTML:
<div align="right"><img src="graphics/odometers/1.png" /id="digit1">
<img src="graphics/odometers/2.png" /id="digit2">
<img src="graphics/odometers/3.png" /id="digit3"></div>
JAVASCRIPT:
var imgCounter = document.getElementById('digit1');
imgCounter.src = "graphics/odometers/white and blue with black background/1.png"; // shows the digit 1
var imgCounter = document.getElementById('digit2');
imgCounter.src = "graphics/odometers/white and blue with black background/2.png"; // shows the digit 2
// etc for as many digits as I want to show
and change the digits in javascript by each ID. It's not hard but for flexibility can I have 1 image ID and string 3 .png's together in javascript? Like this...
IDEA 2: Not sure if this is possible.
HTML:
<div align="right"><img src="" /id="formtimer"></div>
JAVASCRIPT:
// somehow show 3 graphics in a row 123 without having 3 ID tags, only 1 ID tag
var imgCounter = document.getElementById('formtimer');
imgCounter.src = "graphics/odometers/white and blue with black background/1.png";
I know the example above only shows the digit 1 and doesn't do all 3 digits... (because I don't know if it's possible).
Is there a way to display 3 pictures together? lol. Easily? I know anything can technically be done the hard way...
If it's a big pain in the butt I'm ok with IDEA 1 but it's less "freedom" because I have to encode the HTML with multiple ID tags which is tedius...
Just curious what you all think and if you have a solution. :) Much appreciated.
ALSO:
Is it ok to leave the img src="" as a NULL or empty string if I'll later be sticking an image in via javascript?
You don't need to include the <img> elements in the source html at all, you can add them with JavaScript and not even give them ids.
At the point in your source where you want the counter just put an empty div with an appropriate id.
When the counterSet() function below is called with the id of the container div and a value it creates new child <img> elements in the div with src set appropriately, but reuses any existing child <img> elements that are there from any previous value that was set. If the new value has fewer digits than the last than the function removes the leftover <img> elements:
<div id="counter1"></div>
<script>
function counterSet(counterId, val) {
var c = document.getElementById(counterId),
i,
d;
for (i = 0; i < val.length; i++) {
// if the container already had enough child img elements
// for current digit set current img's src, otherwise add
// new img to end
if (i < c.childNodes.length)
c.childNodes[i].src = "graphics/odometers/" + val.charAt(i) + ".png";
else {
d = document.createElement("img");
d.src = "graphics/odometers/" + val.charAt(i) + ".png";
c.appendChild(d);
}
}
// if the container already had too many child img elements
// (from a previous value) remove the leftover digits
while (c.childNodes.length > val.length)
c.removeChild(c.childNodes[val.length]);
}
counterSet("counter1","218");
</script>
I would just use three separate ids.
You can use something like this to set the src attributes:
for (i = 1; i <= NUMBER_OF_IMAGES; i++) {
var img = document.getElementById('img_' + i);
imgr.src = 'images/image_' + i + '.png";
)

Categories

Resources