Reputation: 1918
I am working on a widget which has a 'saved' and 'completed' module. When i remove the element it removes/fades it out from the dom but when I mark it as done it clones it to the completed tab. This is working awesome but the numbers inside the top parenthesis are not adjusting for me. What is a better way of doing this? I may be over thinking this.
I am using length
to capture the amount of div
's inside the parent. This is working good. But when i fadeout
(remove) an element from the dom the counter/length doesn't change. Nor when I clone
the element to the completed tab.
Here is a jsfiddle file I have set up.
http://jsfiddle.net/breezy/jvdnbw4q/
Here is my jQuery
$(document).foundation();
$('.removed-saved-tip').click(function(e){
$(this).closest('.saved-tip').fadeOut();
e.preventDefault();
});
$('.saved-tip-done').click(function(e){
$(this).toggleClass('marked-done');
e.preventDefault();
$(this).closest('.saved-tip').clone().appendTo('#panel2');
});
$('#panel1').each(function() {
var n = $(this).children('.saved-tip').length;
$(".tab-title:first a").text("Saved (" + n + ")");
});
$('#panel2').each(function() {
var n = $(this).children('.saved-tip').length;
$(".tab-title:last a").text("Completed (" + n + ")");
});
Upvotes: 0
Views: 496
Reputation: 25310
If you're going to move forward working with the project, it would probably be more reasonable to move to a specific MVVM (or MV*) framework and avoid manual DOM manipulation altogether.
Below is a simple example using Vue.js, but you could use more or less anything - the idea is to reduce manual labor and focus on the functionality.
Note how the code doesn't include any DOM manipulation, that's left entirely for the framework to handle.
var v = new Vue({
el: 'body',
data: {
items: []
},
computed: {
doneItems: function() {
return this.items.filter(function(item) {
return item.done;
});
}
},
methods: {
addItem: function() {
var value = ("" || this.input).trim();
if (!value.length) return;
this.items.push({
title: value,
done: false
});
this.input = '';
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.12/vue.min.js"></script>
<input autofocus placeholder="Add a new item" v-model="input" v-on="keyup:addItem | key 'enter'">
<p>All items ({{items.length}}):</p>
<ul v-repeat="items">
<li>{{title}}
<input type="checkbox" v-model="done" />
</li>
</ul>
<p>Done items({{doneItems.length}}):</p>
<ul v-repeat="doneItems">
<li>{{title}}
<input type="checkbox" v-model="done" />
</li>
</ul>
Upvotes: 0
Reputation: 79830
You need to call the count logic inside of the event handler for mark and remove.
// Tabs
$(document).foundation();
$('.removed-saved-tip').click(function (e) {
$(this).closest('.saved-tip').addClass('removed').fadeOut();
e.preventDefault();
updateCount();
});
$('.saved-tip-done').click(function (e) {
$(this).toggleClass('marked-done');
e.preventDefault();
$(this).closest('.saved-tip').clone().appendTo('#panel2');
updateCount();
});
updateCount();
function updateCount() {
$('#panel1').each(function () {
var n = $(this).children('.saved-tip').filter(function() {
return !$(this).hasClass('removed');
}).length;
$(".tab-title:first a").text("Saved (" + n + ")");
});
$('#panel2').each(function () {
var n = $(this).children('.saved-tip').filter(function() {
return !$(this).hasClass('removed');
}).length;
$(".tab-title:last a").text("Completed (" + n + ")");
});
}
.tabs-content {
margin: 10px auto 0 auto;
}
.tabs-content .content {
background: #fff;
}
.print-option {
background: #fbf7cc;
padding: 5px 15px;
margin: 0;
}
.print-option h4 {
font-size: 14px;
}
.saved-tip {
padding: 10px 15px;
overflow: hidden;
cursor: pointer;
}
.saved-tip:hover {
background: #efefef;
}
.saved-tip .saved-tip-icon {
float: left;
margin: 0 10px 0 0;
}
.saved-tip h5 {
color: #107CB2;
font-size: 13px;
float: left;
}
.saved-tip .saved-tip-options {
float: right;
}
.saved-tip .saved-tip-options a {
color: #676767;
padding: 0 5px;
border: 1px solid #dedede;
border-radius: 3px;
display: inline-block;
}
.saved-tip .saved-tip-options i {
font-size: 14px;
}
.saved-tip a.marked-done {
color: #107CB2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/foundation/5.5.2/js/foundation/foundation.tab.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/foundation/5.5.2/js/foundation.min.js"></script>
<link rel="stylesheet" href="http://cdn.foundation5.zurb.com/foundation.css" />
<ul class="tabs" data-tab>
<li class="tab-title active"><a href="#panel1">Saved</a>
</li>
<li class="tab-title"><a href="#panel2">Completed</a>
</li>
</ul>
<div class="tabs-content">
<div class="print-option">
<h4>Share these tips with your home. <a href="#">Print now</a></h4>
</div>
<div class="content active" id="panel1">
<div class="saved-tip">
<img class="saved-tip-icon" src="http://placehold.it/20x20">
<h5>Tip title</h5>
<div class="saved-tip-options"> <a class="saved-tip-done" href="#"><i class="fa fa-check"></i></a>
<a class="removed-saved-tip" href="#"><i class="fa fa-times"></i></a>
</div>
</div>
<div class="saved-tip">
<img class="saved-tip-icon" src="http://placehold.it/20x20">
<h5>Tip title</h5>
<div class="saved-tip-options"> <a class="saved-tip-done" href="#"><i class="fa fa-check"></i></a>
<a class="removed-saved-tip" href="#"><i class="fa fa-times"></i></a>
</div>
</div>
</div>
<!-- eo / panel1 -->
<div class="content" id="panel2">
<div class="saved-tip">
<img class="saved-tip-icon" src="http://placehold.it/20x20">
<h5>Tip title</h5>
<div class="saved-tip-options"> <a class="saved-tip-done" href="#"><i class="fa fa-check"></i></a>
<a class="removed-saved-tip" href="#"><i class="fa fa-times"></i></a>
</div>
</div>
<div class="saved-tip">
<img class="saved-tip-icon" src="http://placehold.it/20x20">
<h5>Tip title</h5>
<div class="saved-tip-options"> <a class="saved-tip-done" href="#"><i class="fa fa-check"></i></a>
<a class="removed-saved-tip" href="#"><i class="fa fa-times"></i></a>
</div>
</div>
<div class="saved-tip">
<img class="saved-tip-icon" src="http://placehold.it/20x20">
<h5>Tip title</h5>
<div class="saved-tip-options"> <a class="saved-tip-done" href="#"><i class="fa fa-check"></i></a>
<a class="removed-saved-tip" href="#"><i class="fa fa-times"></i></a>
</div>
</div>
</div>
<!-- eo / panel2 -->
</div>
<!-- eo // tabs content -->
</div>
Upvotes: 1
Reputation: 2008
You need put the each into click function because now with your code each call only when document is ready.
$('.saved-tip-done').click(function (e) {
$(this).toggleClass('marked-done');
e.preventDefault();
$(this).closest('.saved-tip').clone().appendTo('#panel2');
$(".tab-title:first a").text("Saved (" + $('#panel1 .saved-tip').length+")");
$(".tab-title:last a").text("Saved (" + $('#panel2 .saved-tip').length+")");
});
You can remove each and get the number of save tip in one line using $('#panel1 .saved-tip').length
http://jsfiddle.net/jvdnbw4q/1/
Upvotes: 1