Hi friends I am trying to implement click to copy using zclip.
I am having different ids for same class so initially i am finding the id of the element on which i clicked and applying zclip to that element.
$(".coupon_code_text").on('click', function (e) {
pos = "#" + $(this).attr("id");
e.preventDefault();
clktocpy();
function clktocpy(){
$(pos).zclip({
path: 'http://www.steamdev.com/zclip/js/ZeroClipboard.swf',
copy: function () {
return $(pos).text();
}
});
}
})
The following is the php part where I am generating different ids for the same class.
<?php
$count = 0;
foreach($coupons as $value)
{
$count = $count +1;
<div class="coupon_code" >
<a class="coupon_code_text" id ="copypath-<?php echo $count;?>">
<?php echo $array['coupon_code'];?>
</a>
</div>
<?php}?>
Remember that in order to get by id using jQuery you need to append a # to the string.
Like the following #myId, your variable pos only contains the id without the #.
Line 2, fixed
pos = "#" + $(this).attr("id");
Related
I have a PHP function that loops through image results in a database, formats them with HTML, then returns the variable containing the HTML layout to my page.php. This is all working okay, but in the loop I have some script tags that call a function in my script.js file. It takes two parameters (url and count). I am trying to pass the url of the result from the database to the function, create a new img element, and append the passed url to the src attribute of the newly created img tag.
This appears to be working so far - when I console.log the result, I get a load of <img> tags, all with corresponding src attached to them.
I am having trouble with actually getting these back to the front end, though.
My code below shows the part of the php that gets looped through, followed be the Javascript function it calls on each loop.
public function getResultsHtml($page, $pageSize, $term) {
$fromLimit = ($page - 1) * $pageSize;
$query = $this->con->prepare("SELECT * FROM images
WHERE (title LIKE :term
OR alt LIKE :term) AND broken=0
ORDER BY clicks DESC
LIMIT :fromLimit, :pageSize");
$searchTerm = "%" . $term . "%";
$query->bindParam(":term", $searchTerm);
$query->bindParam(":fromLimit", $fromLimit, PDO::PARAM_INT);
$query->bindParam(":pageSize", $pageSize, PDO::PARAM_INT);
$query->execute();
$resultsHtml = "<div class='image-results'>";
$count = 0;
while($row = $query->fetch(PDO::FETCH_ASSOC)) {
$count++;
$id = $row["id"];
$imgUrl = $row["imgUrl"];
$siteUrl = $row["siteUrl"];
$title = $row["title"];
$alt = $row["alt"];
if($title){
$displayText = $title;
} else if ($alt) {
$displayText = $alt;
} else {
$displayText = $imgUrl;
}
$resultsHtml .= "<div class='grid-item image$count'>
<a href='$imgUrl'>
<script>
document.addEventListener('DOMContentLoaded', function() {
loadImage(\"$imgUrl\", \"image$count\");
});
</script>
<span class='details'>$displayText</span>
</a>
</div>";
}
$resultsHtml .= "</div>";
return $resultsHtml;
}
var loadImage = function(src, className){
var image = document.createElement("img");
var aTag = document.querySelectorAll("." + className + " a");
image.onload = function(){
aTag.innerHTML = image;
};
image.onerror = function(){
};
image.setAttribute("src", src);
}
At the moment I'm not geting any results at the front end. In the page source, I can see that inside each anchor tag are script tags, which show the function preloaded with the parameters (loadImage(http://www.com, image22)), but it isn't actually getting a return from the function.
The solution for this with jQuery is below, but I really don't want to use jQuery!
function loadImage(src, className) {
var image = $("<img>");
image.on("load", function() {
$("." + className + " a").append(image);
});
image.on("error", function() {
});
image.attr("src", src);
}
I know that there is some trouble with dynamically writing <script> tags with .innerHTML, but I don't think this is the problem as the script tags are written before the function is called.
I think I have something firing in the wrong order, or I'm missing something that jQuery handles automatically with the .append function.
I have also tried aTag.appendChild(image);, which also gives no results.
I have been using jQuery for a few months, but I am trying to learn Vanilla JS thoroughly - I'm trying to grasp how the jQuery functions actually work, rather than just relying on them blindly.
Any help is massively appreciated!
Beware of that querySelectorAll() returns an array-like NodeList (https://developer.mozilla.org/en-US/docs/Web/API/NodeList), so it should be like this:
(If you only want one element returned user querySelector(), then you don't need the loop)
function loadImage(src, className) {
var image = document.createElement("img");
image.src = src;
image.onload = function() {
var tags = document.querySelectorAll("." + className + " a");
for (var i = 0; i < tags.length; i++) {
tags[i].appendChild(image);
}
}
}
<div class='grid-item image2'>
<a href='https://cdn.pixabay.com/photo/2015/08/21/21/55/star-wars-899693_960_720.jpg'>
<script>
document.addEventListener('DOMContentLoaded', function() { loadImage("https://cdn.pixabay.com/photo/2015/08/21/21/55/star-wars-899693_960_720.jpg", "image2");
});
</script>
<span class='details'>Star Wars 1</span>
</a>
</div>
The problem is that you are using querySelectorAll, which returns a NodeList instead of a single DOM node. This means, you have to iterate over the NodeList and append the image to all the nodes within. For this, you have can either create new copies for each place you want to insert the image, or use cloneNode multiple times.
var each = function (xs, func) {
for (var i = 0; i < xs.length; i += 1) {
func(xs[i]);
}
return xs;
}
var loadImage = function(src, className){
var image = document.createElement("img");
var aTag = document.querySelectorAll("." + className + " a");
image.onload = function(){
each(aTag, function (a) {
a.appendChild(image.cloneNode());
});
};
image.onerror = function(){};
image.alt = '';
image.src = src;
}
loadImage('http://www.fillmurray.com/500/300', 'wrap')
<div class="wrap">
</div>
Going through the other posts i must either have something wrong with my code or my logic is fundamentally flawed.
So what happens is i have a series of array elements that get called/written, these array elements need to have sub elements modified by java script.
Everything was workign before i needed to add an array i.e i was using a single element selector ID for the functions below and got the correct results. However after adding unique ID's in a loop it doesn't want to change.
So here's what happens, I have a separate div that is hidden. This prints out how many elements are in the array as its a PHP session variable. $Carray is a count function and works correctly.
<div class="Carray"><?php echo $Carray;?></div>
Then as the items are looped they add an array ID
<?php
$arrayID = -1;
foreach($_SESSION['activity'] as $key){
foreach($key as $list){
$arrayID += 1;
?>
<div id="subP_<?php echo $arrayID;?>" class="booking_action">-</div>
<div id="booking_people_<?php echo $arrayID;?>" class="booking_people_number">
<?php echo $list["i_quantity"] ?>
</div>
<div id="addP_<?php echo $arrayID;?>" class="booking_action">+</div>
<?php }} ?>
Then in Javascript i call a loop function that counts through however many $Carray elements there are and then corresponds the correct function actions to the correct div ID's
//get the counted array variable and force as an int
var js_var = parseInt($('.Carray').html(),10);
// loop for however many array elements there are
for (i = 0; i < js_var; i++){
// get the amount of people from a field
var ppl_P = parseInt($('#booking_people_'+i).html(),10);
// subtract 1 person and then change the output to match the new people count
$("#subP_"+i).click(function() {
if(ppl_P >= 2){
ppl_P -= 1;
$('#booking_people_'+i]).html(ppl_P);
}
});
// Add 1 person and then change the output to match the new people count
$("#addP_"+i).click(function() {
ppl_P += 1;
$('#booking_people_'+i).html(ppl_P);
});
}
****************************** EDIT **********************
So based on Jimmi Elofsson answer which works beautifully, i want to expand this to effect elements that are not inside the parent/child selectors. The selector is '.booking_price_inner' which is another div stored elsewhere. I am assuming the line that needs the correct syntax is the marked line.
The '.booking_base_price' is within the parent/child element.
$(".subPerson").click(function() {
// Subtract Person
var subPeopleCount = getCurrentCountByPeopleItem($(this).parent()) - 1;
$(this).parent().children('.booking_people_number').html(subPeopleCount>1 ? subPeopleCount : 1);
//Change price
var totalPriceS = subPeopleCount * getBasePrice($(this).parent());
$(this).parent().children('.booking_price_inner').html(totalPriceS); <-------
});
$(".addPerson").click(function() {
//Add person
var addPeopeCount = getCurrentCountByPeopleItem($(this).parent()) + 1;
$(this).parent().children('.booking_people_number').html(addPeopeCount);
//Change price
var totalPriceA = addPeopleCount * getBasePrice($(this).parent());
$(this).parent().children('.booking_price_inner').html(totalPriceA); <------
});
// get the number of people in the specific array
function getCurrentCountByPeopleItem(peopleItem) {
return parseInt(peopleItem.children('.booking_people_number').html());
}
//get the base price
function getBasePrice(peoplePrice){
return parseInt(peoplePrice.children('.booking_base_price').html());
}
Markup
<div id="<?php echo $arrayID;?>" class="booking_people">
<div class="booking_date_header">People:</div>
<div class="subPerson booking_action">-</div>
<div class="booking_people_number"><?php echo $list["i_quantity"] ?></div>
<div class="addPerson booking_action">+</div>
<div class="booking_base_price"><?php echo $list["i_base_price"] ?></div>
</div>
<div class=spacer></div>
<div class=cost>
<div class=booking_price_inner></div>
</div>
If you don't mind, I did some changes in your code.
you could make your add/substract element use the same click function with the help of some DOM traversing. That way you wouldnt need the CArray to keep track of the buttons.
Javascript:
// subtract 1 person and then change the output to match the new people count
$(".subPerson").click(function() {
var subPeopleCount = getCurrentCountByPeopleItem($(this).parent()) - 1;// Substract by one.
$(this).parent().children('.booking_people_number').html(subPeopleCount>1 ? subPeopleCount : 1);
});
// Add 1 person and then change the output to match the new people count
$(".addPerson").click(function() {
var addPeopeCount = getCurrentCountByPeopleItem($(this).parent()) + 1; // Increase by one.
$(this).parent().children('.booking_people_number').html(addPeopeCount);
});
function getCurrentCountByPeopleItem(peopleItem) {
return parseInt(peopleItem.children('.booking_people_number').html());
}
PHP:
<?php
$arrayID = -1;
foreach($_SESSION['activity'] as $key){
foreach($key as $list){
$arrayID += 1;
?>
<div class="booking_people_item" id="<?php echo $arrayID;?>">
<div class="subPerson booking_action">-</div>
<div class="booking_people_number">
<?php echo $list["i_quantity"] ?>
</div>
<div class="addPerson booking_action">+</div>
</div>
<?php }} ?>
I added a div wrapper around your elements called booking_people_item.
from what I see - you're definig click functions in a loop. Those click functions have a reference to a ppl_P variable. When you define the click, it seems OK. But when the click is triggered, the ppl_P variable is already set to the value from loops last iteration. So, whenever you call that click function, it always has the same result, doesn't it?
The proper way to do it would be to pass this ppl_P variable as a parameter, so you don't have a reference to a variable that was already changed in the other scope. Something like:
function addClickFunction(i, ppl_P){
$("#subP_"+i).click(function() {
if(ppl_P >= 2){
ppl_P -= 1;
$('#booking_people_'+i]).html(ppl_P);
}
});
// Add 1 person and then change the output to match the new people count
$("#addP_"+i).click(function() {
ppl_P += 1;
$('#booking_people_'+i).html(ppl_P);
});
}
And then use this function inside the loop:
var ppl;
for (i = 0; i < js_var; i++){
ppl = parseInt($('#booking_people_'+i).html(),10);
addClickFunction(i, ppl);
}
This hasn't been tested, but I'm pretty sure you'll get the point :)
I have the following script within a page on my site which adds + - buttons to a qty entry field:
<script language="javascript">
jQuery.noConflict();
jQuery(document).ready(function() {
var $cartAdd = jQuery('#cartAdd')
, $quantity = $cartAdd.find('input');
$cartAdd.append('<div class="inc button">+</div><div class="dec button">-</div>');
jQuery(".back").change(function(){
$quantity.val(1).change();
});
$cartAdd.click(function(evt) {
var $incrementor = jQuery(evt.target)
, quantity = parseInt($quantity.val(), 10);
if($incrementor.hasClass('inc')) {
quantity += 1;
} else if($incrementor.hasClass('dec')) {
quantity += -1;
}
if(quantity > 0) {
$quantity.val(quantity);
xhr.getPrice();
}
jQuery(".back").change(function(){
xhr.getPrice();
});
});
});
</script>
I want to be able to hide/unhide a div when var $cartAdd goes above 1
I tried using something like
var $cartAdd = jQuery('#cartAdd')
, $quantity = $cartAdd.find('input');
<?php $trigger = "<script>document.write(quantity)</script>"?>
followed by
<?php echo $trigger;?>
and i expected that to echo the value in the entry box but it didn't.
Is it achievable?
You must understand that all php scripts are executed BEFORE the javascript.
What's wrong with simply grabbing the quantity and hiding if needed?
if( $('#cartAdd').find('input').val() > 1 )
{ $('#div_we_want_to_hide').hide() }
just put that inside a document.ready and it should work fine
Not sure this is possible but maybe you can help.
I have a list, where the content of the <li>'s is generated by Javascript, through a function called showLink(); this function is on another server and it's not controlled by me.
The showLink(); function generates a html link. I am interested in the generated anchor text.
QUESTION: Is there a way I can use Jquery to get the anchor text of that link into a Jquery variable?
Here is the code:
<ul class="my_list">
<? $zero = '0';
for($rn = 1; $rn <= $traffic_rows_nr; $rn++){ ?>
<li><script language="JavaScript">showLink(<? echo $rn; ?>)</script></li>
<? } ?>
</ul>
Thank you!
Something like
var anchorText = $("ul.my_list li a").text();
or...
var anchorText = [];
$("ul.my_list li a").each(function() {
anchorText.push($(this).text());
})
// anchorText is now an array of the text in all the anchors in the list
var text = $(".my_list a").text(); Should do it
I have an unordered list with ids like so:
<li id="e1">01</li>
<li id="e2">02</li>
<li id="e3">03</li>
<li id="e4" class="event_day">04</li>
<li id="e5" class="event_day">05</li>
And a div with content like so:
<div id="descriptions">
<div></div>
<div></div>
</div>
I want to copy the ids of the list items with the class event_day and assign them to the divs with a letter at the end so that they would become:
<div id="e4d"></div>
<div id="e5d"></div>
I have come up with:
$("#descriptions>div").each(function() {
$(this).attr("id", $(".event_day").attr("id") + "d");
});
But as you can probably tell, it does not loop and rather takes the first id and assigns it to all the divs resulting in:
<div id="e4d"></div>
<div id="e4d"></div>
I'd highly appreciate it if you could explain the flaw in the logic and maybe even a link to something that I could read to improve my skills. I was looking at http://docs.jquery.com/Attributes/attr#keyfn but it did not make sense. Thanks for reading!
the each function from jquery also passes an index parameter to the callback function.
Provided that the amount of divs in descriptions is the same as the divs with class event_day:
$("#descriptions>div").each(function(n) {
$(this).attr("id", $(".event_day").eq(n).attr("id") + "d");
});
.eq(n) returns the element at position N in the jquery resulset.
Your query could be a little bit more efficient though because now you traverse the dom for each div in descriptions. Better (imho) would be:
var event_days = $("#listIdentifier .event_day");
$("#descriptions>div").each(function(n) {
$(this).attr("id", event_days.eq(n).attr("id") + "d");
});
It may be easier to collect all IDs of event days, then create divs dynamically with the IDs you want as needed.
$("li.event_day").each(function() {
$("#descriptions").append(
$("<div>").attr("id", $(this).attr("id") + "d")
);
});
Could you determine what you need before you render the HTML, and then just draw both the list and the divs accordingly?
<?php
$event_days = array(4,5);
$list = '<ol>';
$divs = '';
for($i=1;$i<30;$i++)
{
// built the list
$list .= '<li id="e'.$i.'" ';
if(in_array($i, $event_days))
{
$list .= 'class="event_day"';
}
$list .= '>Day '.$i.'</li>';
// build the divs
if(in_array($i, $event_day)
{
$divs .= '<div id="e'.$i.'d"></div>';
}
}
$list .= '</ol>';
echo $list;
echo $divs;
?>
The flaw in your logic is that your only matching the first element, which is e4.
So, just create an array and add the ids that match the class event_day:
var myIds=new Array();
$("li.event_day").each(function() {
myIds.push($(this).attr("id") + "d");
});
Then loop through the divs within the description div and set their ids like this:
var count = 0;
$("#descriptions>div").each(function() {
$(this).attr("id", myIds[count]);
count = count + 1;
});