Link to home
Start Free TrialLog in
Avatar of Bruce Gust
Bruce GustFlag for United States of America

asked on

How do I init a PHP page jusing JQuery?

I'm re-creating a project I've been asked to work on and I've got this code looking at me:

<script src="members-edit.js">

<ul>
<li><a href="#summary" aria-controls="summary">Summary</a></li>
</ul>

When the user clicks on the "Summary" link, there's some code on the "members-edit.js" script that looks like this:

      $('a[href="#summary"]').on('click', function() {
            HealthSummary.init();
      });

I don't understand why, but I've been able to follow my nose enough to know that this code is instantiating the "HealthSummary.php" page and the default functionality that kicks into gear.

How?

How is JQuery instantiating the code using "HealthSummary" as opposed to "HealthSummary.php?"

I've got some problems that I need to solve and I thought it best to re-create the environment that I'm working in and this was my first question.

How does "initi" work and why does it not need the complete file name as opposed to "HealthSummry?"

Thanks!
Avatar of Marco Gasi
Marco Gasi
Flag of Spain image

Look at this line
   HealthSummary.init();

Open in new window

This means that somewhere you have a javascript code which instantiates an object called HealthSummary which has a method called init(). There you can find the answer to your question.
SOLUTION
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Bruce Gust

ASKER

OK, gentlemen, I believe I'm seeing the light...

This code resides on members-edit.js:

