Dynamically adding Partial View using Ajax - javascript

I have created a partial view where i am using Bootstrap Glyphicon (collapse and expand) upon button click. But, the JavaScript code is not working here as I am
dynamically adding Partial View using Ajax.
My Controller:
public ActionResult DisplaySearchResults(int Id)
{
if (Id == 317)
{
return PartialView("~/Views/Shared/_PartialReportViews/StatisticalReport.cshtml");
}
else if (Id == 318)
{
return PartialView("~/Views/Shared/_PartialReportViews/Leading_Progeny.cshtml");
}
return PartialView();
}
My main View:
<div class="container">
<div id="partial"></div>
#section scripts{
<script type="text/javascript">
$('.search').click(function () {
var id = $(this).data('assigned-id');
var route = '#Url.Action("DisplaySearchResults", "Home")?id=' + id;
$('#partial').load(route);
});
var partial = $('#partial');
partial.on('shown.bs.collapse', '.collapse', function () {
$(this).closest('.group').find(".glyphicon-plus").removeClass("glyphicon-plus").addClass("glyphicon-minus");
}).on('hidden.bs.collapse', '.collapse', function () {
$(this).closest('.group').find(".glyphicon-minus").removeClass("glyphicon-minus").addClass("glyphicon-plus");
});
</script>
}
<input class="search btn-info" type="button" value="Search" data-assigned-id="#item.ProductId" />
</div>
My Partial View
<div class="group">
<button type="button" value="Button" data-toggle="collapse" data-target="#demo">
<span class="glyphicon glyphicon-plus"></span>
</button>
<div class="container">
<div class="row">
<div class=" col-sm-12">
#using (Html.BeginForm("Report", "Home", FormMethod.Get))
{
#Html.DisplayNameFor(m => m.Name)
#Html.TextBoxFor(m => m.Name, new { #class = "form-control", style = "width: 155px", placeholder = Html.DisplayNameFor(n => n.Name})
#Html.HiddenFor(m => m.Id)
}
</div>
<div id="demo" class="collapse">
<div class="col-sm-12">
#Html.DisplayNameFor(model => model.StartDate)
#Html.TextBoxFor(m => m.StartDate, new { #class = "form-control", style = "width: 155px", placeholder = Html.DisplayNameFor(n => n.StartDate) })
#Html.DisplayNameFor(model => model.Distance)
#Html.DropDownListFor(m => m.Distance, Model.DistanceOptions, "All", new { #class = "form-control", style = "width: 150px;" })
</div>
</div>
</div>
</div>
</div>
Can anyone please guide me where I am going wrong?

