How to get value entered in a text box from a view - c#

My MVC view has a table with an editable field as follows.
<td>
<div class="view">
<%= Model.device_Url%>
</div>
<div class="edit">
<input type="text" name="deviceurl" id = "deviceurl" value="<%= Model.device_Url%>" />
</div>
</td>
The user has the option to edit then save the value entered in the above text box field.
<td class="options">
<div class="view">
Edit
</div>
<div class="edit">
Save
Cancel
</div>
</td>
I would like to call my controller /Live/Update and pass in the value changed in the text box in the URL.
How would I get the value entered inthe text box.
Do I need java script to do this?

You will need javascript unless you want to use a traditional submit.
The easiest approach would be to use jQuery and get the value with a line of code similar to this:
$("#deviceurl").val()
I would then make an ajax call to submit the value back to your controller's action. You also probably want to use the Url.Action helper to build the Url:
$.ajax(
url: '<%=Url.Action("Update")%>,
data : {deviceUrl : $("#deviceurl").val()},
success : function (result){
// handle logic when the update succeeds
}
);
Hope this helps

My advise will for you to use Html.ActionLink instead of using this Save
like this :
<%=Html.ActionLink("Save",
"Live", // <-- Controller Name.
"Update", // <-- ActionMethod
new { streamurl = deviceurl },
new { #class = "save refresh" }
)
%>

Related

How to handle jquery repeater html in mvc

this is my .cshtml page code,i use jquery repeater is in this code repeater is working fine but i want to add some modification in this repeater but i am stuck here. you can see my code.
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data", #class = "repeater" }))
{
<div data-repeater-list="">
<div data-repeater-item="">
<div class="col-lg-12 col-md-12 col-sm-12">
<input type="file" name="Docfiles" />
</div>
</div>
</div>
<input data-repeater-create type="button" value="Add" />
<button>Save</button>
}
#section Scripts{
<!-- Import repeater js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.repeater/1.2.1/jquery.repeater.js"></script>
<script>
$(document).ready(function () {
$('.repeater').repeater({
// (Optional)
// start with an empty list of repeaters. Set your first (and only)
// "data-repeater-item" with style="display:none;" and pass the
// following configuration flag
initEmpty: true,
// (Optional)
// "show" is called just after an item is added. The item is hidden
// at this point. If a show callback is not given the item will
// have $(this).show() called on it.
show: function () {
$(this).slideDown();
},
// (Optional)
// "hide" is called when a user clicks on a data-repeater-delete
// element. The item is still visible. "hide" is passed a function
// as its first argument which will properly remove the item.
// "hide" allows for a confirmation step, to send a delete request
// to the server, etc. If a hide callback is not given the item
// will be deleted.
hide: function (deleteElement) {
if (confirm('Are you sure you want to delete this element?')) {
$(this).slideUp(deleteElement);
}
},
// (Optional)
// Removes the delete button from the first list item,
// defaults to false.
isFirstItemUndeletable: true
})
});
</script>
}
i want to change html in this formate like this as shown in below screenshot.
Firstly,the name format is set in jquery.repeater.js,if you want to change it,you need to change jquery.repeater.js,here is a demo worked:
1.Add the jquery.repeater.js to your project.
I copy the js to my project like this:
2.Find setIndexes in the jquery and change var newName = groupName + '[' + index + '][' + name + ']' +like this(You can also change it to other format you want):
3.change your script src from cdnjs to your own project:
<script src="~/lib/jquery-repeater/jquery.repeater.js"></script>
4.Result:

List hidden value passes wrong value to controller

