I want to populate div with some data. This data is called with help of AJAX, JSON and controller function in asp.net mvc4.
My main goal is to append div with some data.
Here is markup
#using (Ajax.BeginForm(actionName: "GetEncryptedQuery", controllerName: "Home", ajaxOptions: new AjaxOptions {HttpMethod = "Post", OnBegin = "searchBegin", OnSuccess = "searchSuccess", OnFailure = "actionFailed"}, htmlAttributes: new Dictionary<string, object>(){{"id","frmSearch"},{"class","form-schedules"}}, routeValues: null))
{
#Html.ValidationSummary(true)
<div class="form-group">
<div class="form-control-wrapper">
#*<input type="text" class="form-control" id="search-origin" placeholder="Origin">*#
#Html.TextBoxFor(model=>model.Origin,new {#class="form-control",id="search-origin", placeholder="Origin"})
#Html.HiddenFor(model=>model.OriginId,new {#class="form-control",id="search-origin-id"})
</div>
</div>
<div class="form-group">
<div class="form-control-wrapper">
#*<input type="text" class="form-control" id="search-destination" placeholder="Destination">*#
#Html.TextBoxFor(model=>model.Destination,new {#class="form-control",id="search-destination", placeholder="Destination"})
#Html.HiddenFor(model=>model.DestinationId,new {#class="form-control",id="search-Destination-id"})
</div>
</div>
<button type="submit" class="btn btn-red pull-right">GO</button>
}
<!-- partial search origin ajax -->
<div class="search-origin-ajax list-below-origin" id="search-below-origin">
</div>
Here is AJAX Call
$(document).ready(
$("#search-below-origin").change(function(evt) {
if ($("#search-below-origin").val() != "-1") {
$.ajax({
type: 'GET',
dataType: 'json',
cache: false,
url: '/Home/PopulateLocation',
success: function(data) {
$.each(data, function(index, element) {
$.html('<a href="#" class="modal-select-origin"><span class="ajax-star"></span><span class="ajax-content">' + element.valueOf("Name") +
'</span><span class="ajax-icon-area"><span class="icon-area"></span></span></a>').appendTo("#search-below-origin");
});
}
});
}
}));
and here is a function in "home" controller
[HttpGet]
private ActionResult PopulateLocation()
{
var statesResults = from l in _db.Locations.AsParallel()
select new PseudoLocation()
{
Id = l.Id,
Name = l.Name
};
var statesList = Json(statesResults,JsonRequestBehavior.AllowGet);
return statesList;
}
A few problems:
You probably meant to make the method public:
[HttpGet]
public ActionResult PopulateLocation()
{
// ...
}
#search-below-origin is a div and does not appear to contain any elements that could trigger the change event. Did you mean #search-origin?
.html is an instance method on jQuery. You can create an in-memory html snippet just calling jQuery (using $), so you should not need to use .html here:
$('<a href="#" class="modal-select-origin"><span class="ajax-star"></span><span class="ajax-content">' + element.valueOf("Name") +
'</span><span class="ajax-icon-area"><span class="icon-area"></span></span></a>')
.appendTo("#search-below-origin");
Related
I am sorry for being unclear. Here's my code which I hope explain more
Controller:
[HttpPost]
public IActionResult Test(int classid)
{
return View();
}
View:
<form asp-action="Test">
#for (int i = 0; i < Model.Count(); i++)
{
var buttonid = "btnSubmit" + i;
#Html.TextBoxFor(model => Model[i].Name)
#Html.TextBoxFor(model => Model[i].ClassName)
<input name="submit" id="#buttonid" type="button" data-classid="#Model[i].ClassID" value="Go to class Form" class="btn btn-default MyButtonClass" style="font-size: 14px" />
}
<script>
$(document).on("click", ".MyButtonClass", function () {
var id = $(this).data("classid");
alert(id);
$.ajax({
type: "POST",
url: "/StudentController/Test",
data: { classid: id }
});
});
</script>
</form>
So what I wanted to do is when the user click the submit, it will redirect to another form which contain the className information (I know how to redirect to another page), however, the problem is that in another controller, I could only retrieve List and not the selected index className. Is there any method to retrieve the index when the user click submit?
Thanks
I've put an answer below which should hopefuly help you on your way.
First of all, build you your list of students in your controller.
public class TestController : Controller
{
public ActionResult Test()
{
var list = new List<Student>()
{
new Student()
{
Name = "Student1",
ClassID = 1,
ClassName = "ClassA"
},
new Student()
{
Name = "Student2",
ClassID = 2,
ClassName = "ClassB"
},
new Student()
{
Name = "Student3",
ClassID =3,
ClassName = "ClassC"
}
};
//You can call a service and populate your own data.
return View("Test", list);
}
}
Specify the views model
#model List<TestMVC.Student>
Then loop through each student, generating a unique id for each button and putting the classid (what ever key id you need) into the data-classid attribute.
#for (int i = 0; i < Model.Count(); i++)
{
var buttonid = "btnSubmit" + i;
#Html.TextBoxFor(model => Model[i].Name)
#Html.TextBoxFor(model => Model[i].ClassName)
<input name="submit" id="#buttonid" type="button" data-classid="#Model[i].ClassID" value="Go to class Form" class="btn btn-default MyButtonClass" style="font-size: 14px" />
<br/>
}
We also specify a new css class called "MyButton". This will serve the jquery selector.
<style>
.MyButtonClass {
color:red;
}
</style>
Then use Jquery to capture the button clicked, take off the id and post id as a parameter to which ever controller and action you want.
<script>
$(document).on("click", ".MyButtonClass", function () {
var id = $(this).data("classid");
alert(id);
$.ajax({
type: "POST",
url: "/YourController/YourAction",
data: {classid:id}
});
});
</script>
The line for "data". The "classid" must be the same name as the parameter on your controller. So the posted actions signature would be
[HttpPost]
public void YourAction (int classid)
{
}
Hope that helps.
Try this:
<div id="classList">
#for (int i = 0; i < Model.Count(); i++)
{
var buttonid = "btnSubmit" + i;
#Html.TextBoxFor(model => Model[i].Name)
#Html.TextBoxFor(model => Model[i].ClassName)
<button id="#buttonid" data-classid="#Model[i].ClassID" class="btn btn-default MyButtonClass">Go to class Form</butotn>
}
</div>
<script>
$(document).ready(function()
{
$(".MyButtonClass").on("click", function ()
{
var id = $(this).data("classid");
console.log(id);
$.ajax({
type: "POST",
url: "/StudentController/Test",
data: { classid: id },
success: function(data)
{
// put redirect in here
window.location = .....;
},
error: function()
{
// error handling
}
});
});
});//------- this was missing!!!!
</script>
In your controller:
[HttpPost]
public IActionResult Test(int classid)
{
// put debugger here so we know if we landed
return new { success=true};
}
You are using an ajax post so you probably just want data returned, not an entire view. Or do you? What exactly is supposed to happen when you get here?
<script>
$(function () {
var ajaxSubmit = function () {
var $form = $(this);
var settings = {
data: $(this).serialize(),
url: $(this).attr("action"),
type: $(this).attr("method")
};
$.ajax(settings).done(function (result) {
var $targetElement = $($form.data("ajax-target"));
var $newContent = $(result);
$($targetElement).replaceWith($newContent);
$newContent.effect("slide");
});
return false;
};
$("#search-form").submit(ajaxSubmit);
});
</script>
Ok, This script is for searching some content from databse. it works great, but only once. When im trying to hit submit again in my from, its not working again. Only when I refresh page.
Could someone help me?
My from in same index.cshtml file:
<div>
<form id="search-form" method="get" data-ajax="true" data-ajax-target="#zawartosc" data-ajax-update="#zawartosc">
<input id="search-filter" type="search" name="searchQuery"
data-autocomplete-source="#Url.Action("MiejscaPodpowiedzi", "Miejsce")"
placeholder="Wprowadź tekst, aby filtrować..." />
<input type="submit" id="send" value="Send" />
</form>
<div id="zawartosc">
#Html.Partial("_ListaMiejsc")
</div>
My controller:
public class HomeController : Controller
{
private DaneKontekst db = new DaneKontekst();
public ActionResult Index(string searchQuery = null)
{
var miejscaNaSwiecie = db.MiejscaNaSwiecie.Where(o => (searchQuery == null ||
o.NazwaMiejscaNaSwiecie.ToLower().Contains(searchQuery.ToLower()) ||
o.KrajMiejscaNaSwiecie.ToLower().Contains(searchQuery.ToLower()) ||
o.OpisMiejscaNaSwiecie.ToLower().Contains(searchQuery.ToLower()))).ToList();
var ViewModel = new HomeIndexViewModel()
{
MiejscaNaSwiecie = miejscaNaSwiecie
};
if (Request.IsAjaxRequest())
{
return PartialView("_ListaMiejsc", ViewModel);
}
return View(ViewModel);
}
Edited.
Because you are replacing the container. You should update only the content of that.
When you click for the first time, the response of the ajax call (the markup for the form) will replace the div (with id ="zawartosc"). So after this you do not have that div exist in your DOM any more. So your $targetElement is not going be the the container div (because it is gone !)
So instead of replacing the container div, simply update the content of that.
Replace
$($targetElement).replaceWith($newContent);
with
$($targetElement).html($newContent);
$($targetElement).html($newContent);
OR
$($targetElement).Load($newContent);
I have a dropdownlist for Page location with 2 values. When I select a value from the list and click on Save, the value is saved in the database. But when I reload the page, the value which is first in the selection criteria is shown and when I edit other values and click on Save, the value for Page location is also changed. The issue is, I want to see the value which I changed for the Page location when the page is refreshed. Below is my code. Function 'edit' is called when I click on edit of the Page location.
HTML Code:
<script id="editTemplate" type="text/x-kendo-template">
<div class = "row">
<div class="col-sm-8">
<label style="display:none;">Id:</label>
<input type="hidden" id='ID' class="k-textbox" value="#=node.id #" />
</div>
<div class="col-sm-8">
<label >PageLocation:</label>
<select id = "pl">
<option value="local">local</option>
<option value="New Window" >New Window</option>
</select>
</div>
<div class="col-sm-4">
<button id="save" class="k-button k-primary">Save</button>
</div>
</div>
JavaScript:
function edit(itemid){
var editTemplate = kendo.template($("#editTemplate").html());
var treeview = $("#treeview").data("kendoTreeView");
var selectedNode = treeview.select();
var node = treeview.dataItem(selectedNode);
$("<div/>")
.html(editTemplate({ node: node}))
.appendTo("body")
.kendoWindow({
modal: true,
deactivate: function () {
this.destroy();
}
})
.on("click", ".k-primary", function (e) {
var dialog = $(e.currentTarget).closest("[data-role=window]").getKendoWindow();
var textbox = dialog.element.find(".k-textbox");
var Id = $('#ID').val();
var PageLocation = $('#pl').val();
node.text = undefined;
node.set("Pagelocation", PageLocation);
node.set("id", Id);
dialog.close();
var treenode = treeview.dataSource.get(itemid);
treenode.set("Pagelocation", PageLocation);
treenode.set("id", Id);
treenode.PAGE_LOCATION = PageLocation;
treenode.ID = Id;
$.ajax({
url: "/Services/TreeServices.asmx/UpdateTree",
contentType: "application/json; charset=utf-8",
type: "POST",
datatype: "json",
//data: JSON.stringify({ "erpLinksJson": treenode, NodeId: nid, RoleId: rid })
data: JSON.stringify({ "LinksJson": treenode})
});
console.log(JSON.stringify(treenode));
})
}
Service:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public String UpdateTree(LinksJSON LinksJson)
{
using (var context = new Data.WebEntities())
{
context.Configuration.ProxyCreationEnabled = false;
var updNode = context.Links.Where(c => c.ID == LinksJson.ID).FirstOrDefault();
if (updNode != null)
{
updNode.ID = erpLinksJson.ID;
updNode.PAGE_LOCATION = erpLinksJson.PAGE_LOCATION;
context.SaveChanges();
}
JavaScriptSerializer JSON = new JavaScriptSerializer();
return JSON.Serialize(updNode);
}
}
This is the code I have written in View :
<div class="col-lg-12" style="margin-bottom: 20px;">
<div class="form-group">
<label class="col-sm-3 control-label" style=" margin-top: 14px; ">Domains <font size="3" color="red">*</font></label>
<br />
<div class="col-sm-4" style="width:50%;">
#Html.ListBoxFor(m => m.SelectedDomains, Model.AllDomains,
new { #class = "chosen", multiple = "multiple", id = "drpDomains", style = "width: 350px;",onchange="FillDomain();" })
</div>
</div>
</div>
<div class="col-lg-12" style="margin-bottom: 20px;">
<div class="form-group">
<label class="col-sm-3 control-label" style=" margin-top: 14px; ">Domains new categories <font size="3" color="red">*</font></label>
<br />
<div class="col-sm-4" style="width:50%;">
#Html.ListBoxFor(m => m.SelectedDomainCategories, Enumerable.Empty<SelectListItem>(),
new { #class = "select2", multiple = "multiple", id = "multidomaincategory", style = "width: 350px;" })
</div>
</div>
</div>
<link href="~/Scripts/MultiSelect/chosen.css" rel="stylesheet" />
For Domains, I have used Chosen plugin, and for categories, i have used select2 plugin
<script type="text/javascript">
$(".chosen-deselect").chosen({ allow_single_deselect: true });
$(".chosen").chosen().change();
$(".chosen").trigger('liszt:updated');
</script>
<script>
function FillDomain() {
$("#drpDomains option[value='']").removeAttr("selected");
var selectArr = [];
$('#drpDomains').each(function () {
selectArr.push($(this).val());
});
var a = JSON.stringify(selectArr);
var reference = this;
$.ajax({
url: #Url.Content("~/MyTemplate2/FillIndustry1"), //FillIndustry1 is a method in Controller
type: "POST",
dataType: "JSON",
data: { Domain: a },
success: function (DomainCategories) {
$("#multidomaincategory").html("");
$("#multidomaincategory").removeAttr("selected");
var s = JSON.stringify(DomainCategories);
var t = JSON.parse(s);
for (var key in t) {
$("#multidomaincategory").append("<option value=" + t[key]["Value"] + ">" + t[key]["Text"] + "</option>");
}
},
error: function (data) {
alert("failure error" + data);
var t = window.JSON.parse(data.d);
alert("failueee" + t);
}
});
//I'm trying to remove all the selected items from dependent dropdown (#multidomaincategory) when all items from Domains(#drpDomains) are cleared
if ($("#drpDomains").val() == null || $("#drpDomains").val() == "") {
$("#multidomaincategory").removeAttr("selected");
$("#multidomaincategory").css('display', 'none');
}
}
</script>
Controller :
[HttpPost]
public ActionResult FillIndustry1(string Domain)
{
JArray jsonMembersArr = (JArray)JsonConvert.DeserializeObject(Domain);//convert SymptomString from json string to array
ProfessionalTrans objprofessionaltrans = new ProfessionalTrans();
string listdomains = "";
foreach (var a in jsonMembersArr)
{
listdomains = string.Join(",", a);
}
var DomainCategories = objprofessionaltrans.GetDepCategories(listdomains);
return Json(DomainCategories.ToList());
}
Data Access Layer(Transaction):
public IEnumerable<SelectListItem> GetDepCategories(string domains)
{
//GetDepCategories method - To get categories based on Domains
PTS_CommonEntities objentity = new PTS_CommonEntities();
List<SelectListItem> allskills = new List<SelectListItem>();
List<GetCatListbasedDomain> catnames = objentity.usp_GetCatListBasedOnDomains(domains).ToList();
foreach (var it in catnames)
{
allskills.Add(new SelectListItem { Value = it.CategoryID.ToString(), Text = it.CategoryName });
}
return allskills.AsEnumerable();
}
When I am clearing(closing) the selected items in Domains, the respective Categories are cleared from list, but not in the text box
Image Before Clearing
Image After Clearing the Domains
As you can see, the list is being cleared, but the selected items are still being shown in the UI.
Can someone please find out why the items are being displayed even after clearing them???
Because you are trying to clear the wrong element. #multidomaincategory is the select2 list that holds all of the values, there is a dynamic span class that gets rendered to the page right after this element, look at the html that select2 produces in your browser. Try:
$('#multidomaincategory').next().find('li').html('');
They are cleared from the list because $("#multidomaincategory").html(""); clears the html of the list of categories, not the rendered text elements in the text box.
Although a better way: $('#multidomaincategory').select2('data', null)
I have list of divs with some data in there:
<div style="border: 1px solid #dddddd;">
<div id="wrap">
<h3 id="cText">#Model.CommentText</h3>
<a id="runEdit" href="#" >Edit</a>
</div>
</div>
When user click on runEdit link I make edit from this:
e.preventDefault();
var txt = $('#cText').text();
$('#cText').remove();
$('#wrap').prepend('<textarea>' + txt + '</textarea>');
$('#wrap').append('<input type="submit" value="Ok" />');
$('#wrap').append('<input type="submit" value="Cancel" />');
The problem is I added here this two buttons in javascript. But I don't know how to attach some controller action to this buttons?
The problem here is that if I write 5 comments. And click on edit I get 5 edit forms.
$('#editButton').live('click', function (e) {
e.preventDefault();
var container = $(this).closest('.commentWrap');
var itemId = container.attr('id');
var nestId = '#' + itemId;
var txt = $('#commentTextValue').text();
$(nestId + ' #commentTextValue').remove();
$(nestId + ' #editButton').remove();
$(nestId).prepend('<textarea id="editArea">' + txt + '</textarea>');
$(nestId).append('<input type="submit" value="Ok" class="btnOk" />');
})
$('.btnOk').live('click', function (e) {
e.preventDefault();
var container = $(this).closest('.commentWrap');
var itemId = container.attr('id');
var text = container.find('textarea').val();
var nestId = '#' + itemId;
//alert(nestId);
$.ajax({
url: '/Comment/SaveComment',
data: JSON.stringify({ CommentText: text, CommentId: itemId }),
type: 'post',
contentType: 'application/json',
success: function (data) {
if (data.success === true) {
//alert(data.message); // do show/hide stuff here instead of the alert
$(nestId + ' #editArea').remove();
$(nestId + ' .btnOk').remove();
$(nestId).append('<h3 id="commentTextValue">' + data.message + '</h3>');
$(nestId).append('<a id="editButton" href="#">Edit</a>');
}
}
});
});
</script>
<div style="border: 1px solid #dddddd;">
#Html.ActionLink(#Model.Author, "SomeAction")
<div class="commentWrap" id="#Model.CommentId">
<p id="commentTextValue">#Model.CommentText</p>
<a id="editButton" href="#">Edit</a>
</div>
</div>
First add an itemid to the div like this, and convert the id=wrap to a class, as there are more than one of them.
<div class="wrap" id="123"></div>
That way you get a way to reference the id of the item that you are editing.
You should also add a class to the submit button that you inject on the page, fx:
<input type="submit" class="btnOk" value="Ok"/>
Then you can hook up the javascript:
$('.btnOk').live('click',function(e){
e.preventDefault();
var container = $(this).closest('.wrap');
var itemId = container.attr('id');
var text = container.find('textarea')[0].val();
$.ajax({
url: '/mycontroller/savecomment',
data: JSON.stringify({comment: text, id:itemId}), // using JSON2, see below
type: 'post',
contentType: 'application/json',
success: function(data){
if(data.success===true){
alert(data.message); // do show/hide stuff here instead of the alert
}
}
});
});
NOTE: Download the json2 library and add it to you script references - it's a good way to do your json serialization. (https://github.com/douglascrockford/JSON-js)
In your controller you must add an action method to handle the request:
public ActionResult SaveComment(string text, int id)
{
//save your comment for the thing with that id
var result = new {success = true, message = "saved ok"};
return Json(result, JsonRequestBehavior.AllowGet);
}
The answer of Marc is collrect. Surround your code with this. However I strongly recommend you to make as much "html in html" rather than in JavaScript.
The above code could be translated to a better shape, like this,
<div style="border: 1px solid #dddddd;">
<div id="wrap">
<h3 id="cText">#Model.CommentText</h3>
<a id="runEdit" href="#" >Edit</a>
</div>
<div id="editPanel" style="display:none;">
<form action="#Url("Edit", "Whatevercontroller")">
<textarea name="CommentText">#CommentText</textarea>
<input type="submit" value="Ok" />
Cancel
</form>
</div>
</div>
and js would be
function StartEdit() {
$("#wrap").css("display", "none");
$("#editPanel").css("display", "block");
}
function CancelEdit() {
$("#wrap").css("display", "block");
$("#editPanel").css("display", "none");
}
the advantage of this approach that you do not generate too much DOM elements in this case. Otherwise chances tha your JavaScript will become absolutely unmanageable.
You have to put a form tag around your textarea and to set the action of the form by the #Url.Action helper to the needed action.
You need to make Ajax calls to your controller action. Please refer to below link :
http://tugberkugurlu.com/archive/working-with-jquery-ajax-api-on-asp-net-mvc-3-0-power-of-json-jquery-and-asp-net-mvc-partial-views
You will find a sample there.
Basically, what you need to do is as follows:
var d = "poo=1&bar=2";
$.ajax({
type: "POST",
url: "/home/myaction",
data: d,
success: function (r) {
alert(r.data);
},
complete: function () {
alert("I am done!");
},
error: function (req, status, error) {
//do what you need to do here if an error occurs
alert("error");
}
});