jQuery UI自动完成鼠标单击选择不传递值

时间:2018-01-15 17:30:47

标签: php jquery jquery-ui autocomplete jquery-ui-autocomplete

我在PHP页面中使用jQuery UI Autocomplete来获取位置服务。特别是这个使用Remote JSONP数据源类型。我遇到的问题很奇怪,只有一种方式发生。

以下是发生的事情:

  1. 用户输入整个选择。该值按预期分配和传递。
  2. 用户键入部分选择并使用键盘下拉到所需的选择并按下回车键。该值按预期分配和传递。
  3. 用户输入部分选项并点击所需的选项。只传递键入到他们点击的点的段。
  4. 换句话说,如果用户输入Location,则会传递Location。如果用户输入Loca并使用键盘下拉到Location,则会传递Location。但是,如果用户键入Loca并使用鼠标点击Location,则会传递Loca

    这是一个插件,所以我会尽我所能解释并显示相关代码。当我说它被传递时,它将被传递给PHP变量$thisVAR

    我无法弄清楚为什么值会作为输入的段传递而不是分配的完整值。

    这是在创建字段时创建js的PHP:

    $js .= "$( function(){";
    $js .= "$('.error').hide();";
    $js .= "var rollbackValue = '';";
    $js .= "$('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').keyup(function(){";
    $js .= "rollbackValue = $(this).val().slice(0,-1);";
    $js .= "});";
    $js .= "$('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').autocomplete({";
    $js .= "source: function( request, response ){";
    $js .= "$.ajax({";
    $js .= "url: '" . $thisURL . "',";
    $js .= "dataType: 'jsonp',";
    $js .= "data: {";
    $js .= "term: request.term,";
    $js .= "dependents: '". $thisVAR . "',";
    $js .= "field: '". $config->settings['field_name'] . "_" . $suggestiveFieldArray . "',";
    $js .= "fieldSettings: " . json_encode($fieldSettings);
    $js .= "},";
    $js .= "success: function( data ) {";
    if( $fieldSettings['allow_other_countries'] == 'n' ){
        $js .= "if (!data || !Object.keys(data).length){";
        $js .= "$('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').prev('.error')";
        if( !empty($fieldSettings['custom_error']) ){
            $js .= ".html('" . $customError . "')";
        }else{
            $js .= ".html('Sorry, there were no available records found starting with `<span style=\"text-transform: capitalize;\">' + request.term + '</span>`.')";
        }
        $js .= ".fadeIn('slow', function(){ $(this).delay(2500).fadeOut('slow'); });";
        $js .= "$('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').val(rollbackValue);";
        $js .= "} else {";
        $js .= "    response( data );";
        $js .= "}";
    }else{
        $js .= "response( data );";
    }
    $js .= "},";
    $js .= "minLength: 0";
    $js .= "});";
    $js .= "}";
    $js .= "});";
    $js .= "});";
    

    这相当于js中的以下内容(更易于阅读):

    $( function(){
        $('.error').hide();
        var rollbackValue = '';
        $('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').keyup(function(){
            rollbackValue = $(this).val().slice(0,-1);
        });
        $('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').autocomplete({
            source: function( request, response ){
                $.ajax({
                    url: '" . $thisURL . "',
                    dataType: 'jsonp',
                    data: {
                        term: request.term,
                        dependents: '". $thisVAR . "',
                        field: '". $config->settings['field_name'] . "_" . $suggestiveFieldArray . "',
                        fieldSettings: " . json_encode($fieldSettings);
                    },
                    success: function( data ) {
                        if ( !data || !Object.keys(data).length ){
                            $('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').prev('.error')
                            .html('Sorry, there were no available records found starting with `<span style=\"text-transform: capitalize;\">' + request.term + '</span>`.')
                            .fadeIn('slow', function(){ $(this).delay(2500).fadeOut('slow'); });
                            $('#" . $config->settings['field_name'] . "_" . $suggestiveFieldArray . "').val(rollbackValue);
                        } else {
                            response( data );
                        }
                    },
                    minLength: 0
                });
            }
        });
    });
    

    变量$thisVAR已确定并设置在此上方:

    /**
     * Determine our variables for this field
     */
    $thisVAR = ''; $abbr = '';
    if( strpos($suggestiveFieldArray, 'city') !== false ) {
        /**
         * We need the state and country data
         */
        $thisVAR = "$myState|$myCountry";
        $abbr = ( $fieldSettings['abbreviations'] == 'y' ? "true" : "false" );
    }elseif( strpos($suggestiveFieldArray, 'state') !== false ) {
        /**
         * We need the city and country data
         */
        $thisVAR = "$myCity|$myCountry";
        $abbr = ( $fieldSettings['abbreviations'] == 'y' ? "true" : "false" );
    }elseif( strpos($suggestiveFieldArray, 'country') !== false ) {
        /**
         * We need the city and state data
         */
        $thisVAR = "$myCity|$myState";
        $abbr = ( $fieldSettings['abbreviations'] == 'y' ? "true" : "false" );
    }
    

    ... $myCity$myState$myCountry都是从字段值中提取的。

    /**
     * Associative Fields Values
     */
    if($field['name'] == 'theField_city'){
        $myCity = $field['value'];
    }elseif($field['name'] == 'theField_state'){
        $myState = $field['value'];
    }elseif($field['name'] == 'theField_country'){
        $myCountry = $field['value'];
    }
    

