简体   繁体   中英

Refactor Select Elements Matching List of Values

I'm looking for some help on how to write some code to reduce redundant code while maintaining clarity.

Given this HTML (vastly simplified from the real thing):

<div>
    <fieldset>
        <legend>Select Day for Code <span class="typeCode">089</span></legend>
        <select name="date1" id="date1" class="dateSelect">
            <option value="Mon">Monday</option>
            <option value="Tue">Tuesday</option>
            <option value="Wed">Wednesday</option>
            <option value="Thu">Thursday</option>
            <option value="Fri">Friday</option>
        </select>
    </fieldset>
    <fieldset>
        <legend>Select Day for Code <span class="typeCode">087</span></legend>
        <select name="date2" id="date2" class="dateSelect">
            <option value="Mon">Monday</option>
            <option value="Tue">Tuesday</option>
            <option value="Wed">Wednesday</option>
            <option value="Thu">Thursday</option>
            <option value="Fri">Friday</option>
        </select>
    </fieldset>
</div>

I am wanting to see which days were selected for specific codes. Using jQuery, I could use something like this:

$(
    "div fieldset:has(.typeCode):contains(061) .dateSelect option:selected," +
    "div fieldset:has(.typeCode):contains(064) .dateSelect option:selected," +
    "div fieldset:has(.typeCode):contains(065) .dateSelect option:selected", +
    "div fieldset:has(.typeCode):contains(089) .dateSelect option:selected," +
    "div fieldset:has(.typeCode):contains(090) .dateSelect option:selected"
).each(
    function(index) {
        doSomethingHere();
    }
);

However, it seems like there ought to be a way to simplify that selector. Something like this would be nice, but it doesn't seem to be possible:

$(
    "div fieldset:has(.typeCode):contains([061,064,065,089,090]) .dateSelect option:selected"
).each(
    function(index) {
        doSomethingHere();
    }
);

All I can come up with is something like this:

var typeCodes = ["061", "064", "065", "089", "090"];

$("div fieldset:has(.typeCode)").each(
    function(index) {
        var code = $(this).find(".typeCode").text();
        if ($.inArray(code, typeCodes) > -1) {
            var dateSelected = $(this).find(".dateSelect option:selected");
            doSomethingHere();
        }
    }
);

That eliminates duplicate code, but at the cost of reduced clarity.

Is there a better way to do something like this?

I would throw typecode on each fieldset as a custom data-* attribute - filter out the ones you don't want - then check the select ..

HTML:

<fieldset data-typecode="089">
    <legend>Select Day for Code <span class="typeCode">089</span></legend>
    <select name="date1" id="date1" class="dateSelect">
        <option value="Mon">Monday</option>
        <option value="Tue">Tuesday</option>
        <option value="Wed">Wednesday</option>
        <option value="Thu">Thursday</option>
        <option value="Fri">Friday</option>
    </select>
</fieldset>

And the JS:

var typeCodes = ["061", "064", "065", "089", "090"];

$("fieldset[data-typecode]").filter(function() {
    //Get fieldsets with typecodes in above array and with selected options
    var code = $(this).data("typecode");
    return typeCodes.indexOf(code) > -1 && $(this).find("select option:selected").length
}).each(function() {
    //Do something on each fieldset
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM