npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mf-conditional-fields

v1.0.9

Published

MF Conditional Fields: A JavaScript library that show/hide form elements based on the value of one field or many.

Downloads

59

Readme

MF Conditional Fields

npm version

A JavaScript library that show/hide form elements based on the value of one field or many.

MF Conditional Fields

Advantages

  • Lightweight & fast.
  • Comes with a number of different operators.
  • Supports complex conditional rules ( simple as well as grouped rules).
  • Supports dynamic forms ( forms that are updated with new elements after the DOM is loaded ).
  • Supports all form elements regardless of their type ( input, select..etc ).

Disadvantages

  • JSON based and large conditions, which makes writing rules a bit frustrating. However, you can always write you own helpers to create rules faster ( See jQuery and PHP usage for examples )

When To Use

This library is best suited for complex conditions and dynamically generated fields. Field conditions are written in JSON format and it can be hard to generate these manually.

If you plan on using this for your PHP project, make sure to check out the PHP Usage section below.

If you want to use jQuery, you'll need to write your own function or plugin to supply your rules as array of object to mfConditionalFields( '.formSelecotr', {rules: rulesArray} ). ( see Block based rules section for the correct format )

How To Use

  1. Load dist/mf-conditional-fields.min.js.

  2. Add your JSON formatted conditions inside a JS element or to the field you want to show/hide inside a data-conditional-rules attribute.

  3. Call mfConditionalFields('form') (replace form with your form selector)

  4. Let the magic happen

Available Options

To give you more control over the conditional elements, mfConditionalFields offers a set of options that you can specify to change how the library interacts with conditional elements. The options can used like this:

mfConditionalFields('form', {
  rules: 'inline', // accepts `inline`, `block` and array of objects ( see below for examples ).
  dynamic: false, // If set to `true` the library will handle elements added after the DOM is loaded ( see below for examples ).
  unsetHidden: false, // If set to `true` the library will unset the value of any hidden fields.
  disableHidden: false, // If set to `true`, any hidden fields will be set to `disabled`.
  debug: false, // If set to `true` the library will show hints in the console when things aren't working as expected.
  depth: 3 // This allows you to set how deep should the library go in showing/hiding dependent fields.
});

Inline Based Rules

{
   "container":".element-to-show-hide",
   "action":"show",
   "logic":"or",
   "rules":[
      {
         "name":"parent_field_name",
         "operator":"is",
         "value":"parent_field_targeted_value"
      }
   ]
}

Block Based Rules

[
    {
       "field":"field1_name",
       "container":".element-to-show",
       "action":"show",
       "logic":"or",
       "rules":[
          {
             "name":"parent_field_name",
             "operator":"is",
             "value":"parent_field_targeted_value"
          }
       ]
    },
    {
        "field":"field1_name",
        "container":".element-to-hide",
        "action":"hide",
        "logic":"or",
        "rules":[
          {
             "name":"parent_field_name",
             "operator":"isnot",
             "value":"parent_field_targeted_value"
          }
       ]
    },
]

Field

The name attribute of the field you want to show/hide/enable/disable based on the provided rules. Note that this can only be used in the block based rules, inline based rules don't require this. ( if the bold terms don't make sense yet, please keep reading )

Container

The conditional field parent element where you want to perform the hiding/showing action, leave empty to show/hide the field itself.

Action

  • show
  • hide
  • enable
  • disable

Logic

  • or ( meeting one of the rules is enough to perform the action )
  • and ( all the rules must be met to perform the action )

Rules

This should contain the rules you want to meet before showing/hiding the field. The rules can accept one rule in simple format {"name": "a", "operator": "is", "value": "yes"} or multiple rules [{"name": "a", "operator": "is", "value": "yes"}, {"name": "b", "operator": "is", "value": "no"}]

Note: grouped rules are also supported, if you need to create complex conditions, just store them as set of groups in the dependant field rules. Here is a sample of groups:

[
    {
        "field":"dependant_field",
        "container":".field_container",
        "action":"show",
        "logic":"or",
        "rules":[
            {
                "relation":"and",
                "group":[
                    {
                        "name":"ruling_field1",
                        "operator":"is",
                        "value":"One"
                    },
                    {
                        "name":"ruling_field2",
                        "operator":"is",
                        "value":"Two"
                    }
                ]
            },
            {
                "relation":"and",
                "group":[
                    {
                        "name":"ruling_field3",
                        "operator":"b",
                        "value":"One"
                    },
                    {
                        "name":"ruling_field4",
                        "operator":"is",
                        "value":"Two"
                    }
                ]
            },
            {
                "relation":"and",
                "group":[
                    {
                        "name":"ruling_field5",
                        "operator":"is",
                        "value":"None of the above"
                    }
                ]
            }
        ]
    }
]

