skip to Main Content

I’m using the following code to enable/disable radio buttons according to the radio button value which I clicked.

$(document).ready(function(){
//array
var data = [ 
    {"fruit": "apple", "quantity": "5", "package": "bag"}, 
    {"fruit": "apple", "quantity": "10", "package": "bag"}, 
    {"fruit": "apple", "quantity": "15", "package": "bag"}, 
    {"fruit": "grapes", "quantity": "10", "package": "box"}, 
    {"fruit": "mango", "quantity": "5", "package": "bag"}, 
    {"fruit": "mango", "quantity": "10", "package": "bag"},
    {"fruit": "mango", "quantity": "15", "package": "box"},
    {"fruit": "mango", "quantity": "20", "package": "box"},
    {"fruit": "pineapple", "quantity": "5", "package": "bag"},
    {"fruit": "pineapple", "quantity": "10", "package": "bag"},
    {"fruit": "pineapple", "quantity": "15", "package": "box"},
    {"fruit": "pineapple", "quantity": "20", "package": "box"} 
];

function info(cat,value){
    var filteredValue = data.filter(function (item) {
          return item[cat]==value;
    });

    var vf = filteredValue;

    for(var i=0; i<vf.length;i++){
        var obj = vf[i];

        for(var key2 in obj){

            if(key2!=cat){
                //console.log(key2);
                var obj2 = obj[key2];
                //console.log(obj2);

                $("input[name='opt_"+key2+"'][value!='"+obj2+"']").prop("disabled","disabled");


            }
            
        }
    }
}

$(".info input[type='radio']").click(function(){
    var value = $(this).val();
    var cat = $(this).attr("data-cat");

    info(cat,value);

});




    
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">


<div class="container info">
<div class="row">
<div class="col-md-12">

<div>Fruit</div>
<div class="form-check-inline">
  <label class="form-check-label">
    <input type="radio" class="form-check-input" data-cat="fruit" name="opt_fruit" value="apple">Apple
  </label>
</div>
<div class="form-check-inline">
  <label class="form-check-label">
    <input type="radio" class="form-check-input" data-cat="fruit" name="opt_fruit" value="grapes">Grapes
  </label>
</div>
<div class="form-check-inline">
  <label class="form-check-label">
    <input type="radio" class="form-check-input" data-cat="fruit" name="opt_fruit" value="mango">Mango
  </label>
</div>
<div class="form-check-inline">
  <label class="form-check-label">
    <input type="radio" class="form-check-input" data-cat="fruit" name="opt_fruit" value="pineapple">Pineapple
  </label>
</div>

</div>

<div class="col-md-12">

<div>Quantity</div>
<div class="form-check-inline">
  <label class="form-check-label">
    <input type="radio" class="form-check-input" data-cat="quantity" name="opt_quantity" value="5">5
  </label>
</div>
<div class="form-check-inline">
  <label class="form-check-label">
    <input type="radio" class="form-check-input" data-cat="quantity" name="opt_quantity" value="10">10
  </label>
</div>
<div class="form-check-inline">
  <label class="form-check-label">
    <input type="radio" class="form-check-input" data-cat="quantity" name="opt_quantity" value="15">15
  </label>
</div>
<div class="form-check-inline">
  <label class="form-check-label">
    <input type="radio" class="form-check-input" data-cat="quantity" name="opt_quantity" value="20">20
  </label>
</div>

</div>

<div class="col-md-12">

<div>Package</div>
<div class="form-check-inline">
  <label class="form-check-label">
    <input type="radio" class="form-check-input" data-cat="package" name="opt_package" value="bag">Bag
  </label>
</div>
<div class="form-check-inline">
  <label class="form-check-label">
    <input type="radio" class="form-check-input" data-cat="package" name="opt_package" value="box">Box
  </label>
</div>

</div>



</div>
</div>

As you can see, the problem is when I click a radio button input, the others turn disabled incorrectly:

enter image description here

And I want to get this result, for example, if I click on "apple", it must enable only quantity and package radio buttons available for that value according to data array like this:

enter image description here

How can I fix it? I’d like to receive your help.

2

Answers


  1. for(var i=0; i<vf.length;i++){
        var obj = vf[i];
    
        for(var key2 in obj){
    
            if(key2!=cat){
                //console.log(key2);
                var obj2 = obj[key2];
                //console.log(obj2);
    
                $("input[name='opt_"+key2+"'][value!='"+obj2+"']").prop("disabled","disabled");
            }
                
        }
    }
    

    In this loop, each data in obj make other inputs which have different value disabled.
    For example, when you click ‘apple’, obj will be like below.
    {fruit: 'apple', quantity: '5', package: 'bag'}
    {fruit: 'apple', quantity: '10', package: 'bag'}
    {fruit: 'apple', quantity: '15', package: 'bag'}
    And in the for loop,
    quantity: '5' makes input[name='opt_quantity'] which has value ’10’, ’15’, ’20’ disabled
    quantity: '10' makes input[name='opt_quantity'] which has value ‘5’, ’15’, ’20’ disabled
    quantity: '15' makes input[name='opt_quantity'] which has value ‘5’, ’10’, ’20’ disabled
    As a result, all input[name='opt_quantity'] disabled.

    You can simply disabled all input first, and then change "disable" prop false according to the clicked radio button value.

    $(document).ready(function(){
    //array
    var data = [ 
        {"fruit": "apple", "quantity": "5", "package": "bag"}, 
        {"fruit": "apple", "quantity": "10", "package": "bag"}, 
        {"fruit": "apple", "quantity": "15", "package": "bag"}, 
        {"fruit": "grapes", "quantity": "10", "package": "box"}, 
        {"fruit": "mango", "quantity": "5", "package": "bag"}, 
        {"fruit": "mango", "quantity": "10", "package": "bag"},
        {"fruit": "mango", "quantity": "15", "package": "box"},
        {"fruit": "mango", "quantity": "20", "package": "box"},
        {"fruit": "pineapple", "quantity": "5", "package": "bag"},
        {"fruit": "pineapple", "quantity": "10", "package": "bag"},
        {"fruit": "pineapple", "quantity": "15", "package": "box"},
        {"fruit": "pineapple", "quantity": "20", "package": "box"} 
    ];
    
    function info(cat,value){
        var filteredValue = data.filter(function (item) {
              return item[cat]==value;
        });
        
        $("input[name!='opt_" + cat + "']").prop("disabled", true); // disable all input except clicked category input
    
        var vf = filteredValue;
    
        for(var i=0; i<vf.length;i++){
            var obj = vf[i];
    
            for(var key2 in obj){
    
                if(key2!=cat){
                    var obj2 = obj[key2];
    
                    $("input[name='opt_"+key2+"'][value='"+obj2+"']").prop(
                "disabled", false
              );
    
                }
            }
        }
    }
    
    $(".info input[type='radio']").click(function(){
        var value = $(this).val();
        var cat = $(this).attr("data-cat");
    
        info(cat,value);
    
    });
    
    
    
    
        
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    
    
    <div class="container info">
    <div class="row">
    <div class="col-md-12">
    
    <div>Fruit</div>
    <div class="form-check-inline">
      <label class="form-check-label">
        <input type="radio" class="form-check-input" data-cat="fruit" name="opt_fruit" value="apple">Apple
      </label>
    </div>
    <div class="form-check-inline">
      <label class="form-check-label">
        <input type="radio" class="form-check-input" data-cat="fruit" name="opt_fruit" value="grapes">Grapes
      </label>
    </div>
    <div class="form-check-inline">
      <label class="form-check-label">
        <input type="radio" class="form-check-input" data-cat="fruit" name="opt_fruit" value="mango">Mango
      </label>
    </div>
    <div class="form-check-inline">
      <label class="form-check-label">
        <input type="radio" class="form-check-input" data-cat="fruit" name="opt_fruit" value="pineapple">Pineapple
      </label>
    </div>
    
    </div>
    
    <div class="col-md-12">
    
    <div>Quantity</div>
    <div class="form-check-inline">
      <label class="form-check-label">
        <input type="radio" class="form-check-input" data-cat="quantity" name="opt_quantity" value="5">5
      </label>
    </div>
    <div class="form-check-inline">
      <label class="form-check-label">
        <input type="radio" class="form-check-input" data-cat="quantity" name="opt_quantity" value="10">10
      </label>
    </div>
    <div class="form-check-inline">
      <label class="form-check-label">
        <input type="radio" class="form-check-input" data-cat="quantity" name="opt_quantity" value="15">15
      </label>
    </div>
    <div class="form-check-inline">
      <label class="form-check-label">
        <input type="radio" class="form-check-input" data-cat="quantity" name="opt_quantity" value="20">20
      </label>
    </div>
    
    </div>
    
    <div class="col-md-12">
    
    <div>Package</div>
    <div class="form-check-inline">
      <label class="form-check-label">
        <input type="radio" class="form-check-input" data-cat="package" name="opt_package" value="bag">Bag
      </label>
    </div>
    <div class="form-check-inline">
      <label class="form-check-label">
        <input type="radio" class="form-check-input" data-cat="package" name="opt_package" value="box">Box
      </label>
    </div>
    
    </div>
    
    
    
    </div>
    </div>

    *Additionally, it seems to need multiple conditions filtering data when 2 or more category( if you make more than 3 category ) have value.

    Login or Signup to reply.
  2. Your requirements required involving multiple steps to achieve this.

    Start with defining which properties will included in the filter:

    const properties = ['fruit', 'quantity', 'package']
    

    Add a click event to detect user selection:

    $('[name^="opt_"]').click(event => {
        /* code... */
    })
    

    Every time when user select an option, based on your properties defined above, loop through each property and get their current selected value:

    const filter = properties.reduce((filter, property) => {
        return { ...filter, [property]: $(`[name="opt_${property}"]:checked`).val() }
    }, {})
    

    This will return a filter data object:

    {
        "fruit": "pineapple",
        "quantity": "10",
        "package": undefined
    }
    

    Filter the fruits data by using the filter data object. Following function will loop through each item and compare every filter property:

    const filtered = data.filter(row => {
        const isMatched = properties.reduce((match, property) => {
            return match && (!filter[property] || row[property] == filter[property])
        }, true)
    
        return isMatched
    })
    

    Next let’s get the available options (enabled radio buttons) array from the filtered results by using this method:

    const pluckWithoutDuplicate = (array, key) => array.reduce((result, item) => {
        if (!result.includes(item[key])) {
            result.push(item[key])
        }
        return result
    }, [])
    

    The returned available options array will looks like this:

    ["bag", "box"]
    

    Finally update the radio buttons status using the available options array:

    const syncRadioButton = (property, availableValues) => {
        if (property == selectedProperty) {
            return
        }
    
        $(`[name="opt_${property}"]`).each((index, element) => {
            const radioButton = $(element)
            const value = radioButton.val()
            const available = availableValues.includes(value)
            
            radioButton.prop('disabled', !available)
        })
    }
    

    Demo:

    const data = [{
        "fruit": "apple",
        "quantity": "5",
        "package": "bag"
      },
      {
        "fruit": "apple",
        "quantity": "10",
        "package": "bag"
      },
      {
        "fruit": "apple",
        "quantity": "15",
        "package": "bag"
      },
      {
        "fruit": "grapes",
        "quantity": "10",
        "package": "box"
      },
      {
        "fruit": "mango",
        "quantity": "5",
        "package": "bag"
      },
      {
        "fruit": "mango",
        "quantity": "10",
        "package": "bag"
      },
      {
        "fruit": "mango",
        "quantity": "15",
        "package": "box"
      },
      {
        "fruit": "mango",
        "quantity": "20",
        "package": "box"
      },
      {
        "fruit": "pineapple",
        "quantity": "5",
        "package": "bag"
      },
      {
        "fruit": "pineapple",
        "quantity": "10",
        "package": "bag"
      },
      {
        "fruit": "pineapple",
        "quantity": "15",
        "package": "box"
      },
      {
        "fruit": "pineapple",
        "quantity": "20",
        "package": "box"
      }
    ]
    
    const properties = ['fruit', 'quantity', 'package']
    
    /* listen to click event of elements that have name with prefix "opt_" */
    $('[name^="opt_"]').click(event => {
      /* get selected property by extract the value from name "opt_{property}" */
      const selectedProperty = $(event.currentTarget).attr('name').replace('opt_', '')
      const propertyIndex = properties.indexOf(selectedProperty)
    
      /* get properties that come after the selected property */
      const propertiesToReset = properties.slice(propertyIndex + 1)
    
      /* this is optional, whether reset the selection every time or only when selected property was "fruit" */
      if (selectedProperty == 'fruit') {
        /* loop through properties that come after the selected property */
        propertiesToReset.forEach(property => {
          /* reset the property selection */
          $(`[name="opt_${property}"]`).prop('checked', false)
        })
      }
    
      /* get all properties selected values and used as filter data */
      const filter = properties.reduce((filter, property) => {
        return { ...filter,
          [property]: $(`[name="opt_${property}"]:checked`).val()
        }
      }, {})
    
      /* loop through each data item */
      const filtered = data.filter(row => {
        /* loop through each property */
        const isMatched = properties.reduce((match, property) => {
          /* check whether the data item's property is match with the filter data's property  */
          return match && (!filter[property] || row[property] == filter[property])
        }, true)
    
        /* append to the filtered result if this item is matched */
        return isMatched
      })
    
      /* this function is to get specific key's value from multidimensional array, without duplicated value  */
      const pluckWithoutDuplicate = (array, key) => array.reduce((result, item) => {
        if (!result.includes(item[key])) {
          result.push(item[key])
        }
        return result
      }, [])
    
      /* this function is to control whether the radio buttons are avaialble based on available values */
      const syncRadioButton = (property, availableValues) => {
        /* no need to disable current selected property  */
        if (property == selectedProperty) {
          return
        }
    
        /* loop through the property radio buttons */
        $(`[name="opt_${property}"]`).each((index, element) => {
          const radioButton = $(element)
          const value = radioButton.val()
          const available = availableValues.includes(value)
    
          /* enable based on if the value is available */
          radioButton.prop('disabled', !available)
        })
      }
    
      /* get available values of the properties */
      const availableQuantities = pluckWithoutDuplicate(filtered, 'quantity')
      const availablePackages = pluckWithoutDuplicate(filtered, 'package')
    
      /* sync the radio buttons based on available values */
      syncRadioButton('quantity', availableQuantities)
      syncRadioButton('package', availablePackages)
    })
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <div class="container info">
      <div class="row">
        <div class="col-md-12">
          <div>Fruit</div>
          <div class="form-check-inline">
            <label class="form-check-label">
                            <input type="radio" class="form-check-input" data-cat="fruit" name="opt_fruit" value="apple">
                            Apple
                        </label>
          </div>
          <div class="form-check-inline">
            <label class="form-check-label">
                            <input type="radio" class="form-check-input" data-cat="fruit" name="opt_fruit" value="grapes">
                            Grapes
                        </label>
          </div>
          <div class="form-check-inline">
            <label class="form-check-label">
                            <input type="radio" class="form-check-input" data-cat="fruit" name="opt_fruit" value="mango">
                            Mango
                        </label>
          </div>
          <div class="form-check-inline">
            <label class="form-check-label">
                            <input type="radio" class="form-check-input" data-cat="fruit" name="opt_fruit" value="pineapple">
                            Pineapple
                        </label>
          </div>
        </div>
        <div class="col-md-12">
          <div>Quantity</div>
          <div class="form-check-inline">
            <label class="form-check-label">
                            <input type="radio" class="form-check-input" data-cat="quantity" name="opt_quantity" value="5">5
                        </label>
          </div>
          <div class="form-check-inline">
            <label class="form-check-label">
                            <input type="radio" class="form-check-input" data-cat="quantity" name="opt_quantity" value="10">10
                        </label>
          </div>
          <div class="form-check-inline">
            <label class="form-check-label">
                            <input type="radio" class="form-check-input" data-cat="quantity" name="opt_quantity" value="15">15
                        </label>
          </div>
          <div class="form-check-inline">
            <label class="form-check-label">
                            <input type="radio" class="form-check-input" data-cat="quantity" name="opt_quantity" value="20">20
                        </label>
          </div>
        </div>
        <div class="col-md-12">
          <div>Package</div>
          <div class="form-check-inline">
            <label class="form-check-label">
                            <input type="radio" class="form-check-input" data-cat="package" name="opt_package" value="bag">Bag
                        </label>
          </div>
          <div class="form-check-inline">
            <label class="form-check-label">
                            <input type="radio" class="form-check-input" data-cat="package" name="opt_package" value="box">Box
                        </label>
          </div>
        </div>
      </div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search