scrollTo just works on the first link - php

I've got this lines of code that, when the user clicks on the link, the page should scroll down to the respective anchor.
Turns out that it only works with the first link. The others just fire this exception
Uncaught TypeError: Cannot read property 'slice' of undefined
Here's the code
jQuery
$(document).on('click','#scrollTo',function(){
var to = $(this).attr('class');
//alert(to);
//This allways print the correct class name
$(window).scrollTo('div #'+to,'1000');
});
PHP
<ul id="source">
<?php
$sourceRCS = $source->getAllSources();
foreach($sourceRCS as $src)
{
echo '<li data-value="'.$src->name.'">'.$src->name.'</li></a>';
}
?>
</ul>
foreach($sourceRCS as $src)
{
echo '
<div class="custom-label-src">
<div id="'.$src->name.'" class="span12 label-title-src">
'.$src->name.'
</div>
</div>';
}
What am I doing wrong?
Thank you in advance

ID's are supposed to be unique, but you repeat #scrollTo. Try using a CSS class as your target instead.

var to = $(this).attr('class');
$(window).scrollTo('div #'+to,'1000');
You are selecting a class and assigning it to "to". Then you take the class and convert it into an ID in the next line.
Your selector should be like this:
var to = $(this).attr('class');
$(window).scrollTo('div .' + to,'1000');

Html Id's have to be unique. Like previously suggested, try using classes instead. Also, try capturing the event target and scrolling to it:
$(document).click(function(evt){
var target = evt.target;
$(window).scrollTo(target, 1000);
});
However, this will scroll to everything that a user clicks on. A better solution is to set up click event handlers on only the anchor tags that you want to scroll to:
$("#source a").click(function(evt){
evt.preventDefault();
var target = $(evt.currentTarget);
$(window).scrollTo(target, 1000);
// More code here...
});

Related

jQuery automated creation of links from ID in <a> tag

