CONTROLLER:
public ActionResult Index()
{
SonerSevincComEntities context = new SonerSevincComEntities();
var Konular = context.Konu.ToList();
return View(Konular);
}
VİEW:
<div class="primary">
#foreach (var item in Model)
{
<h2>
<a href="Subject?SubjectId=
#Html.DisplayFor(model => item.Id)">
#Html.DisplayFor(model => item.Baslik)</a>
</h2>
<p class="post-info">
<a href="Subject?Tag=
#Html.DisplayFor(model =>item.Etiket)">
#item.Etiket.Split(',').ToString()</a>
</p>
<div class="image-section">
<img src="#Html.DisplayFor(model => item.Resim)"
alt="image post" height="206" width="498" />
</div>
<p>
<a class="more" href="Subject?SubjectId==
#Html.DisplayFor(model => item.Id)">Devamı »</a>
</p>
}
</div>
I want to split under side for (',')
#item.Etiket.Split(',').ToString()
When i run program , i see this code..
System.String[] in stead of Etiket
I tried to solve this with foreach Etiket.Split but id did not work .
How can i solve this problem in View?
<a href="Subject?Tag=
#Html.DisplayFor(model =>item.Etiket)">
#item.Etiket.Split(',').ToString()</a>
it should be like following as you said in your comment
<a href="Subject?Tag=
#Html.DisplayFor(model =>item.Etiket)">
#foreach(var x in item.Etiket.Split(','))
{
#x
}
</a>
String.Split: Returns a string array that contains the substrings in this string that are delimited by elements of a specified string array.
So what you are getting is correct output as per code.
You can try to display first element of substring
#item.Etiket.Split(',')[0]
Related
I want to display data from 2 different tables which are stored in ViewBag at view side but I'm unable to print the data, I get an error
'object' does not contain a definition for 'Name'
The code at controller side
public ActionResult Packages()
{
int Prov_id = 1;
using (var db = new DataContex())
{
ViewBag.pack = db.Packages.Where(x => x.ProviderId == Prov_id).ToList();
ViewBag.service = db.GroupServices.Join(db.PackageServices,
gs => gs.ServiceId,
ps => ps.ServiceId,
(gs, ps) => new
{
name = gs.ServiceName
})
.ToList();
return View();
}
View markup:
#foreach (var item in ViewBag.pack)
{
<div class="col-md-6 bg-white mt-3">
<div class="card border package-grid p-3">
<div class="row">
<div class="col-md-8">
<input type="hidden" />
<h4 class="font-weight-bold py-2">#item.PackageName</h4>
#foreach (var item1 in ViewBag.service)
{
<h6 class="py-1">#item1.Name</h6>
}
<p class="py-3">#item.PackageDescription</p>
</div>
</div>
<div class="row">
<div class="col-md-12 mt-3 d-flex justify-content-between flex-wrap">
<p><strike> Rs. #item.PackagePrice</strike> <span>Rs. #item.PackageOfferPrice</span> </p>
<span>Remove</span>
</div>
</div>
</div>
</div>
}
That is because when you created ViewBag.service you have created anonymous object with property as name with n as LowerCase and at view side you are trying to use #item.Name as N as UpperCase.
Correct the property name and it will work.
I have been able to bind the info to the textbox like so:
<div id="wordsInsideOfText">
#foreach (var item in Model.KVpairs)
{
#Html.TextBoxFor(modelItem => item)
<hr />
}
</div>
but what I am trying to do is something like this:
<div id="wordsInsideOfText">
#foreach (var item in Model.KVpairs)
{
#Html.TextBoxFor().PlaceHolder(modelItem => item)
<hr />
}
</div>
So that I can get the information from my model into the placeholder rather than as regular text.I have looked around some, and maybe I don't fully understand how to phrase my question/search but I wasn't able to come up with anything.
you have to do like this:
#Html.TextBoxFor(modelItem => item, new {placeholder = item})
or:
<input type="text" placeholder="#item"/>
I am making a page that stores clients. Clients can have domains and contacts and jobs.
Each contact/domain/job has edit/delete functionality.
I am using MVC 4 ASP.NET c#
each time you wish to edit/delete it launches a modal form.
The delete view for contact and domain is exactly the same except for the fields that it displays. The domain delete function does not fire anything when it is in partial view. But it succeeds when it is navigated to in the url as a regular view. the contact delete works fine in the partial view.
#model STClient.Models.Domain
#{
ViewBag.Title = "DeleteDomain";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
#using (Html.BeginForm("DeleteDomain", "Client", FormMethod.Post)) {
<div class="modal-header">
<h2>Are you sure you want to delete?</h2>
</div>
<div class="modal-body">
<fieldset>
<div class="display-label">
<h3>
#Html.HiddenFor(model => model.server.ID)
#Html.HiddenFor(model => model.ID)
#Html.DisplayNameFor(model => model.Name):
#Html.DisplayFor(model => model.Name)
</h3>
</div>
<div class="display-label">
<h5>
#Html.DisplayNameFor(model => model.Registrar):
#Html.DisplayFor(model => model.Registrar)
</h5>
</div>
<div class="display-label">
<h5>
#Html.DisplayNameFor(model => model.PrimaryDNS):
#Html.DisplayFor(model => model.PrimaryDNS)
</h5>
</div>
<div class ="display-label">
<h5>
#Html.DisplayNameFor(model => model.SecondaryDNS):
#Html.DisplayFor(model => model.SecondaryDNS)
</h5>
</div>
</fieldset>
</div>
<div class="modal-footer">
<a class="btn" href="">Cancel</a>
<input class="btn btn-danger" type ="submit" value="Delete" />
</div>
}
this is on the details page where the delete link is for the domain.
<div class="modal fade" id="deleteDomain-modal"></div>
<script type="text/javascript">
$(function () {
$(".deleteDomain").click(function () {
$.ajax({
url: "/Client/DeleteDomain",
type: "GET",
data: {id: $(this).attr('id')},
dataType: "html",
success: function(e)
{
$("#deleteDomain-modal").html(e);
}
});
$("#deleteDomain-modal").modal();
});
});
</script>
And finally in the Client Controller
public ActionResult DeleteDomain(int id)
{
Domain domain = db.Domains.Find(id);
if (domain == null)
{
HttpNotFound();
}
return PartialView(domain);
}
[HttpPost, ActionName("DeleteDomain")]
public ActionResult DeleteDomainConfirmed(int id)
{
Domain domain = db.Domains.Find(id);
Server server = db.Servers.Find(id);
db.Domains.Remove(domain);
db.SaveChanges();
db.Servers.Remove(server);
db.SaveChanges();
LogDeleteDomain(domain, server);
return RedirectToAction("Index");
}
I think I had a similar problem. The reason was that parameter value was send as string and not as integer. I had to cast the value. So in your script code you may try to change the line:
data: {id: $(this).attr('id')},
to:
data: {id: parseInt($(this).attr('id'))},
That solved my problem.
a bit of a strange one here. I've got a blog that's another 'dip my toe into MVC' project that will highlight the benefits of our new Intranet. I have a typical blog post page with the article, comments and a form to submit your comments against a given article.
I have a stringly typed main View ("Post") which has the article content, then two Html.RenderAction methods; one to get the comments and one to add comments via a form.
My issue is that when a comment is posted, my GetComments method is called before AddComment, so when the page is refreshed the new comment isn't visible although it has been added to the database. A quick F5 confirms this. I understand that GetComments is being called first due to it being declared first in the view but I'm not sure how to tell the view to do an add before a get.
Here's my code:
Controller:
public ActionResult AddComment()
{
return PartialView("AddComment");
}
[HttpPost]
public ActionResult AddComment(Comment comment)
{
comment.DateSubmitted = DateTime.Now;
db.Comments.Add(comment);
db.SaveChanges();
return PartialView(comment);
}
public ActionResult GetComments(int articleid)
{
var comments = db.Comments.Where(c => c.ArticleID == articleid).ToList();
return PartialView(comments);
}
Post view
#model IntranetBlog.Models.Article
#{
ViewBag.Title = "Post";
}
<div class="row">
<div class="span12">
<h3>#Html.DisplayFor(modelItem => Model.Title)</h3>
<small>by Ruth Barlow on #Html.DisplayFor(modelItem => Model.DateCreated)</small>
#if (Model.Image != null)
{
<p>
<img src="#Url.Action("GetImage", "Home", new { articleID = Model.ArticleID })" alt="" width="150" height="150" />
</p>
}
<div>
#Html.DisplayFor(modelItem => Model.Body)
</div>
<small>Posted under #Html.DisplayFor(modelItem => Model.Category.Name)</small>
</div>
<div class="span12">
#{
Html.RenderAction("GetComments", "Home", new { articleID = Model.ArticleID });
}
</div>
<div class="span12">
#{
Html.RenderAction("AddComment", "Home", new { articleID = Model.ArticleID });
}
</div>
</div>
GetComments partial:
#model IEnumerable<IntranetBlog.Models.Comment>
#if (Model.Any())
{
<h3>What you're saying</h3>
foreach (var item in Model)
{
<div>
Comment: #Html.DisplayFor(modelItem => item.Body)
</div>
<div>
Submitted by: #Html.DisplayFor(modelItem => item.SubmittedBy)
on #Html.DisplayFor(modelItem => item.DateSubmitted)
</div>
<hr />
}
}
else
{
<p>There are no comments for this post. Why not add one?</p>
}
AddComment partial
#model IntranetBlog.Models.Comment
#using (Html.BeginForm())
{
<h3>Why not leave us a comment?</h3>
#Html.ValidationSummary()
<fieldset>
<div class="editor-label">
#Html.LabelFor(model => model.Body)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.Body, 20, 20, null)
#Html.ValidationMessageFor(model => model.Body)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.SubmittedBy)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SubmittedBy)
#Html.ValidationMessageFor(model => model.SubmittedBy)
</div>
<p>
<input type="submit" value="Add comment" id="AddComment" class="btn btn- primary" />
</p>
</fieldset>
}
Hope this makes sense.
Thanks in advance.
The trick is to use Html.Action instead of Html.RenderAction this will allow you to store the result in a variable and then add it to the display where it is needed.
This will allow you to generate the PartialView in the logical order you need, while displaying them in an other order.
See this post for a quick example on how to do it : https://stackoverflow.com/a/13301057/971693
I would suggest to you a slightly different approach. Instead of using Html.BeginForm, think about using Ajax.BeginForm to submit the comment. Being ajax, it will have better performance as it allows your method to just return the comments so you can replace the old ones, or even just the newly added one so it can be added to the bottom of the list. Having said that, this solution does rely on the use of javascript and preferably jquery-unobtrusive-ajax to work and render decent looking client code. You don't have to know javascript to use this method thanks to the AjaxOptions class which has some powerful yet easy to use options built into it.
I have got a problem with submitting data to Post method.
I have a class similar to this:
public class A
{
public int Id{get; set;}
public string Name{get; set;}
public List<B> Bs {get; set;}
}
In the View I have a list of Bs object that I can add to the Bs property of class A without any problem. I can see the result without any problem in my Razor View as well.
The problem occurs when I post the final result to my Add Action Method to save them in my database.
When the final object is sent to my Action method the Bs property is completely empty. So what I did instead was to add that collection to a TempData dictionary and retrieved it in my Add Action method.
My question is simple why is my Bs property empty when its posted to my Edit action method ? The reason why I ask this is because in my AddBs action method I add my Bs to my Model and send it back to View and everything is find up to that point.
Edit:
#SLaks
This is the code I have in my View :
<% using (Html.BeginForm("Create", "A"))
{ %>
<%: Html.ValidationSummary(true) %>
<div class="editor-label">
<%: Html.LabelFor(model => model.Name) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.Name) %>
<%: Html.ValidationMessageFor(model => model.Name) %>
</div>
<% if (Model.Bs.Any())
{ %>
<h3>B List</h3>
<%= Html.Telerik().Grid(Model.Bs)
.Name("CheckedOrders")
.Columns(columns =>
{
columns.Bound(d => d.Id).Width(100);
columns.Bound(d => d.Name).Width(300);
})
.Footer(false)
%>
<% } %>
<br />
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
This is the HTML generated:
<form action="/Admin/BusinessType/Create" method="post">
<fieldset>
<div class="editor-label">
<label for="Name">Name</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="Name" name="Name" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span>
</div>
<div class="t-widget t-grid" id="CheckedOrders"><table cellspacing="0"><colgroup><col style="width:100px" /><col style="width:300px" /></colgroup><thead class="t-grid-header"><tr><th class="t-header" scope="col">Id</th><th class="t-last-header t-header" scope="col">Name</th></tr></thead><tbody><tr><td>2</td><td class="t-last">Heeey</td></tr><tr class="t-alt"><td>3</td><td class="t-last">Testtttt</td></tr></tbody></table></div>
<br />
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
</form>
The Code above shows perfectly fine in my Browser, I can even see the Bs list, but when I type a Name And Click on Create, the Bs list is empty.
I think the secret to this is in the view. I have a similar model in my app. In the view you have to format the names of the controls correctly:
<%
for (int i=0; i<model.Bs.Count; i++)
{
Html.TextBox( string.Format( "Bs[{0}].Property1OfB", i), model.Bs.Property1OfB );
Html.TextBox( string.Format( "Bs[{0}].Property2OfB", i), model.Bs.Property2OfB );
}
%>
The Add method will only receive whatever <input> elements are in the form that posted to it.