<li class="numeric optional" id="contest_max_retweet_input"><label for="contest_max_retweet">Winning retweet number</label><input id="contest_max_retweet" name="contest[max_retweet]" size="50" type="text" /></li>
<li class="numeric optional" id="contest_numofwinners_input"><label for="contest_numofwinners">Number of winners (1-100)</label><input id="contest_numofwinners" name="contest[numofwinners]" size="50" type="text" /></li>
How can I use JQuery to Hide the field: contest_numofwinners_input if there is a value specified by the user in the field: contest_max_retweet_input?
You could try something like:
$('#contest_max_retweet').change(
function(){
if ($(this).val().length) {
$('#contest_numofwinners').hide();
}
else {
$('#contest_numofwinners').show();
}
});
JS Fiddle demo
This hides only the input
element itself, not the containing li
, or corresponding label
, element.
Something like
$("#contest_max_retweet").change(function() {
if($(this).val().length) {
$("#contest_numofwinners").hide();
}
else {
$("#contest_numofwinners").show();
}
})
.trigger("change");
$('#contest_max_retweet').change(function() {
if($('#contest_numofwinners').val() != "")
$('#contest_numofwinners').hide();
});
The problem with change is that you have to leave the input (blur) in order for the function to fire. That's why I prefer keyup.
$("#contest_max_retweet").keyup(function() {
if($(this).val().length > 0) {
$("#contest_numofwinners").hide();
}
else {
$("#contest_numofwinners").show();
}
});
I would toggle based on negation of value at change. I'd also go ahead and trigger the event handler at load to give an initial show/hide state (using a name-spaced event to avoid causing other bound functionality executing).
(Edit: I like what Brandon Boone did regarding keyup for instant action and added a comment to the event name on my code. It will, however, add a little overhead as the function is run for every stroke on the keyboard as opposed to when the field is blurred.)
Demo:
http://jsfiddle.net/JAAulde/fUKfb/3/
Code:
var namespaced_event = 'change.hideRetweet', //use `keyup.hideRetweet` here to avoid waiting for the input to be blurred
contest_max_retweet_wrapper = $( '#contest_max_retweet' ).closest( 'li' ); //hides entire input, label, and container--could be pared down if desired
$( '#contest_numofwinners' )
.bind( namespaced_event, function()
{
contest_max_retweet_wrapper.toggle( ! $( this ).val() );
} )
.triggerHandler( namespaced_event );
David Thomas's answer certainly works well and I would use this for simple cases.
However, I've been working on a plugin that does this with multiple conditions and with multiple elements. I would like to share that now.
Here is the jsfiddle that works for your problem: http://jsfiddle.net/natedavisolds/rVehh/3/
Essentially, load the plugin then on load:
var React = $.extend({}, $.fn.reactor.helpers); // Easier to work with helpers
$('#contest_numofwinners_input').reactIf('#contest_max_retweet', React.IsBlank);
The nice thing is that you can chain the reactIf statement to a set of rules.
Here's the plugin.
(function($){
$.fn.reactTo = function(selector) {
var $elements = $(selector),
$reactor_element = $(this),
_proxy_event = function() {
$reactor_element.trigger('change.reactor');
};
$elements.filter('select').bind('change.reactor', _proxy_event);
$elements.filter('input').bind('keyup.reactor', _proxy_event);
return this;
};
$.fn.reactIf = function(sel, exp_func) {
var $sel = $(sel);
var _func = function() {
return exp_func.apply($sel);
};
this.each(function() {
if (!$(this).hasClass('reactor')) { $(this).reactor(); }
var conditions_arry = $(this).data('conditions.reactor');
if (!$.isArray(conditions_arry)) { conditions_arry = []};
conditions_arry.push(_func);
$(this).data('conditions.reactor', conditions_arry);
});
$(this).reactTo(sel);
return this;
};
$.fn.react = function() {
this.each(function() {
$(this).trigger('change.reactor')
});
return this;
};
$.fn.reactor = function(options) {
var settings = $.extend({}, $.fn.reactor.defaults, options);
this.each(function() {
// var opts = $.meta ? $.extend({}, settings, $this.data()) : settings;
var $element = $(this);
if (!$element.hasClass('reactor')) { $element.data('conditions.reactor', []).addClass('reactor'); }
var is_reactionary = function() {
var conditionalArray = $(this).data('conditions.reactor');
var r = true;
$.each(conditionalArray, function() {
r = (r && this.call());
});
return r;
}
var reaction = function(evt) {
evt.stopPropagation();
if (is_reactionary.apply(this)) {
settings.compliant.apply($element);
} else {
settings.uncompliant.apply($element);
}
}
$element.bind('change.reactor', reaction);
});
return this;
};
$.fn.reactor.defaults = {
compliant: function() {
$(this).show();
},
uncompliant: function() {
$(this).hide();
}
};
$.fn.reactor.helpers = {
NotBlank: function() {
return( $(this).val().toString() != "" )
},
IsBlank: function() {
return( $(this).val().toString() == "" )
},
EqualTo: function(matchStr) {
var _func = function() {
var v = $(this).val();
if (v) { return( v.toString() == matchStr ); }
else { return false; }
}
return _func;
},
LessThan: function(number) {
var _func = function() {
var v = $(this).val();
return(!(v && parseInt(v) > number));
}
return _func;
},
MoreThan: function(number) {
var _func = function() {
var v = $(this).val();
return(!(v && parseInt(v) < number));
}
return _func;
},
Between: function(min, max) {
var _func = function() {
var v = $(this).val();
return(!(v && (parseInt(v) > max || parseInt(v) < min)));
}
return _func;
},
BetweenSameLength: function(min, max) {
var len = min.toString().length;
var _func = function() {
var v = $(this).val();
return(!(v && v.length == len && (parseInt(v) > max || parseInt(v) < min)));
}
return _func;
}
};
})(jQuery);