I believe you need to add the event listeners to the button instead. This appears to work.
$('#demo').on('shown.bs.collapse', function () {
debugger;
$(this).parent().prev('button').find(".glyphicon-plus").removeClass("glyphicon-plus").addClass("glyphicon-minus");
}).on('hidden.bs.collapse', function () {
debugger;
console.log('hide');
$(this).parent().prev('button').find(".glyphicon-minus").removeClass("glyphicon-minus").addClass("glyphicon-plus");
});
And here is a link to fiddle that simply outputs 'show' or 'hide' to your console.log to show that it does indeed work.
https://jsfiddle.net/wuvrp0y3/
Edit for clarification:
You may need to change the selectors used within the functions, as the context of $(this) is no longer valid.
After comments;
It appears that you are calling the $(document).ready function only once, on page load (as you should be), and the -new- partial view does not have the events registered.
I would suggest creating a function that sets up those events (also turning off those events beforehand, as so;
function SetUpCollapse(){
$('.collapse').off('click shown.bs.collapse hidden.bs.collapse');
//This is necessary to prevent multiple calls from triggering this event multiple times.
$('.collapse').on('click', 'shown.bs.collapse', function () {
debugger;
$(this).parent().prev('button').find(".glyphicon-plus").removeClass("glyphicon-plus").addClass("glyphicon-minus");
}).on('hidden.bs.collapse', function () {
debugger;
console.log('hide');
$(this).parent().prev('button').find(".glyphicon-minus").removeClass("glyphicon-minus").addClass("glyphicon-plus");
});
}
Then, in your document.ready, call it;
$(document).ready(function(){
SetUpCollapse();
});
I assume you use ajax to load your partial view. However you do that, there should be an 'on completion' function, simply call that same function within that as well.
IE,
$.ajax({
url: "SomeURLHere",
type: "POST",
data: {data: data},
dataType: "html",
success: function (html) {
//append html
SetUpCollapse();
},
error: function (xhr, ajaxOptions, thrownError) {
}
});

Are your event listeners possibly missing an event?
from
$('.collapse').on('shown.bs.collapse', function () {
to
$('.collapse').on('click', '.shown.bs.collapse', function () {

Related

CKEditor showing HTML tags in ASP.MVC with decode

Everything works perfectly with create/edit pages, where CKEditor encodes input and server side returns decoded for CKEditor to display.
All that goes out of the window when validation error occurs making page reload after it hit the server.
Even though I am decoding on return to the view, CKEditor won't properly render html tags.
If I do Html.Raw for the same field, I can see its showing html properly, so its no the issue with decoding. For the life of me I can't figure out why this case is any different from editing ( loading existing html into CKEditor from dB) which works perfectly. But on page reload it all goes out of whack.
Things I've tried, decoding, encoding, neither. Adding delay to CKEditor initialization.
Server side return code.
if (!ModelState.IsValid)
{
q..Text = System.Net.WebUtility.HtmlDecode(q.Text);
return View(q);
}
View
<div class="form-group">
#Html.LabelFor(model => model.Text, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.Text, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Question.Text, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Text, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.Raw(Model.Text)
</div>
</div>
JavaScript for CKEditor
var ckEditorInstance;
$(document).ready(function () {
CKEDITOR.replace('Text', { htmlEncodeOutput: true, enterMode: CKEDITOR.ENTER_BR });
ckEditorInstance = CKEDITOR.instances.Text;
ckEditorInstance.on('instanceReady', function () { UpdateTextArea(); });
ckEditorInstance.on('change', function () { UpdateTextArea(); });
});
function UpdateTextArea() {
ckEditorInstance.updateElement();
};
</script>
Using CKEditor v4.8.0 • 13-12-2017
Image to show the issue, below CKEditor #Html.Raw(Model.Text) output, showing that html is decoded properly.
Resolved this by using #Html.Raw(Model.Text) Instead of TextAreaFor
With #Html.HiddenFor(model=>Model.Text)
To preserve data when posting to server/controller
And Javascript to update hidden field and encode html
<script type="text/javascript">
var ckEditorInstance;
$(document).ready(function () {
CKEDITOR.replace('ckEditorRaw', { enterMode: CKEDITOR.ENTER_BR });
ckEditorInstance = CKEDITOR.instances.ckEditorRaw;
ckEditorInstance.on('instanceReady', function () { UpdateTextArea(); });
ckEditorInstance.on('change', function () { UpdateTextArea(); });
});
function UpdateTextArea() {
ckEditorInstance.updateElement();
//Set hidden field and escape html
$("#Question_Text").val(new Option((ckEditorInstance.getData())).innerHTML)
};
</script>

calling a button through javascript ASP.NET MVC dropdown list

I want to call a HTML button through a JavaScript function that responds on a drop down list change. But for some reason it's not finding the correct id.
#using (Ajax.BeginForm("GetReport", "Choices",
new AjaxOptions() {
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET",
UpdateTargetId = "reportResults",
}
)) {
#Html.DropDownList("q",(IEnumerable<SelectListItem>)ViewData["YearTermList"], htmlAttributes: new { #class = "form-control" })
<br />
#Html.DropDownList("ChartList", null, htmlAttributes: new { #class = "form-control" })
<br />
<input type="submit" style="display:none" id="ShowList" value="Search"/>
}
<script type="text/javascript">
$(document).ready(function () {
$("#YearTermList").change(function () {
$("#ShowList").click();
});
});
</script>
The JavaScript function doesn't submit the button on the drop down list change.
Selector $("#YearTermList") finds nothing, because the is no id YearTermList in markup.
You should either add id="YearTermList" where you want to add listener or change the selector of listener from #YearTermList to #q, #ChartList or other.

How to get selected value of dropdown when using partial view in mvc?

I am using partial view to display a view inside another and the partial view has the drodown so how to get the value of that dropdown actually i want to display another dropdown based on the value of the first dropdown here is my code in detail:
partial view:
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<link href="~/Content/control.css" rel="stylesheet" />
<fieldset>
<legend></legend>
<div class="editor-label">
#Html.LabelFor(model => model.CompanyID , new {#class="lbldis"})
</div>
<div class="editor-field">
#Html.DropDownListFor(Model => Model.CompanyID, new SelectList(ViewBag.CompanyList as System.Collections.IEnumerable, "_CompanyID", "Company"), "- Select -",new { #class = "txtbox",id="ddln" })
#Html.ValidationMessageFor(model => model.CompanyID)
</div>
<br />
<div>
#Html.DropDownListFor(Model => Model.ClientID, new SelectList(ViewBag.ClientList as System.Collections.IEnumerable, "_ClientID", "Company"), "- Select -",new { #class = "txtbox" })
#Html.ValidationMessageFor(model => model.ClientID)
</div>
</fieldset>
}
and the view where i am calling this partial view:and the name of that view is Index:
<div id="tab-1">
#Html.Partial("~/Views/PartialViews/_company.cshtml")
</div>
All the dropdowns are working fine and getting the values and all but only problem is with the javascript. Please help me on where to write the javascript i.e in partial view or in Index where I am calling my partial view and how to to display another dropdown based on the value of the first one.
What I have tried so far is below:
<script type="text/javascript">
$("#ddln").change(function onchange(dropdown) {
var myindex = dropdown.selectedIndex;
var SelValue = dropdown.options[myindex].value;
if (SelValue == 'Client3')
{
var see = document.getElementById("ddln");
see.style.display = "";
}
})
</script>
If you are using jquery you can handle controls of partial view from main view using on() function. Earlier (before 1.9) you could have used live() but this has been deprecated since.
$(document).ready(function () {
$('body').on("change", "#ddln", function (evt) {
if ($(this).val() != 'val1') //assume if val1 is the value against which we wish to show.
{
$('#ndl').show();
}
else
{
$('#ndl').hide();
}
});
});
To hide or display the 2nd dropdown based on a value in the first:
var clients = $('#ClientID');
$('#CompanyID').change(function() {
var id = $(this).val();
if (id == 'Client3') { // assume you want to hide it if the selected option value is 'Client3'
clients.hide();
} else {
clients.show();
}
});
Edit
Based on OP's last edit which changed the default id attribute from id="Company" to id="ddln", the code would be modified to
$('#ddln').change(function() { ...

Ajax form: OnSuccess, load partial div

I have this Ajax Form
#using(Ajax.BeginForm("AddAttendeeManual", "Attendee", new AjaxOptions { HttpMethod = "POST", OnSuccess = "doneManualEmail" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<div class="form-group">
#Html.TextBoxFor(m => m.SelectedManualEmail.Email, new {#class = "form-control",PlaceHolder="Email"})
</div>
<input type="submit" id="btnManual"class="btn btn-default" value="Add>>" />
}
and a div, both are on same view
<div id="invitedPeoples" data-url="#Url.Action("InvitedAttendees", "Attendee", new { appointmentId = Model.AppointmentId })">
</div>
Everytime the form is submitted, I wanted to load the div that should have a partial view.
This is what I have done
function doneManualEmail(isRequestSucceded) {
$(#Html.IdFor(m=>m.SelectedManualEmail.Email)).val('');
var url = $("#invitedPeoples").data('url');
$.get(url, function (data) {
$('#invitedPeoples').html(data);
});
};
everytime the form is submitted, i get forwarded to InvitedAttendees method, but my partial view doesn't show up.
The first line of the jquery works fine but the part to load partial view doesn't work.
Any thing I'm missing?
Error in Console:

Spring MVC ModelAndView attributes

Hi.
I`m trying to integrate Spring MVC with bootstrap modal - having filter region I want to select item from modal form and set it to the filter via jQuery ajax.
Main idea: show modal popup when user clicks on button to select item, this popup must allow user to search in the list (ajax) and click submit button to select item.
To refresh popup data I return ModelAndView with filtered list of items, and then, if user click 'submit', I send selected index to server where I can get id by index in the list, but ModelMap (and Model too) does not contain this list.
What am I doing wrong?
I have following structure:
Main JSP's:
main.jsp
....
<div class="override side-nav raised" id="filter">
<jsp:include page="filter.jsp"/>
</div>
....
filter.jsp
<f:form method="get" cssClass="search" action="${pageContext.request.contextPath}/search"
commandName="searchModel">
....
<div class="form-group">
<label class="control-label" for="searchDpt"><s:message code="label.department"/></label>
<div class="controls">
<f:input id="searchDpt" cssClass="form-control col-sm-8" cssStyle="width: 75%;" path="dept"/>
<button type="button" id="dsb_filter" class="btn btn-default col-sm-3" data-toggle="modal" data-target="#selectDeptModal"><span
class="glyphicon glyphicon-list"></span></button>
</div>
</div>
....
</f:form>
Modal window for item selection:
modal.jsp
<div id="selectDeptModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"
style="display: none;">
....
<div class="table-responsive" id="dept_table">
<jsp:include page="deptTable.jsp"/>
</div>
<button type="button" class="btn btn-default" onclick="selectDept();"><s:message code="label.select"/></button>
</div>
And jQuery code for ajax search and POSTing data:
function search() {
$.ajax({
url: "departments",
data: "name=" + $("#dpt_filter").val(),
success: function (response) {
$("#dept_table").html(response);
}
});
}
function getSelectedIndex() {
var table = $("#dept_table").find("table")
var selectedRows = table.find("tr.selected-row");
var elements = [];
if (selectedRows.length > 0) {
table.find("tr.selected-row td.index-col").each(function (i, el) {
elements.push(parseInt($(el).text()));
});
}
return elements;
}
function selectDept() {
var selected = getSelectedIndex()[0];
if (selected == undefined || selected.length == 0) {
$("#no_selection").removeClass("hidden");
return;
}
$('#selectDeptModal').modal('hide');
$.ajax({
type: "POST",
url: "deptSelected",
data: { index: selected},
success: function (response) {
$("#filter").html(response);
}
});
}
Controller methods for handling JavaScript:
#RequestMapping(method = RequestMethod.GET, value = "departments")
public ModelAndView getDepartments(#RequestParam(required = false) String name, Model model) {
LOG.debug(name);
model.addAttribute("dpts", departmentService.filterByName(name));
return new ModelAndView("selectDeptDialog/deptTable");
}
#RequestMapping(method = RequestMethod.POST, value = "deptSelected")
public ModelAndView deptSelected(#RequestParam Long index, ModelMap model) {
SearchModel sModel = (SearchModel) model.get("searchModel");
sModel.setDept(index);
Object depts = model.get("dpts");// = null
return new ModelAndView("filter", model);
}
But when getting list of departments in deptSelected it is null.
Thanks in advance!
ModelMaps don't keep their state between requests. You may, however, be able to get some of the same result using a #SessionAttribute, however, I don't think that will get your desired result, either.

Categories

Resources