2 个答案:

答案 0 :(得分:0)

肯定有更好的方法可以做到这一点,但我能够通过添加一个单独的js文件来实现我需要的东西,该文件包含一个宣称&#34; global&#34;从ajax请求返回新数据后要在更改事件上修改的变量。我想我只是想用一个文件做太多。 :(

答案 1 :(得分:0)

如果没有示例数据,我只能做一些猜测。为了使其更流畅,我会调整一些id属性以使用-而不是_。次要偏好和需要考虑的事项。

我使用以下数据进行测试,并对您的HTML做了一些假设。如果您要返回我怀疑您的对象,则该对象必须至少包含labelvalue对。

[{
  label: "San Jose, CA US",
  value: "San Jose",
  city: "San Jose",
  state: "California",
  stateAbbr: "CA",
  country: "United States"
}, {
  label: "Santa Clara, CA US",
  value: "Santa Clara",
  city: "Santa Clara",
  state: "California",
  stateAbbr: "CA",
  country: "United States"
}, {
  label: "Mountain View, CA US",
  value: "Mountain View",
  city: "Mountain View",
  state: "California",
  stateAbbr: "CA",
  country: "United States"
},
{
  label: "Springfield, OR US",
  value: "Springfield",
  city: "Springfield",
  state: "Oregon",
  stateAbbr: "OR",
  country: "United States"
},
{
  label: "Springfield, NY US",
  value: "Springfield",
  city: "Springfield",
  state: "New York",
  stateAbbr: "NY",
  country: "United States"
}];

我还建议使用POST与GET并使用JSON与JSONP。如果您发送单个术语或少量数据,您真的只想使用GET。对于大量数据而言,POST更好,而且更安全。

JSONP只有在您的PHP服务器托管在另一个域内或在Web服务器之外的其他API下才有用。由于PHP正在生成JavaScript代码而AJAX正在调用PHP Self,因此我认为没有理由使用JSONP。

在您的自动完成中,您似乎需要以下内容:

  • 如果未返回任何结果,则生成错误警报
  • 根据用户条目自动填充城市,州和国家/地区
  • 国家可能会也可能不会使用缩写

我假设如果他们开始输入城市名称并进行选择,则应填写相应的州和国家/地区详细信息。

工作示例:https://jsfiddle.net/Twisty/5r1by1xp/

<强> HTML

<div class="ui-widget">
  <ul>
    <li>
      <div class="error"></div>
      <label>City</label>
      <input type="text" id="fn-city" data-abbr="n" />
    </li>
    <li>
      <div class="error"></div>
      <label>State</label>
      <input type="text" id="fn-state" data-abbr="y" style="width: 2em;" />
    </li>
    <li>
      <div class="error"></div>
      <label>Country</label>
      <input type="text" id="fn-country" data-abbr="n" />
    </li>
  </ul>
