New Item not being added to JavaScript collection

Scott Baldridge
Scott Baldridge used Ask the Experts™
on
Hello, I'm new to JavaScript and attempting to make a component to allow users to add URL links to a collection that will be saved to a database.
With my attached code I'm having issues with my _addToLinksList function in that the new link is not added to my _linksStorage collection. When I step through the  _addToLinksList function the expected values are present but the new link is not added.

I could use some pointers as to why and perhaps some help in fixing the issue. Any help is appreciated.


 function LinksManager() {

            var hdnSelectedLinksSelector = "#" + "<%=hdnSelectedLinks.ClientID%>";
            var tblLinksListSelector = "#tblLinks";
            var delLinkSelector = ".delLink";
            var modLinkSelector = ".modLink";
            var addLinkSelector = "#addLinksLink";
            var hdnLinkIdClassSelector = "input.linkId";
            var modifyDialogSelector = "#linksDialog";
            var linkNameSelector = "#linkName";
            var linkUrlSelector = "#linkUrl";
            var linksListItemClassSelector = ".linksListItem";
            var linksListItemTemplateSelector = ".linksListItem-template";
            var tdLinksListContainerSelector = "tdLinksListContainer";
            var _currentLinkForModifyId;

            var _linksStorage = [];

            var _dialogValidationManager = new ValidationManager(undefined, "linksDialogErrorMessages");
            _dialogValidationManager.forseOnChange = false;

            var _linksValidationManager = new ValidationManager(undefined, globalValidationManager.getErrorMessageContainerSelector().substring(1));
            new RequiredHiddenValidator(hdnSelectedLinksSelector, tdLinksListContainerSelector, undefined, _linksValidationManager);

            function _initLinksStorage() {
                var linksList = JSON.parse($(hdnSelectedLinksSelector).val());
                if (linksList) {
                    for (var i = 0; i < linksList.length; i++) {
                        _linksStorage[linksList[i].Id] = linksList[i];
                    }
                }
            }

            function getLinksStorageIds() {
                var ids = [];
                for (var k in _linksStorage) {
                    ids.push(k);
                }
                return ids;
            }

            function _onDelLinkClick() {
                var $listItemTr = $(this).closest(linksListItemClassSelector);
                var lnkId = $listItemTr.find(hdnLinkIdClassSelector).val();
                delete _linksStorage[lnkId];
                $listItemTr.remove();

            }

            function _openDialog(linkForModifyId) {
                _currentLinkForModifyId = linkForModifyId;
                $(modifyDialogSelector).dialog("open");
            }

            function _setDialogFields(linkForModifyId) {
                var lnk = _linksStorage[linkForModifyId];
                $(linkNameSelector).val(lnk.name);
                $(linkUrlSelector).val(lnk.url);
            }

            function _getLinkFromDialogFields() {
                return {
                    name: $(linkNameSelector).val(),
                    url: $(linkUrlSelector).val()
                };

            }

            function _clearDialogFields() {
                $(modifyDialogSelector).find("input").val("");
            }

            function _addToLinksList(lnk) {
                var $listTr = $(linksListItemTemplateSelector).clone();
                $listTr.find(linkNameSelector).text(lnk.name);
                $listTr.find(linkUrlSelector).text(lnk.url);
                $listTr.find(hdnLinkIdClassSelector).val(lnk.Id);
                $listTr.attr("class", linksListItemClassSelector.substring(1));
                $listTr.appendTo(tblLinksListSelector);
                var $sortedTrs = $(linksListItemClassSelector).sort(_customSort);
                $(linksListItemClassSelector).remove();
                $sortedTrs.appendTo(tblLinksListSelector);
            }

            function _customSort(a, b) {
                var nameA = $(linkNameSelector, $(a)).text().toLowerCase();
                var nameB = $(linkNameSelector, $(b)).text().toLowerCase();
                return nameA > nameB ? 1 : -1;
            }

            function _onDialogApply() {
                if (!_dialogValidationManager.validate()) {
                    return;
                }

                var lnk = _getLinkFromDialogFields();

                _linksStorage[lnk.id] = lnk;
                if (!_currentLinkForModifyId) {
                    _addToLinksList(lnk);
                }
                $(modifyDialogSelector).dialog("close");
                _linksValidationManager.discardErrors();
            }

            function _initDialog() {
                $(modifyDialogSelector).dialog({
                    autoOpen: false,
                    width: 400,
                    position: ['center', 100],
                    modal: true,
                    buttons: {
                        "Apply": _onDialogApply,
                        "Cancel": function () { $(this).dialog("close"); }
                    },
                    create: function () {
                        new RequiredValidator(linkNameSelector, undefined, _dialogValidationManager);
                        new RequiredValidator(linkUrlSelector, undefined, _dialogValidationManager);
                    },
                    open: function () {
                        _dialogValidationManager.discardErrors();
                        if (_currentLinkForModifyId) {
                            _setDialogFields(_currentLinkForModifyId);
                        } else {
                            _clearDialogFields();
                        }
                    }
                });
            }

            return {
                onPageLoaded: function () {
                    $(tblLinks).on("click", delLinkSelector, _onDelLinkClick);
                    $(tblLinks).on("click", modLinkSelector, function () {
                        _openDialog($(this).closest("tr").find(hdnLinkIdClassSelector).val());
                    });
                    $(addLinkSelector).click(_openDialog.bind(this, null));
                    _initDialog();
                    _initLinksStorage();
                },
                saveLinksStorage: function () {
                    var lnkArray = $.map(_linksStorage, function (res) {
                        return res;
                    });
                    var data = lnkArray.length === 0 ? null : JSON.stringify(lnkArray);

                    $(hdnSelectedLinksSelector).val(data);
                },
                getRequiredValidationManager: function () {
                    return _linksValidationManager;
                }
            };
        }



