3

How can I access a JSON array from a PHP variable in an external JavaScript file without creating a global variable?

I have a PHP variable $customers that contains a json_encoded array:

$customers = [{"id":"12","name":"Abe Adams"},{"id":"17","name":"Bill Brown"}]

I want to use the contents of the array in a jQuery UI Autocomplete text input.

Rather than make an Ajax request for the autocomplete options, I'd prefer to use the values in the $customers array, which is passed in and ready to go when the user arrives at the page.

I know I can pass the contents of $customers to a JavaScript variable prior to loading the external JavaScript file:

<script>var customers = <?php echo $customers; ?></script>
<script src="external.js"></script>

But this requires creating a global JavaScript variable.

Is there a better way to access the $customers array from my external JS file?


This question has been asked several times previously:

Question: Access PHP var from external javascript file Accepted Answer: Create global var

Question: Pass vars from php to js without ajax Top Answer: Use Ajax

Question: php file send variable to .js external file Top Answer: Use Ajax

Question: Reading a PHP file variables from external JS Top Answer: Use eval

Question: Return JSON data from PHP, and use it using Javascript Accepted Answer: Create global var

Community
  • 1
  • 1
cantera
  • 24,479
  • 25
  • 95
  • 138
  • If you are using autocomplete plugin, then you not need to store that json, set `source` to autocomplete and it will retrieve data. – thecodeparadox Jun 02 '12 at 05:38
  • @thecodeparadox - Could you show me what you mean? Not seeing anything in the jQuery docs on setting source to autocomplete and not sure how it would know where to look. Would be brilliant if this does work. – cantera Jun 02 '12 at 05:47

3 Answers3

2

No, you can't do that without making external.js be a dynamically generated. You can however improve your strategy a little. Instead of having a global named customers have a global object for attaching all your global variables too:

window.Globals = {};
Globals.customers = <?php echo $customers; ?>;
Globals.something_else = <?php echo $something_else; ?>

Don't name it Globals though. Name it something specific to your company or web app/site. This way you will greatly reduce the risk of conflicting variable names with any external scripts, since you only have one global variable you use, and it is named after something specific to your site.

Paul
  • 139,544
  • 27
  • 275
  • 264
  • Thanks - I like this strategy for managing globals and don't think I'd seen it done this way before. Will peruse some of your other responses as well - I'm guessing you've posted other helpful JS tricks. – cantera Jun 02 '12 at 05:44
  • You're welcome @cantera25, and feel free to look around :) Although I don't think of have any posts that are specifically JS tricks rather than answers to specific questions. – Paul Jun 02 '12 at 06:07
1

You could also use a requirejs "pattern":

external.js:

define([], {
    init: function (customerData) {
        ... all your setup
    }
});

On page:

require(['external'], function (externalSetupFile) {
    var customers = <?php echo $customers?>;
    externalSetupFile.init(customers);
});

A big benefit to (in general) having some sort of "init" method that fires off the enhancement of the site is that you can do things like this. For example:

Application = {
   init: function (bootstrapData) {
       UserModel.create(bootstrapData.userModelData); //for example 
       this.config = bootstrapData;
       this.setupUI();
   },
   setupUI: function () {
      //setup autocomplete and the like
      $("#someEl").autocomplete(this.config.customers);
   }
}

An even better part of this is that you can split up what you're doing into small sections, which makes testing and debugging a heck of a lot easier.

Stephen
  • 5,362
  • 1
  • 22
  • 33
  • Thanks Stephen - this is awesome. I've only worked with RequireJS a little bit - do you know where this pattern is documented or any tutorials that explain it? Also, what does the empty array signify in the define() argument? – cantera Jun 03 '12 at 01:52
  • This is kind of a mix-mash of various things I've picked up on from working with single page applications. The empty array isn't necessary.. I add it out of habit, because most modules I work on are interdependent to some extent. Anyway, the 'pattern' is really more something you can pick up from Java and the like.. have a "main" function that gets the application booted and running. That way you can control specifically when the thing starts and what it starts with (i.e. getting data from the page vs an ajax call vs a jsonp call, etc). – Stephen Jun 03 '12 at 09:12
  • I backtracked through some of my books and couldn't nail down a specific example - but if you're interested I would highly recommend http://www.amazon.com/JavaScript-Patterns-ebook/dp/B0046RERXE (it gives some good food for thought) – Stephen Jun 03 '12 at 09:18
0

I think you can implement this, if you're trying with autocomplete plugin.

$("#some_input_field").autocomplete("search.php", {
    // your code
});

or you can do also

$( "#some_input_field" ).autocomplete({
     source: "search.php",
     // some other code
});

Here source.php will replace with the url from where you load data.

thecodeparadox
  • 86,271
  • 21
  • 138
  • 164