Adding extra url query string to #Html.PagedListPager aside page in ajax call - ajax

I am PagedList for pagination when collecting values to my web page through ajax. The ajax call works well but When I click on the pagination links to display other details of the report for other pages, I have no value returned because I am adding extra parameters to the #Html.PagedListPager method aside the page used in the action method.
I am returning values through my partial views. The problem is how to add the extra
parameters to the pagination link.
My partial view code is below
#using Microsoft.Security.Application
#using PagedList
#using PagedList.Mvc
#model IPagedList<LiveChatPrototype.Mvc.Models.Livechat.Chatreportview>
#{
var FromDate = ViewBag.FromDate; //values to be added to pagination link
var ToDate = ViewBag.ToDate; //values to be added to pagination link
}
#if (Model != null)
{
<div class="numlinks">
#Html.PagedListPager(Model, page => Url.Action("DisplayAllchatreport",
new { FromDate = FromDate, ToDate = ToDate, page = page }), new PagedListRenderOptions() { Display = PagedListDisplayMode.IfNeeded, DisplayPageCountAndCurrentLocation = true, DisplayItemSliceAndTotal = true })
</div>
}
Please focus on the bottom part of the code, cause that is were the problem lies adding the ViewBag values to be part of the url so the pargination link is clicked other details can be returned.

FromDate and ToDate values were null. So I edited my controller and passed this values into the model which I was sending into my partialView.
So this allowed me to use them in my pagination links in the partialView

use Request to manage
fromDate = Request.QueryString["fromDate"]
//...

Related

Ajax.Beginform doesn`t trigger onsuccess method in javascript

I`m trying to send a form in mvc with Ajax.beginform and execute on success function. The function is stated in the form and created in the scripts section. However, the function is not fired after the post is submitted.
The view is partial view and is inserted in Index page.
The method which the form calls in the controller is HttpPost and returns the view again which causes the index page to load again.( I suspect here is the problem)
Basically what im trying to achieve is to show a div in my index page(main) saying successfully record edited.
Also, in my bundle config I have the jquery val & the jquery.validate.unobtrusive.js loaded and in the web.config I added in appconfig
What could be wrong? Here is my code.
[HttpPost]
public async Task<ActionResult> EditPostedJob(JobPost job, string dt)
{
using (var context = new ApplicationDbContext())
{
var post = (from p in context.jobPosts where p.JobPostId == job.JobPostId select p).First();
post.AboutJob = job.AboutJob;
post.Headline = job.Headline;
post.JobAddress = job.JobAddress;
post.JobCity = job.JobCity;
post.JobPostCode = job.JobPostCode;
await context.SaveChangesAsync();
//return Json(post,JsonRequestBehavior.AllowGet);
return RedirectToAction("Index", "Manage");
}
}
in my main view I have this message
<div id="success-edited-job" class="alert alert-success">
<strong>Success!</strong> the posted job has been successfully edited.
</div>
and also I have the js which hides this when page is loaded. And then I add the partial view with the form and there is set the success-edited-job div to show when post is successful but it return again the index view and the div is hidden again.
this is my partialview form
#using (Ajax.BeginForm("EditPostedJob", FormMethod.Post, new AjaxOptions() { OnSuccess = "JobEditedSuccessfully", OnFailure = "JobEditFail",HttpMethod="POST" }))
and the js
<script type="text/javascript">
function JobEditedSuccessfully(data) {
alert("lol");
}
function JobEditFail(error) {
console.error(error);
}
</script>

display the selected value from DropDown in a page

Hi Folks i am retrieving Name from database to drop down list. Now i want to display the selected value from DropDown in a page. My code is like follows to retrieve data,am using Fluent data as a framework.
My Controller Action is
var query = Abc.GetProducts();
ViewBag.EnterpriseId = new SelectList(query.AsEnumerable(), "EnterpriseId", "Name");
return View();
My view is ,
#Html.DropDownList("EnterpriseID", (SelectList) ViewBag.EnterpriseID, "--Select Resource--")
You can use a simple js for this:
elem = $('.selectClass');
options = elem.find('option[value="'+DataFromDBHere+'"]');
if(options){
options.prop('selected', 'selected');
}

MVC3 Nesting Partial Views with a call to Ajax.ActionLink