<td id="tdLinksListContainer" colspan="2" valign="top">
                                <span class="markedOutText">Contact Links:&nbsp;</span>
                                <div style="float: right;"><a id="addLinksLink" href="#">Add Link</a></div>
                                <input type="hidden" runat="server" id="hdnSelectedLinks" />
                                <table id="tblLinks" width="100%">
                                    <colgroup>
                                        <col width="80%" />
                                    </colgroup>
                                    <tr class="subLabel">
                                        <td>Name</td>
                                        <td class="tdAction">Actions</td>
                                    </tr>
                                        <%foreach (var lnk in Links)
                                      {%>
                                    <tr class="linksListItem<%=lnk.Id==0 ? "-template" : string.Empty  %>">
                                        <td>
                                            <a target="_blank" href="<%=lnk.Url%>"><%=lnk.Name%></a>

                                            <input type="hidden" class="linkId" value="<%=lnk.Id %>" />
                                        </td>
                                        <td class="tdAction"><a class="delLink" href="#"><%=AppResources.Resources.Common_DelLink%></a>
                                            <a class="modLink" href="#"><%=AppResources.Resources.Common_ModLink%></a></td>

                                    </tr>
                                    <% } %>
                                </table>
                            </td>


<%--Links Dialog--%>
    <div id="linksDialog" class="ui-helper-hidden" title="Add / Modify Link">
        <div class="linksDialogErrorMessages"></div>
        <table id="tblLink" width="100%">
            <tr>
                <td>Name:</td>
                <td>
                    <input type="text" id="linkName" class="text required" />
                </td>
            </tr>
            <tr>
                <td>URL:</td>
                <td>
                    <input type="text" id="linkUrl" class="text required" />
                </td>
            </tr>
        </table>
    </div>

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
var linksListItemTemplateSelector = ".linksListItem-template";
...
var $listTr = $(linksListItemTemplateSelector).clone();

Open in new window

I can't find the .linksListItem-template item in the source you provided.

What might be happening is that your template is hidden (display: none) but when you add your links you are not showing the cloned item after appending it. So try

...
$listTr.appendTo(tblLinksListSelector).show();
...

Open in new window

Author

Commented:
Hello Julian, sorry it took so long to get back to you. .linksListItem-template is near the bottom.

 <tr class="linksListItem<%=lnk.Id==0 ? "-template" : string.Empty  %>">

I tried this to see what would happen if I did this:    $listTr.appendTo(tblLinksListSelector).show();
and what it does is duplicate the existing rows. It does not add the new row.
I do not see what the new row(lnk) is being added to the collection _linksStorage so I attempted to add in this way  _linksStorage.push(lnk);
I see that the new row is in the collection but it does not appear on the screen.

 What am I missing here?
Most Valuable Expert 2017
Distinguished Expert 2018
Commented:
What am I missing here?
Pretty sure it is the show()
Having looked at your code I see you are using appendTo which means the .show needs to be appled to the principle object - not the parameter like this

$listTr.appendTo(tblLinksListSelector).show();

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial