JQuery - Callback Dropdownlist load - javascript

I need to select a value from a Dropdownlist after it has been loaded:
EDIT: In the script associated with the View I have:
//Dropdown cascade call when trigger is called and fill councilDropdown:
$("#districtDropdown").cascade({
url: "/Address/ListCouncilByDistrict",
paramName: "districtId",
firstOption: 'Selecione o Concelho...',
childSelect: $("#councilDropdown")
});
$("#PostalCode").keyup(function () {
loadPTPostalCode();
});
$("#PostalCodeExtension").keyup(function () {
loadPTPostalCode();
});
function loadPTPostalCode()
{
if ($("#PostalCode").val() >= 1000) {
$.ajax({
url: '/Address/GetPTPostalCode',
type: "POST",
dataType: "json",
data: { postalCode: $("#PostalCode").val(), postalCodeExtension: $("#PostalCodeExtension").val() },
success: function (data) {
if (data != null) {
$("#districtDropdown").val(data.PTDistrict_Id); // Set the Dropdown value
$('#districtDropdown').trigger('change'); // Trigger (force the dropdown to load
// *** This is done to soon, the dropdownlist of the Councils is not all loaded yet ***
$("#councilDropdown").val(data.PTCouncil_Id);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus)
}
});
}
}
EDIT: The View
#model Heelp.ViewModels.AddressPTViewModel
<h2>Create</h2>
#using (Ajax.BeginForm(MVC.Address.CreateAddressPT(), new AjaxOptions { OnSuccess = "showLoginConfirmationResultMessage" }, new { #id = "AddressForm" }))
{
#Html.AntiForgeryToken()
<div class="address1">
#Html.LabelFor(model => model.Address1)
#Html.TextBoxFor(model => model.Address1)
#Html.ValidationMessageFor(model => model.Address1)
</div>
<div class="address2">
#Html.TextBoxFor(model => model.Address2)
#Html.ValidationMessageFor(model => model.Address2)
</div>
<div class="city">
#Html.LabelFor(model => model.City)
#Html.TextBoxFor(model => model.City)
#Html.ValidationMessageFor(model => model.City)
</div>
<div class="postalCode">
#Html.DisplayNameFor(m => m.PostalCode)
#Html.TextBoxFor(m => m.PostalCode, new { #Value = "" })
#Html.ValidationMessageFor(m => m.PostalCode)
</div>
<div class="postalCodeExtension">
#Html.LabelFor(model => model.PostalCodeExtension)
#Html.TextBoxFor(model => model.PostalCodeExtension)
#Html.ValidationMessageFor(m => m.PostalCodeExtension)
</div>
<div class="postalCodeCity">
#Html.LabelFor(model => model.PostalCodeCity)
#Html.TextBoxFor(model => model.PostalCodeCity)
#Html.ValidationMessageFor(m => m.PostalCodeCity)
</div>
<div id="district">
#Html.DisplayNameFor(m => m.PTDistrict_Id)
#Html.DropDownListFor(m => m.PTDistrict_Id, Model.PTDistrictList, HeelpResources.PTDistrictViewDropDownListFirstRecord, new { id = "districtDropdown" })
#Html.ValidationMessageFor(m => m.PTDistrict_Id)
</div>
<div id="council">
#Html.DisplayNameFor(m => m.PTCouncil_Id)
#Html.DropDownListFor(m => m.PTCouncil_Id, Model.PTCouncilList, HeelpResources.PTCouncilViewDropDownListFirstRecord, new { id = "councilDropdown" })
#Html.ValidationMessageFor(m => m.PTCouncil_Id)
</div>
<p>
<input type="submit" value="Create" />
</p>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
EDIT:
Cascade Function:
// Cascade function
(function ($) {
$.fn.cascade = function (options) {
var defaults = {};
var opts = $.extend(defaults, options);
return this.each(function () {
$(this).change(function () {
var selectedValue = $(this).val();
if (selectedValue == '') {
opts.childSelect.empty();
return;
}
var params = {};
params[opts.paramName] = selectedValue;
$.post(opts.url, params, function (items) {
//$.getJSON(opts.url, params, function (items) {
opts.childSelect.empty();
if (opts.firstOption != "")
opts.childSelect.append(
$('<option/>')
.attr('value', '')
.text(opts.firstOption));
$.each(items, function (index, item) {
// alert(opts.firstOption);
opts.childSelect.append(
$('<option/>')
.attr('value', item.Id)
.text(item.Name)
);
});
});
});
});
};
})(jQuery);
But when I do that, as the Dropdownlist is not still loaded, the val() is not there yet.
For example, if I put an alert message before, it works fine because it as time to load the dropdown.
How can I set the value of the council dropdown only after the dropdown is loaded?

As your requirement "set the value of the council dropdown only after the dropdown is loaded".
You need perform synchronous Ajax request. You can specify the async option to be false to get a synchronous Ajax request.
$.ajax({
url: '/Address/GetPTPostalCode',
type: "POST",
dataType: "json",
data: { postalCode: $("#PostalCode").val(), postalCodeExtension: $("#PostalCodeExtension").val() },
success: function (data) {
if (data != null) {
$("#districtDropdown").val(data.PTDistrict_Id);
$('#districtDropdown').trigger('change');
// *** This is done to soon, the dropdownlist of the Councils is not all loaded yet ***
$("#councilDropdown").val(data.PTCouncil_Id);
}
},
async: false
});

I would update the cascade plugin to trigger an event when the ddl is updated.
(function ($) {
$.fn.cascade = function (options) {
var defaults = {};
var opts = $.extend(defaults, options);
return this.each(function () {
$(this).change(function () {
// #### store reference to changed element for later ####
var self = this,
selectedValue = $(this).val();
if (selectedValue == '') {
opts.childSelect.empty();
return;
}
var params = {};
params[opts.paramName] = selectedValue;
$.post(opts.url, params, function (items) {
//$.getJSON(opts.url, params, function (items) {
opts.childSelect.empty();
if (opts.firstOption != "")
opts.childSelect.append(
$('<option/>')
.attr('value', '')
.text(opts.firstOption));
$.each(items, function (index, item) {
// alert(opts.firstOption);
opts.childSelect.append(
$('<option/>')
.attr('value', item.Id)
.text(item.Name)
);
});
// #### Trigger event ####
self.trigger("update");
});
});
});
};
})(jQuery);
now you can bind to that:
...
// *** #### fixed #### This is done to soon, the dropdownlist of the Councils is not all loaded yet ***
$("#councilDropdown").on("updated",function(){
$(this).val(data.PTCouncil_Id);
});
}

