How to call a controller method inside the view? - asp.net-mvc

My problem is when i'm trying to get the best 4 posts who's match the same author name , as you see in the following image :
this is the controller :
Controller Code
and here is the view :
View code
so how i can call the controller method from the view , what's the code will looks like ? and thanks ..
also here is the controller method :
public ActionResult SameAuthor(string author)
{
var result = db.Books.Where(b => b.Author_name == author).Take(4).ToList();
return View(result);
}
and the view code (book page , the following code is a part of book page , that show the book details and info , so this code for show under the post details the most 4 post for same author) is :
//DISPLAYING 4 BOOKS FOR SAME AUTHOR
<div class="well">
<div class="row">
#foreach (var item in Model)
{
<div class="col-sm-6 col-md-3">
<div class="thumbnail">
<img src="/Books/RetrieveImage/#item.Book_id" alt="Generic placeholder thumbnail">
</div>
<div class="caption">
<h3>#item.Book_name</h3>
<p>Some sample text. Some sample text.</p>
<p>
<a href="#" class="btn btn-primary" role="button">
Button
</a>
<a href="#" class="btn btn-default" role="button">
Button
</a>
</p>
</div>
</div>
}
</div>
</div>
and thanks

If you are trying to show the result of your SameAuthor action method inside another view, you may use Html.Action helper method to do so.
So in your some other razor view, you can include the below line
#Html.Action("SameAuthor","Book",new {author="Author name here"})

Related

how to change html view using binding in angular 6

I have an angular 6 project , I have a component for book like this
<div class="col-md-4 agileinfo_single_left">
<img id="BigBookView" src="public/books/images/{{book.photo}}" alt=" " class="img-responsive">
</div>
<div class="col-md-8 agileinfo_single_right">
<h1>{{book.name | uppercase}}</h1>
<h2>Series: {{book.seriesName}}</h2>
<h3>Author: {{book.author}}</h3>
<h4></h4>
<div class="w3agile_description">
<h4>Summary : {{book.summary}}</h4>
</div>
<div class="snipcart-item block">
<div class="snipcart-thumb agileinfo_single_right_snipcart">
<h4 class="m-sing">Price: {{book.price}}$</h4>
<h4 class="m-sing">Seller: {{book.seller}}</h4>
</div>
<div class="snipcart-details agileinfo_single_right_details">
<form action="#" method="post">
<fieldset>
<input type="submit" name="submit" value="Add to cart" class="button">
</fieldset>
</form>
</div>
</div>
all of this is inside a modal and every time I choose a book and the modal is opened and suppose to show the book data in this html.
This is the component type script
export class BigBookViewComponent implements OnInit {
#Input()
public book:Book = new Book();
constructor() { }
ngOnInit() {
}
public changeBook(newBook: Book) {
console.log(this.book);
this.book = newBook;
}
}
using the function changeBook I send to this component a new book to show but the html and the UI don't chagne, even though I can see in the console.log(this.book); line that the book is indeed being sent.
How can I change the html to show a diffrent book?
You should assign the book on ngOnInit method.
When assigning in the constructor the single instance of the component will keep the original book.

How to pass an id of an item with a button from a list of items to a modal, then from modal to a controller?