Name

The name attribute of the parent field where the script should be listening for changes

Operator

Comparision operators to compare between the parent field value and the rule value

  • is
  • isnot
  • greaterthan
  • lessthan
  • contains
  • doesnotcontain
  • beginswith
  • doesnotbeginwith
  • endswith
  • doesnotendwith
  • isempty
  • isnotempty

Value

The parent field value we should be watching for to perform the action, this can accept one value, if you want to use more values, you'll need to create more rules.


Usage

PHP Usage ( Inline Based Rules )

  • Create a helper function

    function get_mf_conditional_rules( $action, $rules, $logic = 'or', $container = '.default-field-container' ) {
    
      return json_encode( array(
              'container' => $container,
              'action' => $action,
              'logic' => $logic,
              'rules' => $rules,
            ));
    }
  • Create your form and give it an id or class to use for initialization

      ?>
          <form id="example_form">
          </form>
      <?php
  • Create parent field (trigger)

      ?>
          <div class="form-group">
              <label for="field1">Parent Field</label>   
              <input type="checkbox" name="parent_field" id="field1" value="yes"/>
          <div>
      <?php
  • Create you conditional rules and field like this (dependant field)

      $condition1 = get_mf_conditional_rules( 'show', array(
        'name' => 'parent_field',
        'operator' => 'is',
        'value' => 'yes'
      ) );
      ?>
          <div class="form-group">
            <label for="field2">Dependant Field</label><br>
            <input type="text" name="dependant_field" id="field2" data-conditional-rules="<?php echo htmlspecialchars($condition1); ?>" />
          </div>
      <?php
  • Load the library and Initialize conditional fields

      ?>
        <script src="../dist/mf-conditional-fields.min.js"></script>
        <script>
          mfConditionalFields('#example_form');
        </script>
      <?php

Plain HTML Usage ( Block Based Rules )

  • Create your form and give it an id or class to use for initilizations

      <form id="example_form">
      </form>
  • Create parent field (trigger)

      <div class="form-group">
          <label for="field1">Parent Field</label>   
          <input type="checkbox" name="parent_field" id="field1" value="yes"/>
      <div>
  • Create your conditional field (dependant field)

      <div class="form-group">
        <label for="field2">Dependant Field</label><br>
        <input type="text" name="dependant_field" id="field2" />
      </div>
  • Create a script element and give it the id attribute rules-mf-conditional-fields

      <script type="text/x-rules" id="rules-mf-conditional-fields">
          // Rules here
      </script>
  • Create your conditions based on the block based rules format and put them inside the script element you created

      [
         {
            "field":"dependant_field",
            "container":".form-group",
            "action":"show",
            "logic":"or",
            "rules":{
               "name":"parent_field",
               "operator":"is",
               "value":"yes"
            }
         }
      ]
  • Load the library and Initialize conditional fields ( make sure to pass an object with rules property set to block as a second arguement when calling mfConditionalFields )

    <script src="../dist/mf-conditional-fields.min.js"></script>
    <script>
      mfConditionalFields('#example_form', {rules: 'block'});
    </script>

Usage With Dynamic Forms

To use dynamic forms functionality, you must use inline based rules and initiaize the form like this

mfConditionalFields('#example_form', {
  rules: 'inline', 
  dynamic: true
  });

Then, you must trigger the event mfConditionalFormUpdated each time you add or remove fields. After you do that, the script will implement conditional logic to any new conditional fields in form. ( change the value add to remove if a field is remove )

let mfEvent = new CustomEvent("mfConditionalFormUpdated", { "detail": { "action": "add" } });
document.getElementById('example_form').dispatchEvent(mfEvent);

Making changes ( development )

Want to make changes to the source code? Simply install dependencies using npm install and watch for changes using the command npm run watch.

Once the command npm run watch is executed, you can start making changes to /src/mf-conditional-fields.js and the file will be automatically minified and exported to /dist/mf-conditional-fields.min.js.

Once done and you want to generat a clean minified version ( without source mapping ), run npm run build.


Have an issue or suggestion?

Feel free to share any issues or feature requests by creating an issue

Want to contribute?

Fork, change, send pull request!