提取选择列表的值并使用它来搜索ID值会导致所有剩余的JavaScript失效

Pulling the value of a select list and using it to search for an ID value causes all remaining JavaScript to die

本文关键字:失效 JavaScript 搜索 列表 选择 提取 ID      更新时间:2023-09-26

所以我有一个带有下拉菜单的表单,它提供了国家列表。从中,我希望下拉列表显示其他各种形式的元素,具体取决于所选的国家:

<div class="form-group col-sm-6">
  <label class="control-label" for="CountryId">Country</label>
  <select class="form-control" id="CountryId" name="CountryId"><option value="">&#171; ‹ Select › &#187;</option>
    <option value="6793d318-4a5f-430f-8f39-3d4101a7b9c7">Canada</option>
    <option value="4d60e0c3-6e52-4e36-903d-475527b1096b">United States of America</option>
    <option disabled="disabled" value="">--------------------</option>
    <option value="00000000-0000-0000-0000-000000000000">Not Listed, Specify Below:</option>
  </select>
</div>
<div id="address-switcher">
  <div class="address-switch" id="6793d318-4a5f-430f-8f39-3d4101a7b9c7">
    <div class="form-group col-sm-6">
      <label class="control-label" for="ProvinceId">Province</label>
      <select class="form-control" id="ProvinceId" name="ProvinceId"><option value="">&#171; ‹ Select › &#187;</option>
        <option value="9efb1f88-3bb1-405c-9424-6e13d9b07e2f">Alberta</option>
        <option value="5016c6c0-4d8e-442b-a038-c1a70f0839a2">British Columbia</option>
        <option value="7d65582d-5ca5-45f9-9821-9e2d19a8a6a6">Manitoba</option>
        <option value="76d82f69-a381-4365-8938-b198d62844c9">New Brunswick</option>
        <option value="00604e94-ff78-4d59-bdc2-9f3ca5029afd">Newfoundland and Labrador</option>
        <option value="5dec188a-ae59-49f8-add7-9234feb4bc0f">NorthwestTerritories</option>
        <option value="03461d4d-bdaa-4816-8155-80647ab69c83">Nova Scotia</option>
        <option value="3d2be9b8-2241-4884-8ab5-b6243a9dadc8">Nunavut</option>
        <option value="0e37c496-fa7c-449c-b155-afaf7595eda7">Ontario</option>
        <option value="47550c26-a214-429a-a649-7958bc3f7479">Prince Edward Island</option>
        <option value="1f05662e-4bb7-4f5e-9d5f-e061cdf91c34">Quebec</option>
        <option value="34446020-dd4d-4205-bf2d-34a6d413393e">Saskatchewan</option>
        <option value="291363c1-0710-4127-ab47-429f2a18fbe0">Yukon</option>
      </select>
    </div>
    <div class="clearfix"></div>
    <div class="form-group col-sm-6">
      <label class="control-label" for="PostalCode">Postal Code</label>
      <input class="form-control postalcode text-box single-line" id="PostalCode" maxlength="7" name="PostalCode" type="text" value="" />
    </div>
  </div>
  <div class="address-switch" id="4d60e0c3-6e52-4e36-903d-475527b1096b">
    <div class="form-group col-sm-6">
      <label class="control-label" for="StateId">State</label>
      <select class="form-control" id="StateId" name="StateId"><option value="">&#171; ‹ Select › &#187;</option>
        <option value="22ba78d5-19dc-4672-a20c-1963f56746ac">Alabama</option>
        <option value="9b4ccc2e-e915-4f2e-815a-0ee23cd138ec">Alaska</option>
        <option value="dad82c5b-6b07-4d91-914c-1eb4cc87c6b9">American Samoa</option>
        <option value="a5392b41-f397-473d-9bd9-fc32bd1c1547">Arizona</option>
        <option value="72284a46-6723-4b5c-b45d-9c21a403953e">Arkansas</option>
        <option value="ba55b550-3edd-4b62-bfc1-76ed46847504">California</option>
        <option value="ce60dd97-8810-402e-b235-93eb50603044">Colorado</option>
        <option value="39fd0461-eaee-411f-9b8a-ad887dd91114">Connecticut</option>
        <option value="80832622-2ea4-44f1-b916-8a20e1ed70ee">Delaware</option>
        <option value="7ce45642-6df6-4431-822f-711e97ce3456">District of Columbia</option>
        <option value="f1538bbe-0330-4ffc-b88f-8777dcf09a7a">Florida</option>
        <option value="2aa5b6a8-8f4d-43d4-a1f7-9cb8b3c8b0f5">Georgia</option>
        <option value="da5fbdf5-c77f-475b-ac6e-d1aedc06aeaa">Guam</option>
        <option value="bdeb60fd-ebba-4030-a233-c3ef6b6b605d">Hawaii</option>
        <option value="25bb34c0-a805-48f3-80b7-b968aabbea0e">Idaho</option>
        <option value="cd313f02-0862-489f-ace2-1add4059f974">Illinois</option>
        <option value="44f9ec68-60b0-4bd3-8004-7230f21bacfa">Indiana</option>
        <option value="0989d8da-64bd-44f0-a9a3-4505de785255">Iowa</option>
        <option value="657f0e60-1640-4276-b5a3-5d6d86bfd7c1">Kansas</option>
        <option value="18019d30-db69-4c17-b251-08c8ad21a190">Kentucky</option>
        <option value="eee674df-fdd3-46da-b57c-c5823498431c">Louisiana</option>
        <option value="6cf062dc-3eb4-41eb-b80c-c8f973ac5e1d">Maine</option>
        <option value="bc130b4b-333d-4229-a74c-4888e903fd56">Maryland</option>
        <option value="64e79a3c-276d-4b12-bdce-f2adc892c93c">Massachusetts</option>
        <option value="d0ff1d8a-6ff8-4b20-90c4-083cb55e16a5">Michigan</option>
        <option value="721a4dcc-6900-4fdd-89bd-88265cb9060f">Minnesota</option>
        <option value="2b5d697d-307d-498d-b37e-ae96c56ebf25">Mississippi</option>
        <option value="1dabfd8d-c338-405d-8927-dae85377fa32">Missouri</option>
        <option value="6bef1ad3-430a-42f1-8ae2-87f369c68e47">Montana</option>
        <option value="e220607c-8fc1-4025-ae5b-5aa09398cac9">Nebraska</option>
        <option value="45b7ffe5-b1a2-464a-a714-ed4c4a1e61c2">Nevada</option>
        <option value="4c43f48b-28d1-4366-9167-b6ca09403ba0">New Hampshire</option>
        <option value="655e1cfc-5bae-4044-9c9f-c6d6e5e87db7">New Jersey</option>
        <option value="a690c066-47dd-497a-a7ca-f49bdd78b6b0">New Mexico</option>
        <option value="dbf065d5-e5dd-4d38-b70c-4cc54df13b12">New York</option>
        <option value="bf0d8aa6-b22e-424e-a68d-efbca31847cf">North Carolina</option>
        <option value="794e2fed-bea2-4dd9-8b43-e04d382ae737">North Dakota</option>
        <option value="33564f9f-8c87-4316-967d-9a281bfdf632">Northern Mariana Islands</option>
        <option value="3e40c5ce-8584-4b35-bda8-0feaabed30e3">Ohio</option>
        <option value="4d4d6162-61a6-4d6d-833d-582436656ec5">Oklahoma</option>
        <option value="5e08c48a-8620-4298-87aa-c231ee62b3fc">Oregon</option>
        <option value="f428f11f-63e3-494b-93ba-cd530f269338">Pennsylvania</option>
        <option value="2933e363-ae18-427d-9162-d0971dd5530b">Puerto Rico</option>
        <option value="b690c1d4-3614-4df4-92e7-b23f92baaa6f">Rhode Island</option>
        <option value="d7b739b9-b46f-47c1-83c9-9c96133953b0">South Carolina</option>
        <option value="a6a797f0-a2dd-4e37-949d-bb455d72c5ad">South Dakota</option>
        <option value="3c5583dc-7e14-49e3-996e-ea9d42858fb6">Tennessee</option>
        <option value="f1712b25-a54c-4ad1-81cd-c59005ee5178">Texas</option>
        <option value="26ecd50b-a3e5-48f7-9659-c116e0782e4a">U.S. Virgin Islands</option>
        <option value="540d971e-ae86-40ed-93b0-34f40435f332">Utah</option>
        <option value="da2393c5-050e-4d2e-a82c-ff6469c15432">Vermont</option>
        <option value="4ddb4a88-15c8-4e92-ac75-4619d59186f4">Virginia</option>
        <option value="b8b1d38c-17f2-4eaa-b792-4d52c47eae92">Washington</option>
        <option value="21f91d65-a89c-4d0a-b746-ed39d0ac6948">West Virginia</option>
        <option value="4d0d0315-1b41-4bb2-94bc-1fd4a3633b0a">Wisconsin</option>
        <option value="a2996f17-e126-4853-b265-dd09976646c1">Wyoming</option>
      </select>
    </div>
    <div class="clearfix"></div>
    <div class="form-group col-sm-6">
      <label class="control-label" for="ZipCode">Zip Code</label>
      <input class="form-control zipcode text-box single-line" id="ZipCode" maxlength="10" name="ZipCode" type="text" value="" />
    </div>
  </div>
  <div class="address-switch" id="00000000-0000-0000-0000-000000000000">
    <div class="clearfix"></div>
    <div class="form-group col-sm-6">
      <label class="control-label" for="CountryName">Country</label>
      <input class="form-control text-box single-line" id="CountryName" maxlength="64" name="CountryName" type="text" value="" />
    </div>
    <div class="form-group col-sm-6">
      <label class="control-label" for="ProvinceName">Province</label>
      <input class="form-control text-box single-line" id="ProvinceName" maxlength="64" name="ProvinceName" type="text" value="" />
    </div>
    <div class="clearfix"></div>
    <div class="form-group col-sm-6">
      <label class="control-label" for="Postal">Postal Code</label>
      <input class="form-control text-box single-line" id="Postal" maxlength="10" name="Postal" type="text" value="" />
    </div>
  </div>
