I'm running into this quirk between how Chrome and Firefox execute this function, but I can't figure out why Firefox won't execute. I have checkboxes for which a function listens for any change in any checkbox, then executes some text to appear. But, for one checkbox, I would like to interrupt the usual text and do some regex on it before completion. So, I have a mousedown
event listener which tries to gain this effect. My rationale is that the mousedown
will execute code before the checkbox
change event (not sure if this is true across all browsers).
The weirdness arises when during this mousedown
function, a variable called amt
requires a value. If the variable amt
is entered through a prompt dialog, Firefox will not execute the rest of the function. If, instead, the same variable amt
is entered through an <input>
element instead, the function works fine. In Chrome, the same results are achieved with either method.
Can someone please explain the difference and whether there is a better way to "halt" a function so another function can run before completion?
A fiddle here: http://jsfiddle.net/ufgvoghw/7/
JS
dxOuts = {
dxOut100: 'ITEM #0:',
dxOut101: 'ITEM #1:',
dxOut102: 'ITEM #2: '
};
var final = '';
var sel = null;
$('#_box0').mousedown(function () {
$('#dxOut100').prop('disabled', true); // <-- disable checkbox to ensure click event doesn't take place when label mousedown occurs
// var amt = prompt('Enter amount'); //<-- this doesn't work in firefox, but works in chrome
var amt = $('#amt').val(); //<-- this works in FF and chrome
dxOuts.dxOut100 = dxOuts.dxOut100.replace(/#[\d*(?=\d)]/, '#'+amt);
$('#dxOut100').prop('disabled', false).trigger('click');
});
function printf(){
final += dxOuts[sel] + '\n\n';
$('#output').val(final);
}
$('input:checkbox').on('change', function () {
if($(this).is(':checked')){
sel = $(this).attr('id');
printf();
}
});
HTML
<label id="_box0">
<input type='checkbox' id='dxOut100'>ITEM #</label>
<input id="amt" size=5>
<br>
<label id="_box1">
<input type='checkbox' id='dxOut101'>ITEM #1</label>
<br>
<label id="_box2">
<input type='checkbox' id='dxOut102'>ITEM #2</label>
<br>
<br>
<textarea id='output' cols=25 rows=5></textarea>
Actually, the code below prompt is being executed as expected. The problem is the prompt prevents the default change event for the checkbox to occur. So the string is not added to the end of output.
Why so hard?
If you want separate change event logic for first checkbox, just do it, and move the common code to separate function:
var dxOuts = {
dxOut100: 'ITEM #0:',
dxOut101: 'ITEM #1:',
dxOut102: 'ITEM #2: '
};
var final = '';
var sel = null;
function printf(){
final += dxOuts[sel] + '\n\n';
$('#output').val(final);
}
//common code to call for all checkboxes
function checkboxCnahged(e) {
var checkBox = $(e.target);
if(checkBox.is(':checked')){
sel = checkBox.attr('id');
printf();
}
}
$('#dxOut100').change(function (e) {
if ($(e.target).is(':checked')) { // show prompt only if checked
var amt = prompt('Enter amount'); // <-- now this works
//var amt = $('#amt').val(); //<-- this works in FF and chrome
console.log(amt);
dxOuts.dxOut100 = dxOuts.dxOut100.replace(/#\d*/, '#' + amt); //fixed the regex to replace the whole number, not only the first digit
}
checkboxCnahged.apply(this, arguments);
});
$('input:checkbox:not(#dxOut100)').on('change', function () {
checkboxCnahged.apply(this, arguments);
});
And shorter version with one change handler:
var dxOuts = {
dxOut100: 'ITEM #0:',
dxOut101: 'ITEM #1:',
dxOut102: 'ITEM #2: '
};
var final = '';
var sel = null;
function printf(){
final += dxOuts[sel] + '\n\n';
$('#output').val(final);
}
$('input:checkbox').change(function (e) {
if ($(e.target).is(':checked')) { // show prompt only if checked
if (e.target.id === 'dxOut100') {
var amt = prompt('Enter amount'); // <-- now this works
dxOuts.dxOut100 = dxOuts.dxOut100.replace(/#\d*/, '#' + amt);
}
sel = e.target.id;
printf();
}
});