0

I am working on an ASP.NET MVC4 application and I have this problem. I have an @Url.Action() defined like so:

<a href="@Url.Action("Edit", 
             new { docId = Model.Page.Documents[j].DocumentID, 
                   PageID = Model.Page.PageID, 
                   docName = Model.Page.Documents[j].Name })" >Edit</a>

But as the name says this is supposed to send data which has been edited to a controller action where I will actually perform Update for this entity. docId and PageID are DB ID's which I take from the model and I need them to identify the right entity that I should apply the changes to, so they are static. However docName is a value rendered like :

@Html.TextBoxFor(m => m.Page.Documents[j].Name, new { id = Model.Page.Documents[j].DocumentID})

so the text inside this textbox could be edited and when the link with @Url.Action("Edit"..) is clicked I want to take the current value of the textbox and send it back to server.

You can see above how I am using the @url.Action("Edit"..) but logically :

docName = Model.Page.Documents[j].Name 

keeps the initial value passed from the server and not the current value of the textbox. I couldn't think of more MVC4-like way to send the data to my controller so I resort to the fact that I'll need to use JavaScript(preferably jQuery) to be able to do this. However my knowledge of using jQuery and using jQuery inside MVC4 Razor view is very limited so I seek guidance.

I modified my @Url.Action("Edit"..) like so :

<a href="@Url.Action("EditDocumentName", 
                  new { @onclick="UpdatDocumentName(Model.Page.PageID);"})" >Edit</a>

and added this little script:

<script>
    function UpdatDocumentName(id)
    {
        alert(id);
    }
</script>

I know it's not even near to accomplish my task, but I wasn't even sure if I will be able to pass values to a JS function like so. But since it seems that there's no problem I plan to modify my function to take two parameters :

function UpdatDocumentName(PageId, DocId)

and inside the function to take the value of the textbox.

My question is, how having those values inside my JS function I can send them to my Edit Action in Page controller?

P.S

what I try to achieve is to allow the user to update a certain property of an entity which is part of List of entities rendered on my view. To be more descriptive here is what my view looks like (kind of):

Entity list

which is generated like this:

@for (int j = 0; j < Model.Page.Documents.Count; j++ )
    {
        <tr>
            <td>
                @Html.TextBoxFor(m => m.Page.Documents[j].Name, new { id = Model.Page.Documents[j].DocumentID})
            </td>
            //more properties displayed...

If I am to use form to submit the change I have to wrap each @Html.TextBoxFor(m => m.Page.Documents[j].Name in a form, which I'm not sure is the best approach. But I might be wrong.

There is also icon for Update next to the Delete icon in Delete header but I've missed to show it.

2 Answers 2

1

A more robust solution

Define your controller action like this...

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int pageId, int docId)
{
    //...do some stuff here to perform a delete

   return Json(new 
                  {
                     page = pageId,
                     doc = docId
                  });
}

then in your view the command cell should look like this...

@using(Ajax.BeginForm("Edit", "Page", null, new AjaxOptions()
                                                {
                                                    OnSuccess = "deleteSucceeded,
                                                    OnFailure = "deleteFailed"
                                                }))
{
    @Html.AntiForgeryToken()
    <input type="hidden" name="pageId" value="@Model.Page.PageID"/>
    <input type="hidden" name="docId" value="@Model.Page.Documents[j].DocumentID"/>
    <input type="image" src="path_to_your_delete_image" title="Delete record" />
}

Note that the in the ajax options I have specified the name of a javascript function for OnSuccess and OnFailure respectively. You should remove the row from the HTML table if the operation is successful, or display a message to the user if the operation fails. How to remove the html row? Easy with jQuery...first add custom data attributes to each row so you can easily identify them...

<tr data-doc-id="@Model.Page.Documents[j].DocumentID" data-page-id="@Model.Page.PageID"></tr>

Then define the deleteSucceeded javascript function like this...

function deleteSucceeded(jsonObj){
    $('tr[data-doc-id=' + jsonObj.doc + '][data-page-id=' + jsonObj.page + ']').remove();
}

Hope it helps

Sign up to request clarification or add additional context in comments.

8 Comments

You've guessed right about the controller - public ActionResult Edit(string pageId...). I see you have understanding about using JS in Razor so pls see the updated question and comment if using a form is better option. I was thinking about that but I got to the conclusion that it's not the better way. I might be wrong though.
type: 'GET' - I assume you meant 'POST'? Otherwise, wrong verb. GET requests are supposed to be idempotent.
@Leo I did. You state "You can post this data using the following code sample...", then show jQuery to GET a request - that's inconsistent.
@Tieson T Oh yeah, your right...I'll correct the typo in a min. Thanks
@TiesonT. Sorry to get into the conversation but could you tell an opinion, it Html.BeginForm better option than Ajax, or maybe something different. I was trying by modifing the Url.Action but it seems it's not a very good solution?
|
0

You can use Html.BeginForm("Edit") helper, and by clicking <input type="submit"> send to action Edit your changed Document object - like here:

http://blog.michaelckennedy.net/2012/01/20/building-asp-net-mvc-forms-with-razor/

As I understood, you just want to have an ability to edit a lot of models on one page. If yes, your solution is extremely unfriendly and you can achieve it in better way - and if you want I can show a better approach.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.