View | Details | Raw Unified | Return to bug 30975
Collapse All | Expand All

(-)a/C4/Items.pm (-1 / +1 lines)
Lines 1608-1614 sub PrepareItemrecordDisplay { Link Here
1608
                        my $class = $plugin->noclick ? ' disabled' : '';
1608
                        my $class = $plugin->noclick ? ' disabled' : '';
1609
                        my $title = $plugin->noclick ? 'No popup'  : 'Tag editor';
1609
                        my $title = $plugin->noclick ? 'No popup'  : 'Tag editor';
1610
                        $subfield_data{marc_value} =
1610
                        $subfield_data{marc_value} =
1611
                            qq[<input type="text" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="50" maxlength="$maxlength" value="$defaultvalue" /><a href="#" id="buttonDot_$subfield_data{id}" class="buttonDot $class" title="$title">...</a>\n]
1611
                            qq[<input type="text" id="$subfield_data{id}" name="field_value" class="input_marceditor framework_plugin" size="50" maxlength="$maxlength" value="$defaultvalue" data-plugin="$plugin->{name}" /><a href="#" id="buttonDot_$subfield_data{id}" class="buttonDot $class" title="$title" data-plugin="$plugin->{name}">...</a>\n]
1612
                            . $plugin->javascript;
1612
                            . $plugin->javascript;
1613
                    } else {
1613
                    } else {
1614
                        warn $plugin->errstr;
1614
                        warn $plugin->errstr;
(-)a/Koha/FrameworkPlugin.pm (-84 / +7 lines)
Lines 316-416 sub _process_javascript { Link Here
316
    $script =~ s/\<script[^>]*\>\s*(\/\/\<!\[CDATA\[)?\s*//s;
316
    $script =~ s/\<script[^>]*\>\s*(\/\/\<!\[CDATA\[)?\s*//s;
317
    $script =~ s/(\/\/\]\]\>\s*)?\<\/script\>//s;
317
    $script =~ s/(\/\/\]\]\>\s*)?\<\/script\>//s;
318
318
319
    my $id         = $params->{id} // '';
320
    my $bind       = '';
321
    my $clickfound = 0;
319
    my $clickfound = 0;
322
    my @events     = qw|click focus blur change mouseover mouseout mousedown
320
    my @events     = qw|click focus blur change mousedown mouseup keydown keyup|;
323
        mouseup mousemove keydown keypress keyup|;
324
    foreach my $ev (@events) {
321
    foreach my $ev (@events) {
325
        my $scan = $ev eq 'click' && $self->{oldschool} ? 'clic' : $ev;
322
        my $scan = $ev eq 'click' && $self->{oldschool} ? 'clic' : $ev;
326
        if ( $script =~ /function\s+($scan\w+)\s*\(([^\)]*)\)/is ) {
323
        if ( $script =~ /function\s+($scan\w+)\s*\(/is ) {
327
            my ( $bl, $sl ) = $self->_add_binding( $1, $2, $ev, $id );
324
            my $function_name = $1;
328
            $script .= $sl;
325
            $script .= sprintf( 'registerFrameworkPluginHandler("%s", "%s", %s);', $self->name, $ev, $function_name );
329
            $bind   .= $bl;
330
            $clickfound = 1 if $ev eq 'click';
326
            $clickfound = 1 if $ev eq 'click';
331
        }
327
        }
332
    }
328
    }
333
    if ( !$clickfound ) {    # make buttonDot do nothing
334
        my ($bl) = $self->_add_binding( 'noclick', '', 'click', $id );
335
        $bind .= $bl;
336
    }
337
    $self->{noclick}    = !$clickfound;
329
    $self->{noclick}    = !$clickfound;
338
    $self->{javascript} = _merge_script( $id, $script, $bind );
330
    $self->{javascript} = <<JS;
339
}
340
341
sub _add_binding {
342
343
    # adds some jQuery code for event binding:
344
    # $bind contains lines for the actual event binding: .click, .focus, etc.
345
    # $script contains function definitions (if needed)
346
    my ( $self, $fname, $pars, $ev, $id ) = @_;
347
    my ( $bind, $script );
348
    my $ctl = $ev eq 'click' ? 'buttonDot_' . $id : $id;
349
350
    #click event applies to buttonDot
351
352
    if ( $pars =~ /^(e|ev|event)$/i ) {    # new style event handler assumed
353
        $bind   = qq|    \$("#$ctl").off('$ev').on('$ev', \{id: '$id'\}, $fname);\n|;    # remove old handler if any
354
        $script = q{};
355
    } elsif ( $fname eq 'noclick' ) {    # no click: return false, no scroll
356
        $bind   = qq|    \$("#$ctl").$ev(function () { return false; });\n|;
357
        $script = q{};
358
    } else {                             # add real event handler calling the function found
359
        $bind   = qq|    \$("#$ctl").off('$ev').on('$ev', \{id: '$id'\}, ${fname}_handler);\n|;
360
        $script = $self->_add_handler( $ev, $fname );
361
    }
362
    return ( $bind, $script );
363
}
364
365
sub _add_handler {
366
367
    # adds a handler with event parameter
368
    # event.data.id is passed to the plugin function in parameters
369
    # for the click event we always return false to prevent scrolling
370
    my ( $self, $ev, $fname ) = @_;
371
    my $first  = $self->_first_item_par($ev);
372
    my $prefix = $ev eq 'click' ? ''                    : 'return ';
373
    my $suffix = $ev eq 'click' ? "\n    return false;" : '';
374
    return <<HERE;
375
function ${fname}_handler(event) {
376
    $prefix$fname(${first}event.data.id);$suffix
377
}
378
HERE
379
}
380
381
sub _first_item_par {
382
    my ( $self, $event ) = @_;
383
384
    # needed for backward compatibility
385
    # js event functions in old style item plugins have an extra parameter
386
    # BUT.. not for all events (exceptions provide employment :)
387
    if (   $self->{item_style}
388
        && $self->{oldschool}
389
        && $event =~ /focus|blur|change/ )
390
    {
391
        return qq/'0',/;
392
    }
393
    return '';
394
}
395
396
sub _merge_script {
397
398
    # Combine script and event bindings, enclosed in script tags.
399
    # The BindEvents function is added to easily repeat event binding;
400
    # this is used in additem.js for dynamically created item blocks.
401
    my ( $id, $script, $bind ) = @_;
402
    chomp( $script, $bind );
403
    return <<HERE;
404
<script>
331
<script>
332
\$(document).ready(function () {
405
$script
333
$script
406
function BindEvents$id() {
407
$bind
408
}
409
\$(document).ready(function() {
410
    BindEvents$id();
411
});
334
});
412
</script>
335
</script>
413
HERE
336
JS
414
}
337
}
415
338
416
=head1 AUTHOR
339
=head1 AUTHOR
(-)a/Koha/UI/Form/Builder/Item.pm (+1 lines)
Lines 329-334 sub generate_subfield_form { Link Here
329
                class      => $class,
329
                class      => $class,
330
                nopopup    => $plugin->noclick,
330
                nopopup    => $plugin->noclick,
331
                javascript => $plugin->javascript,
331
                javascript => $plugin->javascript,
332
                plugin     => $plugin->name,
332
            };
