Reputation: 2487
QUESTION:
Perform a "find()" excluding certain elements and their descendants.
REAL CASE:
Code Sample
The purpose of the code below is try to select all elements within $("#lbr_placehld")
, but exclude all those that have the attribute lbr_mval_placehld
and its descendants.
$("#lbr_placehld").find(":not([lbr_mval_placehld])");
HTML sample
<span id="lbr_placehld" lbr_mval_placehld="" lbr_mval_phld_grp_path="mg_bases_n_forms#1">
<div class="form-group">
<label class="col-xs-2 control-label no-padding-right" for="for_str_nm_base">Nome da Base</label>
<div class="col-xs-10">
<div class="clearfix">
<input lbr_mval_fld_nm="str_id_base" name="mg_bases_n_forms#1.str_id_base" type="hidden">
<input class="col-xs-5" lbr_invalidat_msg="" lbr_mval_fld_fdly_nm="Nome da Base" lbr_mval_fld_nm="str_nm_base" name="mg_bases_n_forms#1.str_nm_base" type="text" autocomplete="off" lbr_fdly_nm="Nome da Base 2">
<a href="#" title="Remover este item" class="lbr-tooltip" lbr_mval_op="rmthis" onclick="lbrad_MultivaluedManipulate(this);return false;">
<i class="fa fa-remove red field-border-icon"></i>
</a>
<div lbr_mval_container="" class="widget-box transparent">
<div class="widget-header widget-header-small">
<h6 class="smaller"></h6>
<div class="widget-toolbar">
<a href="#" title="Remover último item" class="lbr-tooltip" lbr_mval_op="rmlast" onclick="lbrad_MultivaluedManipulate(this);return false;" style="display: inline;">
<i class="fa fa-remove red border-icon"></i>
</a>
<a href="#" class="lbr-tooltip" lbr_mval_op="add" onclick="lbrad_MultivaluedManipulate(this);return false;" title="Adicionar item">
<i class="fa fa-plus blue border-icon"></i>
</a>
<a href="#" title="Remover todos itens" class="lbr-tooltip" lbr_mval_op="rmall" onclick="lbrad_MultivaluedManipulate(this);return false;" style="display:none;">
<i class="fa fa-remove red border-icon"></i>
</a>
</div>
</div>
<div class="widget-body">
<div class="widget-main">
<span lbr_mval_grp_path="mg_forms" lbr_mval_last_idx="3">
<div class="form-group">
<label class="col-xs-2 control-label no-padding-right" for="for_str_nm_base">Nome do Form</label>
<div class="col-xs-10">
<div class="clearfix">
<input lbr_mval_fld_nm="str_id_form" name="mg_bases_n_forms#1.str_id_form" type="hidden">
<input class="col-xs-5" lbr_invalidat_msg="" lbr_mval_fld_fdly_nm="Nome do Form" lbr_mval_fld_nm="str_nm_form" name="mg_bases_n_forms#1.str_nm_form" type="text" autocomplete="off" lbr_fdly_nm="Nome do Form 2">
<a href="#" title="Remover este item" class="lbr-tooltip" lbr_mval_op="rmthis" onclick="lbrad_MultivaluedManipulate(this);return false;">
<i class="fa fa-remove red field-border-icon"></i>
</a>
</div>
</div>
</div>
<hr>
</span>
<span lbr_mval_placehld="" lbr_mval_phld_grp_path="mg_forms#0">
<div class="form-group">
<label class="col-xs-2 control-label no-padding-right" for="for_str_nm_base">Nome do Form</label>
<div class="col-xs-10">
<div class="clearfix">
<input lbr_mval_fld_nm="str_id_form" name="mg_forms#0.str_id_form" type="hidden">
<input class="col-xs-5" lbr_invalidat_msg="" lbr_mval_fld_fdly_nm="Nome do Form" lbr_mval_fld_nm="str_nm_form" name="mg_forms#0.str_nm_form" type="text" autocomplete="off" lbr_fdly_nm="Nome do Form 1">
<a href="#" title="Remover este item" class="lbr-tooltip" lbr_mval_op="rmthis" onclick="lbrad_MultivaluedManipulate(this);return false;">
<i class="fa fa-remove red field-border-icon"></i>
</a>
</div>
</div>
</div>
<hr>
</span>
<span lbr_mval_placehld="" lbr_mval_phld_grp_path="mg_forms#1">
<div class="form-group">
<label class="col-xs-2 control-label no-padding-right" for="for_str_nm_base">Nome do Form</label>
<div class="col-xs-10">
<div class="clearfix">
<input lbr_mval_fld_nm="str_id_form" name="mg_forms#1.str_id_form" type="hidden">
<input class="col-xs-5" lbr_invalidat_msg="" lbr_mval_fld_fdly_nm="Nome do Form" lbr_mval_fld_nm="str_nm_form" name="mg_forms#1.str_nm_form" type="text" autocomplete="off" lbr_fdly_nm="Nome do Form 2">
<a href="#" title="Remover este item" class="lbr-tooltip" lbr_mval_op="rmthis" onclick="lbrad_MultivaluedManipulate(this);return false;">
<i class="fa fa-remove red field-border-icon"></i>
</a>
</div>
</div>
</div>
<hr>
</span>
<span lbr_mval_placehld="" lbr_mval_phld_grp_path="mg_forms#2">
<div class="form-group">
<label class="col-xs-2 control-label no-padding-right" for="for_str_nm_base">Nome do Form</label>
<div class="col-xs-10">
<div class="clearfix">
<input lbr_mval_fld_nm="str_id_form" name="mg_forms#2.str_id_form" type="hidden">
<input class="col-xs-5" lbr_invalidat_msg="" lbr_mval_fld_fdly_nm="Nome do Form" lbr_mval_fld_nm="str_nm_form" name="mg_forms#2.str_nm_form" type="text" autocomplete="off" lbr_fdly_nm="Nome do Form 3">
<a href="#" title="Remover este item" class="lbr-tooltip" lbr_mval_op="rmthis" onclick="lbrad_MultivaluedManipulate(this);return false;">
<i class="fa fa-remove red field-border-icon"></i>
</a>
</div>
</div>
</div>
<hr>
</span>
<span lbr_mval_placehld="" lbr_mval_phld_grp_path="mg_forms#3">
<div class="form-group">
<label class="col-xs-2 control-label no-padding-right" for="for_str_nm_base">Nome do Form</label>
<div class="col-xs-10">
<div class="clearfix">
<input lbr_mval_fld_nm="str_id_form" name="mg_forms#3.str_id_form" type="hidden">
<input class="col-xs-5" lbr_invalidat_msg="" lbr_mval_fld_fdly_nm="Nome do Form" lbr_mval_fld_nm="str_nm_form" name="mg_forms#3.str_nm_form" type="text" autocomplete="off" lbr_fdly_nm="Nome do Form 4">
<a href="#" title="Remover este item" class="lbr-tooltip" lbr_mval_op="rmthis" onclick="lbrad_MultivaluedManipulate(this);return false;">
<i class="fa fa-remove red field-border-icon"></i>
</a>
</div>
</div>
</div>
<hr>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<hr>
</span>
Upvotes: 0
Views: 377
Reputation: 2487
A more elaborate approach using @Taplar's "core" ideia.
For more explanation see the code notes below...
// NOTE: Make a JQuery find excluding certain elements and their descendants. By Questor
// . jqPntElOrPntQry - Ancestor over which a ".find()" will be executed using the
// "string" in jqFind. If it is a string then execute it as a JQuery query to define
// the ancestor. Not being a string and not being undefined then it will be the defined
// ancestor (resulting from a JQuery query). If it is undefined then execute the string
// in jqFind as a JQuery query to define the ancestor;
// . jqFind - Perform as a JQuery query on a ".find()" on the ancestor jqPntElOrPntQry.
// When jqPntElOrPntQry is undefined then, simplistically, execute the string in jqFind
// as a JQuery query for the elements you want to find excluding the elements that
// match jqExcl JQuery query and their descendants;
// . jqExcl - A JQuery query that matches the elements you want to exclude along with
// their descendants.
function findExclElmtsNDesc(jqPntElOrPntQry, jqFind, jqExcl){
// NOTE: The approach below makes a filter excluding all elements found in jqExcl
// JQuery query and their children, but excludes from that filter the "parent"
// element (jqElInst/jqFind) if it is also found in jqExcl jqExcl query. By Questor
// [Ref.: https://stackoverflow.com/a/58402312/3223785 ]
var fExclElmtsNDescRtn;
if (typeof jqPntElOrPntQry === "string" ||
jqPntElOrPntQry instanceof String) {
// [Ref.: https://stackoverflow.com/a/9436948/3223785 ]
jqPntElOrPntQry = $(jqPntElOrPntQry);
fExclElmtsNDescRtn = jqPntElOrPntQry.find(jqFind);
} else if (typeof jqPntElOrPntQry !== "undefined") {
fExclElmtsNDescRtn = jqPntElOrPntQry.find(jqFind);
} else {
// [Ref.: https://stackoverflow.com/a/16975373/3223785 ]
fExclElmtsNDescRtn = jqPntElOrPntQry = $(jqFind);
}
// NOTE: Find every nested element. By Taplar
fExclElmtsNDescRtn = fExclElmtsNDescRtn
// NOTE: Filter out any element that has the attribute, or is a descendant
// of an element that has the attribute. EXCLUDE the target element from the
// check. By Taplar and Questor
.filter(function(){
return $(this).closest(jqExcl).not(jqPntElOrPntQry).length === 0;
});
return fExclElmtsNDescRtn;
}
Thanks! =D
Upvotes: 0
Reputation: 24965
var $topElement = $("#lbr_placehld");
// find every nested element
$topElement.find('*')
// filter out any element that has the attribute,
// or is a descendant of an element that has the attribute.
// EXCLUDE the top element from the attribute check
.filter(function(){
return $(this).closest('[lbr_mval_placehld]').not($topElement).length === 0;
});
Upvotes: 1