Reputation: 674
I have a 5 sets of divs with common class names. I need to display child divs based on the value of the select element, which is also under a child div. But absolutely nothing is happening. What am I doing wrong?
$('.item-chooser').each(function() {
var media = $(this).val();
if (media == 'fontawesome') {
$(this).parent('.cta-block').children('.cta-fa-icon').slideDown();
} else if (media == 'image') {
$(this).parent('.cta-block').children('.cta-image-upload').slideDown();
}
$(this).change(function() {
var media = $(this).val();
if (media == 'fontawesome') {
$(this).parent('.cta-block-item-wrap').children('.cta-image-upload').slideUp();
$(this).parent('.cta-block-item-wrap').children('.cta-fa-icon').slideDown();
} else if (media == 'image') {
$(this).parent('.cta-block-item-wrap').children('.cta-fa-icon').slideUp();
$(this).parent('.cta-block-item-wrap').children('.cta-image-upload').slideDown();
}
});
});
.cta-block-item-wrap {
border-bottom: 1px solid #eeeeee;
padding: 10px 0;
}
.cta-image-upload,
.cta-fa-icon {
display: none;
}
.cta-block-item-wrap > label {
font-size: 12px;
font-weight: bold;
margin: 0 50px 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cta-block">
<div class="cta-block-item-wrap cta-icon-image">
<label for="item-chooser">FA Icon/Image:</label>
<select class="item-chooser" name="item-chooser">
<option value="fontawesome">FontAwesome Icon</option>
<option value="image">Image</option>
</select>
</div>
<div class="cta-block-item-wrap cta-image-upload">
<label for="block-image">Upload Image:</label>
<input name="block-image" class="block-image" type="text" value="">
<input type="button" class="cta-insert-image button button-primary button-large" value="Upload">
</div>
<div class="cta-block-item-wrap cta-fa-icon">
<label for="fa-icon-class">Choose FA Icon:</label>
<input type="text" name="fa-icon-class" class="fa-icon-class" value="">
</div>
</div>
<div class="cta-block">
<div class="cta-block-item-wrap cta-icon-image">
<label for="item-chooser">FA Icon/Image:</label>
<select class="item-chooser" name="item-chooser">
<option value="fontawesome">FontAwesome Icon</option>
<option value="image">Image</option>
</select>
</div>
<div class="cta-block-item-wrap cta-image-upload">
<label for="block-image">Upload Image:</label>
<input name="block-image" class="block-image" type="text" value="">
<input type="button" class="cta-insert-image button button-primary button-large" value="Upload">
</div>
<div class="cta-block-item-wrap cta-fa-icon">
<label for="fa-icon-class">Choose FA Icon:</label>
<input type="text" name="fa-icon-class" class="fa-icon-class" value="">
</div>
</div>
Upvotes: 2
Views: 126
Reputation: 29168
First, you are using parent()
to traverse from .item-chooser
to .cta-block
. But parent()
only travels up a single level in the DOM and .cta-block
is not the direct parent of .item-chooser
. I suggest using parents()
or closest()
instead.
.parent() only travels a single level up the DOM tree
I have also replaced children()
with find()
for flexibility and because it may to be a bit faster in your context , but your children()
selector works, too.
$(this).closest('.cta-block').find('.cta-fa-icon').slideDown();
Second, you are iterating through each .item-chooser
to set the initial state and bind an event listener. I suggest simplifying things by binding a "change" event handler and then triggering a change:
$('.item-chooser').on('change',function() { .. }).trigger('change');
Third, you are not sliding up one option when you slide down another. It seems that you'd want to hide the file input when you show the icon input, and vice versa:
$(this).closest('.cta-block').find('.cta-fa-icon').slideDown();
$(this).closest('.cta-block').find('.cta-image-upload').slideUp();
See my demonstration below:
$('.item-chooser').on('change', function() {
var media = $(this).val();
if (media == 'fontawesome') {
$(this).closest('.cta-block').find('.cta-fa-icon').slideDown();
$(this).closest('.cta-block').find('.cta-image-upload').slideUp();
} else if (media == 'image') {
$(this).closest('.cta-block').find('.cta-image-upload').slideDown();
$(this).closest('.cta-block').find('.cta-fa-icon').slideUp();
}
}).trigger('change');
.cta-block-item-wrap {
border-bottom: 1px solid #eeeeee;
padding: 10px 0;
}
.cta-image-upload,
.cta-fa-icon {
display: none;
}
.cta-block-item-wrap > label {
font-size: 12px;
font-weight: bold;
margin: 0 50px 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cta-block">
<div class="cta-block-item-wrap cta-icon-image">
<label for="item-chooser">FA Icon/Image:</label>
<select class="item-chooser" name="item-chooser">
<option value="fontawesome">FontAwesome Icon</option>
<option value="image">Image</option>
</select>
</div>
<div class="cta-block-item-wrap cta-image-upload">
<label for="block-image">Upload Image:</label>
<input name="block-image" class="block-image" type="text" value="">
<input type="button" class="cta-insert-image button button-primary button-large" value="Upload">
</div>
<div class="cta-block-item-wrap cta-fa-icon">
<label for="fa-icon-class">Choose FA Icon:</label>
<input type="text" name="fa-icon-class" class="fa-icon-class" value="">
</div>
</div>
<div class="cta-block">
<div class="cta-block-item-wrap cta-icon-image">
<label for="item-chooser">FA Icon/Image:</label>
<select class="item-chooser" name="item-chooser">
<option value="fontawesome">FontAwesome Icon</option>
<option value="image">Image</option>
</select>
</div>
<div class="cta-block-item-wrap cta-image-upload">
<label for="block-image">Upload Image:</label>
<input name="block-image" class="block-image" type="text" value="">
<input type="button" class="cta-insert-image button button-primary button-large" value="Upload">
</div>
<div class="cta-block-item-wrap cta-fa-icon">
<label for="fa-icon-class">Choose FA Icon:</label>
<input type="text" name="fa-icon-class" class="fa-icon-class" value="">
</div>
</div>
Alternatively, you could name the classes of your divs to correspond with your select values. Then you can simplify your code even further by removing the if
statement.
<div class="cta-option cta-option-image"></div>
<div class="cta-option cta-option-fontawesome"></div>
$container.find('.cta-option').slideUp();
$container.find('.cta-option-'+option).stop(true).slideDown();
See the working demo below:
$('.item-chooser').on('change', function() {
var $this=$(this),
$container=$this.closest('.cta-block'),
option = $this.val();
$container.find('.cta-option').slideUp();
$container.find('.cta-option-'+option).stop(true).slideDown();
}).trigger('change');
.cta-block-item-wrap {
border-bottom: 1px solid #eeeeee;
padding: 10px 0;
}
.cta-option {
display: none;
}
.cta-block-item-wrap > label {
font-size: 12px;
font-weight: bold;
margin: 0 50px 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cta-block">
<div class="cta-block-item-wrap cta-icon-image">
<label for="item-chooser">FA Icon/Image:</label>
<select class="item-chooser" name="item-chooser">
<option value="fontawesome">FontAwesome Icon</option>
<option value="image">Image</option>
</select>
</div>
<div class="cta-block-item-wrap cta-option cta-option-image">
<label for="block-image">Upload Image:</label>
<input name="block-image" class="block-image" type="text" value="">
<input type="button" class="cta-insert-image button button-primary button-large" value="Upload">
</div>
<div class="cta-block-item-wrap cta-option cta-option-fontawesome">
<label for="fa-icon-class">Choose FA Icon:</label>
<input type="text" name="fa-icon-class" class="fa-icon-class" value="">
</div>
</div>
<div class="cta-block">
<div class="cta-block-item-wrap cta-icon-image">
<label for="item-chooser">FA Icon/Image:</label>
<select class="item-chooser" name="item-chooser">
<option value="fontawesome">FontAwesome Icon</option>
<option value="image">Image</option>
</select>
</div>
<div class="cta-block-item-wrap cta-option cta-option-image">
<label for="block-image">Upload Image:</label>
<input name="block-image" class="block-image" type="text" value="">
<input type="button" class="cta-insert-image button button-primary button-large" value="Upload">
</div>
<div class="cta-block-item-wrap cta-option cta-option-fontawesome">
<label for="fa-icon-class">Choose FA Icon:</label>
<input type="text" name="fa-icon-class" class="fa-icon-class" value="">
</div>
</div>
Upvotes: 4
Reputation: 207861
Your hierarchy is wrong when you use .children()
. You should use .siblings()
.
cta-image-upload
and cta-fa-icon
are siblings of cta-block-item-wrap
(item_chooser's parent), not children.
Ex $(this).parent('.cta-block-item-wrap').siblings('.cta-image-upload').slideUp();
Upvotes: 0