Zeliax Zeliax - 1 month ago 21
C# Question

Finding a class in a partialView (MVC) and passing variables to a function

I'm writing a webpage using .Net Core and I recently started using jQuery within my webpage.

PartialView shown in
<div id="details"></div>



@model Program.Models.Device

<dl>
<dt>
@Html.DisplayNameFor(model => model.Alias)
</dt>
<dd>
@Html.DisplayFor(model => model.Alias)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Log)
</dt>
<dd>
<a data-toggle="modal" data-target="#logData">Open</a>

<div class="modal fade" id="logData" tabindex="-1" role="dialog" aria-labelledby="logDataLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">Log for @Html.DisplayFor(model => model.Alias)</h4>
</div>
<div class="modal-body">
@Html.TextAreaFor(m => m.Log, htmlAttributes: new { @class = "form-control", @id = "logTextArea", @placeholder = "Log is empty" })
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
@*This will be used to find the deviceID*@
@Html.HiddenFor(m => m.DeviceID, new { @class = "deviceID" })
<button type="button" class="btn btn-primary" id="save">Save changes</button>
</div>
</div>
</div>
</div>
</dd>
</dl>


To give a general idea of what I will be using the modal for it is for updating a log from one of my models called a Device. The textarea will hold the log for the Device and that is working as intended. However I want to write a JavaScript/jQuery function that takes the text from the textarea and passes it to a function in my controller:

.CS function



public void UpdateLog(int id, string logText)
{
Device device = new Device { DeviceID = id, Log = logText };

_context.Devices.Attach(device);
_context.Entry(device).Property(x => x.Log).IsModified = true;
_context.SaveChanges();
}


JQuery click code



$('#details').on('click', '#save', function () {
var text = $("#logTextArea").val();
var id = $(this).siblings('deviceID').val(); //Getting deviceID
//Running C# method somehow?
});


How would I got about getting the DeviceID in the best manner? EDIT: See modal code and jQuery

Furthermore I've found that to run my controller function I need an
@Url.Action('<function name>', '<controller name>')
but how do I pass variables to such a function as I now would have the log and the id required for the function?

EDIT:



Code has undergone some changes now and I am getting the deviceID now (was previously misunderstanding with vehicleID). My only problem is how to run the .CS function and passing in the two parameters to my .CS function in my jQuery click code.

Thanks!

Answer

You need to make an ajax call to post that data (assuming you want to stay in the same page).

You should start by wrapping your form controls inside a <form> tag and adding @Html.ValidationMessageFor(m => m.Log) and change the button to type="submit" so that you get (and can check) client side validation before posting the data.

<div class="modal-dialog" role="document">
    <div class="modal-content">
        ...
        <form>
            <div class="modal-body">
                @Html.HiddenFor(m => m.DeviceID)
                @Html.TextAreaFor(m => m.Log, htmlAttributes: new { @class = "form-control",     @placeholder = "Log is empty" })
                @Html.ValidationMessageFor(m => m.Log)
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </form>
    </div>
</div>

Then the script will be

var url = '@Url.Action("UpdateLog")'; // assumes its the same controller that generated the view
$('#details').on('submit', 'form', function () { // handle to forms submit() event
    if (!$(this).valid()) {
        return; // cancel (the validation message will be displayed)
    }
    var data = $(this).serialize()
    $.post(url, data, function(response) {
        // do something with the response
    })
    return false; // cancel the default submit
});

Your POST method will then be public ActionResult UpdateLog(int id, string log), however to catch server side validation, you should create a view model decorated with the necessary validation attributes

public class DeviceLogVM
{
    public int ID { get; set; }
    [Required(ErrorMessage = "..")] // add StringLength etc as needed
    public string Log { get; set; }
}

so that the method becomes

public ActionResult UpdateLog(DeviceLogVM model)

so that you can check if ModelState is invalid before saving. Note also that the method should be ActionResult so that you can return something back to the client indicating success or otherwise.