首页 > 解决方案 > 用于下拉列表的 JQuery 搜索字段

问题描述

我有一个使用重力表单和链式选择的 wordpress 表单,在其上添加来自 csv 文件的显示数据作为下拉字段。我只需要在每个下拉列表顶部添加搜索输入字段,以便用户可以搜索数据列表。我还附上了JQuery代码,你能帮我在这段代码中添加这个功能吗

( function( $ ) {

window.GFChainedSelects = function( formId, fieldId, hideInactive, alignment ) {

    var self = this;

    self.formId       = formId;
    self.fieldId      = fieldId;
    self.hideInactive = hideInactive;
    self.alignment    = alignment;

    var $field = $( '#field_' + self.formId + '_' + self.fieldId );

    self.$selects  = $field.find( 'select' );
    self.$complete = $field.find( '.gf_chain_complete' );

    self.isDoingConditionalLogic = false;

    self.init = function() {

        gform.addAction( 'gform_input_change', function( elem, formId, fieldId ) {
            if( self.$selects.index( elem ) != - 1 ) {
                var inputId = $( elem ).attr( 'name' ).split( '_' )[1]; // converts "input_4.1" to "4.1"
                self.populateNextChoices( inputId, elem.value, $( elem ) );
            }
        }, 9 );

        self.$selects.filter( function() {
            var $select = $( this );
            return $select.hasClass( 'gf_no_options' ) || $select.find( 'option' ).length <= 1;
        } ).toggleSelect( true, self.hideInactive );
            //.prop( 'disabled', true ).hide();

        /*var $lastSelect = self.$selects.last();
        self.toggleCompleted( $lastSelect.hasClass( 'gf_no_options' ) || $lastSelect.val() );*/

        gform.addFilter( 'gform_is_value_match', function( isMatch, formId, rule ) {
            return self.isValueMatch( isMatch, formId, rule );
        } );

    };

    self.populateNextChoices = function( inputId, selectedValue, $select ) {

        var nextInputId = self.getNextInputId( inputId ),
            $nextSelect = self.$selects.filter( '[name="input_' + nextInputId + '"]' );

        // if there is no $nextSelect, we're at the end of our chain
        if( $nextSelect.length <= 0 ) {
            self.resetSelects( $select, true );
            self.resizeSelects();
            return;
        } else {
            self.resetSelects( $select );
        }

        if( ! selectedValue ) {
            return;
        }

        if( self.hideInactive ) {

            var $currentSelect = $( '[name="input_' + inputId + '" ]' ),
                $spinner       = new gfAjaxSpinner( $currentSelect, gformChainedSelectData.spinner, 'display:inline-block;vertical-align:middle;margin:-1px 0 0 6px;' );

        } else {

            var $loadingOption  = $( '<option value="">' + gformChainedSelectData.strings.loading + '...</option>' ),
                dotCount        = 2,
                loadingInterval = setInterval( function() {
                    $loadingOption.text( gformChainedSelectData.strings.loading + ( new Array( dotCount ).join( '.' ) )  );
                    dotCount = dotCount > 3 ? 0 : dotCount + 1;
                }, 250 );

            $loadingOption.prependTo( $nextSelect ).prop( 'selected', true );
            $nextSelect.css( { minWidth: $nextSelect.width() } );
            $loadingOption.text( gformChainedSelectData.strings.loading + '.' );

        }

        $.post( gformChainedSelectData.ajaxUrl, {
            action:   'gform_get_next_chained_select_choices',
            input_id: inputId,
            form_id:  self.formId,
            field_id: self.fieldId,
            value:    self.getChainedSelectsValue(),
            nonce:    gformChainedSelectData.nonce
        }, function( response ) {

            if( self.hideInactive ) {

                $spinner.destroy();

            } else {

                clearInterval( loadingInterval );
                $loadingOption.remove();

            }

            if( ! response ) {
                return;
            }

            var choices       = $.parseJSON( response ),
                optionsMarkup = '';

            $nextSelect.find( 'option:not(:first)' ).remove();

            if( choices.length <= 0 ) {

                self.resetSelects( $select, true );

            } else {

                var hasSelectedChoice = false;

                $.each( choices, function( i, choice ) {
                    var selected = choice.isSelected ? 'selected="selected"' : '';

                    if ( selected )  {
                        hasSelectedChoice = true;
                    }

                    optionsMarkup += '<option value="' + choice.value + '"' + selected + '>' + choice.text + '</option>';
                } );

                $nextSelect.show().append( optionsMarkup );

                // the placeholder will be selected by default, rather than removing it and re-adding, just force the noOptions option to be selected
                if( choices[0].noOptions ) {

                    var $noOption = $nextSelect.find( 'option:last-child' ).clone(),
                        $nextSelects = $nextSelect.parents( 'span' ).nextAll().find( 'select' );

                    $nextSelects.append( $noOption );

                    $nextSelects.add( $nextSelect )
                        .addClass( 'gf_no_options' )
                        .find( 'option:last-child' ).prop( 'selected', true );

                    //self.toggleCompleted( true );

                } else {
                    $nextSelect
                        .removeClass( 'gf_no_options' )
                        //.prop( 'disabled', false ).show();
                        .toggleSelect( false, self );

                    if ( hasSelectedChoice ) {
                        $nextSelect.change();
                    }
                }

            }

            self.resizeSelects();

        } );

    };

    self.getChainedSelectsValue = function() {

        var value = {};

        self.$selects.each( function() {
            var inputId = $( this ).attr( 'name' ).split( '_' )[1]; // converts "input_4.1" to "4.1"
            value[ inputId ] = $( this ).val();
        } );

        return value;
    };

    self.getNextInputId = function( currentInputId ) {

        var index     = parseInt( currentInputId.split( '.' )[1] ),
            nextIndex = index + 1;

        if( nextIndex % 10 == 0 ) {
            nextIndex++;
        }

        return parseInt( currentInputId ) + '.' + ( nextIndex );
    };

    self.resetSelects = function( $currentSelect, isComplete ) {

        var currentIndex = self.$selects.index( $currentSelect ),
            $nextSelects = self.$selects.filter( ':gt(' + currentIndex + ')' );

        $nextSelects
            .toggleSelect( true, self.hideInactive )
            .find( 'option:not(:first)' )
            .remove()
            .val( '' )
            .change();

    };

    self.resizeSelects = function() {

        if( self.alignment != 'vertical' ) {
            return;
        }

        // reset width so it will be determined by its contents
        self.$selects.width( 'auto' );

        var width = 0;

        self.$selects.each( function() {
            if( $( this ).width() > width ) {
                width = $( this ).width();
            }
        } );

        self.$selects.width( width + 'px' );

    };

    self.toggleCompleted = function( isComplete ) {
        if( isComplete ) {
            self.$complete.fadeIn();
        } else {
            self.$complete.fadeOut();
        }
    };

    self.isValueMatch = function( isMatch, formId, rule ) {

        if( rule.fieldId != self.fieldId || self.isDoingConditionalLogic ) {
            return isMatch;
        }

        self.isDoingConditionalLogic = true;

        rule = $.extend( {}, rule );

        var valueObj   = self.getChainedSelectsValue(),
            fieldValue = Object.keys( valueObj ).map( function( key ) { return valueObj[ key  ]; } ),
            ruleValue = rule.value.split( '/' );

        for( var i = 0; i < ruleValue.length; i++ ) {
            if( ruleValue[i] == '*' ) {
                ruleValue[i] = fieldValue[i];
            }
        }

        ruleValue  = ruleValue.join( '/' );
        fieldValue = fieldValue.join( '/' );

        isMatch = gf_matches_operation( ruleValue, fieldValue, rule.operator );

        self.isDoingConditionalLogic = false;

        return isMatch;
    };

    $.fn.toggleSelect = function( disabled, hideInactive ) {
        this.prop( 'disabled', disabled );
        if( typeof hideInactive != 'undefined' && hideInactive ) {
            if( disabled ) {
                this.hide();
            } else {
                this.show();
            }
        }
        return this;
    };

    self.init();

};

function gfAjaxSpinner( elem, imageSrc, inlineStyles ) {

    var imageSrc     = typeof imageSrc == 'undefined' ? '/images/ajax-loader.gif': imageSrc,
        inlineStyles = typeof inlineStyles != 'undefined' ? inlineStyles : '';

    this.elem = elem;
    this.image = '<img class="gfspinner" src="' + imageSrc + '" style="' + inlineStyles + '" />';

    this.init = function() {
        this.spinner = jQuery(this.image);
        jQuery( this.elem ).after(this.spinner);
        return this;
    };

    this.destroy = function() {
        jQuery( this.spinner ).remove();
    };

    return this.init();
}

} )( jQuery );