I have a list In my view. For each row, I view button and I am passing Id value as hidden. But when I click any button it is passing wrong hidden value to the controller. Always it passes the first-row hidden value to the controller.
View:
#foreach (var list in Model)
{
<div>
<div > #( ((int)1) + #Model.IndexOf(list)).</div>
<div >#list.details</div>
<div class="col-md-2 row-index">
<button class="btn btn-link" type="submit" name="action:view" id="view">View</button>
<input type="hidden" name="viewId" id="viewId" value="list.WId" />
</div>
</div>
}
Controller:
[HttpPost]
[MultipleButton(Name = "action", Argument = "view")]
public ActionResult ViewDetail(string viewId)
{
return RedirectToAction("ViewDetails");
}
To get all values you need to change the input value type in your controller to array of strings.
I hope that this solution can help you
[HttpPost]
[MultipleButton(Name = "action", Argument = "view")]
public ActionResult ViewDetail(string[] viewId)
{
return RedirectToAction("ViewDetails");
}
if you want to get the exact value you need to duplicate the form within your foreach
in this case you should write somthing like this :
#foreach (var list in Model)
{
<div>
<div > #( ((int)1) + #Model.IndexOf(list)).</div>
<div >#list.details</div>
<div class="col-md-2 row-index">
<form ... > // complete your form attributes
<button class="btn btn-link" type="submit" name="action:view" id="view">View</button>
<input type="hidden" name="viewId" id="viewId" value="list.WId" />
</form>
</div>
</div>
}
Note : You should delete the global form
You should have one form for each row. then you submit that row.
Otherwise as you state it passes first value.
You are setting each value to the same element ID (which is invalid anyway) and name. When you submit your form (which would be more helpful to fully answer your question) it is finding the first element that matches that criteria and submitting it.
There are multiple ways to resolve this such as the already mentioned form per entry but the other preference would be to modify you button to a div and add a click handler to pass the specific value to a js function which would then submit to the controller. Its a preference choice regarding how tightly coupled you want your front end. But the main problem is your element naming convention.

asp.net core mvc model binding with jquery repeater

I am using jquery repeater in my form to dynamically add only a part of input group to form. I did try but couldn't get inputs bind to model, I went blind.
Here my model.
public class SuggestionCreateEditViewModel
{
public Guid[] DetectionId { get; set; }
public SuggestionCreateEditRepeatedModel[] Repeated { get; set; }
}
public class SuggestionCreateEditRepeatedModel
{
public Guid To { get; set; }
public string Description { get; set; }
public DateTime Deadline { get; set; }
}
Form, I removed a lot of parts of form for brevity
<div class="col-lg-9 col-md-9 col-sm-12">
<select asp-for="DetectionId" asp-items="ViewBag.AllDetections" class="m-bootstrap-select m_selectpicker toValidate"
multiple data-actions-box="true" data-width="100%"></select>
</div>
<div class="col-lg-9 col-md-9 col-sm-12 input-group date">
<input name = "Repeated.Deadline" type="text" readonly class="form-control toValidate dtDueDate" />
</div>
<div class="col-lg-12 col-md-12 col-sm-12">
<textarea name = "Repeated.Description" class="form-control toValidate txtSuggestion" type="text" >
</textarea>
</div>
after adding a new repeated section to form and before posting it to server, if I form.serailizeArray() it returns collection like as follows (what jquery form repeater dynamically shape names I believe)
{name: "DetectionId", value: "afca1b82-0455-432e-c780-08d6ac38b012"}
{name: "[0][Repeated.To][]", value: "b1176b82-1c25-4d13-9283-df2b16735266"}
{name: "[0][Repeated.Deadline]", value: "04/04/2019"}
{name: "[0][Repeated.Description]", value: "<p>test 1</p>"}
{name: "[1][Repeated.To]", value: "188806d8-202a-4787-98a6-8dc060624d93"}
{name: "[1][Repeated.Deadline]", value: "05/04/2019"}
{name: "[1][Repeated.Description]", value: "<p>test 2</p>"}
and my controller
[HttpPost]
public IActionResult CreateSuggestion(SuggestionCreateEditViewModel model, IFormFile[] documents)
{...
controller couldn't get Repeated binded, only DetectionId is binded. How should I shape my model to get the data?
Here is a working demo for with jquery.repeater.js, pay attention to this line <div data-repeater-list="Repeated"> which will format the field like name="Repeated[0][Description]"
#model TestCore.Models.SuggestionCreateEditViewModel
#{
ViewData["Title"] = "Contact";
}
<form class="repeater" asp-action="CreateSuggestion" method="post">
<!--
The value given to the data-repeater-list attribute will be used as the
base of rewritten name attributes. In this example, the first
data-repeater-item's name attribute would become group-a[0][text-input],
and the second data-repeater-item would become group-a[1][text-input]
-->
<div data-repeater-list="Repeated">
<div data-repeater-item>
<div class="col-lg-9 col-md-9 col-sm-12">
<select asp-for="DetectionId" asp-items="ViewBag.AllDetections" class="m-bootstrap-select m_selectpicker toValidate"
multiple data-actions-box="true" data-width="100%"></select>
</div>
<div class="col-lg-12 col-md-12 col-sm-12">
<textarea name="Description" class="form-control toValidate txtSuggestion" type="text">
</textarea>
</div>
</div>
</div>
<input data-repeater-create type="button" value="Add" />
<input type="submit" value="Submit"/>
</form>
#section Scripts{
<!-- Import repeater js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.repeater/1.2.1/jquery.repeater.js"></script>
<script>
$(document).ready(function () {
$('.repeater').repeater({
// (Optional)
// start with an empty list of repeaters. Set your first (and only)
// "data-repeater-item" with style="display:none;" and pass the
// following configuration flag
initEmpty: true,
// (Optional)
// "show" is called just after an item is added. The item is hidden
// at this point. If a show callback is not given the item will
// have $(this).show() called on it.
show: function () {
$(this).slideDown();
},
// (Optional)
// "hide" is called when a user clicks on a data-repeater-delete
// element. The item is still visible. "hide" is passed a function
// as its first argument which will properly remove the item.
// "hide" allows for a confirmation step, to send a delete request
// to the server, etc. If a hide callback is not given the item
// will be deleted.
hide: function (deleteElement) {
if (confirm('Are you sure you want to delete this element?')) {
$(this).slideUp(deleteElement);
}
},
// (Optional)
// Removes the delete button from the first list item,
// defaults to false.
isFirstItemUndeletable: true
})
});
</script>
}
By the looks of things, the controller cannot bind the repeater properties back to your view model because the naming of the posted content does not match the naming in your view model (as Topher mentioned).
The DetectionId is named correctly though because the name of the property matches and its not an array.
To resolve an array we need to make sure we include the property name in the form as well as an index so that mvc model binding knows where to bind the result to.
With that, can you try changing the format of the name to:
Repeated[0].To
That should match up with your controller and correctly bind.
For more info on binding, please see this.

