how can i get current model item in mvc - c#

I have this list view that include edit button leads to modal
<table class="table" id="table">
#foreach (var item in Model.model2)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.who_reply)
</td>
<td>
#Html.DisplayFor(modelItem => item.Status)
</td>
<td>
#Html.DisplayFor(modelItem => item.Details)
</td>
<td>
#Html.DisplayFor(modelItem => item.Reply_Id)
</td>
<td>
<input class="edit" id="edit" type="button" value="edit" data-reply="#item.Details" data-Reply_Id="#item.Reply_Id" />
</td>
</tr>
}
</table>
I wrote this jquery code to check Reply_Id value it works fine it gives me the current Reply_Id
$('.edit').click(function () {
alert($(this).data('Reply_Id'));
$('#ModalPopUp6').modal({ backdrop: 'static', keyboard: false });
$("#reply-text6").val($(this).data('reply'));
});
but the problem is that when I press save button in modal only get the first reply_id not the current:
$("#save").click(function () {
alert($('.edit').data('Reply_Id'));
});

Your issue is caused by
$(".class").data(dataname)
which retrieves the first entry, you need to "store" which edit button (reply_id) was clicked - either in a simple variable or in a more robust method such as:
$('.edit').click(function () {
// get the edit button's ID
var id = $(this).data('Reply_Id');
// store it against the modal
$('#ModalPopUp6').data("replyid", id);
$('#ModalPopUp6').modal({ backdrop: 'static', keyboard: false });
$("#reply-text6").val($(this).data('reply'));
});
then
$("#save").click(function () {
// get the original row's ID from the modal
var id = $('#ModalPopUp6').data("replyid");
// find the matching button (then get the parent row for the whole record)
var row = $("[data-Reply_id=" + id + "]").closest("tr");
});

Related

How to update parent table from partial view using Ajax

