Charlie Pugh
Charlie Pugh

Reputation: 342

MVC3 incrementing a variable in javascript(Jquery)

I'm attempting to create a form inside a table that adds a new row every time content is added to the form. Here's my code, and then I'll tell what the problem is.

@{
    //Declare the i variable
    var i = 0;
}

@using (Html.BeginForm())
{
    <table>
        <tr>
            <th>

            </th>
            <th>
                Question
            </th>
        </tr>
        <tr id="@(i+1)">
            <td class="QuestionNum">
                @(i+1))
            </td>
            //This is the cell with the Form field. 
            <td>
                @Html.TextBoxFor(m => m.Questions[i].Question, new { @class = "QuestionBox Last" })
            </td>
        </tr>
    </table>
}

<script>
    $(document).ready(function () {
        SetUpNewLine($('.QuestionBox'));
    });

    function SetUpNewLine(obj) {
        obj.bind('keyup paste', function () {
            if ($(this).val() != "") {
                if ($(this).hasClass("Last")) {

                    //This is the line that isn't working.
                    @(i++)

                    $(this).parents('table').append('<tr id="@(i+1)"><td class="QuestionNum">@(i+1))</td><td>@Html.TextBoxFor(m => m.Questions[i], new { @class = "QuestionBox Last", style="width:100%;" })</td></tr>');
                    $(this).removeClass('Last');
                    SetUpNewLine($('.Last'));
            }
        });
    }
</script>

So, this code works for the first time, but when calling the @(i++) in the Javascript function, it doesn't save the variable change once you get outside of the function. So after the first Html.TextBoxFor, which is for the first item in the Model.Questions object, it does create a new textbox like I wanted, but instead of incrementing the item it changes in the List, it makes them all just edit the second item in the list.

The odd thing is that if I was to do the @(i++) inside the $(document).ready(), it would work fine.

Any ideas on how I could increment the variable correctly? I'm sure there's just something I don't know when it comes to mixing Razor variables and Javascript.

Upvotes: 0

Views: 2351

Answers (2)

scottm
scottm

Reputation: 28703

You need to store the server rendered value of i in javascript.

EDIT This is all wrong. You won't be able to append to your element with razor syntax like you are trying to do. Razor is a server side template language and once it is interpreted to HTML, you can render more HTML from the client side.

EDIT 2 Try something like the following:

var current_index = (@i);

    $(document).ready(function () {
        SetUpNewLine($('.QuestionBox'));
    });

    function getHtml(index){
        return '<tr id="' +index + '"><td class="QuestionNum">'+ index +'</td><td><input type="text" name="Question" class="QuestionBox Last" style="width:100%;"/></td></tr>';
    }

    function SetUpNewLine(obj) {
        obj.bind('keyup paste', function () {
            if ($(this).val() != "") {
                if ($(this).hasClass("Last")) {

                    //This is the line that isn't working.
                    current_index++;

                    $(this).parents('table').append(getHtml(current_index);
                    $(this).removeClass('Last');
                    SetUpNewLine($('.Last'));
            }
        });
    }

Upvotes: 2

Kyle Trauberman
Kyle Trauberman

Reputation: 25684

Store the value of the variable in a hidden form field, so when the form is posted to the server, the incremented value of this variable is sent as well.

<input type="hidden" name="incrementedVar" value="1" />

Javascript to increment it:

$("input[name='incrementedVar']").val($("input[name='incrementedVar']").val() + 1);

and get the value in your controller

public ActionResult MyAction(int incrementedVar)
{
    // the incrementedVar param matches the name of the hidden field. 
    // the model binder will automatically pass the value of the hidden field to this param.
}

Using this code, the variable is controlled entirely by javascript, and the server only gets access to it on postback. You'll need to remove the razor declaration and incrementing code that you currently have.

Upvotes: 0

Related Questions