Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Processing dynamically added elements Material Design Lite

First, the 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>

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

All is good, but the methods componentHandler.upgradeAllRegistered (); or componentHandler.upgradeDom (); in any does not want to renew, re-emerged, the elements on the page.

like image 316
user3275016 Avatar asked Dec 14 '22 12:12

user3275016


2 Answers

I also was having problems cloning an element and getting it to work correctly. What I did was to remove the MDL specific classes from the div and change it to a generic class name that I could select on.

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

became

<div class="upgradeTextField">

Then in javascript, after cloning the element, I selected for those divs within the cloned element and added the MDL specific classes to them. After that, running componentHandler.upgradeDom() seemed to work.

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 haven't verified this, but it seems that when you clone an existing element within the dom that has been upgraded by MDL previously, it won't upgrade it when you add the cloned object to the DOM. So that's why I simply removed the MDL classes so it wouldn't be upgraded beforehand.

Alternatively, if you need it upgraded beforehand and still want to clone it. Then what you can do is to remove the attribute 'data-upgraded' and class 'is-upgraded' from your element after you clone it. Then when you run the componentHandler.upgradeDom() it should upgrade it. So, instead of just setting the class name as in the above snippet, you'd simply remove the upgrade info:

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

This seemed to work for me.

like image 146
kevinvile Avatar answered Apr 06 '23 00:04

kevinvile


Thanks for the answer, but it turned out to solve it more concise 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();
});
like image 28
user3275016 Avatar answered Apr 06 '23 00:04

user3275016