以下脚本使用for:x
类名启用/禁用其嵌套表单控件。问题是嵌套的for:y
元素在它们不应该被启用时被启用。只有在启用嵌套for:y
时才能启用它们。
有人可以为我提供额外的过滤器来排除嵌套for:*
类中的表单元素吗?
换句话说,在下面的示例中,当检查losssold
时,除for:losssold
for:has-buy-sell-agreementtrue
内的子元素元素外,has-buy-sell-agreementtrue
的所有子输入都应启用{{1}还没有检查过。
所以我认为只想在for:has-buy-sell-agreementtrue
中排除这些元素会更容易。
<script type="text/javascript">
$('[class*="for:"]').each(function(){
var klass=$(this).attr('class'),element;
var that = this;
$.each(klass.split(' '),function(index,value){
if(!value)return;
if (value.substr(0,4)=='for:')
element=value.substr(4);
});
$('[name="' + $('#'+element).attr('name') + '"]')
.click(function(){
$(that).toggleClass('disabled', !$('#'+element).is(':checked'))
.find('input,select,textarea') /* insert edge case here */
.each(function(){
if ($('#'+element).is(':checked'))
$(this).removeAttr('disabled');
else
$(this).attr('disabled','disabled');
});
})
.trigger('click');
});
</script>
<li>What would you like to see happen to your business when you (or a co-owner) die, become disabled, or retire? <br/>
<ul><li><label><input type="radio" name="loss" id="losssold" value="sold"/> Sold to other Owners/another Business</label>
<ul class="for:losssold">
<li>Do you have a buy-sell agreement?<br/>
<label><input type="radio" name="has-buy-sell-agreement" id="has-buy-sell-agreementtrue" value="true"/> Yes</label>
<label><input type="radio" name="has-buy-sell-agreement" id="has-buy-sell-agreementfalse" value="false"/> No</label><br/>
<ol class="for:has-buy-sell-agreementtrue"> <!-- nested for class; inner elements shouldn't be affected -->
<li><label for="buy-sell-last-updated">When was the agreement last updated?</label><br/>
<input type="text" name="buy-sell-last-updated" id="buy-sell-last-updated" value=""/>
</li>
<li>Is the agreement funded?<br/>
<label><input type="radio" name="buy-sell-is-funded" id="buy-sell-is-fundedtrue" value="true"/> Yes</label>
<label><input type="radio" name="buy-sell-is-funded" id="buy-sell-is-fundedfalse" value="false"/> No</label>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
答案 0 :(得分:2)
您可能正在寻找'not()'过滤器。在您指定的行中,试试这个:
.find('input,select,textarea').not("[class='for\\:has-buy-sell-agreementtrue'] *")
或者您提到的变量:
.find('input,select,textarea').not("[class='for\\:" + element + "true'] *")
我不认为通常的类选择器(点)会起作用,因为jQuery可能认为它是一个伪选择器,如'checked'或'contains。'
<强> EDITED 强>
Okie dokie,我再给它一个镜头:如果你想缩小输入数量,选择和返回的textrea元素,那么你可以缩小'find'功能或扩大'not'功能。例如,如果您只想对form_1中的表单元素执行操作,那么您可以执行以下操作:
.find('#form_1 input, #form_1 select, #form_1 textarea').not("[class='for\\:" + element + "true'] *");
这里有关于'not'过滤器的更多细节。 'not'过滤器执行以下操作:
因此,上面的元素集只包含不在class = for:has-buy-sell-agreement内的input,select和textarea元素。
哦,我将这个过滤器复制并粘贴到一个简单的html文档上然后就可以了。所以你应该全力以赴!
后来戴夫, 祝你好运。
答案 1 :(得分:2)
filter
函数非常适合删除不匹配表达式的项目,因此您可以更改此内容:
.find('input,select,textarea')
进入这个?
.find('input,select,textarea')
.filter(function() {
// return false to remove an element from the set
return $(this)
.closest('[class^="for\\:"]')
.hasClass('for:' + element);
})
我们的想法是删除任何输入,选择或textareas,这些输入,选择或textareas具有除您所需父级之外的最近父级。
另请注意,我在选择器中对您的:
字符进行了双重转义。 :
是一个在类名中使用的不寻常的字符,因为它暗示了“伪”选择器,并且还会使jquery绊倒(除非你像我上面那样逃避它)。
<小时/> 的修改
啊,是的,我们希望禁用通过嵌套的“for:”div传播,而不是启用 ....我们可以修改这个通过移动过滤如下所示。 (过滤器被移动到一个单独的函数,使其更具可读性。)
.find('input,select,textarea')
.each(function() {
if ($('#'+element).is(':checked')) {
if (isDirectDescendant(this, element)) {
$(this).removeAttr('disabled');
}
}
else {
$(this).attr('disabled','disabled');
}
});
function isDirectDescendant(e, element) {
return $(e)
.closest('[class^="for\\:"]')
.hasClass('for:' + element);
}
答案 2 :(得分:0)
重构HTML是关键:
<li>What would you like to see happen to your business when you (or a co-owner) die, become disabled, or retire? <br/>
<ul>
<li>
<input type="radio" name="loss" id="losssold" value="sold"/>
<label for="losssold"> Sold to other Owners/another Business
</label>
<ul class="nestedList">
<li>Do you have a buy-sell agreement?<br/>
<input type="radio" name="has-buy-sell-agreement" id="has-buy-sell-agreementtrue" value="true"/>
<label for="has-buy-sell-agreementtrue"> Yes
</label>
<input type="radio" name="has-buy-sell-agreement" id="has-buy-sell-agreementfalse" value="false"/>
<label for="has-buy-sell-agreementfalse"> No
</label>
<br/>
<ol class="nestedList">
<li>
<label for="buy-sell-last-updated">
When was the agreement last updated?
</label>
<br/>
<input type="text" name="buy-sell-last-updated" id="buy-sell-last-updated" value=""/>
</li>
<li>Is the agreement funded?
<br/>
<input type="radio" name="buy-sell-is-funded" id="buy-sell-is-fundedtrue" value="true"/>
<label for="buy-sell-is-fundedtrue"> Yes
</label>
<input type="radio" name="buy-sell-is-funded" id="buy-sell-is-fundedfalse" value="false"/>
<label for="buy-sell-is-fundedfalse"> No
</label>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
我已将<input>
标记移到标签之外,以便所有输入都具有<li>
的直接父级。这使得jQuery更容易想出来。这就是我所拥有的:
$('.nestedList input, .nestedList select, .nestedList textarea').attr('disabled', 'disabled');
$('input:radio').click(function() {
$('[name="' + $(this).attr('name') + '"]').each(function() {
if($(this).val() != 'false')
{
if(this.checked == true)
{
$(this).siblings(".nestedList").children('li').children('input, select, textarea').removeAttr('disabled');
} else
{
$(this).siblings(".nestedList").children('li').children('input, select, textarea').attr('disabled','disabled');
}
}
});
});
我已经使用HTML的变体进行了测试,看起来效果很好。
答案 3 :(得分:0)
我最终通过在事件被触发时递归解析子for^=
元素来解决这个问题。
$(function(){
$('[class^="for:"]').each(function(){
var that=this;
function getElement(forElement){
var klass=$(forElement).attr('class'),element;
$.each(klass.split(' '),function(index,value){
if(!value)return;
if(value.substr(0,4)=='for:'){
element=value.substr(4);
return false;
}
});
return '#' + element;
}
function parse(forElement){
var element = getElement(forElement);
if (element == '#') return;
$(forElement)
.toggleClass('disabled', !$(element).is(':checked'))
.find('input,select,textarea')
.each(function(){
if ($(element).is(':checked'))
$(this).removeAttr('disabled');
else
$(this).attr('disabled','disabled');
})
.end()
.find('[class^="for:"]')
.each(function() { parse(this); });
}
var element = getElement(this);
$('[name="' + $(element).attr('name') + '"]')
.click(function() { parse(that); });
parse(this);
});
});