0

I have some jQuery embedded into HTML but I would like to "extract" jQuery and place it into a separate file. Or at least, move it out of the immediate HTML code. I think doing so will fair better in the long run as far as maintainability goes. I hope I am not mistaken by having this principle (SOC) guiding this particular need for refactoring.

I have a <td> table cell inside a table that holds value of quantity and then reacts to a double click event, by loading up an "edit" box for the value.

<td id="qty">

    <?if (!$this->isAnOrder) { ?>
        <script>
        $("#qty" ).dblclick(function() {
            $.get('edit.php?id=<?=$this->id?>', function( data ) {
                $( "#qty" ).html( data );
            });
        });
        </script>
    <? } ?>

    <?=$this->quantity?>

</td>  

Question

How would I separate the concerns of the view (HTML) and responding to UI events on the view (JS)?

Special note: I see that I can move the JS code into a separate JS file, but by doing so I hurt maintainability - how would you be able to tell if this particular <td> field has some JS acting on it? Namely for me part of maintainability is being able to build a mental model of what the code does easily. Simply moving code off into a separate file might hurt that.

So my question becomes - how to separate concerns and keep maintainability intact, if at all possible?

Dennis
  • 7,907
  • 11
  • 65
  • 115
  • There's the middle ground Instead of embedding multiple script tags inside your elements, place your JS in a single script tag in the same HTML file. Unfortunately, the answer to this question really a matter of opinion, and therefore not suited to this site. – jmoerdyk Apr 12 '16 at 19:49

3 Answers3

1

how would you be able to tell if this particular field has some JS acting on it?

There are a few ways, but they will require you to write additional code or use third-party tool. See How to find event listeners on a DOM node when debugging or from the JavaScript code?

Generally speaking, it is still advisable to separate your Javascript from your HTML by saving it to a separate JS file and including it.

Eg, in your head section:

<script src="path/to/my/file.js"></script>

Will have the same effect as writing the javascript directly in your html file.

Community
  • 1
  • 1
MrD
  • 4,986
  • 11
  • 48
  • 90
  • thanks. as far as using the script in the head section, are you advising then to use ``? – Dennis Apr 12 '16 at 19:51
  • 1
    No. It's bad practice to declare listeners directly in the tag. As you are already using jQuery, my advise would be: ("#qty").dblclick(function(){//something here}); and to include this in your external js file – MrD Apr 12 '16 at 19:53
  • 1
    Also, please do not pass parameters to javascript functions by hardcoding PHP expressions into them. Mixing front-end and back-end code leads to maintenance nightmares. Please see http://stackoverflow.com/questions/23740548/how-to-pass-variables-and-data-from-php-to-javascript and consider using ajax or at the very least echoing everything into one JSON structure which you then refer to in your code. Let me know if you have any questions. – MrD Apr 12 '16 at 19:54
0

Since you've got PHP conditionals dictating what show on the page you may want to drop the JS into a function and just call the function.

<?if (!$this->isAnOrder) { ?>
    <script> doStuff(); </script>
<? } ?>

on a seperate file..

function doStuff(){
    $("#qty" ).dblclick(function() {
        $.get('edit.php?id=<?=$this->id?>', function( data ) {
            $( "#qty" ).html( data );
        });
    });
}

You can then put all your PHP conditionals in a single script tag at the bottom of the page.

I wrestled a bear once.
  • 22,983
  • 19
  • 69
  • 116
0

If you really want to keep it clean, and separate out your frontend and backend logic:

  1. Create an HTML file with your desired formatting.
  2. Include a link to the javascript file.
  3. Set up PHP 'controllers' that accept something from POST and respond using JSON.
  4. Have Javascript/jQuery access your PHP controllers and interpret the response.

doSomething.js example:

function doSomething(param) {
    data = {
        'param': param
    };
    $.post(
        'doSomething.controller.php',
        data
    ).done(
        function (data) {
            // success! do something
        }
    ).fail(
        function (xhr) {
            console.log(xhr);
            // failure! do something else
        }
    );
}

doSomething.controller.php example:

<?php

// respond as failure
function fail($message = null,$code = 500) {
    http_response_code($code);
    exit($message);
}

// respond as success
function success($message = null, $code = 200) {
    http_response_code($code);
    exit($message);
}

// access the backend models and interpret the response
function doSomething($param) {
    // do something on the backend
    $json = json_encode($response);
    success($json);
}

// validate params
if (!isset($_POST['param'])) {
    fail("'param' parameter must be in POST request",404);
}

// trigger the main controller logic
doSomething($_POST['param']);
David Wyly
  • 1,671
  • 1
  • 11
  • 19