0

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:

First, the header:

<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>

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')) { 
            val = 'add';
            task = 'added to'; 
        } 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>
2
  • 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
    Commented Feb 10, 2016 at 22:32
  • Please add jQuery(document).ready(function($) at top of the jquery
    – Nehal
    Commented Feb 11, 2016 at 5:07

4 Answers 4

1

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.

1
  • 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. Commented Feb 11, 2016 at 14:00
0

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.

3
  • 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 Commented Feb 11, 2016 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
    Commented Feb 11, 2016 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
    Commented Feb 11, 2016 at 16:52
0

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!!

0

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

Refer the link: https://docs.joomla.org/Help34:Extensions_Module_Manager_Wrapper

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

1
  • 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. Commented Feb 16, 2016 at 16:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.