I am aware of the previous two questions which talk about nesting partial views but the solutions don't work for my design (which might not be the best one but I'm unsure how to adapt it).
Background:
I collect questionnaire responses from users and store them on an sql server as xml files.
I have a partial view which loads a table with all the Responses of a given user, this partialview populates the table with things like Response date, link to xml response document, questionnaire name, link to xml questionnaire document (the questionnaire info is pulled from a different table) and an Ajax ActionLink which redirects to action which parses the two relevant xml documents to print out Question and Answer list (i.e. visualise the response to be human readable) inside the second partial view.
The first partial view contains a div underneath the table which I wish to populate onclick of the Ajax.ActionLink with the second partial view.
Problem:
The answers are rendered correctly however the partial view is loaded into a whole new page, without any styling.
The other solutions to this nesting problem use RenderPartial() however I use return PartialView()
Code:
First Partial View:
<table>
<thead>
<tr><th>headers with other info</th>
<th>Display(/th>
<tr>
</thead>
<tbody>
<tr><td>cells with other info</td>
<td>#Ajax.ActionLink("View", "DisplayResponse","HealthStatus", new { respID = item.UniqueID,qVersion=item.QuestionnaireVersion, qname = item.QuestionnaireName }, new AjaxOptions { UpdateTargetId = "responseDisp" })</td>
</tbody>
</table>
<div id="responseDisp"></div> <--- **This is the div I wish to populate, does anyone know why it's not working?**
DisplayResponse Action (without the logic for parsing the xml documents)
public ActionResult DisplayResponse(Guid respID, int qVersion, String qname) {
var allResponses = ZData.Responses;
var response = (from r in allResponses
where r.UniqueID == respID
select r
).First();
//geting an XML questionnaire document
var questionnaireDetails = ZodiacData.Questionnaires;
var questionnaire = (from q in questionnaireDetails
where q.Name == qname && q.Version == qVersion
select q
).First();
//creating XMLDocument to read the questionnaire
XmlDocument xqdoc = new XmlDocument();
xqdoc.LoadXml(questionnaire.Xml);
XmlElement qroot = xqdoc.DocumentElement;
ViewBag.qroot = qroot;
XmlDocument xrdoc = new XmlDocument();
xrdoc.LoadXml(response.Raw);
XmlElement rroot = xrdoc.DocumentElement;
ViewBag.rroot = rroot;
return PartialView("_PrintedResponse");
}
I would be grateful for any help!
In MVC3 the #AJax. helpers are rendering regular form and a tags with some extra data- attributes. To make the magic work some Javascript is needed which will use this generated data- attributes to make the necessary jQuery ajax calls.
These js functions are living in the jquery.unobtrusive-ajax.js so add this line to your layout or view and it should work:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"
type="text/javascript"></script>
First, as mentioned above, you must have a reference to the jquery.unobtrusive-ajax.js file as this will get things "wired" up correctly for you.
This answer is also in response to your comment on your question about how you're passing your models to your views. You are actually making things more complicated for yourself by using the ViewBag for your model.
By using the ViewBag for your models, you will have a harder time finding/fixing/resolving issues in typo's as well as the great features of the Razor helpers. The ViewBag is a dynamic object and there are no compile time type checks. You don't need to cast your objects either (less code).
The preferred (and best practice) is to hook things up like so:
1) Your controller contains ViewModels (Strongly Typed) that are passed to the ViewModels
Controller
public ActionResult Something() {
return View();
}
public ActionResult UserView() {
UserViewModel mdoel = new UserViewModel {
Email = "me#somewherecool.com",
FirstName = "Your",
SStatuses = new List<SStatus>{
new SStatus {
ID = 0
}
}
};
return PartialView("_SomethingPartial", mdoel);
}
Index ("Something" view)
#{
ViewBag.Title = "Something";
}
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
<h2>Something</h2>
#Ajax.ActionLink("Ajax Click", "UserView", new AjaxOptions { UpdateTargetId = "MyDivContainer", InsertionMode = InsertionMode.Replace })
<div id="MyDivContainer">
<!-- my content should be here -->
</div>
Partial View
#model StackModels.UserViewModel
<div class="par">
#Html.LabelFor(m => m.FirstName)
<div class="field">
#Html.TextBoxFor(m => m.FirstName)
#Html.ValidationMessageFor(m => m.FirstName)
</div>
</div>

MVC Ajax action Link copies itself and appends, how do i fix