I would say there are two approaches here.
1
The best practice would just be to add a callback functionality to your cascade. It could be done like this:
...
$.post(opts.url, params, function (items) {
//$.getJSON(opts.url, params, function (items) {
opts.childSelect.empty();
if (opts.firstOption != ""){
opts.childSelect.append(
$('<option/>')
.attr('value', '')
.text(opts.firstOption));
$.each(items, function (index, item) {
// alert(opts.firstOption);
opts.childSelect.append(
$('<option/>')
.attr('value', item.Id)
.text(item.Name)
);
});
if( typeof(opts.callback) == "function" )opts.callback();//issue callback
}
});
...
It would be used by setting up cascade here:
$("#districtDropdown").cascade({
url: "/Address/ListCouncilByDistrict",
paramName: "districtId",
firstOption: 'Selecione o Concelho...',
childSelect: $("#councilDropdown"),
callback: function(){ districtCallback(); }
});
and defined in whatever manner you wanted like this:
function districtCallback(){
$("#councilDropdown").val($("#districtDropdown").val());
}
2
Quick and dirty.. jsFiddle demo
success: function (data) {
if (data != null) {
$("#districtDropdown").val(data.PTDistrict_Id); // Set the Dropdown value
$('#districtDropdown').trigger('change'); // Trigger (force the dropdown to load
(function councilVal(){
if( typeof($("#councilDropdown").val()) != "undefined" ){
$("#councilDropdown").val(data.PTCouncil_Id);
}else{
setTimeout(councilVal,50);
}
})()
}
}

Try creating two events on dropdown 1. custom event and 2. change event
When user manually changes then dropdown value then change event will be fired.
$('#dictrctDropdown').change(function (event){
$('#dictrctDropdown').trigger('custom');
});
$('#dictrctDropdown').on('custom', function (event, param1){
// Load council dropdown
if(param1){
$("#councilDropdown").val(param1);
}
});
from "/Address/GetPTPostalCode" success call back raise custom event for "dictrctDropdown"
function loadPTPostalCode()
{
if ($("#PostalCode").val() >= 1000) {
$.ajax({
url: '/Address/GetPTPostalCode',
type: "POST",
dataType: "json",
data: { postalCode: $("#PostalCode").val(), postalCodeExtension: $("#PostalCodeExtension").val() },
success: function (data) {
if (data != null) {
$.getJSON('disctrictURL','data to post (if any)',function(response){
//Load district dropdown
/*
$.each(items, function (index, item) {
// alert(opts.firstOption);
opts.childSelect.append(
$('<option/>')
.attr('value', item.Id)
.text(item.Name)
);
});
*/
$("#districtDropdown").val(data.PTDistrict_Id); // Set the Dropdown value
});
//Now use district id load council dropdown and set value
$.getJSON('councilURL','data to post (if any)',function(response){
//Council dropdown
$("#districtDropdown").val('council id'); // Set the Dropdown value
});
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus)
}
});
}
Hope this will help !

Related

dropdown not populating after ajax call in mvc5 platform

Have a good day. I here because of I am suffering a problem. That is I am working with a cascade dropdown in a user controller. When I change the MotherCompany then Division will appear as per mothercompany. My Controller end code is working fine. But in Front End Dropdown is not populating. What I am doing wrong can Anybody help me please. ( Sorry for my BAD English )
controller code:
[HttpPost]
public JsonResult getDivision(int id)
{
var division = db.Divisions.Where(x => x.MotherCompanyId == id).ToList();
List<SelectListItem> listDivision = new List<SelectListItem>();
listDivision.Add(new SelectListItem { Text = "--Select State--", Value = "0" });
if (division != null)
{
foreach (var x in division)
{
listDivision.Add(new SelectListItem { Text = x.Name, Value = x.Id.ToString() });
}
}
return Json(new SelectList(listDivision, "Value", "Text"), JsonRequestBehavior.AllowGet);
}
My Javascript here:
<script type="text/javascript">
$(document).ready(function () {
$("#MotherCompanyId").change(function () {
$("#divisionId").empty();
$.ajax({
url: '#Url.Action("getDivision")',
async: true,
type: "POST",
dataType: "json",
data: { id: $("#MotherCompanyId").val() },
success: function (data) {
$.each(data, function (i, val) {
$('select#divisionId').append(
$("<option></option>")
.attr("Value", val.Value)
.text(val.Text));
});
},
error: function (xhr) {
alert(" An error occurred.");
},
});
return false;
})
});
View: `
<div class="form-group MotherCompanyId">
#Html.LabelFor(model => model.MotherCompanyId, new { #class = "" })
#Html.DropDownList("MotherCompanyId", ViewBag.MotherCompanyId as SelectList, "Select a MotherCompany", htmlAttributes: new { required = "required", style = "display:none;width:100%;" })
#Html.StarkDropDownAjaxLink("/MotherCompany/Create", "AddMore", "")
</div>
<div class="form-group DivisionId">
#Html.LabelFor(model => model.DivisionId, new { #class = "" })
#Html.DropDownList("divisionId", new SelectList(string.Empty, "Value", "Text"), "--Select Division--", new { style = "display:none;width:100%;" })
#Html.StarkDropDownAjaxLink("/Division/Create", "AddMore", "")
</div>`

Knockout children of children loading/options in MVC

I have problem loading children to my option list.
I create an order but I cannot Edit. It will not load the dropdownlists.
My goal is when I press Edit on an order.
It will have selected the current product in the dropdownlist on the orderitem.
And I want to put the price from Product Model to the view(when choosing an item from dropdownlist)
Is there any other way to populate the dropdownlist?
I will upload pictures.
Here is my code javascript code.
var Products = [];
//fetch categories from database
function LoadProducts(element) {
if (Products.length == 0) {
//ajax function for fetch data
$.ajax({
type: "GET",
url: '/Sales/GetProducts',
success: function (data) {
Products = data;
//render catagory
renderProducts(element);
}
})
}
else {
alert("else");
//render catagory to the element
renderProducts(element);
}
}
function renderProducts(element) {
var $ele = $(element);
$ele.empty();
$ele.append($('<option/>').val('0').text('Select'));
$.each(Products, function (i, val) {
$ele.append($('<option/>').val(val.ProductId).text(val.ProductName));
})
}
var Seats = [];
//fetch categories from database
function LoadSeats(element) {
if (Seats.length == 0) {
//ajax function for fetch data
$.ajax({
type: "GET",
url: '/Sales/GetSeats',
success: function (data) {
Seats = data;
//render catagory
renderSeats(element);
}
})
}
else {
//render catagory to the element
renderSeats(element);
}
}
function renderSeats(element) {
var $ele = $(element);
$ele.empty();
$ele.append($('<option/>').val('0').text('Select'));
$.each(Seats, function (i, val) {
$ele.append($('<option/>').val(val.SeatId).text(val.SeatPlace));
})
}
var Employees = [];
//fetch categories from database
function LoadEmployees(element) {
if (Employees.length == 0) {
//ajax function for fetch data
$.ajax({
type: "GET",
url: '/Sales/GetEmployees',
success: function (data) {
Employees = data;
//render catagory
renderEmployees(element);
}
})
}
else {
//render catagory to the element
renderEmployees(element);
}
}
function renderEmployees(element) {
var $ele = $(element);
$ele.empty();
$ele.append($('<option/>').val('0').text('Select'));
$.each(Employees, function (i, val) {
$ele.append($('<option/>').val(val.EmployeeId).text(val.EmployeeName));
})
}
var PaymentMethods = [];
//fetch categories from database
function LoadPaymentMethods(element) {
if (PaymentMethods.length == 0) {
//ajax function for fetch data
$.ajax({
type: "GET",
url: '/Sales/GetPaymentMethods',
success: function (data) {
PaymentMethods = data;
//render catagory
renderPaymentMethods(element);
}
})
}
else {
//render catagory to the element
renderPaymentMethods(element);
}
}
function renderPaymentMethods(element) {
var $ele = $(element);
$ele.empty();
$ele.append($('<option/>').val('0').text('Select'));
$.each
(PaymentMethods, function (i, val) {
$ele.append
($('<option/>')
.val(val.PaymentMethodId)
.text(val.PaymentMethodType));
})
}
var ObjectState = {
Unchanged: 0,
Added: 1,
Modified: 2,
Deleted: 3
};
LoadProducts($('#productCategory'));
var salesOrderItemMapping = {
'SalesOrderItems': {
key: function (salesOrderItem) {
// alert("Salesorderitem mapping key");
return ko.utils.unwrapObservable(salesOrderItem.SalesOrderItemId);
},
create: function (options) {
console.log(options);
return new SalesOrderItemViewModel(options.data);
}
}
};
//var productItemMapping = {
// 'Products': {
// key: function(product) {
// return ko.utils.unwrapObservable(product.ProductId);
// },
// create: function(options) {
// return new SalesOrderViewModel(options.data);
// }
// }
//};
// ko.mapping.fromJS(data, productItemMapping, SalesOrderViewModel);
SalesOrderItemViewModel = function (data) {
//alert("salesorder item view"); // funkade
var self = this;
ko.mapping.fromJS(data, salesOrderItemMapping, self);
//dd: ko.observableArray(Products);
self.itemss = ko.observableArray(Products);
self.selectedItem = ko.observable(Products.ProductId);
//self.product1 = ko.observableArray(Products());
//self.dd = ko.observableArray(function() {
// //data.ProductId = data.Products.ProductId;
// return self.Products();
//});
self.flagSalesOrderAsEdited = function() {
if (self.ObjectState() !== ObjectState.Added) {
self.ObjectState(ObjectState.Modified);
}
// alert("salesorder item view if");
return true;
};
};
SalesOrderViewModel = function (data) {
var self = this;
ko.mapping.fromJS(data, salesOrderItemMapping, self);
//alert("salesorder view model"); // funkade
self.save = function () {
$.ajax({
url: "/Sales/Save/",
type: "POST",
data: ko.toJSON(self),
contentType: "application/json",
success: function (data) {
if (data.salesOrderViewModel !== null)
ko.mapping.fromJS(data.salesOrderViewModel, {}, self);
if (data.newLocation !== null)
window.location = data.newLocation;
}
});
},
self.flagSalesOrderAsEdited = function () {
if (self.ObjectState() !== ObjectState.Added) {
self.ObjectState(ObjectState.Modified);
}
return true;
},
self.deleteSalesOrderItem = function(salesOrderItem) {
self.SalesOrderItems.remove(this);
if (salesOrderItem.SalesOrderItemId() > 0 &&
self.SalesOrderItemsToDelete.indexOf
(salesOrderItem.SalesOrderItemId()) === -1)
self.SalesOrderItemToDelete.push(SalesOrderItemId());
}
self.addSalesOrderItem = function () {
// alert(" add salesorder item"); // funkade
var salesOrderItem = new SalesOrderItemViewModel(
{ SalesOrderItemId: 0, ProductId: 1, Quantity: 1,
ObjectState: ObjectState.Added });
self.SalesOrderItems.push(salesOrderItem);
};
};
//UnitPrice: 1
LoadSeats($('#SeatId'));
LoadEmployees($('#EmployeeId'));
LoadPaymentMethods($('#PaymentMethodId'));
Here is my Edit Partial view.
<table class="table table-striped">
<tr>
<th>Product Name</th>
<th>Quantity</th>
#*<th>Unit Price</th>*#
<th><button class="btn btn-info btn-xs"
data-bind="click: addSalesOrderItem">Add</button></th>
</tr>
<tbody data-bind="foreach: SalesOrderItems">
<tr>
<td>
#*<select id="productCategory" class="pc form-control"
data-bind="value: ProductId">
<option>Select</option>
</select>*#
#*<select data-bind="options: $parent.product1,
optionsText: 'ProductName', optionsValue: 'ProductId',
value: ProductId"></select>*#
<select data-bind=
"options: itemss, optionsText: 'ProductName',
value: ProductId, optionsValue: 'ProductId',
selectedOption: selectedOption"> </select>
</td>
#*<td class="form-group">
<input class="form-control input-sm" data-bind="value: ProductId" /></td>*#
<td class="form-group">
<input class="form-control input-sm" data-bind="value: Quantity"/></td>
#*<td class="form-group">
<input class="form-control input-sm" data- bind="text: UnitPrice"/></td>*#
<td class="form-group">Delete</td>
</tr>
</tbody>
</table>
Here it is when I create
Here it is when I Edit an order
And I get this problem when I save
I have problem loading children to my option list.
I create an order but I cannot Edit. It will not load the dropdownlists.
My goal is when I press Edit on an order.
It will have selected the current product in the dropdownlist on the orderitem.
And I want to put the price from Product Model to the view(when choosing an item from dropdownlist)
I will upload pictures.
I would like a road to follow. I am new to knockout/mvc and I cant find examples on mapping. I would appriatiate any feedpack or steps I can use.
If you need more from me, just write.
Thank you!!!
This is my Create View btw(how it is linked to knockout)
#model TheSolution.Domain.viewModels.SalesOrderViewModel
#using System.Web.Script.Serialization
#{
ViewBag.Title = "Create Sales Order";
}
#{
string data = new JavaScriptSerializer().Serialize(Model);
}
#section scripts
{
<script src="~/Scripts/knockout-3.4.0.js"></script>
<script src="~/Scripts/knockout.mapping-latest.js"></script>
<script src="~/Scripts/salesorderviewmodel.js"></script>
<script type="text/javascript">
var salesOrderViewModel = new SalesOrderViewModel(#Html.Raw(data));
ko.applyBindings(salesOrderViewModel);
</script>
}
#Html.Partial("_EditSalesOrder");
Since Ajax is loading asyc. It didnt had the time to load.
To fix the Edit problem with loading my Dropdown list. I used an ajaxStop in the Views(Create and Edit) It waits until ajax have loaded before GET the view
Here is the code
$(document).ajaxStop(function (event, request, settings) {
var salesOrderViewModel = new SalesOrderViewModel(#Html.Raw(data));
ko.applyBindings(salesOrderViewModel);
});
And with the price I had to do an ko ArrayFirst to match the ProductId observable with the ProductId in the Products Array(the one I loaded with Ajax)
And it would return the UnitPrice value from that row in the model.
This is how it looks like.
self.findItem = function () {
console.log(self.itemss().length);
var thePrice = ko.utils.arrayFirst(self.itemss(), function (item) {
return item.ProductId === self.ProductId();
}).UnitPrice;
console.log(thePrice);
return thePrice * self.Quantity();
}

Kendo ui aspnet mvc grid bind json object returned from action to new row

I have autocomplete control on my grid. After selecting an element from autocomplete I call an event select "onSelectArticle" to import the object using LineBonLivraison_Add action and want to bind it as a json object and not just set values to columns.
The problem happens only to a new added row. For example, when I edit existing rows I can get the properties of the selected object and set values to it like (var item = grid.dataItem(select); item.set("Document", data.Document);) but for new a new row, "item" is null
#section LinesTab {
<style>
.k-widget .templateCell
{
overflow: visible;
}
</style>
<script>
function initMenus(e) {
$(".templateCell").each(function () {
eval($(this).children("script").last().html());
});
}
function onEditGrid(editEvent) {
// Ignore edits of existing rows.
if (!editEvent.model.isNew() && !editEvent.model.dirty) {
//alert("not new dirty")
return;
}
editEvent.container
.find("input[name=Document]") // get the input element for the field
.val("100") // set the value
.change(); // trigger change in order to notify the model binding
}
</script>
<div class="lines-tab-doc">
#(Html.Kendo().Grid<LineBonLivraison>()
.Name("grid-lines-doc")
// Declare grid column
.Columns(columns =>
{
// Cretae all the columns base on Model
columns.Bound(l => l.Article).EditorTemplateName("AutoCompleteArticle");
columns.Bound(l => l.Designation);
columns.Bound(l => l.Quantite);
columns.Bound(l => l.Unite);
columns.Bound(l => l.Commentaire);
columns.Bound(l => l.ReferenceExterne);
columns.Bound(l => l.Commentaire2);
// Edit and Delete button column
columns.Command(command =>
{
command.Edit();
command.Destroy();
}).Width(200);
})
.Events(ev => ev.DataBound("initMenus").Edit("onEditGrid"))
.DataSource(datasoure => datasoure.Ajax()
.Batch(true)
.Model(model =>
{
//model.Id(l => l.Document);
model.Id(l => l.Ligne);
})
.Read(read => read.Action("LinesBonLivraison_Read", "Achat"))
.Create(create => create.Action("LinesBonLivraison_Add", "Achat"))
.Update(update => update.Action("LinesBonLivraison_Update", "Achat"))
.Destroy(delete => delete.Action("LinesBonLivraison_Delete", "Achat"))
.PageSize(10)
)
// Add tool bar with Create button
.ToolBar(toolbar =>
{
toolbar.Create();
toolbar.Save();
})
// Set grid editable.
.Editable(editable => editable.Mode(GridEditMode.InCell).CreateAt(GridInsertRowPosition.Bottom))
.Scrollable(scr => scr.Height(327))
.Sortable()
.Selectable(sel => sel.Mode(GridSelectionMode.Single).Type(GridSelectionType.Row))
.Navigatable()
.Pageable(pageable =>
{
pageable.Refresh(true);
pageable.PageSizes(true);
pageable.Messages(msg => msg.Empty(null));
})
)
</div>
}
AutoComplete Template
<script>
function onSelectArticle(e) {
var dataItem = this.dataItem(e.item.index());
var url = '#Url.Action("LineBonLivraison_Add", "Achat")';
$.ajax({
url: url,
data: {
doc: $("#Numero").val(),
line: e.item.index(),
article: dataItem.Code
}, //parameters go here in object literal form
type: 'GET',
datatype: 'json',
success: function (data) {
if (data == null)
//document.getElementById('labelx').innerHTML = "null";
else {
var grid = $("#grid-lines-doc").data("kendoGrid");
var select = grid.select();
var item = grid.dataItem(select); //prob if it a new row item is null
item.set("Document", data.Document);
item.set("Ligne", data.Ligne);
item.set("Article", data.Article);
//grid.refresh();
}
},
error: function (req, status, error) {
//document.getElementById('labelx').innerHTML = error;
}
});
}
function onAutoComplete() {
return {
text: $("#Article").val()
};
}
<div>
#(Html.Kendo().AutoComplete()
.Name("Article")
.HtmlAttributes(new { style = "width:" + width + ";" })
.DataTextField("Code")
.Filter(FilterType.Contains)
.Enable(enable)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetArticles", "Fiche").Data("onAutoComplete");
})
.ServerFiltering(true);
})
.Events(e =>
{
e.Select("onSelectArticle");
})
)
Action
public JsonResult LineBonLivraison_Add(int? doc, int? line, string article)
{
Models.Achat.LineBonLivraison l = new Models.Achat.LineBonLivraison()
{
Document = doc,
Article = article,
//Fournisseur = doc.Nom,
Ligne = line,
StyleLigne = "Style1",
ReferenceExterne = article
};
return Json(l, JsonRequestBehavior.AllowGet);
}

