Reputation: 6779
This is my situation:
<div id="div1" class="divPhase">
<div class="row margin-top-1">
<div class="column">
<label>Title Phase 1:</label>
<textarea id="title-1" name="title-phase-1" rows="6" required></textarea>
</div>
<div class="column">
<label>Description Phase 1:</label>
<textarea id="description-1" name="description-phase-1" rows="6" required></textarea>
</div>
<a class="removeLink">Remove div1</a>
</div>
</div>
<div id="div2" class="divPhase">
<div class="row margin-top-2">
<div class="column">
<label>Title Phase 2:</label>
<textarea id="title-2" name="title-phase-2" rows="6" required></textarea>
</div>
<div class="column">
<label>Description Phase 2:</label>
<textarea id="description-2" name="description-phase-2" rows="6" required></textarea>
</div>
<a class="removeLink">Remove div2</a>
</div>
</div>
....
....
and so on with div3, div4 etc.
As you can see, for each div (div1
, div2
, div3
, and so on) I have a link which will remove its parent div with class divPhase
.
Here is the code:
$(".removeLink").closest(".divPhase").remove();
What I'm trying to achieve is to have an ascending ordered and contiguous list of divs even after removing some divs.
I'll try to be more clear. As of now if I have, let's say, 5 divs as the ones above (with these ids: div1
, div2
, div3
, div4
and div5
) if I remove div3
with the click on the link with class removeLink
what I get is a list of 4 divs (div1
, div2
, div4
and div5
).
This list is not contiguous because between div2
and div4
we need div3
.
What I'd like to get is div1
, div2
, div3
, div4
(div4
should become div3
and div5
should become).
Moreover I should achieve the same for the textarea's ids (title-5
and description-5
should become title-4
and description-4
while title-4
and description-4
should become title-3
and description-3
).
How do I go about this?
Upvotes: 0
Views: 109
Reputation: 10976
Here's a more elegant way to do it: trigger an event when the .divPhase
is removed (remove-row
), and attach an updateIndexes
listener to it. In the body of this function you can change any attributes you like in a loop of all .divPhase
's.
Note: although the below snippet works for this use case, if you find yourself often needing to add extra modifications per element/ attribute, you might want to consider a data-first/ template rendering solution, like Handlebars or Mustache, for a comprehensive list see javascripting.com
var removeEntry = function() {
$('#rows').trigger('remove-row', [$(this).closest('.row').index()]);
$(this).closest('.row').remove();
};
var updateIndexes = function(e, index) {
var selector = ':input, .divPhase';
$('#rows').children().filter(function(i) {
return i > index;
}).each(function(i) {
$(this).find(selector).add(this).each(function() {
var displayIndex = (i + 1);
if (this.className && this.className.length)
this.className = this.className.slice(0, -1) + displayIndex;
if (this.id && this.id.length)
this.id = this.id.slice(0, -1) + displayIndex;
if (this.name && this.name.length)
this.name = this.name.slice(0, -1) + displayIndex;
if (this.value && this.value.length)
this.value = this.value.slice(0, -1) + displayIndex;
});
});
};
$('#rows').on('remove-row', updateIndexes);
$('.row a').on('click', removeEntry);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="rows">
<div class="row divPhase-1">
<input type="text" name="title-1" id="title-1" value="value-1">
<textarea name="desc-1" id="desc-1"></textarea>
<a href="#desc-1-removed">Remove</a>
</div>
<div class="row divPhase-2">
<input type="text" name="title-2" id="title-2" value="value-2">
<textarea name="desc-2" id="desc-2"></textarea>
<a href="#desc-2-removed">Remove</a>
</div>
</div>
Upvotes: 1
Reputation: 33933
You have to loop throught all the remaining divPhase
, right after the removal on click... To re-number them.
So that is a big loop.
I'm really unsure that this is usefull to do it.
But here is how it can be done anyway.
$(".removeLink").on("click",function(){
$(this).closest(".divPhase").remove();
var divPhase = $(document).find(".divPhase");
for(i=0;i<divPhase.length;i++){
var j= i+1;
divPhase.eq(i).attr("id","div"+j);
// Row class
var row = divPhase.eq(i).find(".row");
row.attr("class","row margin-top-"+j);
// Labels
var labels = divPhase.eq(i).find("label");
for(k=0;k<labels.length;k++){
var labelHtml = labels.eq(k).html();
labels.eq(k).html(labelHtml.substr(0,labelHtml.length-2)+j+":");
}
// Textareas
var textareas = divPhase.eq(i).find("textarea");
for(k=0;k<textareas.length;k++){
var textareaId = textareas.eq(k).attr("id");
textareas.eq(k).attr("id",textareaId.substr(0,textareaId.length-1)+j);
var textareaName = textareas.eq(k).attr("name");
textareas.eq(k).attr("name",textareaName.substr(0,textareaName.length-1)+j);
}
// Remove link
var removeLinkHtml = divPhase.eq(i).find(".removeLink").html();
divPhase.eq(i).find(".removeLink").html(removeLinkHtml.substr(0,removeLinkHtml.length-1)+j);
}
});
Upvotes: 1