I have a table that lists the courses in the system with a Select button for each Course (in a row). When I click Select, the enrolled users of that course are displayed. The Course entity has navigation property public List<CourseRegistration> CourseRegistrations { get; set; }
I have this ViewModel for this purpose:
public class CourseIndexViewModel
{
public int SelectedCourseId { get; set; }
public List<Course> Courses { get; set; }
}
Just under the enrollments list (or registrations) I have a textbox (for keyword) and button to search users for enrollment. I use AJAX to execute an action of controller (UserController) (to which I pass the keyword) which searches users in the db, and passes the result set to a partial view, which returns a table of users with Enroll button in each row.
Everything works fine so far. Now, I need to implement the Enroll button inside the Partial View. However, I will need the id of the course, which is actually available in the main view (i.e., SelectedCourseId). Is there a way to access that value from the partial view? Do I have to (or should I) use hidden input for this purpose?
The biggest challenge is updating the enrollment list shown in the main View after enrolling a new user. I want to use Ajax to do that to prevent page refresh.
Is it feasible and recommended to use Ajax to get the enrollments again from the database and replace the existing enrollments table in the main view with the new table generated in the partial view?
UPDATE
Here is the main view:
#model EcholuMvc.Models.CourseIndexViewModel
<table class="table">
<tr>
<th></th>
<th>
CourseTitle
</th>
<th></th>
</tr>
#foreach (var item in Model.Courses)
{
<tr #(Model.SelectedCourseId == item.CourseId ? "style=background-color:whitesmoke;" : "style=" )>
<td>
#Html.ActionLink("Select", "Index", new { courseId = item.CourseId })
</td>
<td>
#Html.DisplayFor(modelItem => item.CourseTitle)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.CourseId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.CourseId })
</td>
</tr>
if (Model.SelectedCourseId == item.CourseId)
{
<tr>
<td>
<h4>Enrolled users:</h4>
<table class="table">
<tr>
<th>First name</th>
<th>Last name</th>
<th></th>
</tr>
#if (item.CourseRegistrations.Count > 0)
{
var registrations = item.CourseRegistrations;
foreach (var reg in registrations)
{
<tr>
<td>
#reg.Member.FirstName
</td>
<td>
#reg.Member.LastName
</td>
<td>
#Html.ActionLink("Delete", "Delete", new { memberid = reg.MemberId, courseid = reg.CourseId })
</td>
</tr>
}
}
else
{
<tr>
<td colspan="4">No enrollment!</td>
</tr>
}
</table>
<div class="container-fluid">
<div class="row">
<div class="col-sm-9">
<input id="txt_SearchUser" placeholder="Enter a name.." class="form-control " type="text" />
</div>
<input id="btn_SubmitUserSearch" class="btn btn-default btn-sm col-sm-3" type="button" value="Search" />
</div>
<div class="row">
<div id="div_UserSearchResults" class="col-sm-12">
</div>
</div>
</div>
<script>
$("#btn_SubmitUserSearch").click(function () {
$.ajax({
url: 'Account/SearchUsers',
contentType: 'application/html; charset=utf-8',
data: { keyword: $('#txt_SearchUser').val() },
type: 'GET',
dataType: 'html'
})
.success(function (result) {
$('#div_UserSearchResults').html(result);
})
.error(function (xhr, status) {
alert(status);
})
});
</script>
</td>
</tr>
}
}
</table>
And, here is the partial view:
#model IEnumerable<EcholuMvc.Models.ApplicationUser>
<table class="table-striped" >
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
<select id="drp_Role">
<option value="Student" selected="selected">Student</option>
<option value="Instructor">Instructor</option>
</select>
</td>
<td>
<input id="btn_Enroll" data-userid="#item.Id" type="button" />
</td>
</tr>
}
</table>
If you simply want the selected courseId in client side (for your ajax submit of new enrollment or any other thing), you may add a hidden field to the main view and read it from that when needed.
#Html.HiddenFor(s=>s.SelectedCourseId)
Now whenever you need it for your ajax posts, just read the value of this and use
var selectedCourseId=$("#s.SelectedCourseId").val();
But If you want the courseId in your search functionality for some reason, you may pass the selected courseId to your ajax call as a parameter. Keep the course id as the html 5 data attribute to your search input field
<input id="txt_SearchUser" placeholder="Enter a name.."
data-course="#item.CourseId" class="form-control " type="text" />
Now when you make the ajax call, read this value and send it.
$("#btn_SubmitUserSearch").click(function () {
$.ajax({
url: 'Account/SearchUsers',
data: { keyword: $('#txt_SearchUser').val(),
courseId:$('#txt_SearchUser').data("course") },
type: 'GET',
dataType: 'html'
})
.success(function (result) {
$('#div_UserSearchResults').html(result);
})
.error(function (xhr, status) {
alert(status);
})
});
Make sure your SearchUsers endpoint accept this new param and pass that to the resulting partial view it will render.
public ActionResult SearchUsers(string keyword,int courseId)
{
// to do : Do something with the passed values
// to do : return something
}
Also i assume that, with your if condition you are rendering only one search form in your page because you cannot have duplicate id's. Also consider using Url.Action helper method to generate the proper url to the action method instead of hardcoding the url as explained in this post.

Sync two MVC4 (razor) pages

On my main page, I have a textbox with a button called "Set" next to it. When a user clicks on the set button, it opens up a new page like a popup which have list of items with select button users can select.
When a user clicks on a select button, I wanted to sync the corresponding information into the my main page's text box.
Do anyone know how this could be done?
Index HTML Code:
<input type="button" id="Set" name="Set..." value="Set..." class="btn btn-default" />
Index Jquery Code:
$("#Set").click(function () {
window.open('#Url.Action("FileTypeDefinitionSelector", "FileTypeDetails")', '', 'height=500,width=600,left=-150,top=10,status=no,toolbar=no,resizable=yes,scrollbars=yes');
});
List html code:
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Summary)
</td>
<td>
#Html.ActionLink("Select", "Index", new { name=item.Name.Replace(" ", "") })
</td>
</tr>
}

ASP.NET MVC Checboxes disabling/enabling textboxes