</div>

在空白表单上,下拉列表的选择应该隐藏/取消隐藏相关部分:选择US将获得State下拉列表和ZipCode文本字段。选择加拿大将获得一个省下拉列表和一个邮政编码文本字段。等等。我使用了以下JS来实现这种效果:

$('#address-switcher').children('.address-switch').addClass('hidden');
$('#CountryId').change(function () {
  $('#address-switcher').children('.address-switch').addClass('hidden');
  $('#address-switcher').children('#' + this.value).removeClass('hidden');
});

在预先填写的表格中,选择下拉列表的作用完全相同,但我有一个额外的要求:因为已经选择了一个国家,所以我需要自动取消隐藏该国家的正确表格字段。与中一样,如果地址已经在加拿大,我需要在默认情况下自动取消隐藏"省份"下拉列表和"邮政编码"表单字段。我需要能够让JS查看SelectList,看到"Canada"是selected="selected",并取消隐藏其id与加拿大optionvalue匹配的div

为此,我创建了一个"自动解锁器"(位于上面JS块的第二行,就在页面加载时隐藏所有内容的JS之后):

$('#address-switcher').children('#' + $('#CountryId').val()).removeClass('hidden');

它工作得很好,但仅适用于从数据库中预先填写的表单

问题是,所有在填充表单加载时添加此自动取消隐藏的尝试都会导致任何空白表单失败。与中一样,当存在"自动取消隐藏"部分时,空表单的"取消隐藏"脚本将失败。取消隐藏脚本仍然适用于已填充的表单,只是不适用于空白表单。请注释掉"自动取消隐藏",然后poof--空白表单可以再次工作,但已填充表单不再自动取消隐藏。