I am using ordered list design to to make my twitter app to view the tweets. Every Time I call the ajax insert, it puts puts another copy of the ajax link on the page . I am just trying to get the next set of tweets from the controller and inserting them so it lines up. I have tried moving the tags around and but the additional ajax buttons keep showing up.
Thinking it was a css problem i stripped it all out. Wasnt the issue. I will have to reformat my list again to put the closing and openning tags before and after the code block.
I just tried to putting it in a partial view and I put the ajax code in the layout.
Ajax Action Link
#Ajax.ActionLink("Update Tweets", "Index", "Home",
new AjaxOptions
{
UpdateTargetId = "TweetBox",
InsertionMode = InsertionMode.InsertBefore,
HttpMethod = "Get",
})
Partial View
<div id="TweetBox">
<div class="TwitterMessageBox">
<ol>
<li class="TweetLineBody">
#foreach (var item in Model)
{
#Html.Hidden(item.StatusId, item.StatusId)
<div class="TwitProfileImage">
<img src=#Url.Content(item.ImageUrl) alt="#item.ScreenName" />
</div>
<div class="TwitRealName">
#item.User
</div>
<div class="TwitNickName">
#MvcHtmlString.Create(#Html.Namify(#item.ScreenName))
</div>
<div class="TweetText">
#MvcHtmlString.Create(#item.Tweet)</div>
<div class="TweetTime">
#Html.RelativeDate(#item.Created)</div>
<div class="TweetRating">
Rating</div>
}
</li>
</ol>
</div>
</div>
The Controller is just a basic Enumerable List on the Home/ Index
This is the behavior
Lets say you have an ajax call that gets data from a controller action. It inserts before on a targetid thats a div id.
The initial view is perfect
AJAX UPDATE HTML LINK // You click it to get the controller invoke the ajax and get the data
Tweet 1
Tweet 2
etc = its perfect and aligned
You click the Ajax action link in your webpage, It goes out and gets the data but adds a second like like this
AJAX UPDATE HTML LINK
AJAX UPDATE HTML LINK
Tweet 1
Tweet 2 // alignment is still perfect but you have the 2nd ajax links
Now click the ajax link a 3rd time
// alignment is still perfect but you have the 2nd ajax link at top and one sandwiched
AJAX UPDATE HTML LINK
AJAX UPDATE HTML LINK
Tweet 1
Tweet 2
// alignment is still perfect but you have the 2nd ajax link at top and one sandwiched
Plus the Tweets results
AJAX UPDATE HTML LINK
Tweet 1
Tweet 2 // alignment is still perfect but you have the 2nd ajax links at the top and a 3rd List is inserted betweet 2/3
Controller Code per request:
public class HomeController : Controller
{
//
// GET: /Home/
private TwitterContext twitterCtx;
public ActionResult Index()
{
twitterCtx = new TwitterContext();
List<TweetViewModel> friendTweets = (from tweet in twitterCtx.Status
where tweet.Type == StatusType.Public
select new TweetViewModel
{
ImageUrl = tweet.User.ProfileImageUrl,
UserId = tweet.UserID,
User = tweet.User.Name,
ScreenName = tweet.User.Identifier.ScreenName,
StatusId = tweet.StatusID,
Tweet = HomeController.AddWebAndTwitterLinks(tweet.Text),
Created = tweet.CreatedAt
})
.ToList();
return View(friendTweets);
}
My Desired Behavior is 1 ajax link to call the controller and the data inserts
Without seeing all the code, I can only assume you don't have your views sorted out. Your controller appears to be returning the full Index view. If you put your tweet box into a partial view, your ajax action needs to be returning that partial view.

MVC3 Helper DisplayFor Model

I've got a view that displays a list of items. Rather than display items in a grid, I'd like to display 4 items per page, each with an image and multiple properties, displayed in a unique layout.
So, I'd like a foreach to iterate through the items, and each item to get displayed in a div. I could put all the code in the loop, but I'd like to have a custom html helper extension to do this.
I came up with this,
public static MvcHtmlString DisplayViewerFor(this HtmlHelper helper, TestModel model, bool rightAligned = true) {
if (model == null) {
model = new TestModel();
}
var outterDiv = new TagBuilder("div");
outterDiv.AddCssClass(rightAligned ? "item-display-right" : "item-display");
var image = new TagBuilder("image");
image.Attributes.Add("src", "Item/GetImage/" + model.ItemName);
image.Attributes.Add("height", "150");
var editorLabel = new TagBuilder("div");
editorLabel.AddCssClass("editor-label");
//LOOKING TO ADD CODE LIKE THIS HERE
var labelContent= html.LabelFor({my model property here})
editorLabel.InnerHtml += labelContent;
//END OF ADD
return new MvcHtmlString(outterDiv.ToString(TagRenderMode.EndTag));
}
In my method above, I need to display a few more values, and I would like to use the Html.LabelFor and Html.DisplayFor helpers, but the methods aren't available and I'm not sure what to pass to them if they were.
I'm not sure if this is possible or not, but I thought I would ask.
EDIT
I'm trying to use the html.LabelFor. See my code where I have updated it above, adding to it these two lines.
var labelContent= html.LabelFor({my model property here})
editorLabel.InnerHtml += labelContent;
You can see the code above.
EDIT 2
Here is the planned use for this Helper with dummied down view.
#model TestItemDisplayList
#{
ViewBag.Title = "Items";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#foreach(var item in #model.Items){
#Html.DisplayViewerFor(item)
}
You can use the Html.DisplayFor method to render a DisplayTemplate. One of the over loads for the method is to specify a template to use. You can modify your page code to read:
Page:
#model TestItemDisplayList
#{ ViewBag.Title = "Items"; Layout = "~/Views/Shared/_Layout.cshtml"; }
#Html.DisplayFor(model => Model,"TestItemDisplayList")
Display Template for TestItemDisplayList
#model TestItemDisplayList
#* You could limit this loop to the first 4 items *#
#foreach(var item in model.Items){ #Html.DisplayFor(item => item) }
Display Template for TestModel
#model TestModel
<div class="item-display">
<img src="#Url.Action("GetImage", "Image", new { id = Model.ItemName})" height="150"/>
<div class="editor-label">#Html.LabelFor(model => model.PropertyHere)</div>
</div>
I assume that your URL for the image used the default route of {controller}/{action}/{id} so I used the Url.Action and specified your ID.
You could also get away witout using a DisplayTemplate for "TestItemDisplayList" and moving that code in to your page but I wasn't clear if you wanted to add logic in that to limit the number of pages.

Resources