I've got some javascript to change a select box to a text box if an option is selected then change that text box back to a select box if the user hits delete/backspace to the point where they clear the text box.
http://jsfiddle.net/5e1stz46/6/
<select id='visit'>
<option value='1'>option1</option>
<option value='2'>option2</option>
<option value='3'>option3</option>
<option value='Other'>Other</option>
</select>
$('#visit').on('change', function () {
if ((this.value) == 'Other') {
tmp = this;
$(this).replaceWith($('<input/>',{'type':'text','id':'visit'}));
}
});
$(document).keyup(function(e){
if( $('#visit').length ) {
if($('#visit').is(":focus") && $("#visit").val().length == 0){
$("#visit").replaceWith(tmp);
}
}
});
$('#visit').keyup(function(e){
if(e.keyCode == 46 || e.keyCode == 8) {
alert('box now empty');
}
});
When the text box changes back into a select box, all the events it had seem to be lost.
Should I be somehow reading the event listeners when the select box comes back or should I be saving the select box differently to start with?
The events got removed because you're removing associated Html element from the DOM. You can have both select and input and play with .hide() and .show to visualize the correct element and the events will work fine.
Another approach could be to use event delegation.
Changed Html:
<div id="wrapper">
<select id='visit'>
<option value='1'>option1</option>
<option value='2'>option2</option>
<option value='3'>option3</option>
<option value='Other'>Other</option>
</select>
</div>
Changed JavaScript:
$('#wrapper').on('change', '#visit', function () {
if ((this.value) == 'Other') {
tmp = this;
$(this).replaceWith($('<input/>',{'type':'text','id':'visit'}));
}
});
[ ... ]
Rest of the code remains the same. Here is an updated JsFiddle Demo.
Once you remove the element from DOM, all its handlers are gone as well.
One solution would be to always keep the element, but just hide it from the user's view.
$('select[name=visit]').on('change', function () {
if (this.value == 'Other') {
$(this).addClass('hide');
$('input.hide').removeClass('hide');
}
});
$(document).keyup(function (e) {
var $elem = $('input[name=visit]');
if ($elem.length) {
if ($elem.is(":focus") && $elem.val().length == 0) {
$elem.addClass('hide');
$("select[name=visit]").removeClass('hide');
}
}
});
$('input[name=visit]').keyup(function (e) {
if (e.keyCode == 46 || e.keyCode == 8) {
alert('box now empty');
}
});
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select name="visit">
<option value='1'>option1</option>
<option value='2'>option2</option>
<option value='3'>option3</option>
<option value='Other'>Other</option>
</select>
<input type="text" name="visit" class="hide" />
Also as there could be only one element with the unique id I always avoid using id attribute in dynamic HTML.
Second solution
Add a parent div wrapper and attached the handler to it as shown below:
$('#wrapper').on('change', '#visit', function () {
if ((this.value) == 'Other') {
tmp = this;
$(this).replaceWith($('<input/>', {
'type': 'text',
'id': 'visit'
}));
}
});
$(document).keyup(function(e){
if( $('#visit').length ) {
if($('#visit').is(":focus") && $("#visit").val().length == 0){
$("#visit").replaceWith(tmp);
}
}
});
$('#visit').keyup(function(e){
if(e.keyCode == 46 || e.keyCode == 8) {
alert('box now empty');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div id="wrapper">
<select id='visit'>
<option value='1'>option1</option>
<option value='2'>option2</option>
<option value='3'>option3</option>
<option value='Other'>Other</option>
</select>
</div>
JSFIDDLE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With