A. Agius
A. Agius

Reputation: 1271

Jquery UI Widget Factory

$.widget( "app.serverTime", {
    _create: function () {
        $.get("/timestamp.php", function( data ) {
           this.timestamp = data.timestamp;
        })
    },

    getTime:function() {
       return this.timestamp;
    }
});


$(".clock").serverTime();
$(".clock").serverTime("getTime")

I have the above jQuery UI Widget when I call the getTime I am getting in the value I am expected but instead I am getting the jQuery Selector, when i set the value manually without using Ajax it works as expected.

Upvotes: 2

Views: 257

Answers (3)

Twisty
Twisty

Reputation: 30883

Consider the following.

Example: https://jsfiddle.net/Twisty/yft97sme/

JavaScript

$(function() {
  $.widget("app.serverTime", {
    options: {
      server: "https://worldtimeapi.org/api/ip",
      showLabel: true,
      labelValue: "Server Time:"
    },
    _create: function() {
      var self = this;
      self.element.addClass("ui-server-time ui-widget");
      if (self.options.showLabel) {
        $("<label>", {
          class: "ui-server-time-label",
          style: "margin-right: 5px;"
        }).html(self.options.labelValue).appendTo(self.element);
      }
      $("<span>", {
        class: "ui-server-time-display"
      }).appendTo(self.element);
      $("<button>", {
        class: "ui-server-time-refresh",
        style: "margin-left: 5px;"
      }).html("Refresh").button({
        icon: "ui-icon-arrowreturnthick-1-s",
        showLabel: false
      }).click(function() {
        self.getTime();
      }).hide().appendTo(self.element);
      self.getTime();
    },
    _log: function(str) {
      console.log(Date.now(), str);
    },
    _serverTime: null,
    _collectTime: function() {
      var self = this;
      self.beforeGetTime();
      $.ajax({
        cache: false,
        type: "get",
        url: this.options.server,
        success: function(results) {
          self._log("Collected Time: " + results.unixtime);
          self._setTime(results);
        }
      });
    },
    _setTime: function(obj) {
      this._log("Time Setter");
      this._serverTime = obj
    },
    _getTime: function() {
      this._log("Time Getter");
      var dt = new Date(this._serverTime.datetime);
      $(".ui-server-time-display", this.element).html(dt.toString());
      $(".ui-server-time-refresh", this.element).show();
      return this._serverTime;
    },
    beforeGetTime: function() {
      this._log("Before Get Time");
    },
    getTime: function() {
      this._collectTime();
      this._delay(this._getTime, 500);
    },
    _destroy: function() {
      this.element.children().remove();
      this.element.removeclass("ui-server-time");
    }
  });

  $(".clock").serverTime({
    showLabel: false
  });
});

If you run the GET in the creation of the widget, it will show the Server Time from that moment. It will also delay the creation if the server is slow to respond. I would suggest moving the collection of the time to it's own function. This way you can call it whenever you want.

Assuming your PHP Script might return a different value, you may need to adjust the result handling.

Upvotes: 0

Irvin Dominin
Irvin Dominin

Reputation: 30993

I think the issue is because of this. Inside the get function this not refer to the plugin calee object.

So save this reference and use it later like:

$.widget( "app.serverTime", {
    _create: function () {
        var _this=this;
        $.get("/timestamp.php", function( data ) {
           _this.timestamp = data.timestamp;
        })
    },

    getTime:function() {
       return this.timestamp;
    }
});

EDIT

Consider that the $.get is async, so the timestamp property will be set when the $.get finish, but the code runs.

Concept:

$(".clock").serverTime();

setTimeout(function () {
    console.log($(".clock").serverTime("getTime"));
}, 5000);

So think about handle the async properly.

Demo: http://jsfiddle.net/IrvinDominin/5pFkk/

Upvotes: 2

blgt
blgt

Reputation: 8205

Just a small addition to @Irvin's answer: You can use $.proxy to easily change this within the function, and this is especially useful for working with the widget factory;

Additionally you should have a default value for the timestamp variable -- and should include an underscore in front of it's name (as that's the convention for "private" (pseudoprivate) fields -- I assume it's supposed to be private as you have a getter):

$.widget( "app.serverTime", {
    _create: function () {
        $.get("/timestamp.php", $.proxy(function( data ) {
           this._timestamp = data.timestamp;
        }, this))
    },
    _timestamp: "Tue Jul 15 2014 08:50:38 GMT+0100 (GMT Standard Time)",

    getTime:function() {
       return this._timestamp;
    }
});

Upvotes: 1

Related Questions