Pug模板 - 如何将下拉列表中的选项标记为已选

16

我有一个使用Bootstrap 4作为“布局”的Pug模板,从Express/Mongoose服务器接收数据。

我从MongoDB中填充表单,以便可以编辑内容。我一直在寻找方法使下拉列表根据mongoDB文档中的值选择一个选项。

我已经看到了从头开始构建下拉列表并设置选项为“selected”的方法,但表单已经生成并且已经有了下拉列表。 我只需要将选项与mongoDB文档中的值匹配,并将选项设置为在列表中显示。

Pug模板如下:

.row
  .col-sm-6
    .form-group
      label.control-label.requiredField(for='propertyType')
        | Property Type
        span.asteriskField *
      .col-xs-12
        select#propertyType.select.form-control.input-lg(form='addProperty', name='propertyType')
          option(value='0') -- Select --
          option(value='6') Home
          option(value='7') Condo
          option(value='10') Single Family Home
          option(value='11') Town House
          option(value='12') City Apartment
          option(value='13') Villa


script.
  var propertyType = document.getElementById('propertyType');

  for (var i = 0; i < propertyType.options.length; i++) {

    if (propertyType.options[i].value = #{property.typeId}) {
        propertyType.options[i].selected = 'selected';
        propertyType.selectedIndex = i;
        break;
    }

  }
如果我保持代码不变,那么获得新值的实际选项是第一个“-- Select --”,其值从“0”更改为来自MongoDB文档的值“6”。
如果我将javascript更改为像这样将值#{property.TypeId}传递到“selectedIndex”:
propertyType.selectedIndex = #{property.typeId};

然后索引值会改变,'selected'选项也会改变 - 变为'6',但是这会选择options的第6个而不是值为'6'的选项。

下拉框是我似乎无法填充的唯一内容,任何帮助都将不胜感激。

6个回答

25

如果您只需要显示一个预选选项,我认为您不需要使用JavaScript。您可以尝试以下方法:

.row
  .col-sm-6
    .form-group
      label.control-label.requiredField(for='propertyType')
        | Property Type
        span.asteriskField *
      .col-xs-12
        select#propertyType.select.form-control.input-lg(form='addProperty', name='propertyType')
          option(value='0', selected= true) -- Select --
          option(value='6', selected= property.id == 6) Home
          option(value='7', selected= property.id == 7) Condo
          option(value='10', selected= property.id == 10) Single Family Home
          option(value='11', selected= property.id == 11) Town House
          option(value='12', selected= property.id == 12) City Apartment
          option(value='13', selected= property.id == 13) Villa

假设此下拉菜单显示与property.id对应的值,它将标记与property.id中的值相匹配的optionselected属性为true。否则,默认情况下将显示第一个选项。


