0

I am using a WebGrid to allow CRUD on my database (using MVC and EF entities). The grid works and filters they way I want it to. There are two columns that use dropdowns to display a value tied to another table (Projects and People) and these both work well for edits/ updates. I am using JQuery for an add new row and want the new row to have select fields like the grid does (so that the user can just find the person by name instead of having to enter the ID for example). I am referencing this post from another similar question, but when I implement the code I get a syntax error that I'm having trouble understanding.

Here is my scripting on the view side that shows my failed attempt. I'm creating an array from the project repository (Text is the name of the project and Value is the ID field), and populating it with the model values: Model.Projects, and then in the add row function I want to loop through the array to add in the options.

<script type="text/javascript">
var ProjectArray = new Array();
@foreach (var proj in Model.projects)
{
    @:ProjectArray.push(Text: "@proj.Text", Value: "@proj.Value");
}
</script>
<script type="text/javascript">
$(function ()
{
    $('body').on("click", ".add", function () {
    var SelectedProject = "@Model.ProjectID";
    var newRow = $('.save').length;
    console.log('newRow = ' + newRow);
    if (newRow == 0) {
        var index = "new"+$("#meetingList tbody tr").length + 1;
        var ProjectID = "ProjectID_" + index;
        var Date = "Date_" + index;
        var Attendees = "Attendees_" + index;
        var Phase = "Phase_" + index;
        var PeopleID = "PeopleID_" + index;
        var Save = "Save _" + index;
        var Cancel = "Cancel_" + index;

        var tr = '<tr class="alternate-row"><td><span> <input id="' + ProjectID + '" type="select"/></span></td>' +
            @* This is where I use the array to add the options to the select box*@
            ProjectArray.forEach(function (item) {
                if (item.Value == SelectedProject) { '<option selected="selected" value="' + item.Value + '">' + item.Text + '</option>' }
                else { '<option value="' + item.Value + '">' + item.Text + '</option>' }
                +
            });
---remaining script omitted----
                    
                    '<td><span> <input id="' + PeopleID + '" type="text" /></span></td>' +
                    '<td><span> <input id="' + Date + '" type="date" /></span></td>' +
                    '<td><span> <input id="' + Attendees + '" type="text" /></span></td>' +
                    '<td><span> <input id="' + Phase + '" type="text" /></span></td>' +
                    '<td> <a href="#" id="' + Save + '" class="save">Save</a><a href="#" id="' + Cancel + '" class="icancel">Cancel</a></td>' +
                    '</tr>';
                console.log(tr);
                $("#meetingList tbody").append(tr);
            }
        });

I am not sure how to parse the error, but the page source looks like this when creating my client side array:

var ProjectArray = new Array();
ProjectArray.push(Text: "Select Project", Value: ""); //<-- ERROR HERE:
ProjectArray.push(Text: "010111.00", Value: "74");
ProjectArray.push(Text: "013138.00", Value: "2");

So the model getting into the client side works (the text and value pairs are correct), but the error I get is for the first array.push line: missing ) after the argument list. I have played with moving this code block around, putting it in a separate <script> tag and the error likewise follows it around, always on the first array.push line. And regardless of where it is, the rest of my script functions no longer work. I think it must be something silly but I just am not seeing what I'm doing wrong.

The option list does not populate into something I can ever see, it just renders out on the page source as the javascript loop:

var tr = '<tr class="alternate-row"><td><span> <input id="' + ProjectID + '" type="select"/></span></td>' +
ProjectArray.forEach(function (item) {
if (item.Value == SelectedProject) { '<option selected="selected" value="' + item.Value + '">' + item.Text + '</option>' }
else { '<option value="' + item.Value + '">' + item.Text + '</option>' }
+
}); //-- Unexpected token here

And with the push array in its separate script block I get a second error that the last } is an unexpected token. This is some javascripting error I'm sure. But where it is an how to do this are beyond me right now.

Paul Gibson
  • 622
  • 1
  • 9
  • 23
  • 1
    you projected array could look like this var ProjectArray = new Array(); ProjectArray.push({Text: "Select Project", Value: ""}); ProjectArray.push({Text: "010111.00", Value: "74"}); ProjectArray.push({Text: "013138.00", Value: "2"}); – piyush sanadhya Jan 10 '23 at 20:28
  • @piyushsanadhya, thank you! I have added that comment to the linked post as well, this seems to eliminate the first error. Now getting the javascript loop to correctly output the options list based on the array (last code block is what the page source looks like) remains. Thank you for your time! – Paul Gibson Jan 10 '23 at 21:45

1 Answers1

0

I'm not used to javascript, and poor syntax leads to the vague errors I was getting. The first problem was fixed by adding the { . . . } around the array values. Then I created a function to create the arrays I need for people and projects as well as a function to take an array and create the option list to clean up the view code:

function createProjectArray() {
    var ProjectArray = new Array();
    @foreach (var proj in Model.projects)
    {
        if (proj.Value != "") {
            @:ProjectArray.push({ Text: "@proj.Text", Value: "@proj.Value" });
        }
    }
    return ProjectArray;
}

function createPeopleArray() {
    var PeopleArray = new Array();
    @foreach (var person in Model.people)
    {
        if (person.Value != "") {
            @:PeopleArray.push({ Text: "@person.Text", Value: "@person.Value" });
            }
    }
    return PeopleArray;
}

function SelectOptionsString(MyArray, SelectedValue) {
    console.log(MyArray);
    var OptionsList = "";
    MyArray.forEach(item => {
        if (item.Value == SelectedValue) { OptionsList += '<option 
    selected="selected" value="' + item.Value + '">' + item.Text + '</option>'; }
        else { OptionsList += '<option value="' + item.Value + '">' + item.Text 
    + '</option>'; }
    })
        return OptionsList;
    }

Taking this approach allowed me to more easily parse the code and find the syntax errors. The Array.forEach syntax was an interesting hurdle, and this site helped me test out my syntax to eventually get it working as above.

So the server creates the javascript lines to create the array, and then I use the array to create my dropdown options list. This cleans up the add row function code nicely:

$('body').on("click",".addrow", function() {
    var SelectedProject = "@Model.ProjectID";
    var ProjectArray = createProjectArray();
    var ProjectOptions = "";
    ProjectOptions = SelectOptionsString(ProjectArray, SelectedProject);
    var PeopleArray = createPeopleArray();
    var PeopleOptions = "";
    PeopleOptions = SelectOptionsString(PeopleArray, "");

    var tr = '<tr class="alternate-row"><td><span> <select id="' + 
        ProjectID + '>' + ProjectOptions + '</select></span></td>' +
        '<td><span> <select id="' + PeopleID + '>' + PeopleOptions + 
        '</select></span></td>' + '</tr>'
    $("#myWebGrid tbody").append(tr);
 });

And it also allows for some potential code reuse.

Paul Gibson
  • 622
  • 1
  • 9
  • 23