So I have a list of web urls, all fetched from SQL and has an id, an address etc.
I list them in a table using the following:
<div>
<div class="well" margin-left:20px; margin-right:20px">
<h2 style="margin-left:20px; margin-top:10px">Control Added Links</h2>
<table class="table table-bordered">
<thead>
<tr>
<th>
Link Address
</th>
<th>
Check Interval
</th>
<th>
Status
</th>
<th>
#
</th>
</tr>
</thead>
<tbody>
#foreach (var i in links)
{
<tr>
<td>
#i.Address
</td>
<td>
#i.Interval
</td>
<td>
#if (i.Status)
{ <text> ON </text>}
else
{ <text> OFF </text>}
</td>
<td>
<a href="~/Control/Delete/#i.Id">
✖
</a>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
"links" here is a list of Link models:
#{
var links = (List<Link>)ViewData["LinkInfos"];
}
Right now, there is an X button you can click to delete a link from database, by using i.Id of the item 'i'. What I want to do is, ask for a confirmation with a modal, instead of directly deleting.
I delete the link with a function inside controller using the follownig:
public ActionResult Delete(int Id)
{
UserLinks links = new UserLinks();
links.delete(Id, User.Identity.Name);
return RedirectToAction("Index");
}
I changed this code, managed to pass the data from button to modal:
<a data-toggle="modal" data-id="#i.Id" data-request-url="#Url.Action("Delete", "Control")" title="Delete link" class="delete-Link btn btn-danger" href="#deleteLink">
✖
</a>
<div id="deleteLink" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Test</h4>
</div>
<div class="modal-body">
This will delete all records related to this link. Are you sure?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclick="deleteConfirm()">Yes</button>
<button class="btn btn-warning" data-dismiss="modal">No</button>
</div>
</div>
</div>
</div>
<script>
var myLinkId
var url
$(document).on("click", ".delete-Link", function () {
myLinkId = $(this).data('id');
url = $(this).data('request-url');
$(".modal-body #linkId").val(myLinkId);
// As pointed out in comments,
// it is superfluous to have to manually call the modal.
// $('#addBookDialog').modal('show');
});
function deleteConfirm()
{
debugger;
$.post(url), { Id: myLinkId };
}
</script>
But problem right now is passing this data from modal to controller. I wrote the "deleteConfirm" function but it doesn't seem to work, it doesn't go to ~/Control/Delete.
First part of my question is actually solved, I can pass id from button to modal, but I am not sure if it is properly solved so I am asking for that too, I currently pass the id using JavaScript but wonder if I can directly pass from button to modal itself.
I managed to fix my issue and properly delete by creating a modal for each item... which I assume is the sloppy way and can be a problem when I have like, let's say 100 links.
One solution I have in mind but don't know how to implement:
Have a "globalId" parameter inside view, when a button is clicked, i.Id is assigned to globalId, then open the modal, which has globalId as a parameter inside. Just like with , use inside modal, which changes by deletion button you click. But problem is, don't know how to create this global parameter and assign i.Id to it with click of a button.
A way I think I can implement my possible solution:
I want to have a variable in a view, let's say int globalId.
Let's say I press the delete button for id = 10, what I want to happen is simply have "global = id" so I want to assign 10 to number. If id of button is 12, I want "global = id" to happen again, this time to assign 12 to number.
So this way, modal will just use globalId, so I can make it have:
Yes
This way, there will only be one modal, every button will open the same modal and modal will use the same variable. Just value for globalId assigned to this modal will change with click of a button.
Question is, how can I create this local variable and how can I simply assign a new value to this local variable?
I have made some changes in your view which make this possible to work. I have added one hidden field in model and store the id on show event of the model. And on confirm id is get from this hidden field to construct the post url.
<a data-toggle="modal" data-id="#id" data-request-url="#Url.Action("Delete", "Home")" title="Delete link" class="delete-Link btn btn-danger" href="#deleteLink">
✖
</a>
<div id="deleteLink" class="modal fade" role="dialog">
<div class="modal-dialog">
<input type="hidden" id="linkId" />
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Test</h4>
</div>
<div class="modal-body">
This will delete all records related to this link. Are you sure?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclick="deleteConfirm()">Yes</button>
<button class="btn btn-warning" data-dismiss="modal">No</button>
</div>
</div>
</div>
</div>
<script>
$('#deleteLink').on('show.bs.modal', function (e) {
$("#linkId").val($(e.relatedTarget).data('id'));
});
function deleteConfirm()
{
var url = "#Url.Action("Delete", "Control")/" + $("#linkId").val();
$.post(url).success(function () {
location.href = "#Url.Action("Index", "Control")";
});
}
</script>

