timbck2
timbck2

Reputation: 1066

Error when inline Javascript is moved to external file - how can I fix this?

There are dozens of similar questions here on stackoverflow, but I can't find an answer that works. I have a couple of Javascript functions that I'm using repeatedly in multiple pages, so I thought it would be a good idea to move them to external file(s). But when I do, they don't work.

Here are the two functions I currently have in (separate, for now) external files:

function MessageDialog(obj, title, dialogText) {
  //add the dialog div to the page
  $('body').append(String.Format("<div id='messageDialog' title='{0}'><p>{1}</p></div>", title, dialogText));
  //create the dialog
  $('#messageDialog').dialog({
    modal: true,
    resizable: false,
    draggable: false,
    close: function(event, ui) { $('body').find('#messageDialog').remove(); },
    buttons:
      {
        'OK': function() {
          $(this).dialog('close');
        }
      }
  });
}

//Confirmation dialog
function ConfirmationDialog(obj, title, dialogText, okButtonText, cancelButtonText) {
  var confirmed = false;
  if (!confirmed) {
    //add the dialog div to the page
    $('body').append(String.Format("<div id='confirmationDialog' title='{0}'><p>{1}</p></div>", title, dialogText));
    //create the dialog
    $('#confirmationDialog').dialog({
      modal: true,
      resizable: false,
      draggable: false,
      close: function(event, ui) { $('body').find('#confirmationDialog').remove(); },
      buttons:
        {
          $okButtonText: function() {
            $(this).dialog('close');
            confirmed = true;
            if (obj) obj.click();
          },
          $cancelButtonText: function() {
            $(this).dialog('close');
          }
        }
      });
    }
    return confirmed;
}

I'm calling ConfirmationDialog() from an OnClientClick event (in ASP.NET):

MessageDialog() is called from code-behind if there's an error on the btnDelIncident_Click event:

private void DisplayMessageDialog(string msgTitle, string msgText)
{
  StringBuilder msg = new StringBuilder();
  msg.AppendLine("<script type='text/javascript'>");
  msg.AppendFormat("  MessageDialog(this, '{0}', '{1}');" + System.Environment.NewLine, msgTitle, msgText);
  msg.AppendLine("</script>");
  ClientScript.RegisterStartupScript(this.GetType(), "messageDialog", msg.ToString());
}

I'm not getting an error from the ConfirmationDialog() call (though the dialog is not appearing), but the MessageDialog() call (from the code-behind) results in an "Uncaught ReferenceError: MessageDialog is not defined" in the Javascript console.

I'm including the two external Javascript files in the <head> tag, and they're after the jQuery includes:

<script type="text/javascript" src="/Scripts/ConfirmationDialog.js"></script>
<script type="text/javascript" src="/Scripts/MessageDialog.js"></script>

I've also tried putting these two <script> tags at the end of the page, but it made no difference. What am I doing wrong?

EDIT: I was able to solve the dialog box problem by wrapping the functions in (function($) { }); as Neil suggested. Here's the final, working function (declared in an external .js file):

//Confirmation dialog
(function($) {
  var confirmed = false;
  ConfirmationDialog = function(obj, title, dialogText, okButtonText, cancelButtonText) {
    if (!confirmed) {
      //add the dialog div to the page
      $('body').append(String.Format("<div id='confirmationDialog' title='{0}'><p>{1}</p></div>", title, dialogText));
      //create the dialog
      $('#confirmationDialog').dialog({
        modal: true,
        resizable: false,
        draggable: false,
        close: function(event, ui) { $('body').find('#confirmationDialog').remove(); },
        buttons:
        [{
          text: okButtonText,
          click: function() {
              $(this).dialog('close');
              confirmed = true;
              if (obj) obj.click();
           }
         },
         {
           text: cancelButtonText,
           click: function() {
            $(this).dialog('close');
           }
         ]}
      });
    }
    return confirmed;
  };
})(jQuery);

Upvotes: 1

Views: 996

Answers (2)

Dennis Flagg
Dennis Flagg

Reputation: 664

This should help. You need to wait until the DOM is loaded before referencing an element in the MessageDialog client-side method

  private void DisplayMessageDialog(string msgTitle, string msgText)
    {
      StringBuilder msg = new StringBuilder();
      msg.AppendLine("<script type='text/javascript'>");
      msg.AppendFormat("jQuery(function($) { MessageDialog(this, '{0}', '{1}'); });" + System.Environment.NewLine, msgTitle, msgText);
      msg.AppendLine("</script>");
      ClientScript.RegisterStartupScript(this.GetType(), "messageDialog", msg.ToString());
    }

Upvotes: 0

Neil Girardi
Neil Girardi

Reputation: 4933

You definitely do not want to place script tags in an external JavaScript file. Script tags are HTML elements and a .js file is not HTML. Try wrapping your code in an Immediately Invoked Function Expression:

(function() {

    // your code here    

})();

If you are binding function calls to events on DOM nodes, such as 'click' or 'hover' you should make sure the DOM is ready before executing those bindings. jQuery has a method called .ready() which can be used for this:

$(document).ready(function() {
});

Upvotes: 1

Related Questions