user3430245 user3430245 - 5 months ago 15
Javascript Question

How can I apply CSS to a link if at least one input is not original, and undo that change if all inputs are original?

I have a bunch of checkboxes, radio buttons, and text fields on my page. They all have '_boom' appended to the end of the id. I want to detect if any one of these inputs is not its original value, and if so, apply CSS to a button called 'save' on the page. Then, if the user reverts any changes they made and all inputs have their original values, I want to undo the CSS.

I've gotten close with the code below. But let's say I check 3 checkboxes. Upon checking the 1st box, the CSS changes. Good! I check the 2nd and 3rd boxes. The CSS stays the same. Good! But then I uncheck ONE of the boxes, and the CSS reverts. Bad! The CSS should only revert if I undo every change.



$('[id*="_boom"]').change(function() {
var sType = $(this).prop('type'); //get the type of attribute we're dealing with
if( sType === "checkbox" || sType === "radio" ){ //checkbox or radio type
var originalCheckedState = $(this).prop("defaultChecked");
var currentCheckedState = $(this).prop("checked");

if(currentCheckedState !== originalCheckedState){
$("a#save").css("color","#CCCCCC");
}
else {
$("a#save").css("color","black");
}
}

if( sType === "text" ){ //text type
var originalValue = $(this).prop("defaultValue");
var currentValue = $(this).val();

if(currentValue !== originalValue){
$("a#save").css("color","#CCCCCC");
}
else {
$("a#save").css("color","black");
}
}

});

#save {
color: black;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="checkbox" id="check_boom" />
<input type="checkbox" id="check1_boom" />
<input type="checkbox" id="check2_boom" />
<input type="radio" id="radio_boom" />
<input type="text" defaultValue="test" id="text_boom" />
<input type="text" defaultValue="test" id="text2_boom" />
<a href="http://www.google.com" id="save">Save</a>




Answer

There are many possible improvements in your code to make it cleaner and standardized. Things like instead of relying on id you should consider class attribute and all... but I will not revamp your code. Here's the solution to your existing code.

The idea is loop through all the form elements and if atleast one of the elements is different than its default value then set the flag and come out of the loop.

At the end, check for that flag and set the css accordingly.

For this, I have enclosed your elements into a form form1.

$("#form1 :input").change(function() {
        var changed = false;
        formElems = $("#form1 :input");

        for(i=0;i<formElems.length; i++){
        var sType = $(formElems[i]).prop("type");
            if(sType === "checkbox" || sType === "radio"){
                if($(formElems[i]).prop("defaultChecked") !== $(formElems[i]).prop("checked")){
                changed = true;
                break;
            }
            }else if(sType === "text"){
                if($(formElems[i]).prop("defaultValue") !== $(formElems[i]).val()){
                changed = true;
                break;
            }
            }
        }

    if(changed){
    $("a#save").css("color","#CCCCCC"); 
    }else{
    $("a#save").css("color","black"); 
    }
});

And here is your form

<form id="form1">
<input type="checkbox" id="check_boom" />
<input type="checkbox" id="check1_boom" />
<input type="checkbox" id="check2_boom" />
<input type="radio" id="radio_boom" />
<input type="text" defaultValue="test" id="text_boom" />
<input type="text" defaultValue="test" id="text2_boom" />
<a href="http://www.google.com" id="save">Save</a>
</form>