HTML:

<li id="field_1_129" class="gfield field_sublabel_below field_description_below gfield_visibility_visible"><label class="gfield_label" for="input_1_129_1"></label><div class="ginput_container horizontal medium gfield_chainedselect" id="input_1_129"><span id="input_1_129_1_container" class="">
                <select name="input_129.1" id="input_1_129_1" class="" onchange="gf_input_change( this, 1, 129 );"><option value="" selected="selected" class="gf_placeholder">Level</option><option value="Undergraduate">Undergraduate</option><option value="Postgraduate">Postgraduate</option><option value="Foundation">Foundation</option><option value="HND">HND</option><option value="HNC">HNC</option></select>
            </span><span id="input_1_129_2_container" class="">
                <select name="input_129.2" id="input_1_129_2" class="" onchange="gf_input_change( this, 1, 129 );" style="min-width: 260px;"><option value="" selected="selected" class="gf_placeholder">Subject</option><option value="Art">Art</option><option value="Biological Sciences">Biological Sciences</option><option value="Bioscience">Bioscience</option><option value="Business">Business</option><option value="Chemical Engineering">Chemical Engineering</option><option value="Civil Engineering">Civil Engineering</option><option value="Computer Science">Computer Science</option><option value="Construction">Construction</option><option value="Design">Design</option><option value="Electrical Engineering">Electrical Engineering</option><option value="Engineering">Engineering</option><option value="Film">Film</option><option value="Finance">Finance</option><option value="Forensic">Forensic</option><option value="Games">Games</option><option value="Healthcare">Healthcare</option><option value="Jewellery">Jewellery</option><option value="Law">Law</option><option value="Performing Arts">Performing Arts</option><option value="Photography">Photography</option><option value="Policing">Policing</option><option value="Product Design">Product Design</option><option value="Social Science">Social Science</option><option value="Sport">Sport</option></select>
            </span><span id="input_1_129_3_container" class="">
                <select name="input_129.3" id="input_1_129_3" class="" onchange="gf_input_change( this, 1, 129 );" style="min-width: 300px;"><option value="" selected="selected" class="gf_placeholder">University</option><option value="London South Bank University">London South Bank University</option></select>
            </span><span id="input_1_129_4_container" class="">
                <select name="input_129.4" id="input_1_129_4" class="" onchange="gf_input_change( this, 1, 129 );" disabled=""><option value="" selected="selected" class="gf_placeholder">Course</option></select>
            </span><span class="gf_chain_complete" style="display:none;">&nbsp;</span></div></li>