$(document).ready(function(){
   
    $('#member-dob').mask('00/00/0000', {
        placeholder: 'mm/dd/yyyy'
    });
   
    $('#member-ssn-last-4').mask('0000', {
        placeholder: 'SSN Last 4'
    });
   
    $('#member-mobile-phone, #member-alt-phone').mask('000-000-0000', {
        placeholder: '###-###-####'
    });
   
    $('a[href="#summary"]').on('click', function(){
        setTimeout(function(){
            HealthSummary.init();
        }, 250);
    });


This, I believe is being put into motion as a result of the link on the page - the HTML looking like this:

<li><a href="#summary" aria-controls="summary">Summary</a></li>

Correct? I googled "aria-controls" and I didn't get the impression this is used that much (http://www.heydonworks.com/article/aria-controls-is-poop). Still, just because I'm interested in learning, what is it that actually triggers the Javascript? Is it the "<a href="#summary" or is it the "aria-controls?"

Marco, to your point, I went back and looked specifically for a function entitled "HealthSummary" rather than just assuming it was referring to the "HealthSummary.php" page. I found it.

There's a "health-summary.js" script that's being included at the top of the code that looks like this:

var HealthSummary = {
    
    initialized: false,
    
    init: function(){
        var self = this;
        
        if (self.initialized) {
            return true;
        }
        
        $('.health-summary[data-id]').each(function(i){
            
            var $this = $(this),
                id = $this.attr('data-id');
            
            if (id === '') {
                $this.html('<h3 class="text-center">Invalid health summary reference</h3>');
                return true;
            }
            
            $this.html('<h3 class="text-center"><i class="fa fa-refresh fa-spin"></i> &nbsp;Loading Health Summary...<br /><small>(This should only take a few seconds.)</small></h3>');
            
            $.get('/health-summary/' + id, function(resp){
                if (resp.error) {
                    $this.html('<div class="alert alert-danger">' + resp.msg + '</div>');
                    return false;
                }
                
                $this.html(resp.data.html);
            }, 'json').fail(function(){
                $this.html('<div class="alert alert-danger">Unfortunately, something appears to have gone wrong. Please refresh the page to try again.</div>');
            });
            
        });
        
        self.initialized = true;
    }
    
};

Open in new window


It's at this point, I think I'm beginning to smell a resolution. Still...

It's this part of the "health-summary.js" code that got my attention:

$.get('/health-summary/' + id, function(resp){
                if (resp.error) {
                    $this.html('<div class="alert alert-danger">' + resp.msg + '</div>');
                    return false;
                }
               
                $this.html(resp.data.html);
            }, 'json').fail(function(){

It looks as though that it's HERE where the "HealthSummary.php" functionality is being called and displayed.

Here's the first part of the HealthSummary.php page:

class HealthSummary extends BaseController {

     public function _default($id='') {
          if(3mpty($id)) {
          die(App::error("Missing or invalid ID provided ', true));
         }

     $id =MDB::id($id);
          if(!$id) {
          die(App::error('Invalid ID provided.' , true));
          }
     ....

    [b]$resp = $m->getOne(['_id' =>$id]);[/b]

    ...
   }

}

Open in new window


So...

Here's what I'm understanding. Tell me if I'm correct...

members-edit.js has the command being triggered by the link: <li><a href="#summary.."</li>. The command is the "onclick" function which initializes the "HealthSummary" function using "HealthSummary.init."

Unlike my original assumptions as far as "HealthSummary.init" referring to "HealthSummary.php," it's actually referring to the "HealthSummary" var located on the "health-summary.js" page and it's THERE where the "HealthSummary.php" gets called.

But...

I'm looking for anything that says "HealthSummary.php" and I don't see it. I can make assumptions, but I'm not seeing anything definitive.

By the way, this is a Laravel site that's using Twig.

Ray, I wanted to honor your request for all the code, so here it is:

health-summary.js

var HealthSummary = {
    
    initialized: false,
    
    init: function(){
        var self = this;
        
        if (self.initialized) {
            return true;
        }
        
        $('.health-summary[data-id]').each(function(i){
            
            var $this = $(this),
                id = $this.attr('data-id');
            
            if (id === '') {
                $this.html('<h3 class="text-center">Invalid health summary reference</h3>');
                return true;
            }
            
            $this.html('<h3 class="text-center"><i class="fa fa-refresh fa-spin"></i> &nbsp;Loading Health Summary...<br /><small>(This should only take a few seconds.)</small></h3>');
            
            $.get('/health-summary/' + id, function(resp){
                if (resp.error) {
                    $this.html('<div class="alert alert-danger">' + resp.msg + '</div>');
                    return false;
                }
                
                $this.html(resp.data.html);
            }, 'json').fail(function(){
                $this.html('<div class="alert alert-danger">Unfortunately, something appears to have gone wrong. Please refresh the page to try again.</div>');
            });
            
        });
        
        self.initialized = true;
    }
    
};

Open in new window


members-edit.js

$(document).ready(function(){
    
    $('#member-dob').mask('00/00/0000', {
        placeholder: 'mm/dd/yyyy'
    });
    
    $('#member-ssn-last-4').mask('0000', {
        placeholder: 'SSN Last 4'
    });
    
    $('#member-mobile-phone, #member-alt-phone').mask('000-000-0000', {
        placeholder: '###-###-####'
    });
    
    $('a[href="#summary"]').on('click', function(){
        setTimeout(function(){
            HealthSummary.init();
        }, 250);
    });
    
    $('#member-employer').select2({
        ajax: {
            url: '/employers/select2-search',
            dataType: 'json',
            delay: 500,
            data: function (params) {
                return {
                    q: params.term, // search term
                    page: params.page
                };
            },
            processResults: function (data, params) {
                params.page = params.page || 1;
                
                var items = [];
                
                for (var i in data.items) {
                    items.push({
                        id: data.items[i]._id,
                        text: data.items[i].name
                    });
                }
                
                return {
                    results: items,
                    pagination: {
                        more: (params.page * 30) < data.total_count
                    }
                };
            },
            cache: true
        },
        escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
        minimumInputLength: 1
    });
    
    var $formEl = $('#member-form'),
        $btn = $('button[type="submit"]'),
        form = new Form($formEl, {
            btnSelector: $btn
        });
    
    $btn.on('click', function(e){
        e.preventDefault();
        
        var resp = form.postTo($formEl.attr('action'), function(resp){
            window.location.href = '/members/saved/' + resp.data.employer;
        });
    });
    
});

Open in new window


...and HealthSummary.php

<?php

use \AAF\App;
use \AAF\Database\MDB;
use \AAF\Caching\RDS;
use \AAF\Controllers\BaseController;
use \AAF\Twig\Template;

require_once 'lib/Model.php';

class HealthSummary extends BaseController {
    
    public function _default($id='') {
        if (empty($id)) {
            die(App::error('Missing or invalid ID provided.', true));
        }
        
        $id = MDB::id($id);
        if (!$id) {
            die(App::error('Invalid ID provided.', true));
        }
        
        $m = Model::factory('members');
        
        $resp = $m->getOne(['_id' => $id]);
        if ($resp['error']) {
            die(App::error('Unfortunately, we encountered an error while trying to generate your health summary. Please refresh the page and try again.', true));
        } else if ($resp['data']['numrows'] == 0) {
            die(App::error('Unfortunately, we were unable to find the member you requested. Please refresh the page and try again.', true));
        }
        
        die(App::success([
            'html' => $this->_createReport($resp['data']['rows'][0])
        ], true));
    }
    
    public function member() {
        if (!App::valid('member', $_SESSION) || !App::valid('_id', $_SESSION['member'])) {
            Flash::redirect('/events/find?showExpired=1', 'Please help us locate the screening event you participated in. Use the search form below.');
        }
        
        $m = Model::factory('members');
        
        $resp = $m->getOne(['_id' => $_SESSION['member']['_id']], true);
        
        if ($resp['error']) {
            die(App::error('Unfortunately, we encountered an error while trying to generate your health summary. Please refresh the page and try again.', true));
        } else if ($resp['data']['numrows'] == 0) {
            die(App::error('Unfortunately, we were unable to find the member you requested. Please refresh the page and try again.', true));
        }
        
        die($this->render([
            'member' => $_SESSION['member'],
            'html' => $this->_createReport($resp['data']['rows'][0])
        ], 'app/event/report.html.twig'));
    }
    
    public function getReportHtml($id, $screening='') {
        if (empty(User::$data)) {
            Flash::redirect('/login', 'Invalid request.');
        }
        
        $id = MDB::id($id);
        if (!$id) {
            die(App::error('Invalid ID provided.', true));
        }
        
        $m = Model::factory('members');
        
        $resp = $m->getOne(['_id' => $id], true);
        
        if ($resp['error']) {
            return App::error('Unfortunately, we encountered an error while trying to generate your health summary. Please refresh the page and try again.');
        } else if ($resp['data']['numrows'] == 0) {
            return App::error('Unfortunately, we were unable to find the member you requested. Please refresh the page and try again.');
        }
        
        if (!empty($screening)) {
            $sr = [];
            
            foreach ($resp['data']['rows'][0]['responses'] as $response) {
                if ((string) $response['screening'] == $screening) {
                    $sr = $response;
                }
            }
            
            if (empty($sr)) {
                return App::error('Unfortunately, the member you requested does not have a response for the provided screening event.'); 
            }
            
            $resp['data']['rows'][0]['responses'] = [$sr];
        }
        
        return App::success($this->render([
            'member' => $resp['data']['rows'][0],
            'html' => $this->_createReport($resp['data']['rows'][0])
        ], 'app/event/report.html.twig'));
    }
    
    protected function _createReport($member) {
        if (!App::valid('responses', $member) || empty($member['responses']) || !App::valid('_stratification', $member['responses'][0])) {
            return '<div class="alert alert-info">This participant does not have enough response data to generate a health summary.</div>';
        }
        
        $keys = array_keys($member['responses'][0]['_stratification']);
        
   $member['responses'][0]['_stratValuesKeys'] = [];
   
   foreach($member['responses'][0]['_stratificationValues'] as $strat){
   $member['responses'][0]['_stratValuesKeys'][$strat['key']] = $strat;
   }
        
        $vars = [
            'data' => $member,
       'date' => date('m/d/Y'),
            'definitions' => $this->_getBiometricDefinitions($keys, strtolower($member['gender']))
        ];
        
        return $this->render($vars, 'app/health-summary.html.twig');
    }
    
    protected function _getBiometricDefinitions($keys, $gender='male') {
        $def = [];
        
        $resp = MDB::cursor('biometric_definitions', [
            'definition_type' => 'biometric_value',
            'key' => ['$in' => $keys]
        ], [
            //'biometric_category' => 1
            'index' => 1
        ]);
        
        if ($resp['error']) {
            throw new \Exception('Could not load biometric definitions.');
        }
        
        foreach ($resp['data']['cursor'] as $row) {
            if (!isset($def[$row['biometric_category']])) {
                $def[$row['biometric_category']] = [];
            }
            
            $def[$row['biometric_category']][$row['key']] = [
                'label' => $row['labels']['en'],
                'optimal' => App::get($gender, $row['optimal']),
                'desc' => $row['descriptions']['en'],
           'short_desc' => $row['short_descriptions']['en']
            ];
        }
        
        return $def;
    }
    
}

Open in new window


Bottom line: How are the dots connected? I want to build a very scaled down version of what I'm attempting to understand. How is all of this connected?

Thanks!
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
About dots, are you talking about double colons? If so, they stay as concatenation sign for static methods/classes. Briefly, s static method is a method of a class you can call without instantiating an object for that class. Right now I have in mind the javascript class Math, which is static. This class holds a lot of useful methods to perform math calculations. To use them, you just have to import the library Math and call its methods using Math.pow(), for instance. In javascript you use a dot, in Php you use a double colon. So the static class MDB has a method id which expects an integer parameter. Its definition is something like this
class MDB{
     public static id($id){
          //stuff here
     }
}

Open in new window

You can call this method just including the class ('use \AAF\Database\MDB;') and then calling its methods:
$id = MDB::id($id);

Open in new window


If it wasn't static you should have to create an object be3fore to use the class:
$mdb = new MDB();
$id = $mdb->id($id);

Open in new window

Marco! Thanks! That was it!

In the config directory, I found "routes.json" and there you see:

"health_summary": {
        "url": "/health-summary/{id}",
        "handler": "HealthSummary.php",
        "action": "_default",
        "method": ["get"],
        "security": ["user"]
    },

This matches the:

 $.get('/health-summary/' + id, function(resp){
                if (resp.error) {
                    $this.html('<div class="alert alert-danger">' + resp.msg + '</div>');
                    return false;
                }

...comand on the health-summary.js file so the dots are not connected!

Thank you!
As far as "dots," I wasn't referring to the scope resolution operator, I've got a bead on that. It's the JQuery and the various chutes and ladders that are being deployed that I'm trying to track down. Thanks, though, for the thorough-ness. One of the reasons I'm such a fan of EE!
Glad to help you :)