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

Reusing a Dialog with different validators

Expand Messages
  • ex_veritas
    Greetings! I have a dialog (defined in an html file, below), that I d like to use in two different scenarios. These scenarios are get members of an
    Message 1 of 2 , Sep 5, 2009
      Greetings!

      I have a dialog (defined in an html file, below), that I'd like to use in two different scenarios. These scenarios are "get members of an organization", and "get members of a group". The are three differences between them: (a)the text in three places (title, legend, label); (b)the validator; (c)the post data. The return JSON data has the same format, and can be displayed in the same datatable (using the same custom formatters).

      The issue is that the dialog works great, for one time. If I display the "organization" selector, it will work fine. If I then try to display the "group" selector, the dialog displays fine (with the updated text), but the validators appear to be chained (bad), and the postData is weird.

      I tried to use "destroy" on the dialog in the cancel callback on the button (with the intention of merely creating it again each time), but it removed the div defined in the html file, making it impossible to use again. I tried to move the defined div outside of the created container div and then remove the container div from the DOM (which works), but the underlying object still exists, so the problem isn't resolved.

      I tried creating the two scenarios as different objects, but it appears (I could be wrong) that internally the YUI dialog keeps a pointer by the div id, and thus the fact I have two different dialog objects created by the new YAHOO.widget.Dialog(...) doesn't matter.

      Is there anyway to accomplish re-using an HTML defined Dialog when the aforementioned things need to be varied. It seems wasteful to have to define another (duplicate) markup in the html file just to be able to vary a couple of parameters to a dialog.

      Thank you for your insight.
      Kevin


      HTML file
      <div id="divUsersListing" class=" hidden">
      <div class="hd">A Heading</div>
      <div class="bd">
      <form id="frmUsersListing" method="post"
      name="frmUsersListing"
      action="GetInfoXML.jsp">
      <fieldset>
      <legend id="lgndUsersListingCollection">A Legend</legend>
      <label id="lblUsersListingCollection" for="userCollection">Input</label>
      <input type="text" name="userCollection" id="userCollection" />
      <span style="float: right;">
      <a href="javascript:clearInputResultsForm('frmUsersListing','divUsersListingDT');">
      clear fields</a>
      </span>
      <span style="clear: both"></span>
      </fieldset>
      <fieldset>
      <legend id="lgndUsersListingMembers">Members</legend>
      <div id="divUsersListingPaginator"></div>
      <div id="divUsersListingDT"></div>
      </fieldset>
      </form>
      </div>
      </div>

      Excerpted Javascript

      YAHOO.kho.admin = function () {
      /**
      * @param title
      * The title of the dialog
      * @param legend
      * The text to display in the legend around the input field
      * @param label
      * The label text for the input field
      * @param fnSubmit
      * The function to call on submit
      * @param action
      * The action to execute that is specified in the post data
      */
      var listUsersInCollection = function(dlgObj, divId, title, legend, label,
      fnSubmit, fnValidate, action) {

      var div = divId;
      var ele;

      clearInputResultsForm('frmUsersListing', 'divUsersListingDT');

      if (dlgObj === null) {

      //
      // buttons; the "OK"/submit is linked on a listener, so we must use
      // the outer defined variable
      var usersListingBtn = {
      text : "Find",
      // id : "btnUsersInOrgOK",
      handler : fnSubmit,
      submit : true,
      type : "submit",
      isDefault : true
      };

      var btnUsersInOrgCancel = {
      text : "Cancel",
      // id : "btnUsersInOrgCancel",
      handler : handle_UsersListingCancel
      };

      var dlgButtons = [ usersListingBtn, btnUsersInOrgCancel ];

      //
      // set the title for the dialog
      //
      snlBase.setYUIDialogTitle(div, title);

      //
      // set the legend & label
      //
      ele = yud.get("lgndUsersListingCollection");
      snlBase.setTextNodeForElement(ele, legend);
      ele = yud.get("lblUsersListingCollection");
      snlBase.setTextNodeForElement(ele, label);

      //
      // options for the dialog
      //
      var opts = {
      width : "60em",
      effect : {
      effect : YAHOO.widget.ContainerEffect.FADE,
      duration : 0.25
      },
      fixedcenter : false,
      visible : false,
      draggable : true,
      close : true,
      modal : false,
      constraintoviewport : false,
      buttons : dlgButtons,
      postdata : "action=" + action,
      hideaftersubmit : false,
      xy : [ 10, 10 ]
      }; // opts

      dlgObj = new YAHOO.widget.Dialog(div, opts);

      //
      // options for the data table
      //
      var myDtOpts = {
      height : "30em",
      paginator : new YAHOO.widget.Paginator( {
      rowsPerPage : 20,
      containers : "divUsersListingPaginator",
      alwaysVisible : true
      }),
      scrollable : true,
      sortedBy : {
      key : "fullname",
      dir : YAHOO.widget.DataTable.CLASS_ASC
      }
      }; // opts

      //
      // set the callbacks
      //
      dlgObj.callback = {
      argument : {
      divId : usersListingReportDataTableDivId,
      dtOpts : myDtOpts,
      failHdr : "Failed to retrieve users"
      },
      success : handle_UsersListingSuccess,
      failure : handle_generalFailure
      };

      dlgObj.render();

      //
      // remove the hidden class if it is present; the hidden class
      // is necessary to keep it from displaying when the page is first
      // loaded
      ele = yud.get(div);
      if (ele !== null) {
      yud.removeClass(ele, cssClassHidden);
      }



      dlgObj.validate = fnValidate;

      } // if: the dialog is null



      dlgObj.show();


      return dlgObj;
      }; //listUsersInCollection


      var listUsersInGroup = function() {
      snlBase.clearDialogWrapper("divUsersListing");
      var title = "Show Users in Group";
      var legend = "Group";
      var label = "group:";
      var fnSubmit = handle_UsersInGroupSubmit;
      var fnValidate = validate_UsersInGroup;
      var action = "getUsersInGroup";

      groupUsersListingDlgObj =
      listUsersInCollection(groupUsersListingDlgObj,
      usersListingDialogDivId,
      title, legend, label, fnSubmit, fnValidate, action);
      }; //listUsersInGroup

      /**
      * Lists the users in a given organization
      *
      * @return
      */
      var listUsersInOrg = function() {
      snlBase.clearDialogWrapper("divUsersListing");
      var title = "List Users in Organization";
      var legend = "Organization";
      var label = "org:";
      var fnSubmit = handle_UsersInOrgSubmit;
      var fnValidate = validate_UsersInOrg;
      var action = "getUsersInOrg";

      orgUsersListingDlgObj =
      listUsersInCollection(orgUsersListingDlgObj,
      usersListingDialogDivId,
      title, legend, label, fnSubmit, fnValidate, action);

      }; // listUsersInOrg

      }; //admin
    • Satyen Desai
      Hi, If you have a URL I could look at, we can probably get to the bottom of this pretty quickly, however scanning through the snippet you provided, it seems
      Message 2 of 2 , Sep 11, 2009
        Hi,

        If you have a URL I could look at, we can probably get to the bottom
        of this pretty quickly, however scanning through the snippet you
        provided, it seems like you're creating 2 instances of the Dialog,
        using the same DIV, as opposed to 1 instance, which then switches out
        the form content or postdata, text and validation routines, which is
        the way to go:
        > groupUsersListingDlgObj =
        > listUsersInCollection(groupUsersListingDlgObj,
        > usersListingDialogDivId,
        > title, legend, label, fnSubmit, fnValidate, action);
        >

        > orgUsersListingDlgObj =
        > listUsersInCollection(orgUsersListingDlgObj,
        > usersListingDialogDivId,
        > title, legend, label, fnSubmit, fnValidate, action);
        >

        The div is "usersListingDialogDivid" for both, but you're passing in a
        different dlg objects ("groupsUsersListingDlgObj" and
        "orgUsersListingDlgObj") so you're lazy construction null check
        iniside listUsersInCollection() is not going prevent 2 dialogs from
        being created which both share the same DIV, and hence will break.

        You should be able to re-use a dialog with the parameters you mention
        modified, and you're right, this is the way to go. It's just that you
        want to use 1 instance of a Dialog, and flip the pieces which change
        between the 2 use cases, as opposed to creating 2 instances which
        share the same markup [ if that's what is actually going on ]

        Hope that makes sense. As mentioned if you want to post a URL, I can
        verify this for you.

        Regards,
        Satyen

        On Sep 5, 2009, at 11:39 AM, ex_veritas wrote:

        > Greetings!
        >
        > I have a dialog (defined in an html file, below), that I'd like to
        > use in two different scenarios. These scenarios are "get members of
        > an organization", and "get members of a group". The are three
        > differences between them: (a)the text in three places (title,
        > legend, label); (b)the validator; (c)the post data. The return JSON
        > data has the same format, and can be displayed in the same datatable
        > (using the same custom formatters).
        >
        > The issue is that the dialog works great, for one time. If I display
        > the "organization" selector, it will work fine. If I then try to
        > display the "group" selector, the dialog displays fine (with the
        > updated text), but the validators appear to be chained (bad), and
        > the postData is weird.
        >
        > I tried to use "destroy" on the dialog in the cancel callback on the
        > button (with the intention of merely creating it again each time),
        > but it removed the div defined in the html file, making it
        > impossible to use again. I tried to move the defined div outside of
        > the created container div and then remove the container div from the
        > DOM (which works), but the underlying object still exists, so the
        > problem isn't resolved.
        >
        > I tried creating the two scenarios as different objects, but it
        > appears (I could be wrong) that internally the YUI dialog keeps a
        > pointer by the div id, and thus the fact I have two different dialog
        > objects created by the new YAHOO.widget.Dialog(...) doesn't matter.
        >
        > Is there anyway to accomplish re-using an HTML defined Dialog when
        > the aforementioned things need to be varied. It seems wasteful to
        > have to define another (duplicate) markup in the html file just to
        > be able to vary a couple of parameters to a dialog.
        >
        > Thank you for your insight.
        > Kevin
        >
        > HTML file
        > <div id="divUsersListing" class=" hidden">
        > <div class="hd">A Heading</div>
        > <div class="bd">
        > <form id="frmUsersListing" method="post"
        > name="frmUsersListing"
        > action="GetInfoXML.jsp">
        > <fieldset>
        > <legend id="lgndUsersListingCollection">A Legend</legend>
        > <label id="lblUsersListingCollection" for="userCollection">Input</
        > label>
        > <input type="text" name="userCollection" id="userCollection" />
        > <span style="float: right;">
        > <a
        > href
        > =
        > "javascript:clearInputResultsForm
        > ('frmUsersListing','divUsersListingDT');">
        > clear fields</a>
        > </span>
        > <span style="clear: both"></span>
        > </fieldset>
        > <fieldset>
        > <legend id="lgndUsersListingMembers">Members</legend>
        > <div id="divUsersListingPaginator"></div>
        > <div id="divUsersListingDT"></div>
        > </fieldset>
        > </form>
        > </div>
        > </div>
        >
        > Excerpted Javascript
        >
        > YAHOO.kho.admin = function () {
        > /**
        > * @param title
        > * The title of the dialog
        > * @param legend
        > * The text to display in the legend around the input field
        > * @param label
        > * The label text for the input field
        > * @param fnSubmit
        > * The function to call on submit
        > * @param action
        > * The action to execute that is specified in the post data
        > */
        > var listUsersInCollection = function(dlgObj, divId, title, legend,
        > label,
        > fnSubmit, fnValidate, action) {
        >
        > var div = divId;
        > var ele;
        >
        > clearInputResultsForm('frmUsersListing', 'divUsersListingDT');
        >
        > if (dlgObj === null) {
        >
        > //
        > // buttons; the "OK"/submit is linked on a listener, so we must use
        > // the outer defined variable
        > var usersListingBtn = {
        > text : "Find",
        > // id : "btnUsersInOrgOK",
        > handler : fnSubmit,
        > submit : true,
        > type : "submit",
        > isDefault : true
        > };
        >
        > var btnUsersInOrgCancel = {
        > text : "Cancel",
        > // id : "btnUsersInOrgCancel",
        > handler : handle_UsersListingCancel
        > };
        >
        > var dlgButtons = [ usersListingBtn, btnUsersInOrgCancel ];
        >
        > //
        > // set the title for the dialog
        > //
        > snlBase.setYUIDialogTitle(div, title);
        >
        > //
        > // set the legend & label
        > //
        > ele = yud.get("lgndUsersListingCollection");
        > snlBase.setTextNodeForElement(ele, legend);
        > ele = yud.get("lblUsersListingCollection");
        > snlBase.setTextNodeForElement(ele, label);
        >
        > //
        > // options for the dialog
        > //
        > var opts = {
        > width : "60em",
        > effect : {
        > effect : YAHOO.widget.ContainerEffect.FADE,
        > duration : 0.25
        > },
        > fixedcenter : false,
        > visible : false,
        > draggable : true,
        > close : true,
        > modal : false,
        > constraintoviewport : false,
        > buttons : dlgButtons,
        > postdata : "action=" + action,
        > hideaftersubmit : false,
        > xy : [ 10, 10 ]
        > }; // opts
        >
        > dlgObj = new YAHOO.widget.Dialog(div, opts);
        >
        > //
        > // options for the data table
        > //
        > var myDtOpts = {
        > height : "30em",
        > paginator : new YAHOO.widget.Paginator( {
        > rowsPerPage : 20,
        > containers : "divUsersListingPaginator",
        > alwaysVisible : true
        > }),
        > scrollable : true,
        > sortedBy : {
        > key : "fullname",
        > dir : YAHOO.widget.DataTable.CLASS_ASC
        > }
        > }; // opts
        >
        > //
        > // set the callbacks
        > //
        > dlgObj.callback = {
        > argument : {
        > divId : usersListingReportDataTableDivId,
        > dtOpts : myDtOpts,
        > failHdr : "Failed to retrieve users"
        > },
        > success : handle_UsersListingSuccess,
        > failure : handle_generalFailure
        > };
        >
        > dlgObj.render();
        >
        > //
        > // remove the hidden class if it is present; the hidden class
        > // is necessary to keep it from displaying when the page is first
        > // loaded
        > ele = yud.get(div);
        > if (ele !== null) {
        > yud.removeClass(ele, cssClassHidden);
        > }
        >
        > dlgObj.validate = fnValidate;
        >
        > } // if: the dialog is null
        >
        > dlgObj.show();
        >
        > return dlgObj;
        > }; //listUsersInCollection
        >
        >
        > var listUsersInGroup = function() {
        > snlBase.clearDialogWrapper("divUsersListing");
        > var title = "Show Users in Group";
        > var legend = "Group";
        > var label = "group:";
        > var fnSubmit = handle_UsersInGroupSubmit;
        > var fnValidate = validate_UsersInGroup;
        > var action = "getUsersInGroup";
        >
        > groupUsersListingDlgObj =
        > listUsersInCollection(groupUsersListingDlgObj,
        > usersListingDialogDivId,
        > title, legend, label, fnSubmit, fnValidate, action);
        > }; //listUsersInGroup
        >
        > /**
        > * Lists the users in a given organization
        > *
        > * @return
        > */
        > var listUsersInOrg = function() {
        > snlBase.clearDialogWrapper("divUsersListing");
        > var title = "List Users in Organization";
        > var legend = "Organization";
        > var label = "org:";
        > var fnSubmit = handle_UsersInOrgSubmit;
        > var fnValidate = validate_UsersInOrg;
        > var action = "getUsersInOrg";
        >
        > orgUsersListingDlgObj =
        > listUsersInCollection(orgUsersListingDlgObj,
        > usersListingDialogDivId,
        > title, legend, label, fnSubmit, fnValidate, action);
        >
        > }; // listUsersInOrg
        >
        > }; //admin
        >
        >
        >
      Your message has been successfully submitted and would be delivered to recipients shortly.