📜 ⬆️ ⬇️

JQuery plugin - jdDialog. The principle of "transit calls"

Formulation of the problem


In the process of refining the existing administrative page on the “samopisny” engine, it became necessary to replace the rough standard modal dialog boxes with windows that fit into the site design. No one will allow the rewriting of the administrative part, and there is no need for that. The main condition is quick integration into the actual code.

Therefore, it was decided to perform cosmetic surgery.

So, the following requirements are formulated:
')

The first thing turned to search on Google. The existing designs did not suit me, because I wanted to keep the call syntax to the maximum ...

if(confirm('') ) {...} 

or offered to add sufficiently large code fragments in the form of additional functions that describe what will happen after a particular choice in the window (for example, Dialog UI).

In the process of parsing the problem revealed the main problems:


The main question is how to return to the place in the code that has already slipped?

The task became as follows:


Implementing it on jQuery, at least for me, looks like a rather difficult task.

Principle of solution


As a solution, callback functions or timers were used to intercept the selection moment.

I obtained the best result for this task by slightly changing the intermediate conditions of the problem and implementing the following principle:


Thus, the formation of each dialog box is one iteration, one link of the “transit session”. The handler is called twice — the window itself is generated the first time, and the second time it transits to the next condition.

However, if there are several dialog boxes within the same calling function, i.e. they have nesting, a whole “transit chain” is being formed. In each iteration - 2 function calls. And with each new dialog box in sequence, the number of calls to the handler function doubles. I don’t think that it will ever be necessary to invest dozens of windows, so the overhead costs of client browser resources are minimal.

It resembles recursion, but differs in that:


It is convenient to save the selection results in binding to the DOM element that initiated the dialog call in the form of data attributes, non-standard attributes or in the form of named data using the .data () function.

This principle has assigned the working title of "transit-dialogue" or "transit" calls.

In my example, implemented as a jQuery plugin.
The plugin code with an example of calls is posted here .

As I developed, I encountered the following problems:

Problem number 1)

Since dialog boxes can be nested, you have to save the state of each window. To do this, enter the ID of the window.

To solve this space in the call dialog box as a parameter entered the id window. They must be unique within the same calling function. For the developer, this is an inconvenience, but it is risky to generate the id automatically using for example a hash of the input parameters, since theoretically, in the transit chain there can be absolutely identical calls (including with the same texts). In addition, windows are created dynamically - I have not yet found a reliable sign for creating id when generating a window.

Answers are saved for each dialog initializer button, so that we get a kind of “transit namespace”, so that we can use repeated window id in each function. I use 1,2, and so on.

Problem number 2)

It is necessary to distinguish the real click on the control from the transit one. This is necessary in order to start the whole chain of transit calls again.

Decision:

For this purpose, a flag is entered (I have jdReclick). The parameter is assigned to the button before each repeated call and is deleted immediately after processing the repeated call. Focusing on this label, we delete all the data of the “transit session” if:

  1. The last window in the function was processed,
  2. in one of the windows was selected cancel

Problem number 3)

How to distinguish the last this window in the calling function or not. If the window is the last one, we have the right to delete all the data of the “transit session” so that when you press the button again, the algorithm is restarted.

Obstacles:


Solution options:


Now in detail about the implementation in my example


The event on the element starts the initiator function of the “transit-dialog” chain:

 $('#test').click(function() { ... 

The actual launch of the dialog box looks like this:

 $(this).jdDialogs('confirm',1,['?',''],fncname) 

To bind data to an element, you need to pass to the plugin this selector,
in attributes we pass:

1 - window type (plugin method name),
2 - window id
3 - text window parameters
4 - callback function

Processing of the results can be implemented in several ways:

 if(! $(this).jdDialogs('confirm',1,['?','']) ) return; if( $(this).jdDialogs('confirm',1,['?','']) ) { ... } switch( $(this).jdDialogs('confirm',1,['?','']) ) { case 1: ...; default: return; } 

If after calling Alert there is an executing code, you will have to use return, if not - return can be omitted.

 $(this).jdDialogs('alert',0,['!','Project']) 

 if(! $(this).jdDialogs('alert',0,['!',project]) ) return; alert(' '); 

The plugin provides the standard methods confirm, alert, their short aliases cnf, al to shorten the record. You can add your own calls.

All calls run the generic jdDialog method, in which:


In this method, you can change / add new case conditions to form your own set of buttons, as well as output a separate template other than the rest.

Clicking the buttons handles the attached events. For alert, 2 options are offered for the closing button - jdClose0 with cancellation and jdClose1 - with confirmation. Which set is configured in jdGetWin in switch case.

The event is redirected to the jdSetAnswer method. The method recognizes the id of the current window and the id of the initiator of the launch of the dialog box. Knowing the id of the button, we can save the result of the selection with the key on the window id to the “transit session”.

 $(id).data(fname,value); 

Next, we destroy the window using .detach () with an animation effect, for example fadeIn 10

 $('.jdModalBg').detach().fadeIn(10,function() { 

In the callback function, we check: if cancellation, reset the “transit session”. In this method, if the name of the function was passed by the 4th parameter when the dialog box was called, the function is called.

 if(!!fncdo) window[fncdo](); 

Then the transit call starts. Pass the ID of the control - initiator to re-click on it. Those. click on the control - the initiator of the dialogue is emulated.

 methods.jdReclick(id); 

In my example, it is quite simple to add arbitrary constructions with calling and processing windows.

An example of the implementation of the three-button window


1. In the data call, add 2 more parameters: the inscriptions on the two buttons instead of "OK".

 $(this).jdDialogs('confirm2bttn',0,['  ','  3',' ',' ']) 

Using an array with texts allows you to flexibly manage the number of parameters - here you just need to add two more parameters to the array.

2. We connect the call:

  confirm2bttn : function(fid,data,fname) { return methods.jdDialog('Confirm2bttn',fid,data,$(this),fname); } 

3. We connect call processing. The template itself is leaving the old one, changing only the buttons:

 case 'Confirm2bttn': var bttntext1 = data[2]; var bttntext2 = data[3]; jdBttns = '<button class="jdOk jdOk1">'+bttntext1+'</button>'+ '<button class="jdOk jdOk2">'+bttntext2+'</button>'+ '<button class="jdCancel"></button>'; clClass = 'jdClose0'; break; 

4. Add an event to the Ok2 button to distinguish between pressing the buttons - a transit call when you click on .jdOk2 will now return the value 2:

  .on('click','.jdOk2', function() { methods.jdSetAnswer(2,$(this)); }) 

5. Return to the initiator script and set the conditions for different buttons:

 switch($(this).jdDialogs('confirm2bttn',0,['  ','  3',' ',' '])) { case 0: return; case 1: alert(' '); break; case 2: alert(' '); break; default: 

6. Well, you can assign a new style to the elements of the new window, for example, make it green with yellow text. Something like this:

 .jdDialogConfirm2bttn { min-width:380px; max-width:450px; } .jdDialogConfirm2bttn .jdText { min-height:60px; } .jdDialogConfirm2bttn .jdHeader{ background-color: hsl(115,63%,15%); color:#F0C800; } .jdDialogConfirm2bttn .jdHeader .jdClose{ background-color: hsl(114,58%,22%); color:#F5DA50; } 

I assume that the use of the principle of "transit calls" provides a way to solve problems associated with waiting for action from the client. It is enough to use the jQuery library with the proposed extension. The presented fully functional plugin was developed for use with the jQuery library version 1.9, it also works with the most recent version 3.2.1 at the time of this writing.

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


All Articles