0

I have a page with a set number of dropdown's on it at the moment (4), these dropdowns are used to select data from a list and submit it. It is used for selecting teams for a tournament, so at the moment I can only create a tournament with 4 teams.

I want to change it so the page displays only one dropdown saying something like Enter a number of teams and the user selects 4/8/16/32 for example. Based on what number the user selects, the page should then generate this number of dropdowns.

I'm having difficulty doing this, whatever number the user selects, the page then needs to render that amount of dropdowns and name them accordingly i.e #team1, #team2, #team3.

Any ideas how to do this?

Here are my dropdowns at the moment, using Jade template, sorry if there's any confusion by using Jade but it's easy to understand what it is:

div.newMatch
  form.form-horizontal(action='/tournament', id="tournamentForm")
        div.row
      label.control-label(for="tournamentName") Tournament Name:
      div.controls
        input#tournamentName.input-mysize(type="text")
    div.row
      label.control-label(for="team1") Team 1:
      div.controls
        select#team1(style='width: 160px;')
            include teamsDropDown
    div.row
      label.control-label(for="team2") Team 2:
      div.controls
        select#team2(style='width: 160px;')
            include teamsDropDown
    div.row
      label.control-label(for="team3") Team 3:
      div.controls
        select#team3(style='width: 160px;')
            include teamsDropDown
    div.row
      label.control-label(for="team4") Team 4:
      div.controls
        select#team4(style='width: 160px;')
            include teamsDropDown

What I've tried:

                div.row
                    label.control-label(for="tournamentName") Tournament Name:
                    div.controls
                        input#tournamentName.input-mysize(type="text")
                div.row
                    label.control-label(for="nTeamSelector") Tournament Size:
                    div.controls
                        select#nTeamSelector(style='width: 160px;')
                            option Please select...
                            option 2
                            option 4
                            option 8
                            option 16
                            option 32
                div.row.hidden#rowTemplate
                    label.control-label(for="team") Team:
                    div.controls
                        select#team1(style='width: 160px;')
                            include teamsDropDown
                div.row#rowContainer
                script(type='text/javascript')
                    $("#nTeamSelector").change(function(){
                        var nTeams = $("#nTeamSelector").val(); // Get the value of the team selector that you use
                        $("#rowContainer").empty() // Delete all existing dropdowns
                        for (var i=0; i<nTeams; i++){
                            var newRow = $("#rowTemplate").clone(); // Exact copy of the element generated by Jade
                            /*
                                * here you should change all the little fields that 
                                * make the dropdowns different. For example:
                            */
                            newRow.children(".control-label").setText("Team "+(i+1)+":");
                            $("#rowContainer").append(newRow);
                        }
                    });
Erpheus
  • 826
  • 7
  • 17
germainelol
  • 3,231
  • 15
  • 46
  • 82
  • At the moment I simply have the dropdown called `#numTeams`, and I've read around at various examples, but can't think of where to go from there. I'm sure Jade could help as you can insert some for loops using it. Sort of come to here as a last ditch attempt to get some advice. – germainelol Apr 13 '13 at 20:22
  • @lucuma I found an example here basically, http://stackoverflow.com/questions/8280426/how-would-i-dynamically-create-input-boxes-on-the-fly but the problem is that I am using Jade template to create my pages, so I'm wandering how this is possible using Jade. – germainelol Apr 13 '13 at 20:41
  • A suggestion from a user experience standpoint: You could start with one drop down and once they interact with it, add another. Then they can select as many as they want. (I don't know if a non-power-of-two number of drop-downs would work for your application, though.) – icktoofay Apr 13 '13 at 20:48
  • @icktoofay This would also work fine for the solution, or could do anyway, but I don't really understand how I would go about that using Jade rather than pure HTML...or if the HTML would work anyway as I don't know how to create a solution either way. – germainelol Apr 13 '13 at 20:51

2 Answers2

1

Jade is not only server-side: you can also compile Jade templates to run client-side. If I run:

$ jade --client template.jade

I'll get out a template.js file with some code in it that I can use on the client side (as long as I include runtime.js). The JavaScript file generated will declare a function called anonymous which you can pass local variables for the template to run with to as usual.

If I have a template file containing just this:

div.row
  label.control-label(for=id) Team 1:
  div.controls
    select(id=id, style='width: 160px;')
        include teamsDropDown

Then, assuming it uses no variables, you could use almost the normal code for appending:

$(anonymous({id: "team" + (teamCounter++)})).appendTo("#tournamentForm");

(or something like that; I'm sure you can figure it out)

By the way, if you're using Node.js and Browserify 1, you can use simple-jadeify to make the compilation easier.

icktoofay
  • 126,289
  • 21
  • 250
  • 231
1

I haven't worked with Jade but if you can write javascript inside your page and you use jquery (as stated by the tag) you could do something like this:

First add a hidden teamRow inside your page. You will clone it. This might seem hacky but it allows you to create a base model for every team selector inside your template with the special syntax you are using.

div.row.hidden#rowTemplate
  label.control-label(for="team") Team:
  div.controls
    select#team1(style='width: 160px;')
        include teamsDropDown

Javascript:

$("#nTeamSelector").change(function(){

    var nTeams = //get the value of the team selector that you use

    $("#rowContainer").empty() //Delete all existing dropdowns

    for (var i=0; i<nTeams; i++){

        var newRow = $("#rowTemplate").clone(); //exatc copy of the element generated by Jade

        /*
         * here you should change all the little fields that 
         * make the dropdowns different. For example:
         */

        newRow.children(".control-label").setText("Team "+(i+1)+":");


        $("#rowContainer").append(newRow);

    }
});

I've left out things like the rowContainer, wich is a simple div, or the css of the class hidden (but I don't think those are related to the problem).

I haven't done as well what the for in Jade does, wich will probably only change one attribute of the label, and maybe you should change the id of the input. But that will be just another pair of easy javascript lines.

Erpheus
  • 826
  • 7
  • 17
  • I've tried to implement your code above just to see if I can get something to appear, but nothing actually appears when I try to implement it. I've added what I tried to put above if you would take a look, I appreciate the help. – germainelol Apr 13 '13 at 21:19
  • I think it might be that i forgot to remove the hidden class after cloning the element. Run the code with the webinspector open to see if any errors are thrown and put an alert('hi'); line. Just to discard any other errors. – Erpheus Apr 14 '13 at 01:19
  • To remove the hidden class write: newRow.removeClass("hidden") – Erpheus Apr 14 '13 at 01:20
  • `Uncaught TypeError: Object [object Object] has no method 'setText'` is the error I get. – germainelol Apr 14 '13 at 10:44
  • Just the `setText` it doesn't like, not sure why. – germainelol Apr 14 '13 at 10:47
  • As well as this, all the dropDowns are called #team1, I'm having a play to fix it but no success. – germainelol Apr 14 '13 at 10:49
  • Sorry, the setText() method is in fact called text() – Erpheus Apr 14 '13 at 15:18
  • To change the id try: newRow.children("#team1").attr("id","team"+(i+1)); – Erpheus Apr 14 '13 at 15:20