【问题标题】:How to properly clone and update the IDs of Materialize select and pickers?如何正确克隆和更新 Materialise 选择器和选择器的 ID?
【发布时间】:2019-04-26 19:59:06
【问题描述】:

我正在克隆一个 Materialize 表单元素块,包括几个选择、一个时间选择器和一个带有按钮单击事件的文本区域。当前代码使用计数器来增加 id 和 label 的值。正如预期的那样,这适用于像 textarea 这样的基本输入,但对于像 select 或 picker 这样的项目,Materialize 会在多个元素上动态注入其自己的带有哈希 ID 的 JS,而不是骰子。如何正确克隆选择和选​​择器以便它们工作?

我尝试在 Chrome 的开发控制台中手动更改克隆的 ID(查看匹配的哈希),看看我是否至少可以触发选择或选择器,但仍然无法正常工作且没有错误。只有初始块有效。我在想,如果我能让元素至少触发,我可以编写一些代码来定位选择器或单独选择。不确定我是否想太多了。

我让事情工作的一个笨拙的方法是在 html 中创建最大 # 块而不是克隆,隐藏除第一个之外的所有块,然后手动更新 ID,然后在按钮单击时显示每个块。它们都以这种方式工作,但当然它不是 DRY,我必须处理状态。

这是我的克隆尝试代码:

HTML:

<div class="container">
   <div id="mealRequests" class="row">
      <!-- Meal Request #1 -->
      <div class="input-field col s12 meal-request-block">
         <div class="row ">
            <div class="input-field col s12 m6">
               <select id="mealType01">
                  <option value="" disabled selected>Choose your option</option>
                  <option value="Breakfast">Breakfast</option>
                  <option value="Lunch">Lunch</option>
                  <option value="Snack">Snack</option>
                  <option value="Cocktail">Cocktail</option>
               </select>
               <label for="mealType01">Meal type</label>
            </div>
            <div class="input-field col s12 m6">
               <input id="consumptionTime01" type="text" class="timepicker" autocomplete="off" placeholder="09:00 AM">
               <label for="consumptionTime01">Consumption time</label>
            </div>
         </div>
         <div class="row">
            <div class="input-field col s12">
               <select id="vendorChoice01">
                 <option value="" disabled selected>Choose your option</option>
                 <option value="Dig Inn">Dig Inn</option>
                 <option value="Pret">Pret</option>
                 <option value="Au Bon Pain">Au Bon Pain</option>
               </select>
               <label for="vendorChoice01">Vendor</label>
            </div>
         </div>
         <div class="row">
            <div class="input-field col s12">
               <textarea id="menuRequest01" class="materialize-textarea" placeholder="Farmers plate"></textarea>
               <label for="menuRequest01">Menu selections</label>
            </div>
         </div>
      </div>
   </div>
  <div class="row">
    <div class="col s12">
      <button id="addMealRequestBtn" class="btn-text"><i class="material-icons">+</i> Add another meal request</button>
    </div>
  </div>
</div>

JS:

// Initialize Materialize's select and datepicker
$('select').formSelect();
$('.timepicker').timepicker(); 

    // Add click handler for meal requests
    var addMealRequest = function () {

      var $row = $('.meal-request-block').parent(),
          $template = $('.meal-request-block:first').clone(),         
          counter = 1, // used for incrementing input IDs
          limit = 2; // sets a max limit on the total number of clones

      $('#addMealRequestBtn').on('click', function(e) {
        e.preventDefault();
        var $totalCount = $('.meal-request-block').length;

        counter++;

        if ($totalCount < limit) {
          $template.clone().find('.timepicker-modal, select, input, textarea').each(function () {

            //set id to store the updated section number
            var newId = this.id + counter;

            //update for label
            $(this).next().attr('for', newId).addClass('active');

            //update id
            this.id = newId;

          }).end()

          .appendTo($row);  
        }        
      });
    };

    addMealRequest();

CSS:

.input-field div.error {
  position: relative;
  top: -.25rem;
  left: 0rem;
  font-size: 0.8rem;
  color: red;
  transform: translateY(0%);
}

