📜 ⬆️ ⬇️

Plugin for "live" forms

The article is devoted to a plugin that simplifies the life of a client-side programmer.

When filling out a form, it happens that taking into account the entered data, the form must be changed (hide and show the fields). The simplest example: when ordering the delivery of goods, the user chose “self-pickup”, then the fields about the delivery address can be hidden, but it would be great to show a map of directions for self-pickup.

So, what is next

Often this logic remains without implementation, but if you care about your users, you need to do it.
')
The first standard approach is to do a step-by-step wizard, where the form for each step is generated on the server side. In my opinion, this is an unfortunate option, since it requires a chore to break down the process into steps, write a ton of code, and enjoy working with such a form a little.

The second approach is to write javascript wrappers that implements all this logic on the client side. It is especially sad to write “cascade” logic of the type “if you entered a in field A, show B, if you entered c in field B, then show D. If you entered something else in A, hide B and then D”.

Both options can not be called convenient. First of all, because logic is implemented by an imperative style instead of a declarative one appropriate for such cases. But there is a solution!

Decision

In general, when there was a need to implement another such form, it was finally decided to write a plugin for jQuery that would:


I called the resulting plugin jQuery.grewform (such as a growing form). Without a rant - the simplest example . We describe the implemented logic in the Russian language:
 #first   "show",    #p2.  #second   "gogo",    #p3. 

Now let's see how this logic is described using the plugin:
 $('form').grewform({ // #first   "show",    #p2 '#first[value=show]':{ show:'#p2' }, // #second   "gogo",    #p3 '#second[value=gogo]':{ show:'#p3' } }) 


Read more

Next is a detailed description of the plug-in. If everything is more or less clear from the example above, you can skip this section of the article and go to the description of the possibilities.
The behavior of the plugin is given by a set of rules. Each rule consists of a term and a set of actions. After initialization, and so with each change of the form, the plugin checks the term of each rule. During verification, the term is determined to correspond to the current state of the form. Each rule can be in one of three positions:
  1. at the last check the term did not correspond to the state, but now it corresponds to
  2. at the last check the term corresponded to the state, and now it does not correspond
  3. Matching a term to a form does not change

In the first case, the rule is marked as triggered , the DOM elements described in the term (in fact, changing these elements led to the triggering of the rule) receive a label (a class is added) indicating that the such rule is “hanging” on them. Then all the actions described in the rule are started in turn. The second case is more interesting. Likewise, the rule is marked as no longer triggered , the tags from the elements are deleted. Then the negatives of the actions described in the rule are launched (they showed something? Now we hide!), And if in the process some elements are hidden or removed in the DOM, it is first checked
if there are any rules “hanging” on them (see case number 1), if this is the case, then the “rollback” process is started for these rules (works like case number 2). In the third case, nothing happens.
It is worth noting that about checking compliance with terms, only visible form elements are taken into account.

Opportunities

The expression by which it is determined whether it is time to launch an action (term) is a CSS / jQuery-compatible selector. If the form contains elements corresponding to the selector, then the actions of this rule are launched. Sometimes it is necessary for the rule to work only under the double (triple, quad ...) condition, for this you can use the AND function ( example ). This is the only syntax change, but rather an addition.
The first example uses the [value = show] selector. Those who know jQuery very well will rightly say that such selectors should not work if value was changed during the execution of the code. However, the plugin maintains the current state of the value attribute for all <input/> , respectively, everything works as it should.
Let us turn to the description of the types of actions. Here is a list of syntax descriptions:
 { show:'elements_selector', //  (slideDown; slideUp  ) hide:'elements_selector', //  (slideUp; slideDown  ) disable:'elements_selector' // disabled="disabled"    (  ) enable:'elements_selector' //   disabled ( disabled="disabled"  ) check:'elements_selector' // checked="checked"    (  ) uncheck:'elements_selector' //   checked ( checked="checked"  ) set_value:'elements_selector', // value  <input>,  <select>  selected="selected"   <option> add_options: // <option>  <select> { '<select> selector':{ 'value_1':'display_value_1', // <option value="1">display_value_1</option> 'value_2':'display_value_2', ... } or '<select> selector': function //   ( - {'value_1':'display_value_1',...}) }, custom: //   { match:function, //     unmatch:function, //    } } 


As mentioned above, only positive events are described, i.e. Only those that should occur when the rule is triggered. Rollback actions are calculated automatically.
As you can see, almost all actions have the following syntax:
action_name: 'element selector'
The selector syntax is also fully CSS / jQuery compliant. On the elements found by the seleter the specified action will be performed. Actually all actions are described above in the code.

At the end of the largest and most powerful example - the form of the order of psychological consultation =)

Need help

I started writing this plugin 2 weeks ago and we already use it in 2 forms on production. I would be very grateful if you try this plugin and tell us what you are missing.

References:


© picture taken from the Code Complete book

Source: https://habr.com/ru/post/123940/


All Articles