Loading ...
Sorry, an error occurred while loading the content.

Re: Modal dialogs, keylisteners and getData - a new JS class

Expand Messages
  • Christian Tiberg
    Hello! I found an error in the getData method in the CSDialog class that I posted here before. The issue was radios that returned a NodeList with two elements.
    Message 1 of 2 , Aug 18, 2008
    • 0 Attachment
      Hello!

      I found an error in the getData method in the CSDialog class that I posted here before. The issue was radios that returned a NodeList with two elements.

      The change needed is to replace this:

          oElement = [aElements[sName]];

      with this:

          oElement = aElements[sName];
          if (typeof oElement.length == "undefined")
              oElement = [oElement];

      Here's the revised getData method in its entirety:

          getData: function () {
         
                  var oForm = this.form,
                          aElements,
                          nTotalElements,
                          oData,
                          sName,
                          oElement,
                          nElements,
                          sType,
                          sTagName,
                          aOptions,
                          nOptions,
                          aValues,
                          oOption,
                          sValue,
                          oRadio,
                          oCheckbox,
                          i,
                          n;   

                  if (oForm) {
         
                          aElements = oForm.elements;
                          nTotalElements = aElements.length;
                          oData = {};

         
                          for (i = 0; i < nTotalElements; i++) {
         
                                  sName = aElements[i].name;
         
                                  /*
                                          Using "Dom.getElementsBy" to safeguard user from JS
                                          errors that result from giving a form field (or set of
                                          fields) the same name as a native method of a form
                                          (like "submit") or a DOM collection (such as the "item"
                                          method). Originally tried accessing fields via the
                                          "namedItem" method of the "element" collection, but
                                          discovered that it won't return a collection of fields
                                          in Gecko.
                                  */
         
                                  if (typeof sName != "undefined" && sName != "")
                                      {
                                          oElement = aElements[sName];
                                          if (typeof oElement.length == "undefined")
                                              oElement = [oElement];
                                      }
                                  else
                                      oElement = [];
                                  nElements = oElement.length;
         
                                  if (nElements > 0) {
         
                                          if (nElements == 1) {
         
                                                  oElement = oElement[0];
         
                                                  sType = oElement.type;
                                                  sTagName = oElement.tagName.toUpperCase();
         
                                                  switch (sTagName) {
         
                                                  case "INPUT":

                                                          if (sType == "checkbox") {

                                                                  oData[sName] = oElement.checked;

                                                          }
                                                          else if (sType != "radio") {

                                                                  oData[sName] = oElement.value;

                                                          }

                                                          break;

                                                  case "TEXTAREA":

                                                          oData[sName] = oElement.value;

                                                          break;

                                                  case "SELECT":

                                                          aOptions = oElement.options;
                                                          nOptions = aOptions.length;
                                                          aValues = [];

                                                          for (n = 0; n < nOptions; n++) {

                                                                  oOption = aOptions[n];

                                                                  if (oOption.selected) {

                                                                          sValue = oOption.value;

                                                                          if (!sValue || sValue === "") {

                                                                                  sValue = oOption.text;

                                                                          }

                                                                          aValues[aValues.length] = sValue;

                                                                  }

                                                          }

                                                          oData[sName] = aValues;

                                                          break;
         
                                                  }
         
         
                                          }
                                          else {
         
                                                  sType = oElement[0].type;
         
                                                  switch (sType) {
         
                                                  case "radio":

                                                          for (n = 0; n < nElements; n++) {

                                                                  oRadio = oElement[n];

                                                                  if (oRadio.checked) {

                                                                          oData[sName] = oRadio.value;
                                                                          break;

                                                                  }

                                                          }

                                                          break;

                                                  case "checkbox":

                                                          aValues = [];

                                                          for (n = 0; n < nElements; n++) {

                                                                  oCheckbox = oElement[n];

                                                                  if (oCheckbox.checked) {

                                                                          aValues[aValues.length] =
                                                                                  oCheckbox.value;

                                                                  }

                                                          }

                                                          oData[sName] = aValues;

                                                          break;
         
                                                  }
         
                                          }
         
                                  }
         
                          }
         
                  }
       
                  return oData;
         
          }



      Best regards,
      Christian Tiberg


      2008/8/15 Christian Tiberg <ctiberg@...>
      Hello everyone!

      Below is a try to make sense of the mess that is caused by modal dialogs in layers. That is two or more modal dialogs, active at the same time,

      The first thing this does is handling KeyListener objects. Only the topmost dialog is considered "active", and only its listeners should respond, but a KeyListener attached to the document doesn't know that.

      It also hooks into showMaskEvent/hideMaskEvent to preserve the modality and only really have the topmost dialog show its mask.

      The class also contains an overridden getData method, addressing the woeful slowness of the getData of the YAHOO.widget.Dialog class on crowded pages.

      I could've overridden a lot more functions, but I wrote the class in stages. The functions with names ending in CS should really be replaced by overriding the inherited function, but calls to these methods are all over the place in the rest of the system we're making.

      I really hope that someone out there finds this useful. This is my first real javascript class, so please feel free to critique it - I've learned a lot, and hope to learn lots more :)

      var dlgStack = new Array();
      var activeDlg = null;
      var overlayMan = new YAHOO.widget.OverlayManager();

      CSDialog = function(el, userConfig)
      {
          CSDialog.superclass.constructor.call(this, el, userConfig);
          this.initCS();
      };

      YAHOO.extend(CSDialog, YAHOO.widget.Dialog, {
          handleSubmit: function()
          {
              return false;
          },
         
          handleCancel: function()
          {
              return true;
          },

          initCS: function()
          {
              overlayMan.register(this);
             
              this.showMaskEvent.subscribe(function() {
                  YAHOO.util.Dom.addClass(this.element, "yui-panel-modal");
                  var behind = this.getDialogBehind();
                  if (behind != null) behind.hideMask();
              }, this, true);
              this.hideMaskEvent.subscribe(function() {
                  YAHOO.util.Dom.removeClass(this.element, "yui-panel-modal");
                  var behind = this.getDialogBehind();
                  if (behind != null) behind.hideMask();
              }, this, true);
          },
         
          getDialogBehind: function()
          {
              if (this.isActiveDialog())   
                  if (dlgStack.length > 1)
                      return dlgStack[dlgStack.length - 2];
                  else
                      return null;
              else
                  return null;
          },
         
          showCS: function()
          {
              this.show();
              dlgStack.push(this);
              activeDlg = this;
              overlayMan.bringToTop(this);
          },
         
          hideCS: function()
          {
              if (this.isActiveDialog())
                  {
                      dlgStack.pop();
                      if (dlgStack.length > 0)
                          activeDlg = dlgStack[dlgStack.length - 1];
                      else
                          activeDlg = null;
                  }
              this.hide();
          },
         
          cancelCS: function()
          {
              if (this.isActiveDialog())
                  {
                      dlgStack.pop();
                      if (dlgStack.length > 0)
                          activeDlg = dlgStack[dlgStack.length - 1];
                      else
                          activeDlg = null;
                  }
              this.cancel();
          },
         
          submitCS: function()
          {
              if (this.isActiveDialog())
                  {
                      dlgStack.pop();
                      if (dlgStack.length > 0)
                          activeDlg = dlgStack[dlgStack.length - 1];
                      else
                          activeDlg = null;
                  }
              this.submit();
          },

          isActiveDialog: function()
          {
              return this == activeDlg;
          },
         
          enterPressed: function()
          {
              if (this.isActiveDialog())
                  if (this.handleSubmit())
                      this.submitCS();
          },
         
          escPressed: function()
          {
              if (this.isActiveDialog())
                  if (this.handleCancel())
                      this.cancelCS();
          },

          getData: function () {
         
                  var oForm = this.form,
                          aElements,
                          nTotalElements,
                          oData,
                          sName,
                          oElement,
                          nElements,
                          sType,
                          sTagName,
                          aOptions,
                          nOptions,
                          aValues,
                          oOption,
                          sValue,
                          oRadio,
                          oCheckbox,
                          i,
                          n;   

                  if (oForm) {
         
                          aElements = oForm.elements;
                          nTotalElements = aElements.length;
                          oData = {};

         
                          for (i = 0; i < nTotalElements; i++) {
         
                                  sName = aElements[i].name;
         
                                  /*
                                          Using "Dom.getElementsBy" to safeguard user from JS
                                          errors that result from giving a form field (or set of
                                          fields) the same name as a native method of a form
                                          (like "submit") or a DOM collection (such as the "item"
                                          method). Originally tried accessing fields via the
                                          "namedItem" method of the "element" collection, but
                                          discovered that it won't return a collection of fields
                                          in Gecko.
                                  */
         
                                  if (typeof sName != "undefined" && sName != "")
                                      oElement = [aElements[sName]];
                                  else
                                      oElement = [];
                                  nElements = oElement.length;
         
                                  if (nElements > 0) {
         
                                          if (nElements == 1) {
         
                                                  oElement = oElement[0];
         
                                                  sType = oElement.type;
                                                  sTagName = oElement.tagName.toUpperCase();
         
                                                  switch (sTagName) {
         
                                                  case "INPUT":

                                                          if (sType == "checkbox") {

                                                                  oData[sName] = oElement.checked;

                                                          }
                                                          else if (sType != "radio") {

                                                                  oData[sName] = oElement.value;

                                                          }

                                                          break;

                                                  case "TEXTAREA":

                                                          oData[sName] = oElement.value;

                                                          break;

                                                  case "SELECT":

                                                          aOptions = oElement.options;
                                                          nOptions = aOptions.length;
                                                          aValues = [];

                                                          for (n = 0; n < nOptions; n++) {

                                                                  oOption = aOptions[n];

                                                                  if (oOption.selected) {

                                                                          sValue = oOption.value;

                                                                          if (!sValue || sValue === "") {

                                                                                  sValue = oOption.text;

                                                                          }

                                                                          aValues[aValues.length] = sValue;

                                                                  }

                                                          }

                                                          oData[sName] = aValues;

                                                          break;
         
                                                  }
         
         
                                          }
                                          else {
         
                                                  sType = oElement[0].type;
         
                                                  switch (sType) {
         
                                                  case "radio":

                                                          for (n = 0; n < nElements; n++) {

                                                                  oRadio = oElement[n];

                                                                  if (oRadio.checked) {

                                                                          oData[sName] = oRadio.value;
                                                                          break;

                                                                  }

                                                          }

                                                          break;

                                                  case "checkbox":

                                                          aValues = [];

                                                          for (n = 0; n < nElements; n++) {

                                                                  oCheckbox = oElement[n];

                                                                  if (oCheckbox.checked) {

                                                                          aValues[aValues.length] =
                                                                                  oCheckbox.value;

                                                                  }

                                                          }

                                                          oData[sName] = aValues;

                                                          break;
         
                                                  }
         
                                          }
         
                                  }
         
                          }
         
                  }
       
                  return oData;
         
          }
      });

      Best regards,
      Christian Tiberg

    Your message has been successfully submitted and would be delivered to recipients shortly.