I'm a beginner so please be patient. Tried this myself but can't get it to work.
I'm creating a hardcoded lexicon (no DB behind it but 26 a-z pages) - in the code the links will be "lazily" written as such:
<div class="lexicon">
<a id="letter-a"></a>
<a id="letter-b"></a>
<a id="letter-c"></a>
etc.
</div>
I then want a small jquery script before this to "get" the id, strip the "letter-" part and...
add a link to the a-Tag (ie. mylexicon/mypage-a)
add the stripped id as text for the a-Tag
The result should then be:
<a id="letter-a" href="mylexicon/mypage-a">a</a>
Got this far and bailed out:
var $a = $('.lexicon a');
$a.each(function(){
$(this).attr('href', $(this).attr('id'));
})
I also then need a line following this, that reads the last letter of the current URL (there will be 26 of course) and sets a class to the appropriate a-Tag so that I can style it. (jquery or php??)
Many thanks in advance.
There is some other ways but its a good practice to be familiar with this js functions too:
indexOf() and substr()
var _a = jQuery('.lexicon a');
_a.each(function(){
var _this = jQuery(this),// cache variable to boost speed
total_id = jQuery(this).attr('id'),// grab id attribute
altered = total_id.substr(total_id.indexOf('-')+1, total_id.length);// grab all content after '-'
_this.attr('href', 'mylexicon/mypage-'+ altered);
});
this should do what you need
$(document).ready(function(){
var $a = $('.lexicon a');
$a.each(function(){
var string = $(this).attr('id');
var lastCharacter = string.substr(string.indexOf('-')+1);
$(this).attr('href', 'mylexicon/mypage-' + lastCharacter); // add the link
$(this).text( lastCharacter ); // add the last character as text
$(this).attr('class', 'classNae-' + lastCharacter); // add unique class name for styling
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="lexicon">
<a id="letter-a"></a>
<a id="letter-b"></a>
<a id="letter-c"></a>
</div>

expand/collapse div (toggle) when clicking on header

I have the following jQuery code to toggle the view of more information in a div.
$(".expandCollapse").click(function () {
var bidValue = this.id,
expandArea = $("#"+bidValue+'_status')
expandArea.slideToggle(500);
});
The code works to toggle the view of displaying more information when the submission header is clicked. The div IDs of $moreInfo are dynamically created.
$moreInfo = $bidValue.''."_status";
echo "<div class='expandCollapse' id='$bidValue'>Submission</div>";
echo "<div id='$moreInfo'>$displayComments</div>";
However I want to open only one view/div at a time. If a div is open when a submission is clicked it should be closed before the other one is opened.
I've tried several things but it closes or hides all divs. Searching the web only show a solution using anchor tags.
Any thoughts...?
Thanks.
To achieve this you can put a common class on the second div element to allow you to hide them all before showing the next, like this:
echo '<div id="$moreInfo" class="expand-area">$displayComments</div>';
$(".expandCollapse").click(function () {
var bidValue = this.id,
expandArea = $("#" + bidValue + '_status').slideToggle(500)
$('.expand-area').not(expandArea).hide();
});
Also note that you can make your code much more simple and generic by usnig DOM traversal to select the elements, instead of building selector strings based on related id attributes, like this:
$(".expandCollapse").click(function () {
var expandArea = $(this).next('.expand-area').slideToggle(500);
$('.expand-area').not(expandArea).hide();
});
The code above assumes that the elements are siblings, but you can easily amend the next() to traverse however is required.
Assuming the header and content divs are siblings you may use:
$(.expandCollapse + div)
// All <div>s that are immediately after an .expandCollapse
$(".expandCollapse").click(function () {
var bidValue = this.id,
expandArea = $("#"+bidValue+'_status')
expandArea.slideToggle(500);
$('.expandCollapse + div').not(expandArea).hide();
});
$('[id$="_status"]').hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='expandCollapse' id='bidValue1'>Submission1</div>
<div id='bidValue1_status'>displayComments</div>
<div class='expandCollapse' id='bidValue2'>Submission2</div>
<div id='bidValue2_status'>displayComments</div>
<div class='expandCollapse' id='bidValue3'>Submission3</div>
<div id='bidValue3_status'>displayComments</div>

Why is my $(this).prop('class') not working?

Here is what i want: I have multiple <h3> tags that are being uses as a link to reveal answers to FAQ's. Also I have added a form in case that the user did not see any question of interest on that page. The link for the form is at the bottom of the page. Now when the user click on the show form link I would like the window to scroll down to the bottom. I have done this, however when I click on any of the link the window also scrolls to the bottom. I want when the user clicks only on the show form link that the window scrolls.
here is what I have so far:
<body>
<?php
$array = array("link 1","link 2","link 3");
foreach($array as $link)
{
echo "<h3 class='link'>".$link."</h3>";
echo "<div>";
//information to be displayed
echo "</div>";
}
?>
<h3 class="forms">Show Form</h3>
//form information here
</body>
here is the javscript:
<script>
$(document).ready(function(){
$('h3').click('bind',function() {
$(this).toggleClass('open').next().slideToggle(500,function(){
var i = $(this).prop('class');
if(i == 'forms')
{
$("html, body").animate({scrollTop: $(document).height()}, "slow");
}
});
});
});
</script>
I have added an alert to verify my output and when I click on <h3 class="forms"> the alert is blank but when I click on the others the alert showed "link". Can someone help me figure out why the alert is showing blank when I click on the <h3 class="forms"> tag?
You are echoing your LI with the link class, instead of $link.
Also, use
if ($(this).hasClass("forms"))
.prop() should really only be used when accessing the DOM element's properties and not attributes (like class or style, width, etc.). If you want the class, use .attr('class') instead (or, as others have mentioned, you can use .hasClass() to test (with jQuery) if an element has a specific class aplied).
to follow-up on .prop vs .class:
Foo Bar link
var a = document.getElementById('foolink'),
$a = $(a);
$a.prop('href') // like directly calling a.href
$a.prop('id') // again, like directly calling a.id
$a.attr('class') // where as it's actually a.className

An error with in the execution of an ajax

I have been a really big fan of stackoverflow(which led me to ask the question here and not anywhere else), anyway, without further ado...
While creating a shop system, I planned to implement an ajax which buys the item on the fly. Now This is how the loop for retrieving items looks like:
<?php
$shop_query = mysql_query("SELECT * FROM sector0_item WHERE 1");
$numrows = mysql_num_rows($shop_query);
While ($shop_fetch = mysql_fetch_array($shop_query)){
?>
<div id="shop_main">
<div class = 'item_img'>
<a><img src = "http://images.wikia.com/dofus/images/4/4e/Discovery_Potion.png" height = '100px'/></a>
</div>
<div class="item_buy">
<a><center>Price: <?php echo number_format($shop_fetch['item_price']);?></center><br /></a>
<a>Quantity: <input type = 'text' size = '9' id = 'itemquantity'/><br /></a>
<a><p>Point requirement: <?php echo number_format($shop_fetch['item_pt_req']);?></p></a>
<a><input type = 'button' id = 'buy' value = 'buy'/></a><span id = 'buy_status'></span>
</div>
<a><h3><?php echo $shop_fetch['item_name'];?></h3></a>
<a><p><?php echo $shop_fetch['item_desc'];?></p></a>
<a>Item Type: <font color = 'green'><?php echo $shop_fetch['item_class'];?></font></a>
</div>
<br />
<?php
}
?>
However, my ajax seems to act really weird. My implementation was to show a loading gif image.
Script:
<script type = 'text/javascript'>
$('#buy').click (function(){
var quantity = $('#itemquantity').val();
$('#buy_status').html('<img src = "http://www.antibodyresource.com/theme/js/ajax-loader.gif" height = 20px;/>');
});
</script>
The problem is, Only one button shows the circle when clicked. Does the position of the script cause this? Any help is appreciated.
You can only have one item with a given id. When you have multiple elements with the same id, it is indeterminate which one will be returned, but it will usually be the first item only.
If you want multiple buy buttons and want to assign them all the same jQuery event handler, then use a common class name instead of an id.
If you are loading content dynamically and you want event handlers to work for that content, then you need to use delegated event handling.
In jQuery, that is generally done with either .on() or .delegate(). The basic idea is that you pick a static parent object that is not dynamically loaded (perhaps the parent of show_main) and bind the event to that object and then pass the selector of the dynamic element like this (note, I've changed from an id to a class to identify the buy button):
$(staticParentSelector).on('click', '.buyButton', function() {
$(this).closest(".item_buy").find(".buy_status").html('<img src = "http://www.antibodyresource.com/theme/js/ajax-loader.gif" height = 20px;/>');
})
Two things:
It's hard to tell from the sample, but is there an iterator that creates a list of available items? If so, you shouldn't be using IDs which are meant to be unique. If there's really only one #buy then you're fine, though.
When content is updated with Ajax, you're going to lose bindings. Assuming the item related to the #buy button gets replaced with other items, you're better off with a delegated event:
// not in an inline script, but just once, ideally in your main JS file
$(document).ready(function() {
$('#wrapper').on('click', '#buy', (function(){
var quantity = $('#itemquantity').val();
$('#buy_status').html('<img src = "http://www.antibodyresource.com/theme/js/ajax-loader.gif" height = 20px;/>');
});
})
Where #wrapper is some ancestor higher up in the DOM tree that is never destroyed by the Ajax event.
id is unique value - on html page each id must have unique value. Use class instead.
You need to put your code inside $(document).ready(). So its:
$(document).ready( function() {
$('#buy').click( function(){
// do something here
});
});
Also, you may want to list to jfriend00's advice on IDs.

Sending parameter to jQuery function

In a PHP page i have several rows of one table like this
echo '<tr><td>Click</td></tr>';
The $id is dynamically generated from a database
So I want to define the function in jQuery but to pass the parameter to the jQuery function.
For each button I click there will be another parameter passed
Why not use the ID as an identifier for the link like this:
Click me
In jQuery you can bind to the onclick event like this:
// Execute on load
$(document).ready(function(){
// Bind to click
$('a.myjquerylink').click(function(){
// Get the id
var id = $(this).attr('id');
// Do something with the id.
doSomething(id);
});
});
What exactly do you want to do ?
Here's a sample function (it's not using jQuery!) to alert the user that the linked has been pressed and to stop propagating the event, so that it doesn't jump to another page on click
<script type="text/javascript">
function myFunction( param ) {
alert('The button with the id ' + param + ' has been pressed!');
return false;
}
</script>
Well in a dirty way you can assign your id's in rel tag like this:
echo '<tr><td>Click</td></tr>';
than you can search for mybutton class in jquery an add events to it:
$("a.mylink").click(function(){
alert($(this).attr('rel'));
});
So in this case $(this).attr('rel') should be your ID.
As other poster started saying, bind a function to an event. Say you assign a css class to your a tags to make it easier:
echo '<tr><td><a class="specialLinks" href="#" onclick="myFunction('.$id.')">Click</a></td></tr>';
Then you would bind to your class like this:
$('.specialLink').bind('click', function() {
this.preventDefault();
alert($(this.attr("id"));
});
you need to modify your html a bit:
echo '<tr><td><a class="someclass" href="#" id='".$id.'">Click</a></td></tr>';
then you can call it by it's class in JQuery and do what you want:
"$(this)" will be a reference to the clicked item.
$(".someclass").live('click',function(e){ e.preventDefault(); alert($(this).text())});

Categories