问题
I'm trying to dynamically append UIKit Accordions into a sortable list. The initial items (accordions) are working, but the dynamically appended is not working.
HTML
<div class="second-list" data-uk-observe>
<div class="uk-sortable uk-margin uk-accordion" data-uk-sortable="{group:'test'}" data-uk-accordion="{showfirst: false}">
<div class="uk-margin">
<div class="uk-panel uk-panel-box uk-accordion-title">Item 1
<button class="uk-button delete-btn">×</button>
</div>
<div class="uk-accordion-content">test1</div>
</div>
<div class="uk-margin">
<div class="uk-panel uk-panel-box uk-accordion-title">Item 2
<button class="uk-button delete-btn">×</button>
</div>
<div class="uk-accordion-content">test2</div>
</div>
</div>
</div>
JavaScript
// Remove item handler
$(".delete-btn").on("click", function () {
// 400 is default
$(this).closest(".uk-margin").fadeOut(400, function () {
$(this).remove();
});
return false;
});
function addItem () {
var $container = $(".second-list").find("[data-uk-sortable]");
$container.append(
`<div class="uk-margin">
<div class="uk-panel uk-panel-box uk-accordion-title">new item
<button class="uk-button delete-btn">×</button>
</div>
<div class="uk-accordion-content">description</div>
</div>`
);
}
addItem();
This is the minimal example I created to reproduce the problem. The sortable dynamic item is working fine (can be dragged), but the accordion doesn't. When clicking it, I'm getting:
Uncaught TypeError: Cannot read property 'data' of undefined
What I have tried:
Using
data-uk-observe
in the sortable element. I don't feel any difference using it.Trying to initialize the accordion using the UIKit API:
UIkit.accordion($(".uk-margin")); UIkit.accordion($(".uk-accordion-title")); UIkit.accordion($(".uk-accordion-content"));
None of these doesn't fixe the problem.
So, how to correctly append dynamic GetUIKit accordions?
JSFIDDLE
回答1:
It looks like what you want to do is:
- Omit the
data-uk-accordion
attribute. - Save the object returned from calling
UIkit.accordion(element, options)
. - After new accordion child elements have been added, call
accordion.update()
. (assuming you saved the returned object above in a variable calledaccordion
)
For more information about how I arrived at that, check out the related issue on GitHub.
(also posted as an answer on UIKit accordion and ng-repeat doesn't work)
回答2:
Try removing the accordion data from the element before you reinitialize it:
$(".uk-margin").removeData("accordion");
UIkit.accordion($(".uk-margin"));
That worked for me when I was writing an angular directive for this.
回答3:
try update all items of accordion after add,
var component = UIkit.accordion($('.uk-accordion'));
component.update();
That worked for me.
回答4:
I had the same issue but I'm using Meteor. This took me a good hour to get worked out, and I tried several different solutions, including using Template.onRender
, Template.onCreated
, but to no avail. They all seemed to attempt to initialize the UIKit accordion JS too soon.
I probably should've known better, but the right answer was to put @codermonkeyfuel's code before the end of my template helper, like so:
Template.appsList.helpers({
myApps: function() {
if (Meteor.user() ) {
console.log("we have a user: " + Meteor.user() );
var userId = Meteor.userId();
var user = Meteor.users.findOne(Meteor.userId());
console.log("userId: " + userId);
var apps = Meteor.users.findOne({_id: userId}, {
fields: {
myApps: 1
}
}).myApps;
// console.log(myApps);
return user && apps;
}
setTimeout(function() {
var accordion = UIkit.accordion($('.uk-accordion'), {collapse: false});
accordion.update();
}, 1000)
}
});
My head was thinking it was a timing issue with the rendering. In retrospect, the actual solution makes perfect sense. Hope it's useful for anyone using UIKit with MeteorJS. meteor javascript uikit
来源:https://stackoverflow.com/questions/33731080/how-to-correctly-append-dynamic-getuikit-accordions