.meal-request-block {
  background-color: #f0f0f0;
  padding: 24px!important;
}

  .btn-text {
    background: none;
    border: none;
    cursor: pointer;
    font-weight: 600;
    opacity: 1;
    padding: 0;
    transition: all .25s ease;
    &:focus {
      background: transparent;
    }
    &:hover {
      opacity: .75;
    }
  }

还有一支基本笔:https://codepen.io/anon/pen/GLzEvw

以下是 Materialize 注入其 JS 后代码的示例:

选择:

<div class="input-field col s12 m6">
  <div class="select-wrapper">
    <input class="select-dropdown dropdown-trigger" type="text" readonly="true" data-target="select-options-db214a65-6ab6-0918-fd05-e3c7cc84a074">
    <ul id="select-options-db214a65-6ab6-0918-fd05-e3c7cc84a074" class="dropdown-content select-dropdown" tabindex="0">
      <li class="disabled selected" id="select-options-db214a65-6ab6-0918-fd05-e3c7cc84a0740" tabindex="0"><span>Choose your option</span></li>
      <li id="select-options-db214a65-6ab6-0918-fd05-e3c7cc84a0741" tabindex="0"><span>Breakfast</span></li>
      <li id="select-options-db214a65-6ab6-0918-fd05-e3c7cc84a0742" tabindex="0"><span>Lunch</span></li>
      <li id="select-options-db214a65-6ab6-0918-fd05-e3c7cc84a0743" tabindex="0"><span>Snack</span></li>
      <li id="select-options-db214a65-6ab6-0918-fd05-e3c7cc84a0744" tabindex="0"><span>Cocktail</span></li>
    </ul>
    <svg class="caret" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
      <path d="M7 10l5 5 5-5z"></path>
      <path d="M0 0h24v24H0z" fill="none"></path>
    </svg>
    <select id="mealType01" tabindex="-1">
      <option value="" disabled="" selected="">Choose your option</option>
      <option value="Breakfast">Breakfast</option>
      <option value="Lunch">Lunch</option>
      <option value="Snack">Snack</option>
      <option value="Cocktail">Cocktail</option>
    </select>
  </div>
  <label for="mealType01">Meal type</label>
</div>

时间选择器:

<div class="input-field col s12 m6">
  <div class="modal timepicker-modal" id="modal-1bc17566-dd57-4454-0735-057dc30e2263" tabindex="0" style="z-index: 1003; display: none; opacity: 0; top: 4%; transform: scaleX(0.8) scaleY(0.8);">
    <div class="modal-content timepicker-container">
      <div class="timepicker-digital-display">
        <div class="timepicker-text-container">
          <div class="timepicker-display-column"><span class="timepicker-span-hours">12</span>:<span class="timepicker-span-minutes text-primary">30</span></div>
          <div class="timepicker-display-column timepicker-display-am-pm">
            <div class="timepicker-span-am-pm">
              <div class="am-btn">AM</div>
              <div class="pm-btn text-primary">PM</div>
            </div>
          </div>
        </div>
      </div>
      <div class="timepicker-analog-display">
        <div class="timepicker-plate">
          <div class="timepicker-canvas">
            <svg class="timepicker-svg" width="270" height="270">
              <g transform="translate(135,135)">
                <line x1="0" y1="0" x2="1.0409497792752502e-14" y2="85"></line>
                <circle class="timepicker-canvas-bg" r="20" cx="1.2858791391047208e-14" cy="105"></circle>
                <circle class="timepicker-canvas-bearing" cx="0" cy="0" r="4"></circle>
              </g>
            </svg>
          </div>
          <div class="timepicker-dial timepicker-hours timepicker-dial-out" style="visibility: hidden;">
            <div class="timepicker-tick" style="left: 167.5px; top: 24.0673px;">1</div>
            <div class="timepicker-tick" style="left: 205.933px; top: 62.5px;">2</div>
            <div class="timepicker-tick" style="left: 220px; top: 115px;">3</div>
            <div class="timepicker-tick" style="left: 205.933px; top: 167.5px;">4</div>
            <div class="timepicker-tick" style="left: 167.5px; top: 205.933px;">5</div>
            <div class="timepicker-tick" style="left: 115px; top: 220px;">6</div>
            <div class="timepicker-tick" style="left: 62.5px; top: 205.933px;">7</div>
            <div class="timepicker-tick" style="left: 24.0673px; top: 167.5px;">8</div>
            <div class="timepicker-tick" style="left: 10px; top: 115px;">9</div>
            <div class="timepicker-tick" style="left: 24.0673px; top: 62.5px;">10</div>
            <div class="timepicker-tick" style="left: 62.5px; top: 24.0673px;">11</div>
            <div class="timepicker-tick" style="left: 115px; top: 10px;">12</div>
          </div>
          <div class="timepicker-dial timepicker-minutes" style="visibility: visible;">
            <div class="timepicker-tick" style="left: 115px; top: 10px;">00</div>
            <div class="timepicker-tick" style="left: 167.5px; top: 24.0673px;">05</div>
            <div class="timepicker-tick" style="left: 205.933px; top: 62.5px;">10</div>
            <div class="timepicker-tick" style="left: 220px; top: 115px;">15</div>
            <div class="timepicker-tick" style="left: 205.933px; top: 167.5px;">20</div>
            <div class="timepicker-tick" style="left: 167.5px; top: 205.933px;">25</div>
            <div class="timepicker-tick" style="left: 115px; top: 220px;">30</div>
            <div class="timepicker-tick" style="left: 62.5px; top: 205.933px;">35</div>
            <div class="timepicker-tick" style="left: 24.0673px; top: 167.5px;">40</div>
            <div class="timepicker-tick" style="left: 10px; top: 115px;">45</div>
            <div class="timepicker-tick" style="left: 24.0673px; top: 62.5px;">50</div>
            <div class="timepicker-tick" style="left: 62.5px; top: 24.0673px;">55</div>
          </div>
        </div>
        <div class="timepicker-footer">
          <button class="btn-flat timepicker-clear waves-effect" style="visibility: hidden;" type="button" tabindex="3">Clear</button>
          <div class="confirmation-btns"><button class="btn-flat timepicker-close waves-effect" type="button" tabindex="3">Cancel</button><button class="btn-flat timepicker-close waves-effect" type="button" tabindex="3">Ok</button></div>
        </div>
      </div>
    </div>
  </div>
  <input id="consumptionTime01" type="text" class="timepicker" autocomplete="off" placeholder="09:00 AM">
  <label for="consumptionTime01" class="active">Consumption time</label>
</div>

总而言之,我如何克隆选择器和选择器以便它们实际工作?正确定位他们的 ID?以某种方式利用 Materialise 的 API 来做到这一点?到目前为止,我只是在全局初始化选择和时间选择器。

【问题讨论】:

  • 嗨@pete-ankelein,你解决过这个问题吗?我现在也有类似的问题。

标签: jquery materialize


【解决方案1】:

我感觉您的事件处理程序没有附加到您动态创建(克隆)的元素。

Normally, any event handlers bound to the original element are not copied to the clone.

看看这个post

我会将此作为评论,但我目前无法发布 cmets。

【讨论】:

  • 事件处理程序在按钮上,没有被克隆。所有克隆的项目都根据处理程序中的代码显示递增的 ID。我认为它与 Materialize 如何构建选择器和选择器以及我想象的正确定位它(如果可能的话)做更多的事情。
【解决方案2】:

我知道这是一个老问题了,但我刚刚遇到了类似的问题。

我解决它的方法是在克隆之前使用instance.destroy() 销毁所有选择实例,然后在克隆块并将其插入 DOM 后重新初始化选择。

你可以在这里看到工作的 jsFiddle:https://jsfiddle.net/AJLeonardi/szt1enob/53/

【讨论】:

    猜你喜欢
    • 2014-02-07
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    相关资源
    最近更新 更多