【问题标题】:selecting prices from select options with JQuery使用 JQuery 从选择选项中选择价格
【发布时间】:2011-08-24 22:49:29
【问题描述】:

我在一个表单中有一堆选择字段。选择字段中的某些选项有价格。价格始终采用<option>text (+£9.99)</option> 格式,但显然价格可能会有所不同。如果其中一个选项被更改,我希望从选项中获取所有价格。不过,我只想要更改时选择的选项的价格。

使用 JQuery .change() 方法很好,但我很难理解如何使用 .match 方法从选项中返回数值以及如何仅获取选定的选项。我认为正则表达式是'/\(\+£([0-9\.]+)\)/'

$("select").live('change',function () {
  var price = 0;
  $("select option:selected").live('each',function () {
    price += $(this).text().match('/\(\+£([0-9\.]+)\)/');
  });
  alert (price);
})

我正在使用 live,因为表单是通过 ajax 加载的,具体取决于页面上的另一个表单。

任何帮助将不胜感激

谢谢

卢克

编辑:我尝试过 $(this).val().match 而不是 .text 方法。

编辑 2:我无法更改选项的值,因为它对应于数据库中选项的 id。 (参考下面丹尼斯的回答)

更新: 为了在 symfony 中使用下面的正确答案,我必须添加一个自定义小部件:

class myWidgetFormSelect extends sfWidgetFormSelect {

  /**
   * Returns an array of option tags for the given choices
   *
   * @param  string $value    The selected value
   * @param  array  $choices  An array of choices and attributes array key "content" denotes text
   * to be entered in option, all other keys become attributes
   *
   * @return array  An array of option tags
   */
  protected function getOptionsForSelect($value, $choices) {
    $mainAttributes = $this->attributes;
    $this->attributes = array();

    if (!is_array($value)) {
      $value = array($value);
    }

    $value = array_map('strval', array_values($value));
    $value_set = array_flip($value);

    $options = array();
    foreach ($choices as $key => $option) {
      $attributes = array('value' => self::escapeOnce($key));
      if (!is_array($option))
        $content = $option;
      else {
        foreach ($option as $name => $val) {
          if ($name == 'content')
            $content = $val;
          else
            $attributes[$name] = $val;
        }
      }
      if (isset($value_set[strval($key)])) {
        $attributes['selected'] = 'selected';
      }

      $options[] = $this->renderContentTag('option', self::escapeOnce(isset($content) ? $content : ''), $attributes);
    }

    $this->attributes = $mainAttributes;

    return $options;
  }

}

这个类允许选择数组是一个数组,并且使用如下调用具有多个属性:

new myWidgetFormSelect(array(
  'choices' => array(
    '1' /* <- the id of the option */ => array(
      'content' => 'text (+£9.99)',
      'data-price' => '9.99'
    )
  )
))

上面将创建一个带有选项的选择字段:

<option value="1" data-price="9.99">text (+£9.99)</option>

我希望这对遇到相同问题的人有所帮助。

【问题讨论】:

    标签: jquery regex select


    【解决方案1】:

    如果您像这样构建您的选择列表,并在每个选项上使用 data-price 属性:

    <select>
        <option data-price="9.99">text (+£9.99)</option>
        <option data-price="1.99">text (+£1.99)</option>
    </select>
    

    然后您可以使用$('select option:selected').data('price') 访问价格值。看这个活生生的例子:http://jsfiddle.net/8Z8Ft/

    因此你的问题变得简单多了:

    $("select").live('change',function () {
      var price = 0;
      $("select option:selected").each(function () {
        price += parseFloat($(this).data('price'));
      });
      alert (price);
    })
    

    现场示例:http://jsfiddle.net/yqTAB/

    既然你提到了 symfony,我做了一些搜索,发现了这个链接:http://blog.sznapka.pl/symfony-sfwidgetformselect-with-disabled-options/ 它描述了向一个选项添加一个属性(在这种情况下被禁用)。您可以使用相同的方法来添加这些数据属性。

    【讨论】:

    • 感谢 Jamiec 提供的信息,您认为使用 .split(':') 方法和使用 value="id:price" 有什么问题吗?因为这对我来说更简单?
    • @Luke - 我认为,虽然它有效,但它不是一个非常“干净”的解决方案。但是,嘿,有时您会为了便于开发而做出牺牲。
    • 谢谢你,在你挖掘“不是一个非常'干净'的解决方案”时,我决定构建一个干净的解决方案并使用你的 jquery。如果您有兴趣,我用代码更新了我的问题,以在 symfony 表单选择选项中创建属性。
    【解决方案2】:

    您可以像这样构建您的选项:

    <option value="9.99">text (+£9.99)</option>
    

    这样您只需致电$(this).val()。确保你 parseInt 或 parseFloat 否则你最终会连接字符串。


    您的代码的另一个问题:

    $("select option:selected").live('each',function () {
    

    应该是

    $("select option:selected").each(function () {
    

    因为每个都是函数,而不是事件类型

    【讨论】:

    • 嗨 Denis,感谢您的回答,我没有在问题中提及,但值是选项的 id,因为每个选项都来自数据库,并且多个选项可能具有相同的价格。再次感谢
    • 将原始价格放入价值中绝对比尝试将它们解析出文本更好。 +1。
    • @Luke - 在这种情况下使用 data-* 属性,如data-price="9.99"
    • @Jamiec - 你知道在 symfony 1.4 表单生成选项时如何将 data-* 属性添加到选项中吗?
    • @Luke - 不知道。但是,如果它正在生成 HTML,并且无法让您对生成的 HTML 进行精细控制,那么请尽快放弃它。
    【解决方案3】:

    Match 函数会返回一个数组。你应该索引它。

    【讨论】:

      【解决方案4】:

      这应该可行:

      $("select").live('change',function () {
        alert ($(this).val().match('£([0-9.]+)')[1]);
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多