我试过很多方法来"净化"自动解锁器,这样它只有在加载了填写好的表格时才会启动,但所有尝试都失败了:

if ($('#CountryId option:selected').length !== 0) {
  $('#address-switcher').children('#' + $('#CountryId').val()).removeClass('hidden');
}

if (typeof $('#CountryId').val() !== "undefined") {
  $('#address-switcher').children('#' + $('#CountryId').val()).removeClass('hidden');
}

if (typeof $('#CountryId option:selected') !== "undefined") {
  $('#address-switcher').children('#' + $('#CountryId').val()).removeClass('hidden');
}

在每一种情况下,我都确认对空白表单的"消毒"都失败了,因为注释掉自动取消注释(不接触消毒if)会导致空白表单再次工作。

我需要一个不会影响空白表单的取消隐藏脚本的自动取消隐藏程序,或者一个清除if,它将真正完成防止其内容在空白表单上激发的工作。我需要找到一种方法来隔离或清除自动取消隐藏脚本,使其永远没有机会为空白表单激发,但在Country SelectList具有实际选择选项(验证失败后重新加载表单或从DB填写表单)的情况下确实会触发。

我发现的解决方案…很有趣…使用了大量的轻描淡写。

坦率地说:我个人认为JavaScript是魔鬼的编程语言,显然是为了让我们发疯,这一点刚刚得到了支持。