How to get descendants from current page in Umbraco 7?

I have a document type with alias dArticlesMain, and for this page I have the following structure.
dArticlesMain
dArticlesCategory1
Article1
Article2
Article3
dArticlesCategory2
Article1
Article2
Article3
dArticlesCategory3
Article1
Article2
Article3
I'm on dArticlesMain and i want to display all the descendants (Articles) and skip it's childrens (dArticlesCategory)
I have this code which display all the childrens (dArticlesCategory) and the descendants (Articles) also when i use the Article properties it's through an error.
<ul>
#foreach(var page in Model.Content.Descendants())
{
<li>#page.Name</li>
}
</ul>
I have got this code but i can't display by Article properties like articleText or articleImage.
<ul>
#foreach(var page in Model.Content.DescendantsOrSelf().OfTypes("Article"))
{
<li>#page.Name</li>
}
</ul>
I have figured it out, and here's my code...
#{
var rootNode = CurrentPage.AncestorOrSelf(1);
var articlesParent = rootNode.Children("dArticlesMain").FirstOrDefault();
<div class="row">
#foreach (var article in articlesParent.Descendants("article").Where("Visible").RandomOrder())
{
<div class="col-sm-6 col-md-3">
<div class="thumbnail">
<a href="#article.Url">
<img src="#article.articlePhoto" alt="#article.articleName" />
</a>
<div class="caption">
<a class="h4" href="#article.Url">#article.articleName</a>
#Umbraco.Truncate(article.articleFullText, 100)
</div>
</div>
</div>
}
</div>
}

How do I redirect from an MVC Post Action back to the bootstrap popup modal partial view where the post came from?

