在循环期间无法选择表单选项

Posted

技术标签:

【中文标题】在循环期间无法选择表单选项【英文标题】:Can't get form option selected during a loop 【发布时间】:2012-12-25 14:44:11 【问题描述】:

我有一个将值存储到变量中的解析器(duh)。这里有问题的变量是:

$item[2]   <- contains the string 'facebook'

我有一个包含选择菜单的 html 表单。菜单是根据我的数据库中存储的内容动态填充的。这就是我的菜单的构建方式:

<?php
$formats = $wpdb->get_results($wpdb->prepare("
        SELECT * FROM table
        WHERE taxonomy = 'format'
        "));
?>

<div id="format" class="form">
    Format: <?php echo $item[2]; ?>  <!-- echoes the variable to know it works -->
    <?php
        $terms = array();              
        foreach($formats as $key => $term)
            $terms[$term->parent][$term->term_id] = $term;
        
    ?>    
    <select name="formats">
        <option value="empty"></option>
        <?php printTerms($terms, $item); ?> <!--- THIS DOESN'T APPEAR TO PASS $item INTO THE FUNCTION -->
    </select>
</div>

<?php
function printTerms($terms, $item, $parent = 0, $deep = 0) // HOW DO I USE $item ???
    if(count($terms[$parent]) > 0)
        $indent = "";
        for($i = 0; $i < $deep; $i++)
            $indent .= "&nbsp;&nbsp;&nbsp;";
        

        foreach($terms[$parent] as $key => $term)
            if(count($terms[$term->term_id]) > 0)
                if($deep == 0)
                    echo "<option class='toplevel' value='".$term->name."' ".$selected.">".$term->name."</option>";   //     <- Outputs top level parents
                 else 
                    echo "<option class='child".$deep."' value='".$term->name."' ".$selected.">".$indent.$term->name."</option>";  // <- Outputs children that are also parents
                

                printTerms($terms, $term->term_id, ($deep+1));

             else 
                echo "<option class='solo' value='".$term->name."' ".$selected.">".$indent.$term->name."</option>";   // <- outputs bottom level children and solos.
            
        
    

?>

到目前为止,这一切都有效,但这是我的问题。

我希望如果 items[2] 包含字符串“Facebook”(它确实如此),则默认选择相应的菜单选项。

我确实让它在一个简单的静态选择菜单中工作,如下所示:

foreach ($formats as $format) 
    $selected = '';
            if ($item[2] == 'facebook' || $item[2] == 'wall' && $format->slug == 'facebook') 
        $selected = 'selected';
    
    echo "<option value='".$format->name."' ".$selected.">".$format->name."</option>";

$format->slug 包含我想要匹配到 $item[2] 的值。 因此,$term->slug 对应于 $format->slug。

$format->name 是输出到菜单本身的选择选项的标题。 同样,$term->name 对应于 $format->name。

$formats 访问这个 mysql 表:

term_id       name           slug                 taxonomy     parent
1             Entry Form     entry-form           format       0
2             Page           page                 format       3
3             Facebook       facebook             format       0
4             Entry Form     facebook-entry-form  format       3
5             Twitter        twitter              format       0
6             Single        single                format       2

您会注意到我已经将 $selected 变量插入到我的函数中。我的问题是我无法让上面的代码在 printTerms 函数的上下文中工作。

就我的问题而言,假设任何变量中都没有空格(我检查过)。

要记住的一些规则:

$term->slug 和 $item[2] 并不总是匹配。如果 $item[2] 是 'wall',这也会导致默认选择 'facebook'。 (见我上面的代码)。

所以问题是,如何将我的 printTerms() 函数与我的选择代码结合起来?

【问题讨论】:

您是否尝试过将 $item 传递给 printTerms 然后 if($term->name == $item[2]) $selected='selected' ? 对了,忘了把$item传给函数。也就是说,你的建议不起作用。我需要说明 if($item[2] == 'facebook' && $term->slug == 'facebook') $selected='selected'; 因为 $item[2] 和 $term->slug don并不总是匹配。我已经尽我所能尝试了您的解决方案,但没有成功。 如果您正在执行递归并且想要间隔或以其他方式复合一个值,您可以传递初始值和当前值,因此您在递归遍历中没有for。您可能需要trim(strtolower($item[0])) == trim($term-slug)) 来均衡检查并删除任何看不见的空白。将选择的精确空格和所有输出作为代码块粘贴到答案中可能会有所帮助。 你是对的,如果我试图选择一个子选项,我需要修剪空白。但是,即使对于没有空格的父选项,该代码也不起作用。就我而言,$item[2] 或 $term->slug 中没有任何空格。 【参考方案1】:

我稍微修改了您的代码以在没有数据库的情况下工作,以进行测试。真正的“变化”是我将count() 修改为使用isset()

细微的变化是选项现在以换行符分隔,并且函数不输出任何内容,而是返回输出。

这样生成的 HTML 会在我的 Firefox 浏览器中将“Facebook”显示为默认选择。

(缩进,并删除 &lt;/option&gt; 以方便阅读)

<html><body><select>
<option class='solo'     value='Entry Form'>Entry Form
<option class='toplevel' value='Facebook' selected="selected">Facebook
<option class='child1'   value='Page'      >   Page
<option class='solo'     value='Single'    >      Single
<option class='solo'     value='Entry Form'>   Entry Form
<option class='solo'     value='Twitter'   >Twitter
</select></body></html>

PHP测试用例如下:

<?php
        $formats = array(
                array('term_id' => 1, 'name' => 'Entry Form', 'slug' => 'entry-form', 'taxonomy' => 'format', 'parent' => 0),
                array('term_id' => 2, 'name' => 'Page', 'slug' => 'page', 'taxonomy' => 'format', 'parent' => 3),
                array('term_id' => 3, 'name' => 'Facebook', 'slug' => 'facebook', 'taxonomy' => 'format', 'parent' => 0),
                array('term_id' => 4, 'name' => 'Entry Form', 'slug' => 'facebook-entry-form', 'taxonomy' => 'format', 'parent' => 3),
                array('term_id' => 5, 'name' => 'Twitter', 'slug' => 'twitter', 'taxonomy' => 'format', 'parent' => 0),
                array('term_id' => 6, 'name' => 'Single', 'slug' => 'single', 'taxonomy' => 'format', 'parent' => 2),
        );

        $terms = array();
        foreach($formats as $term)
                $a = $term['parent'];
                $b = $term['term_id'];
            $terms[$a][$b] = $term;
        

        function printTerms($terms, $parent = 0, $deep = 0, $item)
        $output = '';
    if(count($terms[$parent]) > 0)
        $indent = "";
        for($i = 0; $i < $deep; $i++)
            $indent .= "   ";
        

        foreach($terms[$parent] as $key => $term)
        
            $selected = ($item == $term['slug']) ? ' selected="selected"' : '';
            if(isset($terms[$term['term_id']]))
            
                if($deep == 0)
                    $output .= "<option class='toplevel' value='".$term['name']."'".$selected.">".$term['name']."</option>";   //     <- Out
puts top level parents
                 else 
                    $output .= "<option class='child".$deep."' value='".$term['name']."'".$selected.">".$indent.$term['name']."</option>";
// <- Outputs children that are also parents
                
                $output .= "\n";
                $output .= printTerms($terms, $term['term_id'], ($deep+1), $item);

             else 
                $output .= "<option class='solo' value='".$term['name']."'".$selected.">".$indent.$term['name']."</option>";   // <- outputs
 bottom level children and solos.
                $output .= "\n";
            
        
    
        return $output;


        print "<html><body><select>";
        print printTerms($terms, 0, 0, 'facebook');
        print "</select></body></html>";

?>

更新:我们可以在之前的 printTerms 函数的基础上进行更灵活的匹配。

首先,我们将printTerms() 重命名为printTermsBase(),并从中删除所有对选项选择的引用。然后输出将是一堆形式的行

 <option class='something' value='somethingelse'>text</option>

现在我们可以在输出上运行文本匹配。下面的函数,当通过“墙”时,将选择“墙”;如果没有“墙”,它将选择“facebook”;如果那也不存在,它将不选择任何内容。您可以反转数组以便选择“墙”除非 facebook 存在。文本匹配准确:“facebook-form”将被忽略。如果您希望将“facebook”与“facebook-form”匹配,则需要使用preg* 函数。

 function printTerms($terms, $item)
 
     $items = array($item, 'facebook');
     $options = printTermsBase($terms, 0, 0);
     foreach($items as $raw)
     
         // We could use preg_match here for even greater flexibility
         $search="value='$raw'";
         if (false === strpos($options, $search))
             continue;
         // One of the option matches.
         // We just replace    value='something'
         // with               value='something' selected='selected'
         return str_replace($search, $search.' selected="selected"', $options);
     
     // No match. Return options unchanged.
     return $options;
 

【讨论】:

问题是 $item 和 $term['slug'] 并不总是匹配的。如果项目是“墙”,我也希望默认选择“Facebook”。可以有几个字符串可以匹配 Facebook 和另一组几个字符串可以匹配 Twitter。这就是我的选择代码使用显式字符串匹配的原因。 那么您的 slug 中是否有可能同时包含“wall”和“Facebook”,并且比如说,“wall”是项目?因为在这种情况下,您需要对 printTerms() 的架构进行更彻底的更改。 我试图想出一个更通用的解决方案。查看更新的答案。 不,slug 只是 facebook,但 $items 可以是任何东西。如果 $items 包含 wall 或 facebook,则选择应在 facebook 上,否则应为空白。查看我的选择代码以了解我在做什么。 让我把问题简化一下,因为我不明白。假设选择是我发布的,没有任何selected。应该选择哪一个选项(如果有的话)?

以上是关于在循环期间无法选择表单选项的主要内容,如果未能解决你的问题,请参考以下文章

无法提交表单选择选项Vuelidate

在下拉菜单更改期间确认保存

vue循环生成的表单,el-select初始化之后再选择其他选项视图不更新。

onclick javascript 无法使用 Firefox 上的选择选项完全刷新表单

在选择选项上自定义引导表单控件

Vue.js 属性或方法“选项”未在实例上定义,但在渲染期间被引用