简体   繁体   中英

Applying different styles to different elements in a better way?

I have this function , which applies css styles + couple of plugins + hide/show to a bunch of elements. These elements are children of "item" element and have id's which contain this "item" number. Also these rules apply for different types of items. It works fine, but it is monstrous. Can you suggest couple of better ways of doing this?

Note: PackageElement and duration are global vars.

function HideItemElements(Type,ItemNum) {
                    switch (Type) {
                        case 'HW':
                            $("#Country" + ItemNum).addClass("Chzn").show().chosenImage({ width: "204px", no_results_text: "Oops, nothing found!"});                         
                            $("#Countrylabel" + ItemNum).show();
                            $("#LineOptions" + ItemNum).text("Edit Support");
                            $("#ItemImage" + ItemNum).attr("src", "Styles/images/u79_normal.png");
                            break;
                        case 'SW':
                            if (PackageElement.attr("name") == "HW") {
                            }
                            else {
                                $("#Serials" + ItemNum).show();
                                $("#Serialslabel" + ItemNum).show();
                                $("#OtherOpts" + ItemNum)
                                .attr("style", "height:113px");
                            }
                            $("#ItemImage" + ItemNum).attr("src", "Styles/images/u131_normal.png");
                            break;
                        case 'SERVICE':
                            $("#ItemImage" + ItemNum).attr("src", "Styles/images/u149_normal.png");
                            $("#LineOptions" + ItemNum).hide();
                            break;
                        case 'CONTRACT':
                            if (PackageElement.attr("name") == "HW") {
                                $("#Countrylabel" + ItemNum).hide();
                                $("#Country" + ItemNum).hide().removeClass("Chzn");
                                $("#OtherOpts" + ItemNum).children().eq(2).hide();
                                if (duration.get_selectedItem().get_value() == "Other") {
                                    $("#ItemStarting" + ItemNum).show()
                                    .datepicker({ dateFormat: "dd-mm-yy" })
                                    .datepicker("setDate", "+0d")
                                    .attr("style", "top:9px");
                                    $("#ItemStartinglabel" + ItemNum).show()
                                    .attr("style", "top:-4px");
                                    $("#ItemEnd" + ItemNum).show()
                                    .datepicker({ dateFormat: "dd-mm-yy" })
                                    .datepicker("setDate", "+1y")
                                    .attr("style", "top:52px");
                                    $("#ItemEndlabel" + ItemNum).show()
                                    .attr("style", "top:38px");
                                    $("#OtherOpts" + ItemNum)
                                    .attr("style", "height:82px");
                                }
                                else {
                                    $("#ItemDuration" + ItemNum).show().addClass("Chzn").chosen({ width: "204px", disable_search: true });
                                    $("#ItemDurationlabel" + ItemNum).show();
                                }
                            }
                            else if (PackageElement.attr("name") == "SW") {
                                $("#Serials" + ItemNum).hide();
                                $("#Serialslabel" + ItemNum).hide();
                                if (duration.get_selectedItem().get_value() == "Other") {
                                    $("#ItemStarting" + ItemNum).show()
                                     .datepicker({ dateFormat: "dd-mm-yy" })
                                     .datepicker("setDate", "+0d")
                                     .attr("style", "top:9px");
                                    $("#ItemStartinglabel" + ItemNum).show()
                                    .attr("style", "top:-4px");
                                    $("#ItemEnd" + ItemNum).show()
                                    .datepicker({ dateFormat: "dd-mm-yy" })
                                    .datepicker("setDate", "+1y")
                                    .attr("style", "top:52px");
                                    $("#ItemEndlabel" + ItemNum).show()
                                    .attr("style", "top:38px");
                                    $("#OtherOpts" + ItemNum)
                                    .attr("style", "height:82px");
                                }
                                else {
                                    $("#ItemDuration" + ItemNum).show()
                                    .attr("style", "top:9px").addClass("Chzn").chosen({ width: "204px", disable_search: true });
                                    $("#ItemDurationlabel" + ItemNum).show();
                                    $("#ItemStartinglabel" + ItemNum).show()
                                    .attr("style", "top:38px");
                                    $("#ItemStarting" + ItemNum).show()
                                    .datepicker({ dateFormat: "dd-mm-yy" })
                                    .datepicker("setDate", "+0d")
                                    .attr("style", "top:52px");
                                    $("#OtherOpts" + ItemNum)
                                    .attr("style", "height:82px");
                                } 
                            }
                            else {              
                                if (duration.get_selectedItem().get_value() == "Other") {
                                    $("#ItemStarting" + ItemNum).show()
                                     .datepicker({ dateFormat: "dd-mm-yy" })
                                     .datepicker("setDate", "+0d")
                                     .attr("style", "top:9px");
                                    $("#ItemStartinglabel" + ItemNum).show()
                                    .attr("style", "top:-4px");
                                    $("#ItemEnd" + ItemNum).show()
                                    .datepicker({ dateFormat: "dd-mm-yy" })
                                    .datepicker("setDate", "+1y")
                                    .attr("style", "top:52px");
                                    $("#ItemEndlabel" + ItemNum).show()
                                    .attr("style", "top:38px");
                                    $("#OtherOpts" + ItemNum)
                                    .attr("style", "height:208px");
                                }
                                else {
                                    $("#ItemDuration" + ItemNum).show()
                                    .attr("style", "top:9px").addClass("Chzn").chosen({ width: "204px", disable_search: true });
                                    $("#ItemDurationlabel" + ItemNum).show();
                                    $("#ItemStartinglabel" + ItemNum).show()
                                    .attr("style", "top:38px");
                                    $("#ItemStarting" + ItemNum).show()
                                    .datepicker({ dateFormat: "dd-mm-yy" })
                                    .datepicker("setDate", "+0d")
                                    .attr("style", "top:52px");
                                    $("#OtherOpts" + ItemNum)
                                    .attr("style", "height:208px");
                                }
                                $("#Serials" + ItemNum).show()
                                .attr("style", "top:96px; left: -97px; width: 296px;");
                                $("#Serialslabel" + ItemNum).show()
                                .attr("style", "left:-97px; top:84px");
                            }
                            $("#LineOptions" + ItemNum).hide();
                            $("#ItemImage" + ItemNum).attr("src", "Styles/images/u77_normal.png");
                            break;
                        case 'ACCESSORY':
                            $("#LineOptions" + ItemNum).hide();
                            $("#ItemImage" + ItemNum).attr("src", "Styles/images/u90_normal.png");
                            break;
                    }

If you need me to add something to the question - ask for it in the comments please.

Edit: The main issue is the "contract" case.

You could also tidy things up significantly if you had separate functions to handle each process, for example:

$("#ItemStarting" + ItemNum).show()
  .datepicker({ dateFormat: "dd-mm-yy" })
  .datepicker("setDate", "+0d")
  .attr("style", "top:52px");

is something that appears 5 times in your switch, you could create a function & handle it like this instead

function setup_item_starting(ItemNum, date_format, set_date, top_px) {
    $("#ItemStarting" + ItemNum).show()
      .datepicker({ dateFormat: date_format })
      .datepicker("setDate", set_date)
      .css("top", top_px);
}

and then simply perform calls like:

setup_item_starting(ItemNum, "dd-mm-yy", "+0d", "52px");

in your switch statement, whenever you need to perform a change.

Do the same kind of thing for your other elements like ItemDurationlabel ItemDuration ItemEnd etc.. and you'll quickly chop your switch statement down to a reasonable size.

You are trying to change the DOM/HTML presentation based on runtime state in javascript. It looks like you're looking for a binding framework such as KnockoutJs or AngularJs!

A binding framework does exactly what you need: it moves the behavior into declarations (see example) so that you then only have to manipulate your javascript runtime state afterwards. Doing so, frees up your hands to deal with your businesslogic without having to deal with event-handlers and DOM manipulation all the time. The binding framework will reflect any runtime state change in the DOM for you.

This is also the 'modern' way to go these days, especially in larger (enterprise?) projects. Especially AngularJs is currently soaring in popularity due to its robustness (provides a total solution, including dependency injection, routing, service management and so on).

Declarative behavior example with KnockoutJs:

Javascript runtime state:

var countries = [{ name: 'Germany', type: 'HW' }, { name: 'Iran', type: 'SW' }];

HTML with behavior binding

<ul data-bind="foreach: countries">
    <li data-bind="text: $data.name, css: { Chzn: $data.type == 'HW' }"></li>
</ul>

Now any change to this data will automagically result in changes to the HTML. AngularJs will have similar facilities.

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