render partial view from jquery not working - c#

I have some issues with rendering a partial view using jquery. Even if it was asked more than once (here), I didn't found a solution that worked for me:
My view:
#model IEnumerable<OdeToFood.Models.RestaurantListViewModel>
#{
ViewBag.Title = "Home Page";
}
<form method="get" action="#Url.Action("Index")" data-otf-ajax="true" data-otf-target="#restaurantlist">
<input type="search" name="searchTerm" />
<input type="submit" value="Search By Name" />
</form>
#Html.Partial("_Restaurants", Model)
My partial view:
#model IEnumerable<OdeToFood.Models.RestaurantListViewModel>
<div id="restaurantList">
#foreach (var item in Model)
{
<div>
<h4>#item.Name</h4>
<div>#item.City, #item.Country</div>
<div>REviews: #item.CountOfReviews</div>
<hr />
</div>
}
</div>
otf.js:
$(function () {
var ajaxFormSubmit = function () {
var $form = $(this);
var options = {
url: $form.attr("action"),
type: $form.attr("method"),
data: $form.serialize()
};
$.ajax(options).done(function (data) {
var $target = $($form.attr("data-otf-target"));
$target.replaceWith(data);
});
return false;
};
$("form[data-otf-ajax='true']").submit(ajaxFormSubmit);
});
index action of my controller:
public ActionResult Index(string searchTerm = null)
{
var model =
_db.Restaurants
.OrderByDescending(r => r.RestaurantReviews.Average(a => a.Rating))
.Where(r => searchTerm == null || r.Name.StartsWith(searchTerm))
.Select(r => new RestaurantListViewModel
{
Id = r.Id,
Name = r.Name,
City = r.City,
Country = r.Country,
CountOfReviews = r.RestaurantReviews.Count()
}
)
.Take(10);
if (Request.IsAjaxRequest())
{
return PartialView("_Restaurants", model);
}
return View(model);
}
My issue is that nothing happens when I press search button. I've added an test alert like:
$.ajax(options).done(function (data) {
var $target = $($form.attr("data-otf-target"));
alert('test');
$target.replaceWith(data);
});
and the alert showed when I've clicked the search button, but in site nothing happens. Anyone knows what is my issue?

You have #restaurantlist as the target, whereas div id is actually restaurantList. Capital "L".

Related

MVCGrid.NET - How to reload the grid?

I am using MVCGrid.NET http://mvcgrid.net/
And I created a Non-Fluent grid http://mvcgrid.net/gettingstarted see Non-Fluent Example
GridDefinition<YourModelItem> def = new GridDefinition<YourModelItem>();
GridColumn<YourModelItem> column = new GridColumn<YourModelItem>();
column.ColumnName = "UniqueColumnName";
column.HeaderText = "Any Header";
column.ValueExpression = (i, c) => i.YourProperty;
def.AddColumn(column);
def.RetrieveData = (options) =>
{
return new QueryResult<YourModelItem>()
{
Items = new List<YourModelItem>(),
TotalRecords = 0
};
};
MVCGridDefinitionTable.Add("NonFluentUsageExample", def);
Now I have my grid appear when you submit a form, but when I submit the form again, I am expecting new data, but the grid does not reload or refresh or anything. It does't even reset when I refresh the page, I have to do a full reload of the page to reset it, which is lame, does anyone know how to refresh or reload the grid when I want to show new data?
I have even tried this: http://mvcgrid.net/demo/NoQueryOnPageLoad
But it did not reload or refresh.
PLEASE HELP!
It reloads, try this,
//model class
public class YourModelItem
{
public int Id { get; set; }
public string YourProperty { get; set; }
}
//controller
public class HomeController : Controller
{
private static List<YourModelItem> _modelItems = new List<YourModelItem>();
public ActionResult Index()
{
GridDefinition<YourModelItem> def = new GridDefinition<YourModelItem>();
GridColumn<YourModelItem> column = new GridColumn<YourModelItem>();
column.ColumnName = "UniqueColumnName";
column.HeaderText = "Any Header";
column.ValueExpression = (i, c) => i.YourProperty;
def.AddColumn(column);
def.RetrieveData = (options) => new QueryResult<YourModelItem>()
{
Items = _modelItems,
TotalRecords = 0
};
MVCGridDefinitionTable.Add("NonFluentUsageExample", def);
return View();
}
[HttpPost]
public JsonResult Add(YourModelItem item)
{
_modelItems.Add(item);
return Json(true, JsonRequestBehavior.AllowGet);
}
}
index.cshtml
#{
ViewBag.Title = "Home Page";
}
#using MVCGrid.Web
<div class="jumbotron">
<div id="form1">
<div class="form-group">
<label for="Id">ID</label>
<input type="number" class="form-control" id="Id" aria-describedby="Id" placeholder="Enter Id">
</div>
<div class="form-group">
<label for="YourProperty">YourProperty</label>
<input type="text" class="form-control" id="YourProperty" placeholder="Enter Your Property">
</div>
<button id="addItem">Submit</button>
</div>
<br />
#Html.MVCGrid("NonFluentUsageExample")
</div>
#section scripts {
<script type="text/javascript">
$(document).ready(function () {
$("#addItem").click(function () {
var formData = { Id: $('#Id').val(), YourProperty: $('#YourProperty').val() };
$.ajax({
type: "POST",
url: "/Home/add",
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(formData),
success: function(data) {
if (data) {
MVCGrid.reloadGrid('NonFluentUsageExample');
}
}
});
});
});
</script>
}
_layout.cshtml -> body
<body>
<div class="container body-content">
#RenderBody()
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
<script src="~/MVCGridHandler.axd/script.js"></script>
#RenderSection("scripts", required: false)
</body>
It adds item and reloads after "Submit".
Just have installed MVCGrid in new asp.net mvc - Install-Package MVCGrid.Net
Put these lines as above

Return a partial view and append it to a div in index.cshtml view Mvc4

I am trying to do something like, i have an index view which has some tags on each on one when click i want to return a partial view and append it to the div in main index.cshtml view
my code i below
Index.cshtml
#model OyeAPI.Models.User
#{
object user = Session["userId"];
ViewBag.Title = "Index";
}
<link href="#Url.Content("~/Content/css/style.css")" rel="stylesheet"/>
<div class="main_Container">
#if (Session["userId"] == null) {
<div class="login_div">
#Html.Partial("~/Views/Shared/_signin.cshtml")
</div>
}else
{
<div style="height:100px;">
<p>OyePortal</p>
</div>
// <p>#Html.ActionLink("clickme", "callLogs", "contactWeb")</p>
<div style="position:relative; left:400px;">
<div>
<p id="contacts">Contacts</p> | <p id="callLogs">Call Logs</p> |
<p id="messages">Phone Messages</p> | <p >Groups</p>
</div>
<div id="container_inner_frame">
<h1>Welcome fuck it clickme </h1>
</div>
</div>
}
</div>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
#*<script src="#Url.Content("~/Scripts/jquery-1.10.2.js")" type="text/javascript"></script>*#4
<script type="text/javascript">
$("#contacts").on("click", function () {
$("#container_inner_frame").html('#Html.Partial("~/Views/Shared/_contacts.cshtml")');
});
$("#callLogs").on("click", function () {
$("#container_inner_frame").html('#Html.Partial("~/Views/Shared/_callLogs.cshtml")');
});
$("#messages").on("click", function () {
$("#container_inner_frame").html('#Html.Partial("~/Views/Shared/_Phonemessages.cshtml")');
});
</script>
shared View _callLogs.cshtml
#model OyeAPI.Models.CallLogs
#{
List<Model.CallLogsModel> ListCallLogs = (List<Model.CallLogsModel>)ViewData["Data"];
Int64 CallID = 0;
string callNumber = null;
string callDuration = null;
string callType = null;
string date = null;
string daytime = null;
}
<div class="main_Container">
<div>
<div>
<ul>
<li>Contact ID</li><li>Contact Name </li><li>Contact Number</li>
</ul>
</div>
#if (ListCallLogs != null)
{
foreach (var item in ListCallLogs)
{
CallID = item.CallId;
callNumber = item.PhoneNumber;
callDuration = item.CallDuration;
callType = item.CallType;
date = item.CallDate.ToShortDateString();
daytime = item.CallDayTime.ToShortTimeString();
<div>
<ul>
<li>#CallID</li><li>#callNumber </li><li>#callDuration</li><li>#callType</li><li>#date </li><li>#daytime</li>
</ul>
</div>
}
}
else
{
<p>Empty String list no messages</p>
}
</div>
</div>
Controller contactWeb function callLogs
[HttpPost]
[AllowAnonymous]
public ActionResult callLogs()
{
Int64 userID = Convert.ToInt64(Session["userId"]);
try
{
List<CallLogsModel> callModel = new List<CallLogsModel>();
ICallLogs callLogObject = new CallLogsBLO();
callModel = callLogObject.GetCallLogs(userID);
ViewData["Data"] = callModel;
}
catch (Exception e)
{
}
return PartialView("_callLogs", ViewData["Data"]);
}
But its not working, when i run the code before login it hit the _callLogs shared view first and after that it show the login screen and when i click the callLogs it dosen't display any thing. i my be missing something
Your approach is not right:
you are writing jquery event, you have to send an ajax call to an action and return partial view of CallLogs and then append it to container div.
do like this:
$("#callLogs").on("click", function () {
$("#container_inner_frame").load('#Url.Action("callLogs","YOurController")');
});
or like this:
$("#callLogs").on("click", function () {
$.ajax({
url: '#Url.Action("callLogs", "YourControllerName")',
success: function (response) {
$("#container_inner_frame").html(response);
}
error: function () {
alert("error occured");
}
});
});
If you use the jQuery unobtrusive Ajax library, you should be able to do something as simple as this to load content from a partial on a button/link click. Note that you need to have a controller which returns a PartialViewResult (this can then reference your view) :
#Ajax.ActionLink("Click Me", "Action", "Controller", new AjaxOptions{ InsertionMode=InsertionMode.InsertAfter, UpdateTargetId="MyTargetDivId"})
<div id="MyTargetDivId"></div>
Try this :
$("#callLogs").on("click", function () {
$.ajax({
url: '#Url.Action("callLogs", "YourController")',
type: 'get',
datatype: 'json',
success: function (data) {
$('div#container_inner_frame').html(data);
}
});
});

Reloading partial page after jQuery ajax command