How do I redirect from an MVC Post Action back to the bootstrap popup modal partial view where the post came from?
Here is the PartialView sitting in the Bootstrap modal popup on the page.
It has a div with a validation taghelper waiting for any model errors.
#model CreateRoleViewModel
<div class="panel panel-primary partialModalFormDivs">
#Html.Partial("_ModalHeader",
new ModalHeader
{
Heading = "ADD ROLE",
glyphiconClass = "glyphicon glyphicon-random"
}
)
<div class="panel-body">
<div asp-validation-summary="All" class="text-danger"></div>
<form asp-action="CreateRole" method="post">
<div class="form-group">
<label asp-for="RoleName"></label>
<input asp-for="RoleName" class="form form-control" />
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Create</button>
<a asp-action="Index" class="btn btn-default">Cancel</a>
</div>
</form>
</div>
</div>
It posts to this action:
[HttpPost]
public async Task<IActionResult> CreateRole(CreateRoleViewModel createRoleViewModel)
{
if (ModelState.IsValid)
{
IdentityRole role = new IdentityRole(createRoleViewModel.RoleName);
IdentityResult result
= await _roleManager.CreateAsync(role);
if (result.Succeeded)
{
return RedirectToAction("Index");
}
else
{
foreach (IdentityError error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
}
}
return View(createRoleViewModel);
}
I can return a PartialView like this at the end:
return View("_CreateRole", createRoleViewModel);
But then the whole page is cleared and this partial is returned with no layout file.
How can I return the results back to the modal popup window.
I understand the problem and the current behavior. But has anyone else solved this?
I think what you want to do is an ajax post and then just return a partial view and replace the form. The form should be inside a container div with an id that is used to replace its contents with the ajax post result. To do this you need to include the jquery unobtrusive ajax script which will auto wire the ajax based on the data-* attributes on the form as shown below
<div class="panel-body">
<div asp-validation-summary="All" class="text-danger"></div>
<div id="resultcontainer">
<form asp-action="CreateRole" method="post"
data-ajax="true"
data-ajax-method="POST"
data-ajax-mode="replace"
data-ajax-update="#resultcontainer"
>
<div class="form-group">
<label asp-for="RoleName"></label>
<input asp-for="RoleName" class="form form-control" />
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Create</button>
<a asp-action="Index" class="btn btn-default">Cancel</a>
</div>
</form>
</div>
</div>
and don't forget to return a partial view
return PartialView(createRoleViewModel);

<img> element with onclick submits the form instead of firing action

I am having a weird issue in my Login.cshmtl view which I posted below. So on the top right corner of my login page, I have two textboxes for credentials and two .png images as their labels, a "Remember Me" checkbox and a .png image as its label, and finally a "ForgotPassword" .png image defined as:
<img onclick="location.href ='#Url.Action("ForgotPassword", "Account")'" src="~/Content/Images/ForgotPassword.png" />
Everything worked fine until I changed this line as follows:
<input type="image" onclick="location.href ='#Url.Action("ForgotPassword", "Account")'" src="~/Content/Images/ForgotPassword.png" />
Surprisingly, now my image-button is broken and it submits the page! Using the debugger I observe that POST method of my Login action is called instead of ForgotPassword action. Can you please explain how this happens? Below, I am posting the Login.cshtml view with irrelevant parts removed.
#model FooProject.Web.ViewModels.LoginViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
....
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="navbar navbar-fixed-top">
<div class="navbar-header">
<input type="image" class="navbar-brand" onclick="location.href ='#Url.Action("Index", "Home")'" src="~/Content/Images/logo.png"/>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav" style="margin:10px">
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
<div class="nav navbar-nav navbar-right">
<div class="row">
<div class="col-md-5">
<span class="actionLink">
<img src="~/Content/Images/Username.png"/>
</span>
</div>
<div class="col-md-7">
<span class="actionLink">
<img src="~/Content/Images/Password.png"/>
</span>
</div>
</div>
#using (Html.BeginForm("Login", "Account", FormMethod.Post, new { id = "loginForm", #class = "navbar-right form-inline" }))
{
#Html.AntiForgeryToken()
<div class="row">
<div class="col-md-5">
#Html.TextBoxFor(m => m.UserName, new { #class = "" })
</div>
<div class="col-md-5">
#Html.PasswordFor(m => m.Password) <br />
</div>
<div class="col-md-2" style="padding-left:0">
<input type="image" alt="Submit" src="~/Content/Images/Login.png" style="width:45px" />
</div>
</div>
<div class="row">
<div class="col-md-5">
#Html.CheckBoxFor(m => m.RememberMe)
<span class="actionLink">
<img src="~/Content/Images/RememberMe.png" style="height:11px;vertical-align:top;margin-top:2px" />
</span>
</div>
<div class="col-md-7">
<img onclick="location.href ='#Url.Action("ForgotPassword", "Account")'" src="~/Content/Images/ForgotPassword.png" />
</div>
</div>
}
</div>
</div>
</div>
</div>
</div>
</body>
</html>
<input type="image"> works as submit button, so this is expected behavior.
But there is solution:
<input type="image" onclick="location.href ='#Url.Action("ForgotPassword", "Account")'; return false;" src="~/Content/Images/ForgotPassword.png" /> will do the trick.
By adding return false; you prevent submission from being executed.
There is also alternative solution:
There is no reason to replace img tag with input. If you want to see cursor on hover, you can do it with CSS:
img.submit:hover {
cursor: pointer;
}
and decorate img with submit class:
<img class="submit" onclick="location.href ='#Url.Action("ForgotPassword", "Account")'" src="~/Content/Images/ForgotPassword.png" />
And the way I would do that:
<a href='#Url.Action("ForgotPassword", "Account")'>
<img src="/Content/Images/ForgotPassword.png" />
</a>
By changing the image tag to an input tag you've create an image as a submit button and it's doing what you should expect: submitting the form with the action and method defined.
See http://www.w3schools.com/tags/att_input_type.asp for more information
From the W3C Wiki (emphasis is mine):
The image button state represents either an image from which a user
can select a coordinate and submit the form, or alternatively a button
from which the user can submit the form. The element is a button,
specifically a submit button

Resources