I have a view with three textboxes and a CheckBox:
#foreach( var item in Model )
{
<tr>
<td>
#Html.CheckBox("name")
</td>
<td>
#Html.EditorFor(m => item.Toolbox)
</td>
<td>
#Html.EditorFor(m => item.Name)
</td>
<td>
#Html.EditorFor(m => item.Link)
</td>
</tr>
}
And how i can create JS code to bind this checkboxes to diffirent textboxes? This "name" check box should disable/enable three textboxes for every time loop creates it. There are 500+ items in Model.
You may set counter and create unique class or some attribute for each block. For example:
<table id="myTable">
#{
int c = 0;
for(int i = 0; i < Model.Count; i++)
{
c++;
<tr class="#("block"+c)">
<td>
#Html.CheckBox("name", new {data_block=c})
</td>
<td>
#Html.EditorFor(m => item.Toolbox)
</td>
<td>
#Html.EditorFor(m => item.Name)
</td>
<td>
#Html.EditorFor(m => item.Link)
</td>
</tr>
}
</table>
and then javascript code:
$(function(){
$('#myTable checkboxes').click(function(){
var checkbox = $(this),
blockNum = checkbox.data('block'),
inputs = $('tr.block'+blockNum),
state = checkbox.is(':checked');
$.each( inputs, function( i, el ){
$(el).prop("disabled", state);
});
});
});
Another way
<table id="myTable">
#foreach( var item in Model )
{
<tr>
<td>
#Html.CheckBox("name", new { #class = "nameCheckbox" })
</td>
<td>
#Html.TextBoxFor(m => item.Toolbox, new { #class = "someCleverClassName" })
</td>
<td>
#Html.TextBoxFor(m => item.Name, new { #class="someCleverClassName" })
</td>
<td>
#Html.TextBoxFor(m => item.Link, new { #class="someCleverClassName" })
</td>
</tr>
}
</table>
And the javascript
$(function(){
$('#myTable .nameCheckbox').click(function(){
$(this).closest('tr').find('.someCleverClassName').prop("disabled", $(this).prop('checked'));
});
});

Fill control with another MVC