</div>

<强> CSS

.ui-widget ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.ui-widget ul li label {
  display: inline-block;
  width: 80px;
}

.ui-widget .error {
  font-size: 65%;
  color: red;
}

<强>的JavaScript

// Only used for example & jsFiddle
var myData = [{
  label: "San Jose, CA US",
  value: "San Jose",
  city: "San Jose",
  state: "California",
  stateAbbr: "CA",
  country: "United States"
}, {
  label: "Santa Clara, CA US",
  value: "Santa Clara",
  city: "Santa Clara",
  state: "California",
  stateAbbr: "CA",
  country: "United States"
}, {
  label: "Mountain View, CA US",
  value: "Mountain View",
  city: "Mountain View",
  state: "California",
  stateAbbr: "CA",
  country: "United States"
}, {
  label: "Springfield, OR US",
  value: "Springfield",
  city: "Springfield",
  state: "Oregon",
  stateAbbr: "OR",
  country: "United States"
}, {
  label: "Springfield, NY US",
  value: "Springfield",
  city: "Springfield",
  state: "New York",
  stateAbbr: "NY",
  country: "United States"
}];

$(function() {
  $('.error').hide();
  var rollbackValue = '';
  $("[id|='fn']").keyup(function() {
    rollbackValue = $(this).val().slice(0, -1);
  });
  $("[id|='fn']").focus(function() {
    $(this).addClass("activeField")
  }).blur(function() {
    $(this).removeClass("activeField");
  }).autocomplete({
    source: function(request, response) {
      var fnid = $(".activeField").attr("id");
      var dep = fnid.slice(fnid.indexOf("-") + 1);
      var term = request.term.toLowerCase();
      $.ajax({
        url: '/echo/json/',
        type: "POST",
        dataType: 'json',
        data: {
          json: JSON.stringify(myData),
          term: request.term,
          dependents: dep,
          field: fnid,
          fieldSettings: JSON.stringify({
            abbreviations: $("#" + fnid).data("abbr")
          })
        },
        success: function(data) {
          var results = [];
          $.each(data, function(k, v) {
            var depResult = v[dep].toLowerCase();
            if (depResult.indexOf(term) === 0) {
              results.push(v);
            }
          });
          if (results.length == 0) {
            console.log("No Results Found.");
            $("#" + fnid).parent().find(".error")
              .html('Sorry, there were no available records found starting with `<span style=\"text-transform: capitalize;\">' + term + '</span>`.')
              .fadeIn('slow', function() {
                $(this).delay(2500).fadeOut('slow');
              });
            $("#" + fnid).val(rollbackValue)
            ''
          }
          response(results);
        },
        minLength: 0
      });
    },
    select: function(e, ui) {
      $("#fn-city").val(ui.item.city);
      $("#fn-state").val(ui.item.stateAbbr);
      $("#fn-country").val(ui.item.country);
      return false;
    }
  });
});

我个人不会使用PHP来生成JavaScript本身。它可以完成,如果您使用模板并且大量数据不是静态的,您可能无法远离它。例如,您可以在JS文件中定义和存储各种函数;通过<script>添加它们,然后从PHP传递给它们:

<强> JS

function makeAutoComplete(fID){
  var $field = $("#" + fID);
  $field.autocomplete();
}

<强> PHP

$js = "<script src='myfunctions.js'></script>\r\n";
$js .= "<script>\r\n";
$js .= "makeAutoComplete('" . $config->settings['field_name'] . "-" . $suggestiveFieldArray . "')\r\n";
$js .= "</script>\r\n";

通过这种方式,您可以最小化交叉上下文的数量。它还使得故障排除和测试变得更容易。我也将你的PHP脚本分开。可以制作小型PHP脚本,只需将数据发布给他们然后返回数据。

希望有所帮助。