Handling Dynamically Added Material Design Lite Elements

First code:

$(document).ready(function() { $('#member_pattern').hide(); $('.add-member').click(function() { var clone = $('#member_pattern').clone(), cont = $('.members-cont'); $(cont).append(clone); $(cont).find('#member_pattern').show(200, function() { $(this).attr('id', ''); componentHandler.upgradeAllRegistered(); }); }); }); 
 <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script> <link rel="stylesheet" href="https://storage.googleapis.com/code.getmdl.io/1.0.2/material.blue-indigo.min.css" /> <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Roboto:300,400,500,700" type="text/css"> <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> <script src="https://storage.googleapis.com/code.getmdl.io/1.0.0/material.min.js"></script> <div class="members-cont"> <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> <input class="mdl-textfield__input" type="text" id="first_name_<?php echo $member->id; ?>" value="<?php echo $member['first_name']; ?>"/> <label class="mdl-textfield__label" for="first_name_<?php echo $member->id; ?>"></label> </div> </div> <button class="add-member add-member-top mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored"> <i class="material-icons">add</i> </button> <div id="member_pattern" class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> <input class="mdl-textfield__input" type="text" id="[name]_[id]" value=""/> <label class="mdl-textfield__label" for="[name]_[id]"></label> </div> 

Purpose: By clicking the button on the page, dynamically insert another field [.mdl-textfield], you want to apply the "material design" in Google

Everything is fine, but componentHandler.upgradeAllRegistered () methods ; or componentHandler.upgradeDom (); in any does not want to be updated, reappear, elements on the page.

+4
source share
2 answers

I also had issues with cloning the item and working correctly. I did to remove certain MDL classes from the div and change it to the common class name that I could select.

 <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> 

has become

 <div class="upgradeTextField"> 

Then in javascript, after cloning the element, I selected for these divs in the cloned element and added MDL classes to them. After that, the working componentHandler.upgradeDom () component works.

 var textFieldUpgrades = cloned.querySelectorAll('.upgradeTextField'); if(textFieldUpgrades) { for(var i=0;i<textFieldUpgrades.length;++i) { textFieldUpgrades[i].className = 'mdl-textfield mdl-js-textfield mdl-textfield--floating-label'; } } componentHandler.upgradeDom(); 

I have not tested this, but it seems that when you clone an existing element inside the dom that was previously updated by MDL, it will not update it when you add the cloned object to the DOM. So I just deleted the MDL classes so that it would not be updated in advance.

Alternatively, if you need to update it in advance and still want to clone it. Then you can remove the attribute “updated data” and the class “updated” from your element after cloning it. Then, when you run the Handler.upgradeDom () component, it should update it. Therefore, instead of just specifying the class name, as in the above snippet, you simply delete the update information:

 textFieldUpgrades[i].setAttribute('data-upgraded',''); textFieldUpgrades[i].className = textFieldUpgrades[i].className.replace(/is-upgraded/g,''); 

It seemed to work for me.

+5
source

Thanks for the answer, but it turned out to be a shorter way

 var index = $('.member-section').length; var clone = $('.member-section-pattern').clone(); $(clone) .removeClass('member-section-pattern') .find(':not([data-upgraded=""])').attr('data-upgraded', ''); $('.members-cont').append(clone); $(clone).show(200, function() { componentHandler.upgradeAllRegistered(); }); 
+4
source

All Articles