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
});
Related
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);
}
});
})
I have been trying to make this work for several days now. I cannot access a profile object from its associated user object. I have the latest versions of Ember and ember-data
Ember-data: 1.0.0-beta15
Ember: 1.10.0 production
I have a simple table view that lists my users and a couple properties. Here is the view:
<script type="text/x-handlebars" data-template-name="users/verification-candidates">
<div class="small-12 column">
<h1>Candidates for Verification</h>
<table>
<tr>
<th>System ID</th>
<th>Email</th>
<th>Created At</th>
<th>Legal First Name</th>
<th>Legal Last Name</th>
<th></th>
<th></th>
</tr>
{{#each user in model itemController="candidate" }}
<tr>
<td> {{ user.id }}</td>
<td> {{ user.email }}</td>
<td>{{ user.created_at }}</td>
<td>{{ user.legal_first_name }}</td>
<td>{{ user.legal_last_name }}</td>
<td><button id="verify" {{ action "markVerified" }}>Verify</button></td>
<td><button id="disable" {{ action "markDisabled" }}>Disable</button></td>
</tr>
{{/each}}
</table>
</div>
</script>
The models are like so:
App.Profile = DS.Model.extend({
user: DS.belongsTo('user'),
incognito_name : DS.attr('string'),
advisor_id : DS.attr('number'),
created_at : DS.attr('date'),
//etc..
App.User = DS.Model.extend({
profile: DS.belongsTo('profile',{ async: true }),
email: DS.attr('string'),
sign_in_count: DS.attr('number'),
last_sign_in_at: DS.attr('date'),
//etc...
I am using the rest adapter:
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://localhost:1337',
defaultSerializer: 'json'
});
Pertinent routes:
App.Router.map(function(){
this.resource('users', { path: '/users'}, function(){
this.route('verification-candidates');
});
this.resource('profiles', { path: '/profiles' }, function(){
})
});
App.UsersRoute = Ember.Route.extend({
model: function(){
return this.store.find('user');
}
});
App.ProfilesRoute = Ember.Route.extend({
model: function(){
return this.store.find('profile');
}
})
App.UsersVerificationCandidatesRoute = Ember.Route.extend({
model : function(){
var items = this.store.find('user', { role: "advisor", disabled: false, is_verified: false });
return items;
},
})
My server is a sails.js back end, which accesses a database created by a Rails application.
I want to alter the profile in this object controller, but cannot access it in any meaningful form:
App.CandidateController = Ember.ObjectController.extend({
actions: {
markVerified: function(){
var user = this.get('model');
var profile = user.get('profile');
console.log(profile); //output 1
console.log(profile.incognito_name); //output 2
}
}
});
The output2 is undefined. Output 1 gives me some sort of object with properties __nextSuper, __ember_meta, a bunch of other things, isFulfilled, and content. But, no object properties from the model definition. This appears to be a promisearray,but, I thought this was the way to get a related object. Meanwhile, when I try to treat it as a PromiseArray, per the documentation, i get null, like this:
App.CandidateController = Ember.ObjectController.extend({
actions: {
markVerified: function(){
var user = this.get('model');
user.get('profile').then(function(content){
console.log("promise content is " + content);
//prints 'promise content is null'
})
//console.log(profile);
//console.log(profile.incognito_name);
}
}
I am fairly certain all my back end server/client things are in order, as I can access the user objects and work with them on the page. I am thinking it may be related to how the profile relates to the user via advisor_id, but, I am so confused right now. I am very much at my wit's end.
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 am trying to add pagination support to my meteor app but my template shows a blank page as soon as I add the {{{pagination}}} tag in my template. There are no errors in the log.
My client js (routing info) looks like this
Meteor.Router.add({
'/': function () {
var user;
if (Meteor.loggingIn()) {
console.log('home: loading');
return 'loading';
}
user = Meteor.user();
if (!user) {
console.log('homer: signin');
return 'user_signin';
}
// start on 'start' page
console.log('home: start');
return 'page';
},
'/landing': 'landing',
'*': 'not_found',
'/landing/:page': function (page) {
Session.set('page', page) ;
return 'landing' ;
}
});
My Landing.js looks like this
Template.userList.pagination = function () {
return Pagination.links('/landing', Meteor.users.find({}).count(), {currentPage: Session.get('page'), perPage: 8}) ;
}
My landing template is as follows:
</thead>
<tbody>
{{#each users}}
{{> user}}
{{/each}}
{{{pagination}}}
</tbody>
</table>
I see a couple things with the code posted.
I don't know much about the Pagination addin but it looks like you have it inside the table tag and according to this (https://github.com/egtann/meteor-pagination) it renders a div. I believe that would be invalid.
In your routes you have the wildcard '*' before the 'landing/:page'. I believe it would match that one first. Should have the '*' be the last route you add.
Here my problem:
I have an input text and behind a date picker ui: and I would like to get the datepicker's value in razor:
Index.cshtml
<input id="datePickerCalendar" type= "text"/>
<script type="text/javascript">
$(document).ready(function () {
$('#datePickerCalendar').datepicker({
altFormat: "dd-mm-yy",
dayNamesMin: ["Di", "Lu", "Ma", "Me", "Je", "Ve", "Sa"],
monthNames: ["Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"],
changeMonth: true,
onSelect: function () {
/*('#datePickerCalendar').change(loadCalendar());*/
}
});
});
</script>
<table border="1" class="tableCalendar" id="calendar">
<caption> Veuillez sélectionner l'horaire souhaité </caption>
<th id="court"></th>
#foreach(var item in Model) {
foreach(var court in item.TennisCourts){
if (court.Outside == true)
{
<td id="court" class="court">Court n°#court.Number (Extérieur)</td>
}
else
{
<td id="court" class="court">Court n°#court.Number (Intérieur)</td>
}
}
}
#foreach (var item in Model)
{
var chooseDate = $('#datePickerCalendar').value; // here ! This instruction is not correct...
}
I'm Building a dynamic calendar that allow the user to make a reservation for a tennis court...
So, my questions are:
1)How to get the value from the datepicker in razor ?
2)How can I get the value every time when the user change the date ?
Thanks in advance
You need to post your value to a action method on the controller, surround the field with a form
#using (Html.BeginForm("Controller", "Action", FormMethod.Post))
{
}
Then change your field into a server side rendered one (So the model binder can capture the new value)
#Html.TextBoxFor(m => m.MyDate)
The action method needs to take the model as argument and it needs to have the DateTime property named MyDate
edit:
If you will be sending values from the server you need to be sure the client datepicker and the serer uses the same date format. This is a bit tricky, but I did this with the globalize jquery plugin, you have to choose if you want to hardcode the ui culture, or if the sever will use the client culture. This is done in web.config
Hardcoded
<globalization culture="se-SE" uiCulture="se-SE" enableClientBasedCulture="false" />
Client chooses
<globalization enableClientBasedCulture="true" />
edit2
Sorry for all my edits :D
A good way for sending server settings like datetime and such is to create a settings razor view and change its mime type to javascript, also be sure to have caching otherwise the client will load it every time
#{
Layout = null;
Response.Expires = 120;
Response.CacheControl = "public";
Response.ContentType = "text/javascript";
}
MyAppName = {};
MyAppName.settings = {
culture: "#Thread.CurrentThread.CurrentCulture.Name",
timeFormat: "#Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortTimePattern.ToLower()",
dateFormat: "#Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern.ToLower().Replace("yyyy", "yy")",
}