事实证明,无法确认SelectList是否没有所选项目,因为…卷筒…即使在空白和空表单上,可见条目也被视为"所选项目",而(顺便说一句)在任何人机交互之前

威士忌。探戈狐步舞。

我发现了一个解决方案,这是幸运的,因为我构建表单的两个重要属性:

  1. 在一个从数据库中预先填写的表格(使用上面的HTML,在我的OP中)上,我将Country SelectList设置为而不是。在最顶部有一个"choose one"条目。因为内容是从数据库中提取的,所以没有必要有一个,而且实际上需要not将国家作为可选项,因为业务逻辑将国家作为用户配置文件的必需项。它们需要具有"Canada"、"United States"或"None of the above"(然后触发手动国家和省文本字段),因此SelectList的每个value实际上都有内容。或者从本质上讲,它不仅仅是一个空字符串。

  2. 在加载时为空的表单上,Country SelectList在其列表顶部确实有一个"choose one"条目,以便不会自动取消隐藏一组可能不适合用户的表单字段,并强制他们显式选择一个国家/地区(业务逻辑禁止该DB字段为空值)。此项可能有一个value=""(零长度字符串),但它确实有一个值,即使它是零长度的字符串。

我需要寻找的不是一个没有选择项目的SelectList,而是一个选择列表,其中所选项目没有其值的内容

再次:威士忌。探戈狐步舞。

因为页面加载时的空表单将显示"Select One"项目,该项目是"正式选择的"项目从一开始就不可能真正检查SelectList是否有所选项目,因为即使表单为空,它也总是有一个。在中,不可能有未选择的SelectList所有SelectList都具有选定状态,即使完全为空且未被用户触碰。

现在:威士忌。探戈狐步舞。

最后,我的解决方案(谢天谢地,它实际上可以在Chrome和Firefox上运行)是这样的:

if (typeof $('#CountryId').val() !== 'undefined') {
  $('#address-switcher').children('.address-switch').addClass('hidden');
  if ($('#CountryId').val() !== '') {
    $('#address-switcher').children('#' + $('#CountryId').val()).removeClass('hidden');
  }
  $('#CountryId').change(function () {
    $('#address-switcher').children('.address-switch').addClass('hidden');
    $('#address-switcher').children('#' + this.value).removeClass('hidden');
  });
}

注意我是如何显式检查SelectList的,以查看当前选择的值是否为而不是空字符串?:

if ($('#CountryId').val() !== '') {

这就是一切不同的原因。

我添加了根if (typeof …){},这样脚本就不会在每个页面上启动,因为它在几个页面上都是必需的,因此存在于每个页面上的公共js中。