I have a view with a table of products that can be added to a shopping cart. Each row has a DropDownList with allowed quantities that can be ordered along with a button to add to cart. Everything is populating and displaying properly. I know how to pass the item ID in the ActionLink but how can I get the value of the DownDownList associated with the table row of the ActionLink that was clicked?
I am guessing possibly using JQuery that fires when the ActionLink is clicked?
I also thought of making every row a form but that seems overkill.
Is there an easy MVC way to do this?
In prepping more info for a proper question and went ahead and solved it. Thank you Stephen for the nudge and info.
I tried putting a Html.BeginForm around each <tr> tag in the details section. This did indeed work for me. I was able to easily get the unique form info to POST for each individual row. However, when I would enable JQuery DataTables the submit would break. DataTables must be capturing the submit or click somehow. Haven't figured that out but it made me try JQuery which seems a much better way to do it.
Here is how I construct the table data row:
#foreach (var item in Model)
{
<tr>
<td>
<img src="#item.GetFrontImage()" width="100" />
</td>
<td>
<strong>#Html.DisplayFor(modelItem => item.DisplayName)</strong>
</td>
<td>
#Html.DisplayFor(modelItem => item.CustomerSKU)
</td>
<td>
#Html.DropDownList("OrderQty", item.GetAllowedOrderQuantities(), htmlAttributes: new { #class = "form-control" })
</td>
<td>
<a class="btn btn-default pull-right" data-id="#item.ID">Add to Cart</a>
</td>
</tr>
}
This creates a select with id of OrderQty and I embedded the item ID in data-id attribute of the link. I then used this JQuery to capture the info and POST it to my controller. Just have a test div displaying the results in this example:
// Add to Cart click
$('table .btn').click(function () {
// Gather data for post
var dataAddToCard = {
ID: $(this).data('id'), // Get data-id attribute (Item ID)
Quantity: $(this).parent().parent().find('select').val() // Get selected value of dropdown in same row as button that was clicked
}
// POST data to controller
$.ajax({
url: '#Url.Action("AddToCart","Shopping")',
type: 'POST',
data: JSON.stringify(dataAddToCard),
contentType: 'application/json',
success: function (data) { $('#Result').html(data.ID + ' ' + data.Quantity); }
})
});
The JQuery function receives the reference to the link being clicked so I can extract the Item ID from the data-id attribute. I can then get a reference to the dropdown (select) that is in the same row by using .parent.parent (gets me to the <tr> tag) and then just finding the next 'select' tag. Probably pretty obvious to a lot of you.
This works great for my purposes. I can also update other elements with data returned from the POST.
Thank you
Karl
for the table in html:
<div class="table-responsive">
<table id="employeeTable"class="table table-bordered">
<thead>
<tr>
<th class="text-center">ُُُEmpId</th>
<th class="text-center">Name</th>
<th class="text-center">Absense State</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>#item.Id</td>
<td>#item.Name</td>
<td class="text-center">#Html.DropDownList("DDL_AbsentStatus", new SelectList(ViewBag.statusList, "Id", "Name"), new { #class = "form-control text-center" })</td>
</tr>
}
</tbody>
</table>
</div>
in javascript to get the selected value:
//Collect Date For Pass To Controller
$("#btn_save").click(function (e) {
e.preventDefault();
if ($.trim($("#datepicker1").val()) == "") {
alert("ادخل تاريخ يوم صحيح!")
return;
}
var employeesArr = [];
employeesArr.length = 0;
$.each($("#employeeTable tbody tr"), function () {
employeesArr.push({
EmpId: $(this).find('td:eq(0)').html(),
EntryDate: $.trim($("#datepicker1").val()),
StatusId: $(this).find('#DDL_AbsentStatus').val()
});
});
$.ajax({
url: '/Home/SaveAbsentState',
type: "POST",
dataType: "json",
data: JSON.stringify(employeesArr),
contentType: 'application/json; charset=utf-8',
success: function (result) {
alert(result);
emptyItems();
},
error: function (err) {
alert(err.statusText);
}
});
})
Related
I am getting details from mongodb using express api and calling it using AJAX in front-end, i am able to get the details but not able to display it in a table.
I have tried appending it in a table. I have attached some code on what i have done.
The AJAX Part
$.ajax({
type: 'GET',
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json",
url: "http://localhost:8000/employees",
success:function(data){
data.forEach(element => {
$("#Name").append("<td>"+element.Name+"</td>");
$("#EmployeeId").append("<td>"+element.EmpId+"</td>");
$("#Designation").append("<td>"+element.Designation+"</td>");
$("#Email").append("<td>"+element.Email+"</td>");
});
},
error:function( errorMessage)
{
console.log(errorMessage);
}
});
The HTML part
<table>
<th>Name</th><th>EmployeeId</th><th>Designation</th><th>Email</th>
<tr>
<td id="Name"></td>
<td id="EmployeeId"></td>
<td id="Designation"></td>
<td id="Email"></td>
</tr>
</table>
I am currently getting entire output in single
i want the data in separate .
Current Output
You're getting all the data put into the same td because you're only using one row.
The way your code is running is basically...
<td id="Name">
<td>{value1}</td><td>{value2}</td>
</td>
....
You need to create rows tr inside the callback, instead of just appending data to the columns td
What you can do to fix this, is building entire rows in the success callback..
$.ajax({
type: 'GET',
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json",
url: "http://localhost:8000/employees",
success:function(data){
data.forEach(element => {
var row = document.createElement("tr");
var name = document.createElement('td');
var employeeID = document.createElement('td');
var designation = document.createElement('td');
var email = document.createElement('td');
name.innerHTML = element.Name;
employeeID.innerHTML = element.EmpID;
designation.innerHTML = element.Designation;
email.innerHTML = element.Email;
row.appendChild(name);
row.appendChild(employeeID);
row.appendChild(designation);
row.appendChild(email);
$('#table').append(row);
});
},
error:function( errorMessage)
{
console.log(errorMessage);
}
});
and in your HTML, just apply the ID to table or whatever you want.
Edit::
Also, syntactically, you should put the table headers inside a row as well, so,
<tr>
<th>Name</th>
<th>Employee ID</th>
...
</tr>
The item I am trying to access in the following HTML is "GMV DLL VERSION2"
<div class="container content">
<main>
<h2 id="rpcs--gmv-dll-version">RPCs → GMV DLL VERSION</h2>
<h3 id="vista-file-8994">VISTA File 8994</h3>
<table>
<thead>
<tr>
<th>property</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr>
<td>label</td>
<td>GMV DLL VERSION2</td>
I am trying to scrape this website (http://vistadataproject.info/artifacts/vistaRPC%20documentation/GMV%20DLL%20VERSION)
and output it into a text file. I successfully did a test run with reddit.com. However I cannot seem to get this page to get even a single element off of it. To test it, even before tackling the table I've been trying to scrape some elements that come quite early (in top area) of the page.
The lack of classNames and Id in the tables is tricky enough, but not being able to get even the title text is really making me wonder what is going on. Any input will be appreciated.
request(http://vistadataproject.info/artifacts/vistaRPC%20documentation/GMV%20DLL%20VERSION, (err, res, body) => {
if (err) {
console.log('Error: ' + err);
}
console.log('Status: ' + res.statusCode);
const $ = cheerio.load(body);
$('header.masthead > div.container').each(( index, tr ) => {
// var children = $(this).children();
const tableData = $(this).find('a.logo').text();
console.log("Table Contents: " + tableData);
fs.appendFileSync('test.txt', tableData + '\n' + 'Captured');
});
The problem is that 'masthead' is a class name, not an id. Same deal with 'container' and 'logo'. So you need to adjust your selector accordingly:
$('header.masthead > div.container').each(( index, tr ) => {
However, that only gets you the header information, which does not include the tables containing the 'property => value' data. For that information you just need to look for child tables under the '<main>' tag.
I have a collection that has three fields: name(String), email(String) and appointments(Object)
I query the collection inside a router.get based on user email
router.get('/appointments', ensureAuthenticated, function(req, res, next) {
var query = {email: req.user.email};
PatientList.find(query, function(err, data){
if (err) throw err;
res.render('appointments', {data : data, title: 'Appointments'});
});
});
data from the query above looks like this:
{ __v: 0,
name: 'dan',
email: 'dan#gmail.com',
appointments:
[ { _id: 58373466542d6ae430a13337,
position: '1',
name: 'dan',
email: 'dan#gmail.com',
serviced: false,
hospital: 'Toronto hospital',
date: 'Thursday, November 24, 2016',
__v: 0 },
{ _id: 5837346a542d6ae430a13339,
position: '2',
name: 'dan',
email: 'dan#dan.com',
serviced: false,
hospital: 'Calgary hospital',
date: 'Thursday, November 24, 2016',
__v: 0 },
]
I want to access these fields inside the appointments field and display them on a table using handlebars. My html with handlebars looks like this
<table class="table table-striped table-bordered">
<thead>
<tr>
<td>Clinic</td>
<td>Appointment Date</td>
<td>Patient Number</td>
<td>Clinic Queue Status</td>
</tr>
</thead>
<tbody>
{{#each data}}
<tr>
<td>{{this.appointments.hospital}}</td>
<td>{{this.appointments.date}}</td>
<td>{{this.appointments.position}}</td>
<td>{{#if this.appointments.serviced}}
Please return to the clinic immediately.
{{else}}
Patient is currently being served.
{{/if}}
</td>
</tr>
{{/each}}
</tbody>
</table>
But it is not printing anything in the table
Passing properties to your view ( template ) via res.render results in those properties become available for use in your template.
You are passing a data property in your handlebars template, so you need to use your data variable inside, which is an object, that contains the appointments array.
In order to properly render them you need to use #each against data.appointments like :
{{#each data.appointments}}
<tr>
<td>{{hospital}}</td>
<td>{{date}}</td>
<td>{{position}}</td>
<td>{{#if serviced}}
Please return to the clinic immediately.
{{else}}
Patient is currently being served.
{{/if}}
</td>
</tr>
{{/each}}
Also keep in mind that when you use #each all of the properties of your array are served as locals for this block. So this. is not necessary anymore.
I just need to wrap column into hyperlink. So that a user can click on item of Number Column and can be redirected.
Here is my current View:-
#foreach (var item in Model) {
<tr>
<th>
#Html.ActionLink("Read", "Read", new { id = item.id})
</th>
<td>
#Html.DisplayFor(modelItem => item.Number)
</td>
</tr>
Trying to do something like this. I know its not right but need to know the right way to do it. I am new to MVC
#Html.ActionLink(#Html.DisplayFor(modelItem => item.Number).ToString(), "Read", new { id = item.id })
You can't really, but you can just use Url.Action instead:
<a href="#Url.Action("Read", new { id = item.id })">
#Html.DisplayFor(modelItem => item.Number)
</a>
I don't know if there's a way to do this with ActionLink (I suspect there isn't, at least not in any way I'd want to support in the code.) But you can manually craft an a tag and still keep its URL dynamic by using Url.Action() instead:
<a href="#Url.Action("Read", new { id = item.id })">
#Html.DisplayFor(modelItem => item.Number)
</a>
I'm just starting to learn MVC so try to bear with me.
I have a table that has a few options to the side that you can edit, delete and show the details of.
If I click the Details button now It will take me to another page (Details.cshtml)
which is located in the same Controller as the Index.cshtml which displays the table above.
This is the code for the table (Index.cshtml)
#model Collusus.Models.IndexModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<h2>Hello #Html.ActionLink(Model.userLoggedIN, "getProfile")</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table id="myTable" class="tablesorter">
<thead>
<tr>
<th>Change ID</th>
<th>Owner</th>
<th>Priority</th>
<th>Disposition Date</th>
<th>Completion Date</th>
<th>Do what?</th>
</tr>
</thead>
<tbody>
#for(int i=0; i<Model.changes.Count(); i++)
{
<tr>
<td>#Model.changes[i].ID</td>
<td>#Model.changes[i].Owner</td>
<td>#Model.changes[i].Priority</td>
<td>#Model.changes[i].DispositionDate.ToShortDateString()</td>
<td>#Model.changes[i].ActualCompletionDate.ToShortDateString()</td>
<td>#if (Model.changes[i].Owner == Model.userLoggedIN)
{
#Html.ActionLink("Delete", "Delete", new { id=Model.changes[i].ID })
#Html.ActionLink("Edit", "Edit", new { id=Model.changes[i].ID })
}
#Html.ActionLink("Details", "Details", new { id=Model.changes[i].ID })
</td>
</tr>
}
</tbody>
</table>
As you can see because of the code below, it will just take me to another page.
#Html.ActionLink("Details", "Details", new { id=Model.changes[i].ID })
What I want to do:
Open Delete,Edit or Details view in a dialog instead of another page.
Be able to still have the same functionality as if they were just opening another page.
I don't know if that makes too much sense. I've tried to explain it the best I could and been frustrated searching Google / trying code from other solutions but can't get it to work.
If you suggest another way besides the JQUERY dialog I'm willing to go that option too. All help is appreciated since I've been so frustrated.
I'm assuming you want to open them into a modal dialog. To accomplish this you can return partial views from your controller.
You can add a class to your action links like this:
#Html.ActionLink("Details", "Details", new { id=Model.changes[i].ID }, new { #class = "details-modal" })
Your Details action method:
public ActionResult Details(int id)
{
// Your code here
return PartialView("_Details", myModel); // return the partial view with the model
}
jQuery (off the top of my head so it may not be 100% correct):
$('#my-dialog').dialog({
autoOpen: false,
width: 400,
resizable: false,
modal: true
});
$('.details-modal').click(function() {
var theURL = $(this).attr('href');
$('#my-dialog').load(theURL, function() {
$(this).dialog('open');
});
return false; // ensures the browser is not redirected to the link's URL
});