I want to pass the Model.Game ID from Details page to another view page which is Cart.
The way I do is inserting the #Html.DisplayFor(model => model.Game.ID) in the app-route-id. Is that appropriate to do so?
Details.cshtml
#page "{id:int}"
#model GameSanctuary.Pages.Games.DetailsModel
#{
ViewData["Title"] = "Details";
}
<h2>Details</h2>
<div>
<h4>Game</h4>
<hr />
<dl class="dl-horizontal">
<dt>
#Html.DisplayNameFor(model => model.Game.G_Description)
</dt>
<dd>
#Html.DisplayFor(model => model.Game.G_Description)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Game.G_Genre)
</dt>
<dd>
#Html.DisplayFor(model => model.Game.G_Genre)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Game.G_Price)
</dt>
<dd>
#Html.DisplayFor(model => model.Game.G_Price)
</dd>
</dl>
</div>
<div>
<a asp-page="./Index">Back to List</a>
<a asp-page="./Cart" asp-page-handler="buynow" class="btn" asp-route-id="#Html.DisplayFor(model => model.Game.ID)">Add to Cart</a>
</div>
Cart.cshtml.cs
public async Task<IActionResult> OnGetBuyNow(int id)
{
cart = SessionHelper.GetObjectFromJson<List<Item>>(HttpContext.Session, "cart");
if (cart == null)
{
cart = new List<Item>();
cart.Add(new Item
{
Game = await _context.Game.FirstOrDefaultAsync(m => m.ID == id)
});
SessionHelper.SetObjectAsJson(HttpContext.Session, "cart", cart);
}
return RedirectToPage("Cart");
}
The id value that I retrieved in OnGetBuyNow is 0 but the expected value should be 1 based on the model.Game.ID in Details.cshtml. Is that something missing in between?
no, it's not appropriate.
Html.DisplayFor() renders the display template which matches whatever type you use it on. That's not what you want. What you want is a simple number surely which can be injected directly like this:
asp-route-id="#Model.Game.ID"
I would start there and see if that gives you what you want
Related
i have a create form, Which posts value to actionCreate() like
Form - dropdown
Dynamic form depending on the dropdown above
<?php $form = ActiveForm::begin(['id' => 'dynamic-form']);?>
<?=
$form->field($model, 'techpark_id')->dropDownList($techparks, ['prompt' => '- Choose a Techpark -',
'onchange' => '
$.get( "' . Yii::$app->urlManager->createUrl('campaign-request/techpark-details?id=') . '"+$(this).val(), function( data ) {
$( "#details" ).html( data );
});
']);
?>
<div id="details">
</div>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
Now the onchange event in the dropdown -> techpark_id will post id to campaign-request/teckpark-details
Yii::$app->urlManager->createUrl('campaign-request/techpark-details?id=7)
This actionTechparkDetails will renderPartial like this with values to dropdown list depending upon the value $id
public function actionTechparkDetails($id) {
$details = [new \app\models\CampaignRequestAdDetails];
$connection = Yii::$app->getDb();
$command = $connection->createCommand('
SELECT adspace_type_id,type,number_of_adspace,number_of_filled,adspace_value FROM `Techpark`
JOIN techpark_adspace ON techpark.id = techpark_id
JOIN adspace_type ON adspace_type_id = adspace_type.id
WHERE techpark.id=:id', [':id' => $id]);
$result = $command->queryAll();
$adspace_type_id = ArrayHelper::map($result, 'adspace_type_id', 'type');
return $this->renderAjax('_campaignDetails', [
'details' => (empty($details)) ? [new \app\models\CampaignRequestAdDetails] : $details,
'adspace_type_id' => $adspace_type_id
]);
}
campaignDetails has a dynamic form which populates the value depending on the selected dropdown() value ($id)
My _campaignDetails.php
<?php $form = ActiveForm::begin(['id' => 'dynamic-form']);?>
<div class="panel panel-default">
<div class="panel-heading"><h4><i class="glyphicon glyphicon-envelope"></i> Campaign details</h4></div>
<div class="panel-body">
<?php
DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper', // required: only alphanumeric characters plus "_" [A-Za-z0-9_]
'widgetBody' => '.container-items', // required: css class selector
'widgetItem' => '.item', // required: css class
'limit' => 20, // the maximum times, an element can be cloned (default 999)
'min' => 4, // 0 or 1 (default 1)
'insertButton' => '.add-item', // css class
'deleteButton' => '.remove-item', // css class
'model' => $details[0],
'formId' => 'dynamic-form',
'formFields' => [
'adspace_type_id',
'number_of_adspace',
],
]);
?>
<div class="container-items"><!-- widgetContainer -->
<?php foreach ($details as $i => $detail): ?>
<div class="item panel panel-default"><!-- widgetBody -->
<div class="panel-heading">
<div class="pull-right">
<button type="button" class="add-item btn btn-success btn-xs"><i class="glyphicon glyphicon-plus"></i></button>
<button type="button" class="remove-item btn btn-danger btn-xs"><i class="glyphicon glyphicon-minus"></i></button>
</div>
<div class="clearfix"></div>
</div>
<div class="panel-body">
<?php
// necessary for update action.
if (!$detail->isNewRecord) {
echo Html::activeHiddenInput($detail, "[{$i}]id");
}
?>
<div class="row">
<div class="col-sm-4">
<?= $form->field($detail, "[{$i}]adspace_type_id")->dropDownList($adspace_type_id) ?>
</div>
<div class="col-sm-4">
<?= $form->field($detail, "[{$i}]number_of_adspace")->textInput() ?>
</div>
</div><!-- .row -->
</div>
</div>
<?php endforeach; ?>
</div>
<?php DynamicFormWidget::end(); ?>
</div>
Now when i fill up the form and submit, i am unable to get the values of form (_campaignDetails.php which was rendered partially), inside actionCreate().
And also the remove item is not working in the dynamic form. Which would perfectly working if rendered inside the same form(i have another form which works fine with add/remove item of dynamic form).
I am using widget to dynamic form github.com/wbraganca/yii2-dynamicform
OR tell me how can i achieve the above scenario in any other format/manner using differnt approach. If you donot get what i want to achieve is
Depending on a dropdown value, i want a dynamic form which collects input with respect to value selected.
Thanks
I tried to insert a breakpoint before each action and I was stuck at a point when ClassId value in HttpGet method takes the actual(correct)Id of the class which needs to be deleted but ClassId value in HttpPost method does not match with the ClassId value of the HttpGet method, infact value of ClassId in HttpPost returns null due to which I run into an exception error that object has null value. It would be really great if any one can acknowledge me that how that error can be removed. Thanks. Below is the code for the controller and the corresponding view respectively.
Controller Code
[HttpGet]
public IActionResult Delete(int ClassId)
{
return View(db.Class.Include(x => x.Student).First(c => c.ClassId == ClassId));
}
[ActionName("Delete")]
[HttpPost]
public IActionResult DeletePost(int ClassId)
{
var r = db.Class.First(a => a.ClassId == ClassId);
var student = r.StudentId.ToString();
db.Remove(r);
db.SaveChanges();
return RedirectToAction("Details", "Student", new { id = student });
}
View Code
#model DemoProject.Models.Class
#{
ViewData["Title"] = "Delete Class";
}
<h3>Are you sure you want to delete this?</h3>
<div>
<hr />
<dl class="dl-horizontal">
<dt>
#Html.DisplayNameFor(model => model.ClassName)
</dt>
<dd>
#Html.DisplayFor(model => model.ClassName)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Title)
</dt>
<dd>
#Html.DisplayFor(model => model.Title)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Text)
</dt>
<dd>
#Html.DisplayFor(model => model.Text)
</dd>
</dl>
<form asp-action="Delete">
<div class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-danger" />
<div class="row">
<a asp-action="Details" asp-controller="Student" asp-route-id="#Model.Student.StudentId">Back</a>
</div>
</div>
</form>
</div>
You have two options:
As #stephen.vakil said, add a hidden field for the ClassId property to your view within the <form> element.
View with Hidden Field
#model ModelBinding.Models.Class
#{
ViewData["Title"] = "Delete Class";
}
<h3>Are you sure you want to delete this?</h3>
<div>
<hr/>
<dl class="dl-horizontal">
<dt>
#Html.DisplayNameFor(model => model.ClassName)
</dt>
<dd>
#Html.DisplayFor(model => model.ClassName)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Title)
</dt>
<dd>
#Html.DisplayFor(model => model.Title)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Text)
</dt>
<dd>
#Html.DisplayFor(model => model.Text)
</dd>
</dl>
<form asp-action="Delete">
<div class="form-actions no-color">
#Html.HiddenFor(model => model.ClassId)
<input type="submit" value="Delete" class="btn btn-danger"/>
<div class="row">
<a asp-action="Details" asp-controller="Student" asp-route-id="#Model.Student.StudentId">Back</a>
</div>
</div>
</form>
</div>
Add asp-route-id="#Model.ClassId" to your <form> tag and change the ClassId parameter name of your DeletePost method to id.
View with asp-route-id
#model ModelBinding.Models.Class
#{
ViewData["Title"] = "Delete Class";
}
<h3>Are you sure you want to delete this?</h3>
<div>
<hr/>
<dl class="dl-horizontal">
<dt>
#Html.DisplayNameFor(model => model.ClassName)
</dt>
<dd>
#Html.DisplayFor(model => model.ClassName)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Title)
</dt>
<dd>
#Html.DisplayFor(model => model.Title)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Text)
</dt>
<dd>
#Html.DisplayFor(model => model.Text)
</dd>
</dl>
<form asp-action="Delete" asp-route-id="#Model.ClassId">
<div class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-danger"/>
<div class="row">
<a asp-action="Details" asp-controller="Student" asp-route-id="#Model.Student.StudentId">Back</a>
</div>
</div>
</form>
</div>
Controller with Renamed Action Parameter
[HttpGet]
public IActionResult Delete(int classId)
{
return View(db.Class.Include(x => x.Student).First(c => c.ClassId == classId));
}
[ActionName("Delete")]
[HttpPost]
public IActionResult DeletePost(int id)
{
var r = db.Class.First(a => a.ClassId == id);
var student = r.StudentId.ToString();
db.Remove(r);
db.SaveChanges();
return RedirectToAction("Details", "Student", new { id = student });
}
Unless you just can't use <hidden> fields for some reason, option 1 is the superior choice.
I'm trying to update partialview after ajax call, the partial view is updating but the previous content not deleted from screen.
I have now the prevoious one and the current results on the screen.
That's my code:
public ActionResult FindMovies(string text)
{
ViewBag.ShowButton = Rented;
FindMovie(text);
if (movies.Count == 0)
ViewBag.Movies = "null";
else
ViewBag.Movies = "notNull";
return View(movies);
}
public ActionResult Rent(int id)
{
if (Rented.Equals("no"))
{
movieRent = db.Movies.Find(id);
movieRent.UserRent = userId;
movieRent.Rented = true;
db.Entry(movieRent).State = EntityState.Modified;
db.SaveChanges();
Rented = "yes";
movies.Find(x => x.ID == id).UserRent = userId;
movies.Find(x => x.ID == id).Rented = true;
}
return PartialView("MovieList", movies);
}
That's the view:
<div class="center">
#{Html.RenderPartial("MovieList", Model);}
</div>
and its the partialview:
#model IEnumerable<MvcMovies.Models.Movies>
<ul class="result">
#foreach (var item in Model)
{
<li>
<table>
<tr>
<th>
<figure>
<img src="#Url.Content(#item.Path)"
width="100" height="100" alt="movie logo" />
</figure>
</th>
<th>
<article>
<div class="editor-label">
#Html.DisplayFor(modelItem => item.Name)
</div>
<div class="editor-label">
#Html.DisplayFor(modelItem => item.Year)
</div>
<div class="editor-label">
#Html.DisplayFor(modelItem => item.StageManager)
</div>
<div class="editor-label">
#Html.DisplayFor(modelItem => item.Ganre)
</div>
<div class="editor-label">
#Html.DisplayFor(modelItem => item.Summary)
</div>
<div class="rent" id="rent">
#if (item.Rented.Equals(true))
{
<label>Rented</label>
}
else
{
#Ajax.ActionLink("Rent",
"Rent",
"Subscription",
new { id = item.ID },
new AjaxOptions()
{
UpdateTargetId = "rent",
OnComplete = "onAjaxComplete",
HttpMethod = "post",
})
}
</div>
</article>
</th>
</tr>
</table>
</li>
}
</ul>
Thanks.
I'm new to MVC. How can I refresh part of my main view after submit action in one of my partial views. I'm trying to make adding comments. I didn't use ajax until now so any help is good. I want after I create new comment in PartialView "Create" that it appers in PartialView GetCommentsByTicket...I hope that this is enough explanation...
#model HelpDeskApp.Models.Ticket
#{
ViewBag.Title = "Details";
}
#*<h2>Details</h2>*#
<div class="panel panel-green">
<div class="panel-heading">
Ticket
</div>
<div class="panel-body">
<div>
#*<h4>ticket</h4>
<hr />*#
<dl class="dl-horizontal">
<dt>
#Html.DisplayNameFor(model => model.TicketId)
</dt>
<dd>
#Html.DisplayFor(model => model.TicketId)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Subject)
</dt>
<dd>
#Html.DisplayFor(model => model.Subject)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Description)
</dt>
<dd>
#Html.DisplayFor(model => model.Description)
</dd>
<dt>
#Html.DisplayNameFor(model => model.AddedDate)
</dt>
<dd>
#Html.DisplayFor(model => model.AddedDate)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Category1.Name)
</dt>
<dd>
#Html.DisplayFor(model => model.Category1.Name)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Priority1.Name)
</dt>
<dd>
#Html.DisplayFor(model => model.Priority1.Name)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Status1.Name)
</dt>
<dd>
#Html.DisplayFor(model => model.Status1.Name)
</dd>
<dt>
#Html.DisplayNameFor(model => model.User.FirstName)
</dt>
<dd>
#Html.DisplayFor(model => model.User.FirstName)
</dd>
</dl>
</div>
<p>
#*#Html.ActionLink("Edit", "Edit", new { id = Model.TicketId }) |*#
#Html.ActionLink("Back to List", "Index")
</p>
<div id="postcomments">
<hr />
<h4>Komentari</h4>
#{ Html.RenderAction("CommentsByTicket", "Comments", new { ticketId = Model.TicketId });}
</div>
<div id="create comments">
#{ Html.RenderAction("Create", "Comments", new { Ticket = Model.TicketId });}
</div>
</div>
</div>
<div class="panel-footer">
Panel Footer
</div>
</div>
This is homework, an ASP.NET MVC and Web forms Web application using a repository (with data hard coded and no database) to rate doctors. The user should be able to edit and delete records, but when the application is run, and the "Delete" link is pressed for one of the records, the Delete page does not show the details of that record. Why not?
Here are the Delete methods:
public ActionResult Delete(string DoctorPicture)
{
repo.Remove(DoctorPicture);
return View("Delete");
}
[HttpPost]
public ActionResult Delete(string DoctorPicture, FormCollection collection)
{
try
{
// TODO: Add delete logic here
repo.Remove(DoctorPicture);
return View("Delete");
}
catch
{
return View();
}
}
From repo.Remove(DoctorPicture); it goes here in TestDoctorRepository, and doctor is null. Is it supposed to be?
public void Remove(string DoctorPicture)
{
var doctor = from d in doctors where d.DoctorPicture == DoctorPicture select d;
doctors.Remove(doctor.FirstOrDefault());
}
This is what my list of doctors looks like. Is my path for the images posing a problem?
public TestDoctorRepository()
{
doctors = new List<Doctor> {
new Doctor { DoctorPicture = "Images/0cropped.jpg", DoctorName = "Michael Shores", DoctorSpecialty = "Opthamology", times = 0, rating = 0, rated = true, avg=0, fave = true },
//more doctors
};
}
public Doctor GetDoctorByDoctorPicture(string DoctorPicture)
{
var selectedDoctor = from d in doctors
where d.DoctorPicture == DoctorPicture
select d;
return selectedDoctor.FirstOrDefault();
}
Delete View:
#model MidtermApplication.Models.Doctor
#{
ViewBag.Title = "Delete";
}
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<fieldset>
<legend>Doctor</legend>
<div class="display-label">
#Html.DisplayNameFor(model => model.DoctorPicture)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.DoctorPicture)
</div>
<div class="display-label">
#Html.DisplayNameFor(model => model.DoctorName)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.DoctorName)
</div>
<div class="display-label">
#Html.DisplayNameFor(model => model.DoctorSpecialty)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.DoctorSpecialty)
</div>
<div class="display-label">
#Html.DisplayNameFor(model => model.rating)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.rating)
</div>
<div class="display-label">
#Html.DisplayNameFor(model => model.times)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.times)
</div>
<div class="display-label">
#Html.DisplayNameFor(model => model.fave)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.fave)
</div>
<div class="display-label">
#Html.DisplayNameFor(model => model.rated)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.rated)
</div>
</fieldset>
#using (Html.BeginForm()) {
<p>
<input type="submit" value="Delete" /> |
#Html.ActionLink("Back to List", "Index")
</p>
}