Malcolm
Malcolm

Reputation: 12864

MVC 4 Unable to call javascript function from another js file

I am trying call the loadTimesheet function in object weeklytimesheet from another js file.

I get a Object doesn't support property or method 'loadTimesheet' error.

EDIT: My intellisense in VS2012 is not working either if that has any bearing on it.

mylester.index.js

$(document).ready(function () {

    $("#newtimesheet").click(function () {
        weeklytimesheet.loadTimesheet();
    });
});

mylester.weeklytimesheet.js

var weeklytimesheet = new function () {
    load = function () {
        var wkending =  getWeekEnding();
        var proId = $("#newtimesheet").attr("proid");
        $("#divtimesheet").load("/Timesheet/NewTimesheet", new { proId: proID, enddate: wkending });
        open();
    };

    open = function() {
        $("#clipboarddialog").dialog({
            autoOpen: true,
            height: 800,
            width: 860,
            modal: true,
            title: "Edit Timesheet",
            buttons: {
                "Save": function () {
                    editorForm.saveForm();
                    $(this).dialog("close")
                },
                Cancel: function () { $(this).dialog("close") }
            }
        });

    };

    getWeekEnding = function () {
        var wkending;
        $(".datepicker").datepicker();
        $("#datepickerdialog").dialog({
            autoOpen: true,
            close: function () {
                wkending = $("#weekending").val();
            },
            show: {
                effect: "blind",
                duration: 1000
            },
            hide: {
                effect: "explode",
                duration: 1000
            }
        });
        return wkending;
    }

    return
    {
        loadTimesheet: load
    };
}();

Upvotes: 1

Views: 1504

Answers (1)

Valentin Waeselynck
Valentin Waeselynck

Reputation: 6051

The problem is that carriage return after the new, it tells the function to return undefined. fix it this way:

return {
  loadTimesheet: load
};

This machanism is known as semicolon insertion is one of the 'awful parts' of JavaScript that Douglas Crockford lists in his excellent book, JavaScript, The Good Parts.

Also, I suggest 2 improvements in your code :

1) don't use new. It's not meant for what you are doing here. If what you want is a local scope for declaring your helper functions, here's a trick : use a function expression that you that you call immediately:

  var weeklytimesheet = (function () {
    // do your local stuff ...
    return {
      loadTimesheet: load
    };
  } ()); // see? call the function immediately. That's how you make nontrivial expressions in JS.

2) Don't assign variables that you have not declared (load, open, getWeekEnding). You may have got this habit from Python, but in JavaScript it has a very bad effect : these variables are interpreted as properties of the global Object (window), which makes them not local at all and pollutes the global namespace. I think you don't want that; using function declarations (function open () {...}) solves this neatly.

So to sum up, here is how I would rewrite your code :

var weeklytimesheet = (function () {
  function load () {
    var wkending =  getWeekEnding();
    var proId = $("#newtimesheet").attr("proid");
    $("#divtimesheet").load("/Timesheet/NewTimesheet", new { proId: proID, enddate: wkending });
    open();
  }

  function open () {
    $("#clipboarddialog").dialog({
      autoOpen: true,
      height: 800,
      width: 860,
      modal: true,
      title: "Edit Timesheet",
      buttons: {
        "Save": function () {
          editorForm.saveForm();
          $(this).dialog("close")
        },
        Cancel: function () { $(this).dialog("close") }
      }
    });

  }

  function getWeekEnding () {
    var wkending;
    $(".datepicker").datepicker();
    $("#datepickerdialog").dialog({
      autoOpen: true,
      close: function () {
        wkending = $("#weekending").val();
      },
      show: {
        effect: "blind",
        duration: 1000
      },
      hide: {
        effect: "explode",
        duration: 1000
      }
    });
    return wkending;
  }

  return {
    loadTimesheet: load
  };

}());

Upvotes: 1

Related Questions