MVC jquery autocomplete multiple values working for first time only

i trying to autocomplete multiple values in my mvc project , but it autocomplete for first value and second nothing occurred
my view code :
#Html.TextBox("SentUsers", "", new { #class = "text-box"})
#Html.Hidden("UsersId")
java script code :
<script type="text/javascript">
var customData = null;
var userId;
$(function () {
$("#SentUsers")
.bind("keydown", function (event) {
if (event.keyCode === $.ui.keyCode.TAB &&
$(this).data("ui-autocomplete").menu.active) {
event.preventDefault();
}
})
.autocomplete({
minLength: 2,
source: function (request, response) {
$.ajax({
url: "/Ajax/AutoCompleteUsers",
type: "POST",
dataType: "json",
data: { term: request.term },
success: function (data) {
alert(data);
customData = $.map(data, function (item) {
userId = item.UserId;
return { label: item.Name + "(" + item.Email + ")", value: item.Name }
});
response(customData, extractLast(request.term))
}
})
},
focus: function () {
// prevent value inserted on focus
return false;
},
select: function (event, ui) {
var usersIdVal = $("#UsersId").val();
usersIdVal += ", " + userId;
$("#UsersId").val(usersIdVal)
var terms = split(this.value);
// remove the current input
terms.pop();
// add the selected item
terms.push(ui.item.value);
// add placeholder to get the comma-and-space at the end
terms.push("");
this.value = terms.join(", ");
return false;
}
});
});
function split(val) {
return val.split(/,\s*/);
}
function extractLast(term) {
return split(term).pop();
}
controller code :
public JsonResult AutoCompleteUsers(string term)
{
var result = (from r in db.UserItems
where r.Name.ToLower().Contains(term.ToLower())
select new { r.Name, r.Email, r.UserId }).Distinct();
return Json(result, JsonRequestBehavior.AllowGet);
}
when i trying static javascript array the autocomplete multiple values working perfect !
i think error may be in this block , but i dont know the solution
customData = $.map(data, function (item) {
userId = item.UserId;
return { label: item.Name + "(" + item.Email + ")", value: item.Name }
});
Thanks every body who tried to solve my question , and who isnt, i solved my question, and here is the solution for everybody:
my view code :
#Html.TextBox("SentUsers", "", new { #class = "text-box"})
#Html.Hidden("UsersId")
my javascript code :
<script type="text/javascript">
$(function () {
$("#SentUsers")
.bind("keydown", function (event) {
if (event.keyCode === $.ui.keyCode.TAB &&
$(this).data("ui-autocomplete").menu.active) {
event.preventDefault();
}
})
.autocomplete({
minLength: 2,
source: function( request, response ) {
$.getJSON("/Ajax/AutoCompleteUsers", {
term: extractLast( request.term )
}, response );
},
search: function () {
// custom minLength
var term = extractLast(this.value);
if (term.length < 2) {
return false;
}
},
focus: function () {
// prevent value inserted on focus
return false;
},
select: function (event, ui) {
var usersIdVal = $("#UsersId").val();
usersIdVal += ", " + ui.item.userId;
$("#UsersId").val(usersIdVal)
var terms = split(this.value);
// remove the current input
terms.pop();
// add the selected item
terms.push(ui.item.value);
// add placeholder to get the comma-and-space at the end
terms.push("");
this.value = terms.join(", ");
return false;
}
});
});
function split(val) {
return val.split(/,\s*/);
}
function extractLast(term) {
return split(term).pop();
}
my controller code :
public JsonResult AutoCompleteUsers(string term)
{
var result = (from r in db.UserItems
where r.Name.ToLower().Contains(term.ToLower())
select new { label = r.Name + "(" + r.Email + ")", value = r.Name, userId = r.UserId }).Distinct();
return Json(result, JsonRequestBehavior.AllowGet);
}