I am very new to both JQuery and Asp.net MVC 3 (C#), so I apologize if this is trivial. I have an MVC partial view (Index.cshtml) that has a list of tasks. These tasks are contained within indivudal divs that I have in a list style layout. I have a button called "add task" that opens a dialog. This dialog will save the added task to the database via an AJAX Json call to the controller.
This is where I am having trouble - after the dialog closes I would like the list of tasks to reload with the task i just added. I have found examples where the entire page is reloaded, and I found examples where the controller is supposed to return a rendered view. My problem is that the dialog is being opened from the partial I want to reload. Is there a way to accomplish what I am trying to do.
Index.cshtml
#model IEnumerable<TaskManagementApplication.Models.Project>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div id="ProjectAccordionWrapper">
#foreach (var item in Model)
{
<div class="ProjectWrapper">
<h3>#item.Name</h3>
<div class="column">
<button class="createTaskButton" id="#item.ProjectID">Create New Task</button>
#foreach(var task in item.Tasks) {
var buttonClass = "taskID" + task.TaskID;
<div class="portlet">
<div class="portlet-header">#task.TaskName</div>
<div class="portlet-content">#task.TaskDescription</div>
<button class="editTaskButton" id="#task.TaskID">Edit Task</button>
</div>
}
</div>
</div>
}
</div>
<div id="dialog-form" title="Create new user">
<p class="validateTips">All form fields are required.</p>
<form>
<fieldset>
<label for="TaskName">Task Name</label>
<input type="text" name="TaskName" id="name" class="text ui-widget-content ui-corner-all" />
<label for="TaskDescription">Task Description</label>
<input type="text" name="TaskDescription" id="description" value="" class="text ui-widget-content ui-corner-all" />
<input type="hidden" name="TaskID" id="ID" />
<input type="hidden" name="ProjectID" id="ProjectID" />
</fieldset>
</form>
</div>
Partial Javascript
function GetTask(id) {
if (id.length > 0) {
$.ajax({
url: '/Project/GetTaskFromID',
type: "POST",
data: { "id": id },
success: PopulateDialogFields,
error: HandleError
});
}
}
function PopulateDialogFields(data) {
$("#name").val(data.TaskName);
$("#description").val(data.TaskDescription);
$("#ID").val(data.TaskID);
}
function HandleError(data) {
alert(data.error);
var foo = data;
}
function SaveTask() {
var taskName = $("#name").val();
var taskDescription = $("#description").val();
var id = $("#ID").val();
var projectID = $("#ProjectID").val();
if (id.length > 0) {
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "taskID": id }
});
}
else {
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "projectID": projectID }
});
}
}
$("#dialog-form").dialog({
autoOpen: false,
height: 300,
width: 350,
modal: true,
buttons: {
"OK": function () {
SaveTask();
$(this).dialog("close");
},
Cancel: function () {
$(this).dialog("close");
}
},
close: function () {
allFields.val("").removeClass("ui-state-error");
window.location.reload(true);
},
open: function () {
var id = $(this).data("id");
var projectID = $(this).data("projectID");
$("#ProjectID").val(projectID);
var button = $("#" + id);
GetTask(id);
}
});
$(".editTaskButton")
.button()
.click(function () {
$("#dialog-form").data('id', this.id).dialog("open");
});
$(".createTaskButton")
.button()
.click(function () {
$("#dialog-form").data('projectID', this.id).dialog("open");
});
I am relatively new to jQuery and ASP.NET MVC as well, however, here's what first comes to mind.
In order to maintain the AJAX-y aspect of the page, I suggest that you create a method that handles a POST which returns a JSON formatted set of TaskManagementApplication.Models.Project. This method can optionally return filtered results.
The markup would look like this,
<div id="ProjectAccordionWrapper">
<div id="ProjectWrapperTemplate" class="ProjectWrapper" style="display: none;">
<h3 id="itemName"></h3>
<div class="column">
<button class="createTaskButton" id="itemProjectID">Create New Task</button>
<div id="portletTemplate" class="portlet">
<div class="portlet-header" id="taskName"></div>
<div class="portlet-content" id="taskDescription"></div>
<button class="editTaskButton" id="taskID">Edit Task</button>
</div>
</div>
</div>
</div>
Next, you would have jQuery clone the ProjectWrapperTemplate element, and set all of the corresponding fields.
$(function () {
$.ajax({
url: '/Project/GetTasks',
type: "POST",
data: { }
}).done(function (data) {
data.forEach(function (element) {
AppendProjectWrapper(element);
});
});
function AppendProjectWrapper(data) {
var projectAccordionWrapper = $('#ProjectAccordionWrapper');
var projectWrapper = $('#ProjectWrapperTemplate').clone(true, true);
projectWrapper.id = nothing; // remove the id, so as to not have duplicates
projectWrapper.style.display = nothing; // remove the style "display: none"
var itemName = projectWrapper.children('#itemName'); // h3
itemName.id = nothing;
itemName.text(data.ItemName);
var itemProjectID = projectWrapper.children('#itemProjectID'); // button Create New Task
itemProjectID.id = data.ItemProjectID;
var portletTemplate = projectWrapper.children('#portletTemplate'); // div
data.Tasks.forEach(function (element) {
var portlet = portletTemplate.clone();
portlet.id = nothing;
var taskName = portlet.children('#taskName');
taskName.id = nothing;
taskName.text(element.TaskName);
var taskDescription = portlet.children('#taskDescription');
taskDescription.id = nothing;
taskDescription.text(element.TaskDescription);
var editTaskButton = portlet.children('#taskID');
editTaskButton.id = element.TaskID;
portlet.appendTo(projectWrapper);
});
portletTemplate.remove(); // remove the portlet template element
projectWrapper.appendTo(projectAccordionWrapper);
}
}
Finally, have '/Project/SaveTask' return a JSON formatted TaskManagementApplication.Models.Project of the currently saved task.
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "taskID": id }
}).done(function (data) {
AppendProjectWrapper(data);
});
The return data for '/Project/GetTasks' should look as follows:
[
{
ItemName: '#item.Name',
ItemProjectID: '#item.ProjectID',
Tasks: [
TaskName: '#task.TaskName',
TaskDescription: '#task.TaskDescription',
TaskID: '#task.TaskID'
]
}
]
The return data from '/Project/SaveTask' should follow the same format, except or the outer-most array.
Please note that a lot of this code is untested.
It may be easiest to refactor the list into another action+view. Then, you can call this in both the original Index.cshtml view, and via the .load() method in jQuery. So, assuming this:
Projects controller
[HttpGet]
[ChildActionOnly]
public ActionResult Tasks(int id)
{
// create the appropriate model object as an IEnumerable of your Task type
return View(model);
}
Tasks.cshtml
#foreach(var task in Model) {
var buttonClass = "taskID" + task.TaskID;
<div class="portlet">
<div class="portlet-header">#task.TaskName</div>
<div class="portlet-content">#task.TaskDescription</div>
<button class="editTaskButton" id="#task.TaskID">Edit Task</button>
</div>
}
You would adjust Index.cshtml like so:
#model IEnumerable<TaskManagementApplication.Models.Project>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div id="ProjectAccordionWrapper">
#foreach (var item in Model)
{
<div class="ProjectWrapper">
<h3>#item.Name</h3>
<div class="column">
<button class="createTaskButton" id="#item.ProjectID">Create New Task</button>
<div id="tasks-#item.ProjectID">
#Html.Action("Tasks", "Project", new { id = item.ProjectID })
</div>
</div>
</div>
}
</div>
//... the rest of the view
And finally,
// this should happen inside the callback of your .ajax() method
$('#tasks-'+projectID).load('/project/tasks/'+ projectID);

ASP.NET MVC 4 - Ajax Form - Passing value to the controller

Here is the final, which works! Thanks to bob-the-destroyer.
I just had to change this :
<script>
$(function () {
$('#formSearch').ajaxForm(function (result) {
$('#divArefresh').fadeOut('slow').fadeIn("slow").load('/Feed/Search');
});
});
</script>
Into this :
<script>
$(function () {
$('#formSearch').ajaxForm(function (result) {
$('#divArefresh').fadeOut('slow').fadeIn("slow").load(result);
});
});
</script>
EDIT: I thought that this :
// In /Feed/Index.cshtml
#using (Html.BeginForm("Search", "Feed", FormMethod.Post, new { id = "formSearch" }))
{
<input type="text" id="search" name="search" />
<input type="submit" value="save"/>
}
<script>
$(function () {
$('#formSearch').ajaxForm(function (result) {
$('#divArefresh').fadeOut('slow').fadeIn("slow").load('/Feed/Search');
});
});
</script>
With this :
// In Controller/Feed/
public ActionResult Search(string search)
{
if (!String.IsNullOrEmpty(search))
return Content("Variable : " + search);
else
return Content(":(");
return Content("Pas ajax :(");
}
Would do the trick, but it isn't. It always shows ":(". I'm really lost.
//////////////////////
I just wonder how to make this. I've tried many ways but I really don't manage to do it.
It's pretty easy to understand what I want to do :
I have a div which contains all the informations I want to show :
<div id="divArefresh">
<div id="accordion-container">
#foreach (var i in #ViewBag.feedsItem)
{
... Things ....
}
</div>
</div>
And I want to make a « search function », like this :
<!-- le champs de recherche -->
#{var options2 = new AjaxOptions()
{
Url = Url.Action("Search", "Feed"),
LoadingElementDuration = 200000,
OnComplete = "divSearch",
HttpMethod = "GET"
};
using (Ajax.BeginForm(options2))
{
<input type="text" name="search" id="search" placeholder="Votre recherche"/>
<input type="submit" id="submit" value="chercher"/>
}
}
Here is my « divSearch »
function divSearch() {
$('#divArefresh').fadeOut('slow').fadeIn("slow").load('/Feed/Search');
}
When I submit something, it goes fine in my action :
public ActionResult Search(string search)
{
Users user = db.UserProfiles.Find(Session["id"]);
if (Request.IsAjaxRequest())
{
var wordSearched = Request["search"].ToString(); --> NULL
var feeds = (from u in db.Feed
where u.UsersId == user.UsersId
select u).ToList(); --> FINE
var feedsItems = from u in db.FeedsItem
where u.Title.Equals(wordSearched)
select u;
ViewBag.feedsItem = feedsItems.ToList();
return PartialView("Search", feeds);
}
return PartialView("Search");
}
BUT this :
Request["search"].ToString();
is always null when I try with the debugger. Even the « search » variable is null
If someone have an idea on how to make this work...
Kai23

CKEditor Raw data to controller

I am using CKeditor in MVC 3 app.
Right now i am in need of saving text with HTML tags to DB, problem is that Ckeditors GetData() method returns raw format of data (http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#getData)
I need a way to make that raw format to normal string with Html tags
View :
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>TextEditionViewModel</legend>
#Html.DropDownListFor(model=>model.Id, Model.Texts)
<div class="editor-label">
#Html.LabelFor(model => model.Text)
</div>
<div class="editor-field">
#Html.TextAreaFor((model => model.Text), new { #Id = "editor1" })
#Html.ValidationMessageFor(model => model.Text)
</div>
<script type="text/javascript">
CKEDITOR.replace('editor1');
</script>
<script type="text/javascript">
var editor_data = CKEDITOR.instances['editor1'].getData();
var url = '#Url.Action("EditText1", "Admin")';
var data = { CommentText: editor_data };
function Save() {
alert(editor_data);
$.post(url, { CommentText: editor_data }, function (result) {
});
};
$('#Id').change(function () {
var selectedText = $(this).val();
if (selectedText != null && selectedText != '') {
$.getJSON('#Url.Action("Text","Admin")', { Id: selectedText }, function (text) {
CKEDITOR.instances['editor1'].setData(text);
});
}
});
</script>
</fieldset>
<p>
<input type="button" value="Save" onclick="Save()"/>
</p>
}
If editor_data is set to Normal "Text" string everything works!
Controller
public ActionResult EditText1(String CommentText)
{
return null;
}
You could decorate your controller action with the [ValidateInput] attribute to allow POSTing HTML tags which is not authorized by ASP.NET by default:
[HttpPost]
[ValidateInput(false)]
public ActionResult EditText1(string commentText)
{
return null;
}
UPDATE:
The problem is related to the fact that the editor_data variable is not accessible in the Save method.
You could do this:
<script type="text/javascript">
function Save() {
var editor_data = CKEDITOR.instances['editor1'].getData();
var url = '#Url.Action("EditText1", "Admin")';
var data = { CommentText: editor_data };
$.post(url, data, function (result) {
});
}
...
</script>

Categories

Resources