# Uncaught TypeError: $(…).attr is not a function I have a page that I'm currently using in a wrapper (iframe) and it works perfectly fine. I've decided to make it a module (so we don't have dual scroll bars and it is more mobile friendly). My problem is that when I put the page in the module that I get an error on the links: Uncaught TypeError:$(...).attr is not a function

The page is rather long, so I'll post what I believe are the key portions:

<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.5/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="/P3Live/_includes/css/tables.css">
<link rel="stylesheet" type="text/css" href="/P3Live/_includes/css/user_settings.css">
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script type="text/javascript" language="javascript" src="//cdn.datatables.net/1.10.5/js/jquery.dataTables.min.js"></script>
<script src="/P3Live/_includes/js/general_functions.js"></script>


I have verified that jquery is loaded by testing a link with the following jquery:

    $("a").on("click", function (e) { e.preventDefault(); if (typeof jQuery != 'undefined') { // jQuery is loaded => print the version alert(jQuery.fn.jquery); } alert('You are here. id:'+$(this).attr("data-title"));
});


This reported back with 1.11.1 which is correct.

Here is the problematic code:

$("a").on("click", function (e) { e.preventDefault(); var src =$(this).attr("href");
var title = $(this).attr("data-title"); var width =$(this).attr("data-width");
var height = $(this).attr("data-height"); iframe.attr({ width: width, height: height, src: src }); dialog.dialog("option", "title", title).dialog("open"); });  I can only guess that it is some conflict since it works fine on its own, but I don't know what is causing it. Any help would be greatly appreciated... Thanks.. EDITED - here is the full code: <!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css"> <link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.5/css/jquery.dataTables.min.css"> <link rel="stylesheet" type="text/css" href="/P3Live/_includes/css/tables.css"> <link rel="stylesheet" type="text/css" href="/P3Live/_includes/css/user_settings.css"> <script src="http://code.jquery.com/jquery-1.11.1.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script> <script type="text/javascript" language="javascript" src="//cdn.datatables.net/1.10.5/js/jquery.dataTables.min.js"></script> <script src="/P3Live/_includes/js/general_functions.js"></script> </head> <body> <div class="container-fluid"> <?php error_reporting(E_ERROR);$includes_url = $_SERVER['DOCUMENT_ROOT'] . "/P3Live/_includes/"; include_once($includes_url. "php/OpenDB.php");
include_once($includes_url. "php/GetUserInfo.php");$UserInfo = GetJoomUser();

if(!isset($UserInfo) ||$UserInfo['id'] == 0) {
exit("You must be logged in to use this page.");
}

if(!isset($_GET['UserID'])) {$_GET['UserID'] = $UserInfo['id']; } if($_GET['UserID'] == $UserInfo['id']) {$CurrentUser = true;
} else {
$CurrentUser = false; } // Create Course Name Array$strSQL = "SELECT * FROM p3pro_courses.course_names";
$result = mysqli_query($conn, $strSQL); if(!$result) { exit("Cannot connect to database to get Course Names."); }
while($data = mysqli_fetch_assoc($result)) {
$key =$data['CourseID'];
$Courses[$key] = $data['Course_Name']; } // Get User Courses$strSQL = "SELECT * FROM p3pro_p3live.users WHERE JomID = " . $_GET['UserID'];$result = mysqli_query($conn,$strSQL);
if(!$result) { exit("Cannot connect to database to get User Course List."); }$row = mysqli_fetch_assoc($result);$CourseCSV = $row['courses'];$UserCourses = explode(",", $CourseCSV); foreach($UserCourses as $key=>$value) {
$Course_Name =$Courses[$value];$UserCourseList[$value] =$Course_Name;
}

asort($UserCourseList); if($row['HolesPlayed']>89) {
$handicap =$row['p3_handicap']*18;
$handicap_display =$handicap . "(" . $row['p3_handicap'] . " per hole)"; } else {$handicap_display = "n/a";
}
?>
<div class="container-fluid" style="display:inline-block;">
<div id="left" class="inline top" style="padding-right:20px; width:25%; min-width:250px;">
<h3>User Settings &amp; Data</h3>
<form id="UserInfo" name="UserInfo">
<input type="hidden" name="user_id" id="user_id" value=<?php echo $UserInfo['id']; ?> /> <fieldset> <!-- Timezone --> <div id="input0"> <label class="inline label" for="timezone">Timezone : <a href="#" tabindex="-1" id="popover1" rel="popover1" class="pop" data-content="" data-original-title="Timezone"> <img src="/P3Live/images/icons/help.png" data-toggle="tooltip" title="" ie="tooltip1"> </a> <div id="popover1-content" style="display:none;"> <div class="popTitle">Timezone</div> <div class="popContent"> <font color=#000000> <p>This is the user's default timezone.</p> </font> </div> </div> </label> <div class="inline"> <?php$ZoneID = $row['default_timezone'];$strSQL = "SELECT zone_name, gmt_offset FROM p3pro_timezones.zone
LEFT JOIN p3pro_timezones.timezone ON zone.zone_id = timezone.zone_id
WHERE zone.zone_id = " . $ZoneID . " AND time_start<" . time() . " ORDER BY time_start DESC LIMIT 1";$result = mysqli_query($conn,$strSQL);
$tz_info = mysqli_fetch_assoc($result);
echo $tz_info['zone_name'] . " (" .$tz_info['gmt_offset']/(60*60) . " hours)";
?>
</div>
<div class="inline"><span id="err_timezone"></span></div>
</div>
<?php
if($CurrentUser) {?> <center> <a href="/P3Live/forms/select_timezone.php" data-title='Select Timezone' data-width='550px' data-height='200px'>Edit Timezone</a> </center> <?php } ?> <!-- P3 Handicap --> <div id="input1"> <label class="inline label" for="p3_handicap">P3 Handicap : <a href="#" tabindex="-1" id="popover2" rel="popover2" class="pop" data-content="" data-original-title="P3 Handicap"> <img src="/P3Live/images/icons/help.png" data-toggle="tooltip" title="" ie="tooltip1"> </a> <div id="popover2-content" style="display:none;"> <div class="popTitle">P3 Handicap</div> <div class="popContent"> <font color=#000000> <p>This is the user's online handicap. Will display 'n/a' if the user has not hit the 90 hole threshold for an established handicap.</p> <p>The number displayed here is rounded to 2 decimal places, but the full values are used for computation</p> </font> </div> </div> </label> <div class="inline"> <?php if($row['HolesPlayed']<90) {
$p3_handicap='n/a'; } else {$p3_full = number_format(($row['p3_handicap'] * 18),2);$p3_handicap = $p3_full . " (" . number_format($row['p3_handicap'],2) . " per hole)";
}
echo $p3_handicap; ?> </div> <div class="inline"><span id="err_p3_handicap"></span></div> </div> <!-- P3 Holes Played --> <div id="input1"> <label class="inline label" for="p3_holesPlayed">P3 Holes Played : <a href="#" tabindex="-1" id="popover2_5" rel="popover2_5" class="pop" data-content="" data-original-title="P3 Holes Played"> <img src="/P3Live/images/icons/help.png" data-toggle="tooltip" title="" ie="tooltip1"> </a> <div id="popover2_5-content" style="display:none;"> <div class="popTitle">P3 Holes Played</div> <div class="popContent"> <font color=#000000> <p>Number of Stroke Play holes played (used to establish handicap. Handicap is not calculated until you have played 90 holes)</p> </font> </div> </div> </label> <div class="inline"> <?php echo$row['HolesPlayed'];
?>
</div>
<div class="inline"><span id="err_p3_handicap"></span></div>
</div>
<!-- P3 Points -->
<div id="input2">
<label class="inline label" for="points_available">Points Available :
<a href="#" tabindex="-1" id="popover3" rel="popover3" class="pop" data-content="" data-original-title="Points Available">
<img src="/P3Live/images/icons/help.png" data-toggle="tooltip" title="" ie="tooltip1">
</a>
<div id="popover3-content" style="display:none;">
<div class="popTitle">Points Available</div>
<div class="popContent">
<font color=#000000>
<p>This is the number of avialable points for this user.</p>
</font>
</div>
</div>
</label>
<div class="inline">
<?php
echo $row['points_available']; ?> </div> <div class="inline"><span id="err_points_available"></span></div> </div> <?php if($CurrentUser) {
?>
<!-- Blacklisted Players -->
<div id="input3">
<label class="inline label top" for="blacklist">Blacklisted Players :
<a href="#" tabindex="-1" id="popover4" rel="popover4" class="pop" data-content="" data-original-title="Blacklisted Players">
<img src="/P3Live/images/icons/help.png" data-toggle="tooltip" title="" ie="tooltip1">
</a>
<div id="popover4-content" style="display:none;">
<div class="popTitle">Blacklisted Players</div>
<div class="popContent">
<font color=#000000>
<p>These are the players you currently have on your blacklist.</p>
<p>They will not be able to join any private matches nor will you be able to invite them.</p>
</font>
</div>
</div>
</label>
<div class="inline">
<a href="/P3Live/forms/select_blacklist_members.php" id="ManageBlacklist" data-title='Manage Blacklist' data-width='300px' data-height='400px'>Manage Blacklist</a>
<?php
$Blacklist = explode(",",$row['blacklist']);
if(sizeof($Blacklist)>0) { echo "<br /><ul>"; foreach($Blacklist as $key=>$value) {
echo "<li>" . getJoomlaUsername($value) . "</li>"; } echo "</ul>"; } else { echo "n/a"; } ?> </div> <div class="inline"><span id="err_blacklist"></span></div> </div> <?php } ?> <div id="mailing_lists"><h3>Mailing Lists</h3> <ul style="list-style-type: none;"> <li> <input type="checkbox" class="ml_option" name="ml_18" id="ml_18" />&nbsp; &nbsp;Announcements <a href="#" tabindex="-1" id="popover5" rel="popover5" class="pop" data-content="" data-original-title="Mailng List: Announcements"> <img src="/P3Live/images/icons/help.png" data-toggle="tooltip" title="" ie="tooltip1"> </a> <div id="popover5-content" style="display:none;"> <div class="popTitle">Mailng List: Announcements</div> <div class="popContent"> <font color=#000000> <p>This mailing list will be used for general announcements such as product changes, releases, and sales. It will also be used for Tournament Announcements and other activities.</p> </font> </div> </div> </li> <li> <input type="checkbox" class="ml_option" name="ml_19" id="ml_19" />&nbsp; &nbsp;Site Updates <a href="#" tabindex="-1" id="popover6" rel="popover6" class="pop" data-content="" data-original-title="Mailng List: Site Updates"> <img src="/P3Live/images/icons/help.png" data-toggle="tooltip" title="" ie="tooltip1"> </a> <div id="popover6-content" style="display:none;"> <div class="popTitle">Mailng List: Site Updates</div> <div class="popContent"> <font color=#000000> <p>This mailing list will be used for updates to both the P3 and P3 Live websites.</p> </font> </div> </div> </li> <li> <input type="checkbox" class="ml_option" name="ml_20" id="ml_20" />&nbsp; &nbsp;Software Updates <a href="#" tabindex="-1" id="popover7" rel="popover7" class="pop" data-content="" data-original-title="Mailng List: Software Updates"> <img src="/P3Live/images/icons/help.png" data-toggle="tooltip" title="" ie="tooltip1"> </a> <div id="popover7-content" style="display:none;"> <div class="popTitle">Mailng List: Site Updates</div> <div class="popContent"> <font color=#000000> <p>This mailing list will be used for updates to the ProGolf software.</p> </font> </div> </div> </li> </ul> </div> </fieldset> </form> </div> <?php if(in_array(18,$UserInfo['usergroups'])) { ?><script>$('#ml_18').prop('checked',true)</script><?php } else { ?><script>$('#ml_18').prop('checked',false)</script> <?php }
if(in_array(19,$UserInfo['usergroups'])) { ?><script>$('#ml_19').prop('checked',true)</script><?php } else { ?><script>$('#ml_19').prop('checked',false)</script> <?php } if(in_array(20,$UserInfo['usergroups'])) { ?><script>$('#ml_20').prop('checked',true)</script><?php } else { ?><script>$('#ml_20').prop('checked',false)</script> <?php }
?>
<div id="right" class="inline top" style="width:70%; min-width:250px;">
<h3>Courses owned by this user</h3>
<?php
if($CurrentUser) { ?> <center> <a href="/P3Live/forms/user_courses.php" data-title='Course Info' data-width='1100px' data-height='620px'>Manage my Courses</a> </center> <?php } ?> <table id="results" border="1" class="display"> <thead> <th>Course Name</th> </thead> <tbody> <?php foreach($UserCourseList as $key=>$value) {
?>
<tr><td><?php echo $value; ?></td></tr> <?php } ?> </tbody> </table> </div> </div> <script>$(function () {
var iframe = $('<iframe frameborder="0" marginwidth="0" marginheight="0" allowfullscreen></iframe>'); var dialog =$("<div id='dialog'></div>").append(iframe).appendTo("body").dialog({
autoOpen: false,
modal: true,
resizable: false,
width: "auto",
height: "auto",
close: function () {
iframe.attr("src", "");
location.reload();  // Refresh the page when the dialog is closed so Users column is correct
}
});
$("a").on("click", function (e) { e.preventDefault(); var src =$(this).attr("href");
var title = $(this).attr("data-title"); var width =$(this).attr("data-width");
var height = $(this).attr("data-height"); iframe.attr({ width: width, height: height, src: src }); dialog.dialog("option", "title", title).dialog("open"); }); });$(document).ready(function() {
$('#results').DataTable({ // Set default show settings "iDisplayLength": 10, "bPaginate": true });$(".ml_option").click(function() {
var id = $(this).attr('id'); if($("#"+id).is(':checked')) {
} else {
val= 'remove';
task = 'removed from';
}
id = id.replace("ml_", "");
$.ajax({ type: "POST", dataType: "json", url:"/P3Live/_includes/php/UserGroups.php", data: {type:val,user_id: document.getElementById('user_id').value,group_id:id}, success: function(response) { if (response.status == "success") { // Do nothing.. just continue console.log("Successfully "+task+" mailing list.") } else { console.log(response.message); } }, error: function(response) { for (var k in response){ if (typeof response[k] !== 'function') { console.log("Key is " + k + ", value is " + response[k]); } } } }); }) var frmPopovers_1 = document.getElementById('UserInfo').getElementsByClassName('pop');$(frmPopovers_1).each(function() {

var $pElem_frm1=$(this);
var elementName_frm1=$pElem_frm1.attr("id"); var element_frm1 = document.getElementById(elementName_frm1); var xPosition_frm1 = 0;$pElem_frm1.popover (
{
trigger: "hover",
placement: "right",
html:true,
title: getPopTitle($pElem_frm1.attr("id")), content: getPopContent($pElem_frm1.attr("id"))
}
);
});
});

function getPopTitle(target) {
return $("#" + target + "-content > div.popTitle").html(); } function getPopContent(target) { return$("#" + target + "-content > div.popContent").html();
}

function closeIframe()
{
$('#dialog').dialog('close'); return false; } </script> </body>  • Hello Charles - I assume you are showing an external page with an iframe. But can you clarify what you mean when you say "I put the page in the module"? What exactly you are doing? I could further assume, you are getting the source code of that page and pasting it in a custom html module? In such case, you must pay attention, on the scripts and the libraries, you might be loading twice jquery - or you might end up with a different script order, so that's why the js errors. – FFrewin Feb 10 '16 at 22:32 • Please add jQuery(document).ready(function($) at top of the jquery – Nehal Feb 11 '16 at 5:07

I assume you are showing an external page with an iframe. But can you clarify what you mean when you say "I put the page in the module"? What exactly you are doing?

I could further assume, you are getting the source code of that page and pasting it in a custom html module?

In such case, you must pay attention, on the scripts and the libraries. For example, you might be loading twice the jQuery library (which is very likely) - or you might end up with a different scripts loading order, so that's why the js errors.

• I'm not using the custom HTML. I've physically created this as a module and installed it in Joomla. Within the Joomla module (in this case called mod_user_settings) there is a php page which runs (mod_user_settings.php). This is that page. I don't believe there are 2 versions of jquery running because if I comment out the jquery load in the heading I get all kinds of errors about jquery not be loaded. – Charles Wilkins IV Feb 11 '16 at 14:00

Try this:

var title = $(this).data("title"); var width =$(this).data("width");
var height = $(this).data("height");  but leave your link attributes named the way they are data-title, data-width, and data-height You may also want to wrap your code in this as well: jQuery(document).ready(function($){

});


Complete it would look similar to this:

<a href="https://www.google.com" data-width="300px" data-height="300px" data-title="my title" class="link">Google.com</a>

jQuery(document).ready(function($){$("a").on("click", function (e){
e.preventDefault();
var src = $(this).attr("href"); var title =$(this).data("title");
var width = $(this).data("width"); var height =$(this).data("height");
iframe.attr({
width: '"'+width+'"',
height: '"'+height+'"',
src: '"'+src+'"'
});
});
});


To verify that your variables are grabbing the correct data you can console.log(width) or height or title or src to see the output in the debugger console. You probably wanna assign a class to the links as well so you can listen for clicks on a.className instead of every single link on your page.

• I added the jQuery(document).ready(function(\$){ around the element and it now passes the src correctly. However, when it attempts the get it appends the src to the existing url instead of attempting to get the appropriate url. When I click the 'Manage my Courses' link I get localhost:8080/cms/index.php/user-utilities/%22/P3Live/forms/… 404 (Component not found). I'm sure this is because of the first part of the url (localhost:8080/cms/index.php/user-utilities). I also cannot remove the quotes (%22) or it will not attempt to load the url at all – Charles Wilkins IV Feb 11 '16 at 16:00
• Remove the quotes from around the variable names within your iframe method. I added them not knowing how your data attributes were structured and you may not need them. If it is appending the Url you need to set your href to the full url instead of a relative url – Terry Carter Feb 11 '16 at 16:12
• Reading your comment again it sounds like you just need to use the absolute url of your manage course link as opposed to the relative url – Terry Carter Feb 11 '16 at 16:52

For anyone struggling with modals in Joomla, I found a solution that works. Use the following within PHP:

 JHtml::_('behavior.modal');


And then something similar to this: your link

I did find that I wanted to override the default modal class though. The default uses a fixed position: absolute (which I overwrote to be position:relative) so my links stayed in place. I also overwrote the z-index to 0 (otherwise the link was on top of any menu system).

Works like a charm and all my modals are displaying as expected (and responsive).

Thanks to all for your attempt at assisting!!

In Joomla, to load an iframe we already have a module with type "Wrapper". And their various settings are given like scroll, width etc.

You can try using this and see if it solves your problem.

• Thanks for the information, but I was creating a module instead of using a wrapper as the wrapper uses an iframe. When using an iframe, you will get multiple scroll bars and the page will not be very responsive. – Charles Wilkins IV Feb 16 '16 at 16:20