333
            };
333
        } else {
334
        } else {
334
            warn $plugin->errstr;
335
            warn $plugin->errstr;
(-)a/authorities/authorities.pl (+1 lines)
Lines 200-205 sub create_input { Link Here
200
                maxlength  => $max_length,
200
                maxlength  => $max_length,
201
                javascript => $plugin->javascript,
201
                javascript => $plugin->javascript,
202
                noclick    => $plugin->noclick,
202
                noclick    => $plugin->noclick,
203
                plugin     => $plugin->name,
203
            };
204
            };
204
        } else {    # warn and supply default field
205
        } else {    # warn and supply default field
205
            warn $plugin->errstr;
206
            warn $plugin->errstr;
(-)a/cataloguing/value_builder/EXAMPLE.pl (-22 / +4 lines)
Lines 65-101 my $builder = sub { Link Here
65
<script>
65
<script>
66
function Focus$id(event) {
66
function Focus$id(event) {
67
    if( \$('#'+event.data.id).val()=='' ) {
67
    if( \$('#'+event.data.id).val()=='' ) {
68
        \$('#'+event.data.id).val('EXAMPLE:');
68
        \$('#'+event.data.id).val('Focus');
69
    }
69
    }
70
}
70
}
71
71
72
function MouseOver$id(event) {
72
function Blur$id(event) {
73
    return Focus$id(event);
73
    if( \$('#'+event.data.id).val()=='' ) {
74
    /* just redirecting it to Focus for the same effect */
74
        \$('#'+event.data.id).val('Blur');
75
}
76
77
function KeyPress$id(event) {
78
    if( event.which == 64 ) { /* at character */
79
        var f= \$('#'+event.data.id).val();
80
        \$('#'+event.data.id).val( f + 'AT' );
81
        return false; /* prevents getting the @ character back too */
82
    }
83
}
84
85
function Change$id(event) {
86
    var colors= [ 'rgb(0, 0, 255)', 'rgb(0, 128, 0)', 'rgb(255, 0, 0)' ];
87
    var curcol= \$('#'+event.data.id).css('color');
88
    var i= Math.floor( Math.random() * 3 );
89
    if( colors[i]==curcol ) {
90
        i= (i + 1)%3;
91
    }
75
    }
92
    var f= \$('#'+event.data.id).css('color',colors[i]);
93
}
76
}
94
77
95
function Click$id(event) {
78
function Click$id(event) {
96
    var fieldvalue=\$('#'+event.data.id).val();
79
    var fieldvalue=\$('#'+event.data.id).val();
97
    window.open(\"../cataloguing/plugin_launcher.pl?plugin_name=EXAMPLE.pl&index=\"+event.data.id+\"&result=\"+fieldvalue,\"tag_editor\",'width=700,height=700,toolbar=false,scrollbars=yes');
80
    window.open(\"../cataloguing/plugin_launcher.pl?plugin_name=EXAMPLE.pl&index=\"+event.data.id+\"&result=\"+fieldvalue,\"tag_editor\",'width=700,height=700,toolbar=false,scrollbars=yes');
98
    return false; /* prevents scrolling */
99
}
81
}
100
</script>|;
82
</script>|;
101
};
83
};
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc (-3 / +3 lines)
Lines 173-183 Link Here
173
                                readonly="readonly"
173
                                readonly="readonly"
174
                            />
174
                            />
175
                        [% ELSE %]
175
                        [% ELSE %]
176
                            <input type="text" id="[%- mv.id | html -%]" name="[% kohafield | html %]" class="input_marceditor [% kohafield | html %]" maxlength="[%- mv.maxlength | html -%]" value="[%- mv.value | html -%]" />
176
                            <input type="text" id="[%- mv.id | html -%]" name="[% kohafield | html %]" class="input_marceditor framework_plugin [% kohafield | html %]" maxlength="[%- mv.maxlength | html -%]" value="[%- mv.value | html -%]" data-plugin="[% mv.plugin | html %]" />
177
                            [% IF ( mv.nopopup ) %]
177
                            [% IF ( mv.nopopup ) %]
178
                                <a href="#" id="buttonDot_[%- mv.id | html -%]" class="[%- mv.class | html -%]" title="No  popup">...</a>
178
                                <a href="#" id="buttonDot_[%- mv.id | html -%]" class="[%- mv.class | html -%]" title="No  popup" data-plugin="[% mv.plugin | html %]">...</a>
179
                            [% ELSE %]
179
                            [% ELSE %]
180
                                <a href="#" id="buttonDot_[%- mv.id | html -%]" class="[%- mv.class | html -%]" title="Tag editor">...</a>
180
                                <a href="#" id="buttonDot_[%- mv.id | html -%]" class="[%- mv.class | html -%]" title="Tag editor" data-plugin="[% mv.plugin | html %]">...</a>
181
                            [% END %]
181
                            [% END %]
182
                            [% UNLESS no_plugin %]
182
                            [% UNLESS no_plugin %]
183
                                [%# FIXME - from batchMod-edit, jQuery is included at the end of the template and cataloguing plugins are not working in this situation %]
183
                                [%# FIXME - from batchMod-edit, jQuery is included at the end of the template and cataloguing plugins are not working in this situation %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt (-1 / +1 lines)
Lines 539-545 Link Here
539
                        <div class="alert alert-info">The autoBarcode system preference is set to [% Koha.Preference('autoBarcode') | html %] and items with blank barcodes will have barcodes generated upon save to database</div>
539
                        <div class="alert alert-info">The autoBarcode system preference is set to [% Koha.Preference('autoBarcode') | html %] and items with blank barcodes will have barcodes generated upon save to database</div>
540
                    [% END %]
540
                    [% END %]
541
541
542
                    <div id="outeritemblock"></div>
542
                    <div id="outeritemblock" class="marc_editor"></div>
543
                </fieldset>
543
                </fieldset>
544
            [% END %][%# | html UNLESS subscriptionid %]
544
            [% END %][%# | html UNLESS subscriptionid %]
545
        [% END %][%# IF (AcqCreateItemOrdering) %]
545
        [% END %][%# IF (AcqCreateItemOrdering) %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt (-1 / +1 lines)
Lines 236-242 Link Here
236
                                                [% IF ( NoACQframework ) %]
236
                                                [% IF ( NoACQframework ) %]
237
                                                    <p class="required"> No ACQ framework, using default. You should create a framework with code ACQ, the items framework would be used </p>
237
                                                    <p class="required"> No ACQ framework, using default. You should create a framework with code ACQ, the items framework would be used </p>
238
                                                [% END %]
238
                                                [% END %]
239
                                                <div id="outeritemblock"></div>
239
                                                <div id="outeritemblock" class="marc_editor"></div>
240
                                            </div>
240
                                            </div>
241
                                        </div>
241
                                        </div>
242
                                        <div id="acq-create-ordering">
242
                                        <div id="acq-create-ordering">
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/authorities.tt (-2 / +2 lines)
Lines 449-455 Link Here
449
        </div>
449
        </div>
450
    [% END # /IF duplicateauthid %]
450
    [% END # /IF duplicateauthid %]
451
451
452
    <form method="post" id="f" name="f" action="/cgi-bin/koha/authorities/authorities.pl">
452
    <form method="post" id="f" name="f" action="/cgi-bin/koha/authorities/authorities.pl" class="marc_editor">
453
        [% INCLUDE 'csrf-token.inc' %]
453
        [% INCLUDE 'csrf-token.inc' %]
454
        <input type="hidden" name="op" value="cud-add" />
454
        <input type="hidden" name="op" value="cud-add" />
455
        <input type="hidden" name="original_op" value="[% op | html %]" />
455
        <input type="hidden" name="original_op" value="[% op | html %]" />
Lines 755-761 Link Here
755
                                                                    [% IF mv.noclick %]
755
                                                                    [% IF mv.noclick %]
756
                                                                        <a href="#" class="buttonDot tag_editor disabled" tabindex="-1" title="No popup">...</a>
756
                                                                        <a href="#" class="buttonDot tag_editor disabled" tabindex="-1" title="No popup">...</a>
757
                                                                    [% ELSE %]
757
                                                                    [% ELSE %]
758
                                                                        <a href="#" id="buttonDot_[% mv.id | html %]" class="buttonDot tag_editor" title="Tag editor">...</a>
758
                                                                        <a href="#" id="buttonDot_[% mv.id | html %]" class="buttonDot tag_editor" title="Tag editor" data-plugin="[% mv.plugin | html %]">...</a>
759
                                                                    [% END %]
759
                                                                    [% END %]
760
                                                                    [% mv.javascript | $raw %]
760
                                                                    [% mv.javascript | $raw %]
761
                                                                [% END #/IF ( mv.type == 'text1' ) %]
761
                                                                [% END #/IF ( mv.type == 'text1' ) %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt (-4 / +4 lines)
Lines 889-895 Link Here
889
                        window.close();
889
                        window.close();
890
                    </script>
890
                    </script>
891
                [% ELSE %]
891
                [% ELSE %]
892
                    <form method="post" name="f" id="f" action="/cgi-bin/koha/cataloguing/addbiblio.pl" onsubmit="return Check();">
892
                    <form method="post" name="f" id="f" action="/cgi-bin/koha/cataloguing/addbiblio.pl" onsubmit="return Check();" class="marc_editor">
893
                        [% INCLUDE 'csrf-token.inc' %]
893
                        [% INCLUDE 'csrf-token.inc' %]
894
                        <input type="hidden" value="[% IF ( biblionumber ) %]view[% ELSE %]items[% END %]" id="redirect" name="redirect" />
894
                        <input type="hidden" value="[% IF ( biblionumber ) %]view[% ELSE %]items[% END %]" id="redirect" name="redirect" />
895
                        <input type="hidden" value="" id="current_tab" name="current_tab" />
895
                        <input type="hidden" value="" id="current_tab" name="current_tab" />
Lines 1165-1171 Link Here
1165
                                                            [% END %]
1165
                                                            [% END %]
1166
1166
1167
                                                        [% ELSIF ( mv.type == 'text_complex' ) %]
1167
                                                        [% ELSIF ( mv.type == 'text_complex' ) %]
1168
                                                            <input type="text" id="[%- mv.id | html -%]" name="[%- mv.name | html -%]" value="[%- mv.value | html -%]" class="input_marceditor framework_plugin" tabindex="1" size="[%- mv.size | html -%]" maxlength="[%- mv.maxlength | html -%]" />
1168
                                                            <input type="text" id="[%- mv.id | html -%]" name="[%- mv.name | html -%]" value="[%- mv.value | html -%]" class="input_marceditor framework_plugin" tabindex="1" size="[%- mv.size | html -%]" maxlength="[%- mv.maxlength | html -%]" data-plugin="[% mv.plugin | html %]" />
1169
                                                            [% mv.javascript | $raw %]
1169
                                                            [% mv.javascript | $raw %]
1170
                                                        [% ELSIF ( mv.type == 'hidden' ) %]
1170
                                                        [% ELSIF ( mv.type == 'hidden' ) %]
1171
                                                            <input tabindex="1" type="hidden" id="[%- mv.id | html -%]" name="[%- mv.name | html -%]" size="[%- mv.size | html -%]" maxlength="[%- mv.maxlength | html -%]" value="[%- mv.value | html -%]" />
1171
                                                            <input tabindex="1" type="hidden" id="[%- mv.id | html -%]" name="[%- mv.name | html -%]" size="[%- mv.size | html -%]" maxlength="[%- mv.maxlength | html -%]" value="[%- mv.value | html -%]" />
Lines 1217-1225 Link Here
1217
                                                                    <span class="buttonDot tag_editor disabled" tabindex="-1" title="Field autofilled by plugin"></span>
1217
                                                                    <span class="buttonDot tag_editor disabled" tabindex="-1" title="Field autofilled by plugin"></span>
1218
                                                                [% ELSE %]
1218
                                                                [% ELSE %]
1219
                                                                    [% IF mv.plugin == "upload.pl" %]
1219
                                                                    [% IF mv.plugin == "upload.pl" %]
1220
                                                                        <a href="#" id="buttonDot_[% mv.id | html %]" class="tag_editor upload framework_plugin" tabindex="1"><i class="fa fa-upload" aria-hidden="true"></i> Upload</a>
1220
                                                                        <a href="#" id="buttonDot_[% mv.id | html %]" class="tag_editor upload framework_plugin" tabindex="1" data-plugin="[% mv.plugin | html %]"><i class="fa fa-upload" aria-hidden="true"></i> Upload</a>
1221
                                                                    [% ELSE %]
1221
                                                                    [% ELSE %]
1222
                                                                        <a href="#" id="buttonDot_[% mv.id | html %]" class="buttonDot tag_editor framework_plugin" tabindex="1" title="Tag editor">Tag editor</a>
1222
                                                                        <a href="#" id="buttonDot_[% mv.id | html %]" class="buttonDot tag_editor framework_plugin" tabindex="1" title="Tag editor" data-plugin="[% mv.plugin | html %]">Tag editor</a>
1223
                                                                    [% END %]
1223
                                                                    [% END %]
1224
                                                                [% END %]
1224
                                                                [% END %]
1225
                                                            </span>
1225
                                                            </span>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt (-1 / +1 lines)
Lines 225-231 Link Here
225
        <div class="row">
225
        <div class="row">
226
            <div class="col-md-2 order-sm-2 order-md-1"> [% INCLUDE 'biblio-view-menu.inc' %] </div>
226
            <div class="col-md-2 order-sm-2 order-md-1"> [% INCLUDE 'biblio-view-menu.inc' %] </div>
227
            <div class="col-md-10 order-md-2 order-sm-1">
227
            <div class="col-md-10 order-md-2 order-sm-1">
228
                <div id="cataloguing_additem_newitem" class="item_edit_form page-section">
228
                <div id="cataloguing_additem_newitem" class="item_edit_form page-section marc_editor">
229
                    <form id="f" method="post" action="/cgi-bin/koha/cataloguing/additem.pl?biblionumber=[% biblio.biblionumber | html %]" name="f">
229
                    <form id="f" method="post" action="/cgi-bin/koha/cataloguing/additem.pl?biblionumber=[% biblio.biblionumber | html %]" name="f">
230
                        [% INCLUDE 'csrf-token.inc' %]
230
                        [% INCLUDE 'csrf-token.inc' %]
231
                        <input type="hidden" name="op" value="[% op | html %]" />
231
                        <input type="hidden" name="op" value="[% op | html %]" />
(-)a/koha-tmpl/intranet-tmpl/prog/js/additem.js (-16 lines)
Lines 337-362 function cloneItemBlock(index, unique_item_fields, callback) { Link Here
337
                var cloneIndex = "itemblock" + random;
337
                var cloneIndex = "itemblock" + random;
338
                callback(cloneIndex);
338
                callback(cloneIndex);
339
            }
339
            }
340
            BindPluginEvents(data);
341
        },
340
        },
342
    });
341
    });
343
}
342
}
344
343
345
function BindPluginEvents(data) {
346
    // the script tag in data for plugins contains a document ready that binds
347
    // the events for the plugin
348
    // when we append, this code does not get executed anymore; so we do it here
349
    var events = data.match(/BindEventstag_\d+_subfield_._\d+/g);
350
    if (events == null) return;
351
    for (var i = 0; i < events.length; i++) {
352
        window[events[i]]();
353
        if (i < events.length - 1 && events[i] == events[i + 1]) {
354
            i++;
355
        }
356
        // normally we find the function name twice
357
    }
358
}
359
360
function clearItemBlock(node) {
344
function clearItemBlock(node) {
361
    var index = $(node).closest("div").attr("id");
345
    var index = $(node).closest("div").attr("id");
362
    var block = $("#" + index);
346
    var block = $("#" + index);
(-)a/koha-tmpl/intranet-tmpl/prog/js/cataloging.js (-58 / +44 lines)
Lines 1-5 Link Here
1
/* global __ */
1
/* global __ */
2
/* exported openAuth ExpandField CloneField CloneSubfield UnCloneField CloneItemSubfield CheckMandatorySubfields */
2
/* exported openAuth ExpandField CloneField CloneSubfield UnCloneField CloneItemSubfield CheckMandatorySubfields registerFrameworkPluginHandler */
3
3
4
/*
4
/*
5
 * Unified file for catalogue edition
5
 * Unified file for catalogue edition
Lines 253-260 function CloneField(index, hideMarc, advancedMARCEditor) { Link Here
253
253
254
            var inputs = divs[i].getElementsByTagName("input");
254
            var inputs = divs[i].getElementsByTagName("input");
255
            var id_input = "";
255
            var id_input = "";
256
            var olddiv;
257
            var oldcontrol;
258
256
259
            for (j = 0; j < inputs.length; j++) {
257
            for (j = 0; j < inputs.length; j++) {
260
                if (
258
                if (
Lines 323-333 function CloneField(index, hideMarc, advancedMARCEditor) { Link Here
323
                        }
321
                        }
324
                    }
322
                    }
325
                }
323
                }
326
                if ($(inputs[1]).hasClass("framework_plugin")) {
327
                    olddiv = original.getElementsByTagName("li")[i];
328
                    oldcontrol = olddiv.getElementsByTagName("input")[1];
329
                    AddEventHandlers(oldcontrol, inputs[1], id_input);
330
                }
331
            }
324
            }
332
            // when cloning a subfield, re set its label too.
325
            // when cloning a subfield, re set its label too.
333
            try {
326
            try {
Lines 380-403 function CloneField(index, hideMarc, advancedMARCEditor) { Link Here
380
                    if (buttonDot) {
373
                    if (buttonDot) {
381
                        // 2 possibilities :
374
                        // 2 possibilities :
382
                        try {
375
                        try {
383
                            if ($(buttonDot).hasClass("framework_plugin")) {
376
                            // do not copy the script section.
384
                                olddiv = original.getElementsByTagName("li")[i];
377
                            var script =
385
                                oldcontrol =
378
                                spans[0].getElementsByTagName("script")[0];
386
                                    olddiv.getElementsByTagName("a")[0];
379
                            spans[0].removeChild(script);
387
                                AddEventHandlers(
388
                                    oldcontrol,
389
                                    buttonDot,
390
                                    id_input
391
                                );
392
                            }
393
                            try {
394
                                // do not copy the script section.
395
                                var script =
396
                                    spans[0].getElementsByTagName("script")[0];
397
                                spans[0].removeChild(script);
398
                            } catch (e) {
399
                                // do nothing if there is no script
400
                            }
401
                        } catch (e) {
380
                        } catch (e) {
402
                            //
381
                            //
403
                        }
382
                        }
Lines 493-499 function CloneSubfield(index, advancedMARCEditor) { Link Here
493
    var selects = clone.getElementsByTagName("select");
472
    var selects = clone.getElementsByTagName("select");
494
    var textareas = clone.getElementsByTagName("textarea");
473
    var textareas = clone.getElementsByTagName("textarea");
495
    var linkid;
474
    var linkid;
496
    var oldcontrol;
497
475
498
    // input
476
    // input
499
    var id_input = "";
477
    var id_input = "";
Lines 513-524 function CloneSubfield(index, advancedMARCEditor) { Link Here
513
        linkid = id_input;
491
        linkid = id_input;
514
    }
492
    }
515
493
516
    // Plugin input
517
    if ($(inputs[1]).hasClass("framework_plugin")) {
518
        oldcontrol = original.getElementsByTagName("input")[1];
519
        AddEventHandlers(oldcontrol, inputs[1], linkid);
520
    }
521
522
    // select
494
    // select
523
    for (i = 0, len = selects.length; i < len; i++) {
495
    for (i = 0, len = selects.length; i < len; i++) {
524
        id_input = selects[i].getAttribute("id") + new_key;
496
        id_input = selects[i].getAttribute("id") + new_key;
Lines 551-563 function CloneSubfield(index, advancedMARCEditor) { Link Here
551
        linkid = id_input;
523
        linkid = id_input;
552
    }
524
    }
553
525
554
    // Handle click event on buttonDot for plugin
555
    var links = clone.getElementsByTagName("a");
556
    if ($(links[0]).hasClass("framework_plugin")) {
557
        oldcontrol = original.getElementsByTagName("a")[0];
558
        AddEventHandlers(oldcontrol, links[0], linkid);
559
    }
560
561
    if (advancedMARCEditor == "0") {
526
    if (advancedMARCEditor == "0") {
562
        // when cloning a subfield, reset its label too.
527
        // when cloning a subfield, reset its label too.
563
        var label = clone.getElementsByTagName("label")[0];
528
        var label = clone.getElementsByTagName("label")[0];
Lines 605-627 function CloneSubfield(index, advancedMARCEditor) { Link Here
605
    clone.querySelectorAll("input.input_marceditor").value = "";
570
    clone.querySelectorAll("input.input_marceditor").value = "";
606
}
571
}
607
572
608
function AddEventHandlers(oldcontrol, newcontrol, newinputid) {
609
    // This function is a helper for CloneField and CloneSubfield.
610
    // It adds the event handlers from oldcontrol to newcontrol.
611
    // newinputid is the id attribute of the cloned controlling input field
612
    // Note: This code depends on the jQuery data for events; this structure
613
    // is moved to _data as of jQuery 1.8.
614
    var ev = $._data(oldcontrol, "events");
615
    if (typeof ev != "undefined") {
616
        $.each(ev, function (prop, val) {
617
            $.each(val, function (prop2, val2) {
618
                $(newcontrol).off(val2.type);
619
                $(newcontrol).on(val2.type, { id: newinputid }, val2.handler);
620
            });
621
        });
622
    }
623
}
624
625
/**
573
/**
626
 * This function removes or clears unwanted subfields
574
 * This function removes or clears unwanted subfields
627
 */
575
 */
Lines 850-852 $(document).ready(function () { Link Here
850
        },
798
        },
851
    });
799
    });
852
});
800
});
853
- 
801
802
Koha.frameworkPlugins ||= {};
803
function registerFrameworkPluginHandler(name, eventType, handler) {
804
    // 'focus' and 'blur' events do not bubble,
805
    // so we have to use 'focusin' and 'focusout' instead
806
    if (eventType === 'focus') eventType = 'focusin';
807
    else if (eventType === 'blur') eventType = 'focusout';
808
809
    Koha.frameworkPlugins[name] ||= {};
810
    Koha.frameworkPlugins[name][eventType] ||= handler;
811
}
812
$(document).ready(function() {
813
    function callClickPluginEventHandler (event) {
814
        event.preventDefault();
815
        callPluginEventHandler.call(this, event);
816
    }
817
818
    function callPluginEventHandler (event) {
819
        event.stopPropagation();
820
821
        const plugin = event.target.getAttribute('data-plugin');
822
        if (plugin && plugin in Koha.frameworkPlugins && event.type in Koha.frameworkPlugins[plugin]) {
823
            event.data = {};
824
            if (event.target.classList.contains('buttonDot')) {
825
                event.data.id = event.target.closest('.subfield_line').querySelector('input.input_marceditor').id;
826
            } else {
827
                event.data.id = event.target.id;
828
            }
829
830
            Koha.frameworkPlugins[plugin][event.type].call(this, event);
831
        }
832
    }
833
834
    // We use delegated event handlers here so that dynamically added elements
835
    // (like when cloning a field or a subfield) respond to these events
836
    // without having to re-attach events manually
837
    $('.marc_editor').on('click', '.buttonDot', callClickPluginEventHandler);
838
    $('.marc_editor').on('focusin focusout change mousedown mouseup keydown keyup', 'input.input_marceditor.framework_plugin', callPluginEventHandler);
839
});

Return to bug 30975