Bootstrap Modal pass input parameter to controller without closing modal

I have a Modal with 2 Tabs and I have an input on one of them. I need to pass the value of that input to the controller after clicking the search button. After that, the modal should stay. How can i pass the parameter to the controller without closing the modal?
<div class="modal-body">
#using (Html.BeginForm("SearchKuerzel", "Home"))
{
<div class="input-group mb-3">
<input type="text" class="form-control" placeholder="USZ-Kürzel" id="MyParameter" aria-label="USZ-Kürzel" aria-describedby="basic-addon2">
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="submit">Mitarbeiter suchen</button>
</div>
</div>
}
</div>
You can either use javascript like #3xGuy has said or use jquery such as below:
$('#MyParameter').val();
to get the value and then use ajax to send information to the controller. From here can do whatever you want in the controller and just return Json such as below from the controller.
return Json(new {success = //true or false or whatever});
EDIT:
Once you have done what you want in the controller, you can return the value like I have returned the variable 'success' in the code above. In the result section of the ajax request you can get the data from the controller such as this:
//the rest of the ajax request
success: function(result)
{
//Change the value of html element to success in this case
$('#//id of the element').text(result.success)
}
EDIT 2:
To return two Json strings do as above but add another return such as:
return Json(new {string1 = //whatever, string2 = //whatever});
And in the ajax access them like:
success:function(result)
{
var return1= result.string1;
var return12 = result.string2;
}

MVC 3 Partial View within dialog not working

I have a datatable webpage that shows a list of user in a datatable. On the user page there is a button create new user. On clicking this launches a modal jQuery dialog box for the user to enter details off the new user. There is a Cancel button which just closes the dialog box and a Save User button which on clicking calls DoSaveUser method in my controller. I can see from debugging that I get into the DoSaveUser method which should at the end return to a PartialView if the create user was successful saying User was saved. However my dialog were you enter details is not getting replaced with the Success message - even though the user is getting created - i.e - after I hit the save button - if I then cancel the dialog and refresh the original user page I can see the datatable updated with my new user.
Code on UserList page (there are more fields in the dialog than just forename but have removed them to make question have less code). So when CreateUser button is clicked my newUserDialog is launched.
<div id="newUserDialog">
#using (Html.BeginForm("DoSaveUser", "MyController", FormMethod.Post, new { id = "saveForm" }))
{
<div id="resultContainer">
<table class="ui-widget-content" style="width: 565px; margin-top: 10px;">
<tr>
<td style="width: 100px;">
</td>
<td class="label">
Forename :
</td>
<td class="value">
#Html.TextBoxFor(model => model.Forename, new { style = "width:150px" })
</td>
</tr>
</table>
<div class="ui-widget-content Rounded" style="width: 565px; margin-top: 10px; text-align: center;">
<input id="Cancel" type="button" class="dialog-button" value="Cancel" style="margin: 5px" />
<input id="DoSaveUser" type="submit" class="dialog-button" value="Save User" style="margin: 5px" />
</div>
</div>
}
Javascript code for Save User on the dialog being clicked - submit the form.
$(function () {
$('#saveForm').submit(function () {
var formData = $("#saveForm").serializeArray();
$.ajax({
url: this.action,
type: this.method,
data: formData,
dataType: "json",
success: function (result) {
$('#resultContainer').html(result);
}
});
return false;
});
});
Now in My DoSaveUser method in my controller which I can set a breakpoint and hit and see all the values being sent in correctly for the corresponding fields - once I have saved to the DB this is return.
return PartialView("UserSuccess", model);
And this is all that view contains in the cshtml..note what I wanted was the result container Div which contains all my textbox fields and labels to be replaced with User Created successfully. And then I will need an ok on this page which on clicking will close the dialog box and refresh the UserList page and show the datatable updated with the new user. However when I click save the textboxes just stay on the Div and the Div does not get changed - but if I then cancel the dialog and refresh the page I can see the datatable updated with my new user. Is there something I am missing? (note - i have added jquery.unobtrusive-ajax.js to my _Layout page)
#model MyProject.Models.UserModel
#{
ViewBag.Title = "UserSuccess";
}
<div id="resultContainer">
User Created Successfully
</div>
Are you sure that your initial html do have a #resultContainer div? If you don't the
$('#resultContainer').html(result);
line won't match anything. If you do on the other hand, you will get duplicate nested #resultContainer divs which is also an error (id must be unique).
The right way to do it is to add an empty div in your original html:
<div id="resultContainer"></div>
And in your view output just the content to go inside the div.
#model MyProject.Models.UserModel
#{
ViewBag.Title = "UserSuccess";
}
User Created Successfully
I have to say what you are doing is not a good way of using dialog and partial view in ASP.NET MVC applications. I can give you some simple code to show an idea:
If list.cshtml is a list of users page, and edit.cshtml is a partial view that has an edit form in.
On list page:
$(".grid-row .edit").click(function(){
editUser($(this).attr("data-id"));
});
function editUser(id){
var $dialog=$("#dialogEditUser");
if($dialog.length == 0){
$dialog=$("<div id='dialogEditUser'>").appendTo("body");
}
$dialog.dialog({
...
open:function(){
$dialog.load("/user/edit/"+id, function(){
//todo: handle form events
});
}
});
$dialog.dialog("open");
}
You can also make the open dialog function in a static method, like:
MvcSolution.Dialog = function (id, title, options) {
var $dialog = $("#" + id);
if ($dialog.length == 0) {
$dialog = $("<div id='" + id + "' class='dialog' title='" + title + "'></div>").appendTo("body");
}
$dialog.dialog(options);
$dialog.dialog("open");
};
You can find a good c# and js framework for MVC here

Categories