admin管理员组

文章数量:1410674

I have a widget that I have been working on, that contains a <script> tag inside the $widget->form() method. I use the following in my source code, within the script tag:

<script>
    (function ($) {
        var desrdPostTypeSelector = '#<?php echo $this->get_field_id( 'desired_post_type' ); ?>';
        var beginPostTypeSelector = '#<?php echo $this->get_field_id( 'beginning_post_type' ); ?>';

        $('#<?php echo $this->get_field_id( 'isSingle' ); ?>').on( 'change', function() {
            $( '.<?php echo $multi_post_class ?>, #<?php echo $beginning_post_tag_id ?>' ).toggleClass('hidden', this.checked);
        });

        $('#<?php echo $this->get_field_id( 'isTaxonomy' ); ?>').on( 'change', function() {
            $( '#<?php echo $beginning_post_tag_id ?>' ).toggleClass('hidden', this.checked);
        });

        $('#<?php echo $this->get_field_id( 'isSingle' ); ?>, #<?php echo $this->get_field_id( 'isTaxonomy' ); ?>').on( 'change', function () {
            if ( $('#<?php echo $beginning_post_tag_id ?>').hasClass('hidden') ) {
                clearAllDisabledBy( getListOfOptionElements( $( desrdPostTypeSelector )[0] ) );
            } else {
                disableOptionsBasedOnSelected( $( beginPostTypeSelector )[0], $( desrdPostTypeSelector )[0] );
            }
        } );

        $('#<?php echo $this->get_field_id( 'beginning_post_type' ); ?>').on( 'change submit', function () {
            clearAllDisabledBy( getListOfOptionElements( $( desrdPostTypeSelector )[0] ) );
            disableOptionsBasedOnSelected( this, $( desrdPostTypeSelector )[0] );
        } );
    })(jQuery);
</script>

Then, when I go to Appearance -> Widgets and I copy my widget over to a sidebar none of the JavaScript works! I looked at the rendered HTML and saw this:

Why is the unrendered widget number __i__ showing up in the JavaScript but not in the HTML portion? This is a fresh drag-and-drop instance of the widget, mind you, no page refresh. However, when I refresh the page, everything works fine. Am I doing something wrong here?

The file where the JavaScript functions are located is being included in the Sources list in dev tools, I can also see it in the HTML, but for kicks here's how I enqueue that:

In plugin file:

function enqueue_scripts() {
    wp_enqueue_script(
        'related_posts_script_helpers',
        plugin_dir_url( __FILE__ ) . "assets/related-posts-script-helpers.js",
        array( 'jquery' ),
        '1.0'
    );
}

if ( is_admin() ) {
    add_action( 'admin_enqueue_scripts', 'enqueue_scripts' );
}

Is this is a timing issue (on my part) or a bug in WordPress? Any help would be much appreciated. Thank you!

I have a widget that I have been working on, that contains a <script> tag inside the $widget->form() method. I use the following in my source code, within the script tag:

<script>
    (function ($) {
        var desrdPostTypeSelector = '#<?php echo $this->get_field_id( 'desired_post_type' ); ?>';
        var beginPostTypeSelector = '#<?php echo $this->get_field_id( 'beginning_post_type' ); ?>';

        $('#<?php echo $this->get_field_id( 'isSingle' ); ?>').on( 'change', function() {
            $( '.<?php echo $multi_post_class ?>, #<?php echo $beginning_post_tag_id ?>' ).toggleClass('hidden', this.checked);
        });

        $('#<?php echo $this->get_field_id( 'isTaxonomy' ); ?>').on( 'change', function() {
            $( '#<?php echo $beginning_post_tag_id ?>' ).toggleClass('hidden', this.checked);
        });

        $('#<?php echo $this->get_field_id( 'isSingle' ); ?>, #<?php echo $this->get_field_id( 'isTaxonomy' ); ?>').on( 'change', function () {
            if ( $('#<?php echo $beginning_post_tag_id ?>').hasClass('hidden') ) {
                clearAllDisabledBy( getListOfOptionElements( $( desrdPostTypeSelector )[0] ) );
            } else {
                disableOptionsBasedOnSelected( $( beginPostTypeSelector )[0], $( desrdPostTypeSelector )[0] );
            }
        } );

        $('#<?php echo $this->get_field_id( 'beginning_post_type' ); ?>').on( 'change submit', function () {
            clearAllDisabledBy( getListOfOptionElements( $( desrdPostTypeSelector )[0] ) );
            disableOptionsBasedOnSelected( this, $( desrdPostTypeSelector )[0] );
        } );
    })(jQuery);
</script>

Then, when I go to Appearance -> Widgets and I copy my widget over to a sidebar none of the JavaScript works! I looked at the rendered HTML and saw this:

Why is the unrendered widget number __i__ showing up in the JavaScript but not in the HTML portion? This is a fresh drag-and-drop instance of the widget, mind you, no page refresh. However, when I refresh the page, everything works fine. Am I doing something wrong here?

The file where the JavaScript functions are located is being included in the Sources list in dev tools, I can also see it in the HTML, but for kicks here's how I enqueue that:

In plugin file:

function enqueue_scripts() {
    wp_enqueue_script(
        'related_posts_script_helpers',
        plugin_dir_url( __FILE__ ) . "assets/related-posts-script-helpers.js",
        array( 'jquery' ),
        '1.0'
    );
}

if ( is_admin() ) {
    add_action( 'admin_enqueue_scripts', 'enqueue_scripts' );
}

Is this is a timing issue (on my part) or a bug in WordPress? Any help would be much appreciated. Thank you!

Share Improve this question asked Apr 27, 2017 at 20:44 mrCleanmrClean 1991 silver badge10 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

the __i__ widget instance is a place holder/template for new widget instances when they are create on the UI. Widgets are assigned an actual widget number that will replace the __i__ when they are added to a sidebar and then An ajax request is sent from the UI to the server to update it with the new number, no response is expected from the server for that.

So what happens is that the __i__ instance is just duplicated into the sidebar UI with the only thing being changed is the __i__ being replaced with an actual number on all of the form fields. your JS is not a form field.

Hopefully this explains the why, and why it works after a save (a widget save will probably also solve the problem), as after the save the widget's HTML is fully generated on the server side and not only emulated in JS.

How to fix? do not add JS snippets in the form. Use classes on the elements you want to make "dynamic" and use the jQuery APIs which can locate the element relative to the currently clicked one. For example, if the element is on the "root" of the widget, get the element parent and find() the element below it which has the class you want to manipulate.

本文标签: pluginsWhy is the unrendered widget number i showing up in the JavaScript but not in the HTML