Posting to Popup Controller Before the Parent Page Controller

How do I force a popup page to post to its controller first before posting to the parent controller? The popup page is setting up some session variables that would be used in the parent page. When the user double click on the grid on the pop-up page, it goes directly to the parent controller instead of going to the child controller.
Here is the parent where the popup is being called
//Javascript to open the popup window
#using (Html.BeginForm("Student", "StudentPage", FormMethod.Get, new { onsubmit = "", id = "student" }))
{
//where the popup window is located
}
Here is the popup form:
#using (Html.BeginForm("Index", "StudentInformation", FormMethod.Post, new {id="StudentSearchForm"}))
{
#(Html
.Telerik()
.Grid((IEnumerable<OverrideStudent>)SessionWrapper.Student.OtherStudentSelected)
.Name("StudentData")
.DataKeys(Keys =>
{
Keys.Add(c => c.StudentID);
})
.DataBinding(databinding => databinding.Server())
.Columns(columns =>
{
columns.Bound(p => p.StudentId)
.Title("Student ID")
.Width(15)
.Sortable(true)
.Filterable(false);
columns.Bound(p => p.StudentDescription)
.Title("Description")
.Width(65)
.Sortable(true)
.Filterable(false);
columns.Command(command =>
{
command.Custom("AddStudent")
.Text("Select")
.DataRouteValues(routes =>
{
routes.Add(o => o.StudentID).RouteKey("StudentID");
routes.Add(o => o.StudentDescription).RouteKey("StudentDescription");
})
.Action("Student", "StudentInfo");
.HtmlAttributes(new { onclick = "PostData(this);StudentSelectClick(this)" });
}).Width(20);
}).ClientEvents(clients => clients
.OnComplete("OnComplete")
//.OnDataBinding("DataBinding")
//.OnDataBound("onRowDataBound")
.OnRowSelected("StudentDoubleClick")
)
.Sortable()
.Selectable()
.Filterable(filtering => filtering
.Enabled(true)
.Footer(true)
.HtmlAttributes(new { style = "padding-right: 0.0em;" }))
}
//This is the script that handles that double click:
function StudentDoubleClick(e) {
var fromCourse = "#SessionWrapper.Student.FromCoursePage";
var fromList = "#SessionWrapper.Student.FromListingPage";
if (fromCourse == "True") {
$('tr', this).live('dblclick', function () {
alert("Inside TR count = " + count);
count = count + 1;
DoSearchStudent(e);
});
}
if (fromList == "True") {
$('tr', this).live('dblclick', function () {
DoSearchStudent(e);
});
}
}
function DoSearchStudent(e) {
var row = e.row;
var StudentID = row.cells[0].innerHTML;
var StudentDescription = row.cells[1].innerHTML;
// alert(procCodeDesc);
var data = { "StudentID": StudentID, "StudentDescription": StudentDescription, "action": "Double Click" };
var url = '#Url.Action("Student", "StudentInfo")';
$.ajax({
url: url,
type: 'post',
dataType: 'text',
cache: false,
async: false,
data: data,
success: function (data) {
window.top.location.href = window.top.location.href;
},
error: function (error) {
alert("An error has occured and the window will not be closed.");
}
});
}
//This is the controller that I need to go to first
public class StudentInfoController : Controller
{
.......
public string Student(string StudentID, string StudentDescription, string action)
{
if (StudentDescription != null)
{
StudentDescription = HttpUtility.HtmlDecode(StudentDescription);
}
try
{
RedirectToAction("AddStudent", "StudentInfo", new { StudentID = StudentID, StudentDescription = StudentDescription, action = action });
}
catch (Exception e)
{
return "Error " + e.ToString();
}
return "Success";
}
}
After the double click, it goes directly to the controller below instead. AS a result, my variables are not being set resulting in null exception.
public class StudentPageController : Controller
{
.......
public string Student(string StudentID, string StudentDescription, Student Students)
{
...........
}
}
It was a timing issue. When the user close the popup window, the popup thread is not done executing. At the same time, another thread starts to run, and not all the session variables are set as of yet. Before closing the popup window, I added a 1 second delay.
setTimeout('StudentWindow.close()', 1000);

Categories