I have experience in C#, but don't have any in Javascript.
What I want to achieve shouldn't be that hard, but I just can't get it to work:
I want to fill the text property of a label with the text property of a textbox.
This needs to be done at the KeyUpEvent.
I already created the KeyUpEvent and it is working, but it doesn't fill my label's text property using the following code:
<script type="text/javascript">
$(document).ready(function ()
{
$("##Html.FieldIdFor(model => model.Quantity)").keyup(OnQuantityChanged);
});
function OnQuantityChanged()
{
alert("onQuantityChanged event fired.")
document.getElementById('##Html.FieldIdFor(model => model.SubTotalExclTax)').value = document.getelementById('##Html.FieldIdFor(model => model.UnitPriceExclTax)').value
}
</script>
So I create a function called OnQuantityChanged() and I call this function on KeyUp event.
The alert in my function: alert("onQuantityChanged event fired.") gets called and shows me a dialog, so the function does get called.
I'm using #Html.FieldIdFor, for getting the id of the control. I think this is implemented by NopCommerce and down here is the definition of the FieldIdFor method:
public static string FieldIdFor<T, TResult>(this HtmlHelper<T> html, Expression<Func<T, TResult>> expression)
{
var id = html.ViewData.TemplateInfo.GetFullHtmlFieldId(ExpressionHelper.GetExpressionText(expression));
// because "[" and "]" aren't replaced with "_" in GetFullHtmlFieldId
return id.Replace('[', '_').Replace(']', '_');
}
I think I made a syntax error, but don't know how to debug Javascript, since setting a breakpoint in Visual Studio(2012), doesn't pause the code.
I think the line below has some incorrect syntax, correct me if i'm wrong:
document.getElementById('##Html.FieldIdFor(model => model.SubTotalExclTax)').value = document.getelementById('##Html.FieldIdFor(model => model.UnitPriceExclTax)').value
Update
HTML of page is below:
<table>
<tr>
<td>
#Html.NopLabelFor(model => model.UnitPriceInclTax):
</td>
<td>
#Html.EditorFor(model => model.UnitPriceInclTax)#Model.UnitPriceInclTax
</td>
</tr>
<tr>
<td>
#Html.NopLabelFor(model => model.UnitPriceExclTax):
</td>
<td>
#Html.EditorFor(model => model.UnitPriceExclTax)#Model.UnitPriceExclTax
</td>
</tr>
<tr>
<td>
#Html.NopLabelFor(model => model.Quantity):
</td>
<td colspan="2">
#Html.EditorFor(model => model.Quantity, new { id = "lblQuantity"})
</td>
</tr>
<tr>
<td>
#Html.NopLabelFor(model => model.SubTotalInclTax):
</td>
<td>
#Html.EditorFor(model => model.SubTotalInclTax)#Model.SubTotalInclTax
</td>
</tr>
<tr>
<td>
#Html.NopLabelFor(model => model.SubTotalExclTax):
</td>
<td>
#Html.EditorFor(model => model.SubTotalExclTax)#Model.SubTotalExclTax
</td>
</tr>
</table>
You don't need # when using document.getElementById just string representing id is enough.
There is no value of a label you could just set innerText property.
Pure javascript solution:
document.getElementById("YourID").innerText = "New Text";
JQuery Solution
$("#YourID").text("New Text");
That part of server side code is not executed by ASP.NET since it is inside a string. You can resole using a variable to store the id:
var subTotalId = #Html.FieldIdFor(model => model.SubTotalExclTax);
and then use the subTotalId in your javascript (given that Html.FieldIdFor return the id of the element.
A better way is to use only javascript, with ASP.NET MVC you should know the ids of the DOM elements, so why do you need to find them at runtime?
Why not using Jquery:
$('#IdOfSubTotalElement').val();

Ajax call success is failing

This ajax call never creates the alert on success even though it has reached and returned success = true on the server side method.
#model IEnumerable<Test.Models.Task>
#Styles.Render("~/Content/Site.css")
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<div id ="alerts">
#Html.Action("_Tasks")
<script type="text/javascript">
$(document).ready(function poll() {
$.ajax({
type: 'GET',
cache: false,
url: '#Url.Action("TasksRefresh")',
dataType: "json",
complete: function () { setTimeout(poll, 10000); },
success: function (data) {
alert("Testing")
}
});
})();
</script>
#* <script type="text/javascript">
var alerts = '#ViewBag.Alerts';
#foreach (var i in alerts)
{
}
</script>*#
</div>
<table>
<tr>
<th>Category</th>
<th>Severity</th>
<th>Assigned to Role</th>
<th>Assigned To</th>
<th>Chart #</th>
<th>Note</th>
<th>Alert</th>
<th>Status</th>
<th>Creator By</th>
<th>Create Date</th>
<th>Due Date</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.LookupTaskCategory.CategoryName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LookupTaskSeverity.SeverityName)
</td>
<td>
#Html.DisplayFor(modelItem => item.AssignedToRoleName)
</td>
<td>
#Html.DisplayFor(modelItem => item.AssignedToName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Patient.ChartNo)
</td>
<td>
#Html.DisplayFor(modelItem => item.Note)
</td>
<td>
#Html.DisplayFor(modelItem => item.AlertFlag)
</td>
<td>
#Html.DisplayFor(modelItem => item.LookupTaskStatu.StatusName )
</td>
<td>
#Html.DisplayFor(modelItem => item.CreatedByName)
</td>
<td>
#Html.DisplayFor(modelItem => item.CreatedOnDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.DueDate)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
#Html.ActionLink("Details", "Details", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
This is the server side method in my controller. I have tried to replace JsonResult with ActionResult, but it didn't change the outcome.
public JsonResult TasksRefresh()
{
//Testing to see if this return ever gets received by ajax.
return Json(new { success = true });
}
You're getting an exception on the server - try debugging the .NET code, or watching your response with the browser tools, to see it.
If you want to return a JSON object on a GET method, you need to include a JsonRequestBehavior parameter to the Json call, like:
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
EDIT
Actually, it looks like you can't see it if you debug on the server - you'd have to see it in the response. Apparently the exception is thrown further down after the Json method.

Categories