但是如果你有30个选项(我知道很多),你将不得不编写大量的代码。这似乎会增加更新代码库的难度。 - Pandafinity
很抱歉Mohit,但我认为这是一种低效的解决方案。特别是如果您有其他工作流程使用不同的标识符来使某些内容“可选”。比如说,如果您有一个动态数据集,其中的组使用不同的选择器来定义默认值?那么您将不得不添加更多的代码来区分这些选择器...谢谢。 - Pandafinity
@Pandafinity :( 不确定为什么对你不起作用,但我使用它。逻辑很简单,如果在jade中将selected属性赋值为true,则在html中会以selected="selected"的形式显示,并且该选项将被选中。因此,在这里我们的一个表达式将会是真或者默认情况下第一个选项将被选中。 - Mohit Bhardwaj
1
@MohitBhardwaj 我想我之前理解错了。现在虽然还是会出现 'selected=""',但是已经可以正常工作了。感谢你的帮助。 - kiml42
1
我使用修改过的版本select#content-display.form-control(name='grid_entry_source_type') each elem in [{'name': '全部', 'value': 1}, {'name': '拾取', 'value': 2}] option(value=elem.value, selected=(elem.value === result.grid_entry_source_type))= elem.name - kewang
显示剩余4条评论

12

我在for循环中使用了Mohit Bhardwaj的答案,以获得一个简单的解决方案。

select(name='image')
  option(value='' selected=!project.image) (empty)
  for img in images
    option(value=img.id selected=(img.id === project.image.id)) #{img.alt}

5

更新

希望自己回答问题没问题。我尝试了Mohit的方法,但对我没有用。

我在每个<select>输入下添加了一个“script”部分:

script.
  var pOptions = document.getElementById('propertyType').options;
  for (i=0; i < pOptions.length; i++) {
    if (pOptions[i].value == #{property.typeId}) pOptions[i].selected = true;
  }

2
没问题,自己回答自己的问题是完全可以的。这是一个问答网站,每个问题都应该有一个答案! - Mr Lister

3

查看此处的文档,我找到了一种不需要JavaScript并且可以内联使用的解决方案。

这是我在我的代码中使用的方式:

select(name="priority")
    each priority in priorities
        option(value=priority.id selected=(job.priority.id == priority.id) ) #{priority.name}

谢谢您提供的解决方案,它指引我找到了我的解决方案。在我的模板中有一个变量,所以我简单地使用了'option(value="xy" selected=(xy==variable)) xy',它完美地解决了我的问题! - portal TheAnGeLs

0
              here is index.pug
              /////////////////////   

           extends layout


           block content
           h1= title
           //- p Welcome to #{title}
         style.
         input[type=text], select {
         width: 20%;
         padding: 12px 20px;
         margin: 8px 0;
         display: inline-block;
         border: 1px solid #ccc;
         border-radius: 4px;
         box-sizing: border-box;
          }
       input[type=submit] {
       width: 10%;
       background-color: #4CAF50;
       color: white;
       padding: 14px 20px;
       margin: 8px 0;
       border: none;
       border-radius: 4px;
       cursor: pointer;
        }
       input[type=submit]:hover {
       background-color: #45a049;
       }
     div {
      border-radius: 1px;
      background-color: #f2f2f2;
      padding: 20px; }
     link(rel='stylesheet', href='/scripts/css/bootstrap.css')
     script(src="/scripts/js/bootstrap.min.js")
     //-      //- 

       script(src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js")
       script(src="/jquery/jquery.js")
       h3 Choose Your Skill
       - var  optos = skills
 div
    form(action='/Skill' method="post")
 div
    label Enter- 
    input(type='text',id='zaftot',name="zaftot" ,onKeyup="myFunc(this.value)"         
    autofocus="autofocus") 
    input(type='submit',  value='Submit')  
 div   

    select(name='dropdown' id="myselect" size="4" ,onClick="myclick()",style="margin- 
    left:40px" )


    script.
          function myclick(){ 
          var t=$("#myselect").val().toString();
          $("#zaftot").val(t);
          $("#zaftot").focus();
          $("#myselect").hide();
        /// alert(t);
         };
     function memo(){ 
       /// remove  all items of list
        var x = document.getElementById("myselect");
        while(true){ 
        if (x.length > 0) {
          x.remove(x.length-1);
               }
               else{
                 break;
               }
             }
          }

     function myFunc(inp){
        $("#myselect").show();

          memo(); //clear list before initiatig new one
       if (inp.length >0){
        //alert(inp +'----hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh');
        var aa =!{JSON.stringify(optos)}
        var uu =inp.trim().toLowerCase();
         for (i = 0; i < aa.length; i++) {
          var  tt =aa[i].trim().toLowerCase();
          //var y =tt.substr(0,uu.length);
          //alert(uu);
          //if(tt.substr(0,uu.length))===uu {  // substr() not working i dont know
            if(tt.indexOf(uu)>-1){ 
              $('#myselect').append('<option>' + aa[i] + '</option>');
            };
         };
     };
    };
     ////////////////////////////////////////////////////

          here is  routes /index.js  
          /////////////////////////////

        /*esversion=6 */
        var express = require('express');
        var router = express.Router();

       router.get("/", function (req, res) {
        var  skills =["MVC", "C#", "mmm","mlll","moo","muuu" 
        ,"mdd","mkkkk","Node  
        JS", 
       "mkyy" ,  "Python" ,  "IDE visual studio","Mssql"];
        res.render('index', {
          title : "Select technology",
         skills:skills
        });
       });

     router.post("/Skill" , function(req, res){
     console.log(req.body);
     res.render('Skill',{
     skill: req.body.dropdown
     });
     });

    module.exports = router;
        //////////////////////////////////////
           package json
          {
         "name": "aziz",
            "version": "0.0.0",
            "private": true,
          "scripts": {
           "start": "nodemon ./bin/www"
         },
         "dependencies": {
         "bootstrap": "^4.1.3",
         "cookie-parser": "~1.4.3",
         "debug": "~2.6.9",
        "eslint": "^5.5.0",
         "express": "~4.16.0",
         "http-errors": "~1.6.2",
        "jquery": "^3.3.1",
        "morgan": "~1.9.0",
        "nodemon": "^1.18.4",
         "popper.js": "^1.14.3",
         "pug": "2.0.0-beta11"
        },
      "author": "azizsallam",
       "license": "ISC"
        }     
        ///////////////////////////
         add these two line to app.js

 ////////////ADD TO APP.JS the next line how to call bootstrap files in yuor          
            ///////////////////  the next line how to call bootstrap files 
 in yuor view ///////////////////
 app.use('/scripts', express.static(__dirname + 
 '/node_modules/bootstrap/dist/'));
 app.use('/jquery', express.static(__dirname + 
 '/node_modules/jquery/dist/'));
   //////////////////////////////////

使用Node、Express和pug模板引擎的工作示例,修改自Stack Overflow上的另一篇帖子,发布于2018年5月19日,作者为Chen V。http://chen.about-powershell.com/2018/05/dynamically-populate-data-for-drop-down-list-using-pug-in-node-js/ - aziz sallam
这非常广泛。 - Vega
请在您的回答中添加解释 - mastisa
使用 Express Generator 构建您的应用程序文件夹并初始化 JSON 包。 - aziz sallam
MR Saeed --- 我刚刚也添加了 PACKAGE.JSON - aziz sallam

0
这里有一种方法可以实现此操作,而无需使用脚本标签或展开循环。
-var selected = true;
select(id=field.id required=required)
    each op in field.options
        option(value=op name=field.name selected=selected) #{op}
        -if(selected){
            -selected=false;
        -}

这将使用属性设置语法将列表中的第一个选项设置为“selected”(如果在评估时selected为true,则selected=selected将附加标签)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接