标签: jquerysearch

解决方案


我创建了一个脚本,它会在每个选择的顶部添加一个输入字段(虽然没有 css)。每次用户修改输入字段的值时,都会过滤其后的选择标签。

请运行代码段并将脚本复制到您的代码中。确保将它放在脚本的末尾,可能位于页脚标签或正文标签的末尾。

$(document).ready(function() {
  $(".ginput_container>span").each(function() {

    if ($(this).attr("id") != null) {

      // if id attribute is not null, do something
      if ($(this).attr("id").indexOf("container") > -1) {

        // if id has the word 'container' do something
        // add an input field
        $(this).prepend("<input class='filter-input' style='display:block;'/>");
      }
    }
  });
});

$(document).on("keyup", ".filter-input", function() {

  // store filter value
  var filterValue = $(this).val();

  $(this).parent().find("option").each(function() {

    // loop through the option fields inside the parent span
    if ($(this).html().toUpperCase().indexOf(filterValue.toUpperCase()) > -1) {

      // show if filter is a substring
      $(this).show();
    } else {

      // else hide
      $(this).hide();
    }
  });
});

function gf_input_change() {
  // don't include this
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<li id="field_1_129" class="gfield field_sublabel_below field_description_below gfield_visibility_visible">

  <label class="gfield_label" for="input_1_129_1"></label>
  <div class="ginput_container horizontal medium gfield_chainedselect" id="input_1_129">

    <span id="input_1_129_1_container" class="">
      <select name="input_129.1" id="input_1_129_1" class="" onchange="gf_input_change( this, 1, 129 );">
        <option value="" selected="selected" class="gf_placeholder">Level</option>
        <option value="Undergraduate">Undergraduate</option>
        <option value="Postgraduate">Postgraduate</option>
        <option value="Foundation">Foundation</option>
        <option value="HND">HND</option>
        <option value="HNC">HNC</option>
      </select>
    </span>

    <span id="input_1_129_2_container" class="">
      <select name="input_129.2" id="input_1_129_2" class="" onchange="gf_input_change( this, 1, 129 );" style="min-width: 260px;">
        <option value="" selected="selected" class="gf_placeholder">Subject</option>
        <option value="Art">Art</option>
        <option value="Biological Sciences">Biological Sciences</option>
        <option value="Bioscience">Bioscience</option>
        <option value="Business">Business</option>
        <option value="Chemical Engineering">Chemical Engineering</option>
        <option value="Civil Engineering">Civil Engineering</option>
        <option value="Computer Science">Computer Science</option>
        <option value="Construction">Construction</option>
        <option value="Design">Design</option>
        <option value="Electrical Engineering">Electrical Engineering</option>
        <option value="Engineering">Engineering</option>
        <option value="Film">Film</option>
        <option value="Finance">Finance</option>
        <option value="Forensic">Forensic</option>
        <option value="Games">Games</option>
        <option value="Healthcare">Healthcare</option>
        <option value="Jewellery">Jewellery</option>
        <option value="Law">Law</option>
        <option value="Performing Arts">Performing Arts</option>
        <option value="Photography">Photography</option>
        <option value="Policing">Policing</option>
        <option value="Product Design">Product Design</option>
        <option value="Social Science">Social Science</option>
        <option value="Sport">Sport</option>
      </select>
    </span>

    <span id="input_1_129_3_container" class="">
      <select name="input_129.3" id="input_1_129_3" class="" onchange="gf_input_change( this, 1, 129 );" style="min-width: 300px;">
        <option value="" selected="selected" class="gf_placeholder">University</option>
        <option value="London South Bank University">London South Bank University</option>
      </select>
    </span>

    <span id="input_1_129_4_container" class="">
      <select name="input_129.4" id="input_1_129_4" class="" onchange="gf_input_change( this, 1, 129 );" disabled=""> 
        <option value="" selected="selected" class="gf_placeholder">Course</option>
      </select>
    </span>

    <span class="gf_chain_complete" style="display:none;">&nbsp;</span>

  </div>
</li>


推荐阅读