Pass Dropdown combobox value with Json auto filling userform - javascript

I have a dropdown/combo box, this is how its made
#Html.DropDownList("combobox", Model.Sizes, "--select--")
It uses a jquery ui widget which is,
<script>
(function ($) {
$.widget("custom.combobox", {
_create: function () {
this.wrapper = $("<span>")
.addClass("custom-combobox")
.insertAfter(this.element);
this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
},
_createAutocomplete: function () {
var selected = this.element.children(":selected"),
value = selected.val() ? selected.text() : "";
this.input = $("<input>")
.appendTo(this.wrapper)
.val(value)
.attr("title", "")
.addClass("custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left")
.autocomplete({
delay: 0,
minLength: 0,
source: $.proxy(this, "_source"),
//ADDED HERE
select: function(event, ui) {
sizeID=ui.item.id;
}
})
.tooltip({
tooltipClass: "ui-state-highlight"
});
this._on(this.input, {
autocompleteselect: function (event, ui) {
ui.item.option.selected = true;
this._trigger("select", event, {
item: ui.item.option
});
},
autocompletechange: "_removeIfInvalid"
});
},
_createShowAllButton: function () {
var input = this.input,
wasOpen = false;
$("<a>")
.attr("tabIndex", -1)
.attr("title", "Show All Items")
.tooltip()
.appendTo(this.wrapper)
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass("ui-corner-all")
.addClass("custom-combobox-toggle ui-corner-right")
.mousedown(function () {
wasOpen = input.autocomplete("widget").is(":visible");
})
.click(function () {
input.focus();
// Close if already visible
if (wasOpen) {
return;
}
// Pass empty string as value to search for, displaying all results
input.autocomplete("search", "");
});
},
_source: function (request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response(this.element.children("option").map(function () {
var text = $(this).text();
if (this.value && (!request.term || matcher.test(text)))
return {
label: text,
value: text,
option: this
};
}));
},
_removeIfInvalid: function (event, ui) {
// Selected an item, nothing to do
if (ui.item) {
return;
}
// Search for a match (case-insensitive)
var value = this.input.val(),
valueLowerCase = value.toLowerCase(),
valid = false;
this.element.children("option").each(function () {
if ($(this).text().toLowerCase() === valueLowerCase) {
this.selected = valid = true;
return false;
}
});
// Found a match, nothing to do
if (valid) {
return;
}
// Remove invalid value
this.input
.val("")
.attr("title", value + " didn't match any item")
.tooltip("open");
this.element.val("");
this._delay(function () {
this.input.tooltip("close").attr("title", "");
}, 2500);
this.input.autocomplete("instance").term = "";
},
_destroy: function () {
this.wrapper.remove();
this.element.show();
}
});
})(jQuery);
$(function () {
$("#combobox").combobox();
$("#toggle").click(function () {
$("#combobox").toggle();
});
});
</script>
I then am trying to pass the value of this dropdown using Json likeeee
<script type="text/javascript">
$(function () {
$("[name='combobox']").change(function () {
$.getJSON('#Url.Action("GetSize")', { sizeID: $("[name='combobox']").val() }, function (Size) {
// Fill the fields according to the Jsondata we requested
$("#KID").val(Size["KammID"]);
This uses the get size action in my controller which is,
public JsonResult GetSize(int sizeID)
{
var Size = db.AllSizes.Find(sizeID);
return Json(Size, JsonRequestBehavior.AllowGet);
}
Andddddd this worked perfectly with my normal dropdown, but once i changed it to a combo box it seems its not getting the sizeID,
HELP BENJI

you could add in a select function as outlined here:
Get value in jquery autocomplete
so when an option is selected you store the value in a variable.
eg:
var sizeID;
.autocomplete({
delay: 0,
minLength: 0,
source: $.proxy(this, "_source"),
select: function(event, ui) {
sizeID=ui.item.id;
}
})

Related

How do you do something when the escape key is pressed on an input field, but not on blur events for that input field?

For example, consider the TodoMVC app.
I'm writing my own version of that app. When you double click a todo item, an input field shows up.
When that input field blurs, I want to save the changes. But if the user makes changes and then presses escape, I don't want to save the changes.
The problem is that pressing the escape key on the input field triggers a blur event. So when I press escape, the function I have that listens for escape key presses runs... but so does the function that listens for the blur event.
How can I do something when the escape key is pressed, and not run the blur event function?
views/todo.js
var app = app || {};
app.TodoView = Backbone.View.extend({
tagName: 'li',
className: 'list-group-item',
template: _.template( $('#todo-template').html() ),
render: function() {
this.$el.html( this.template(this.model.toJSON()) );
this.$el.find('.edit-mode').hide();
this.$el.find('.remove-todo').hide();
return this;
},
events: {
'click input[type="checkbox"]': 'check',
'mouseenter': 'showRemove',
'mouseleave': 'hideRemove',
'click .remove-todo': 'remove',
'dblclick .todo-title': 'showEditMode',
'keyup input.edit-todo': 'updateOnEnter',
'blur input.edit-todo': 'closeAndUpdate'
},
initialize: function() {
this.listenTo(this.model, 'change', this.render);
},
check: function(e) {
this.model.save({
completed: true
});
},
showRemove: function(e) {
$(e.currentTarget).find('.remove-todo').show();
},
hideRemove: function(e) {
$(e.currentTarget).find('.remove-todo').hide();
},
remove: function(e) {
var $el = $(e.currentTarget);
this.model.destroy({
success: function(model) {
app.todos.remove(model);
$el.closest('li').remove();
},
error: function() {
alert('Unable to remove todo.');
}
});
},
showEditMode: function(e) {
var $el = $(e.currentTarget);
var $editMode = $el.closest('li').find('.edit-mode');
$el.closest('.view-mode').hide();
$editMode.show();
$editMode.find('.edit-todo').focus();
},
updateOnEnter: function(e) {
if (e.which === 13) {
this.closeAndUpdate();
}
else if (e.which === 27) {
this.closeEditMode();
}
},
closeEditMode: function() {
var $input = this.$el.find('.edit-todo');
$input.closest('li').find('.view-mode').show();
$input.closest('.edit-mode').hide();
},
closeAndUpdate: function() {
var self = this;
var $input = this.$el.find('.edit-todo');
var newTitle = $input.val();
if (newTitle !== this.model.get('title')) {
this.model.save({
title: newTitle
}, {
success: function(model) {
self.closeEditMode();
},
error: function() {
alert('Unable to update todo');
}
});
}
else {
this.closeEditMode();
}
}
});
You can set some boolean flag inside keypress handler when Esc is pressed, and then check it inside blur handler:
...
events: {
...
"keypress .edit" : "keypress",
"blur .edit" : "blur"
},
...
close: function() {
...
},
blur: function() {
if (!this.escFlag) this.close();
this.escFlag = false;
},
keypress: function(e) {
if (e.keyCode == 27) this.escFlag = true;
},
...

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);
}

jqDialog inside KnockoutJS if binding

I have jqDialogs inside if bindings("Tabs"). After I go to another tab and than back it causes initializing of jqDialogs and creates a new instance => so I have than 2 or more(depends on number of jumps from tab to tab) same dialogs instead of one.
Thanks!
<!-- ko if: IsTabVisible-->
<div data-bind="jqDialog:{buttons:[{ text: '#Resources.Resource.Save',
click: Save},{ text: '#Resources.Resource.Cancel',
click: UndoChanges}], modal: true, autoOpen: false,
close: UndoChanges, title: "title"},
dialogVisible: Isvisible, jqButton:{
index: 0, disabled: HasError}">
//some content
</div>
<!-- /ko -->
ko.bindingHandlers.jqDialog = {
modifyDialog: function (e) {
if (ko.isWriteableObservable(e.data.prop)) {
e.data.prop(e.data.state);
}
else {
e.data.el.dialog(e.data.state === true ? "open" : "close");
}
},
functionMouseHover: function (e) {
if (!e.data.state) {
if (e.data.el.data('timeoutId') == null) {
var timeoutId = setTimeout(function () {
ko.bindingHandlers.jqDialog.modifyDialog(e);
e.data.el.data('timeoutId', null);
}, 650);
e.data.el.data('timeoutId', timeoutId);
}
}
else {
if (e.data.el.data('timeoutId') != null) {
clearTimeout(e.data.el.data('timeoutId'));
e.data.el.data('timeoutId', null);
}
ko.bindingHandlers.jqDialog.modifyDialog(e);
}
},
init: function (element, valueAccessor, allBindingsAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor()) || {},
mouseOverElement = ko.utils.unwrapObservable(allBindingsAccessor().mouseOverElement)
$el = $(element);
//do in a setTimeout, so the applyBindings doesn't bind twice from element being copied and moved to bottom
setTimeout(function () {
var dialog = $(element).dialog(options);
var functionMouseHover = null;
if (mouseOverElement != null) {
$(mouseOverElement).mouseenter({ state: true, el: $el, prop: allBindingsAccessor().dialogVisible }, ko.bindingHandlers.jqDialog.functionMouseHover).
mouseleave({ state: false, el: $el, prop: allBindingsAccessor().dialogVisible }, ko.bindingHandlers.jqDialog.functionMouseHover);
dialog.mouseenter({ state: true, el: $el, prop: allBindingsAccessor().dialogVisible }, ko.bindingHandlers.jqDialog.functionMouseHover).
mouseleave({ state: false, el: $el, prop: allBindingsAccessor().dialogVisible }, ko.bindingHandlers.jqDialog.functionMouseHover);
}
}, 0);
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).dialog("destroy");
});
},
update: function (element, valueAccessor, allBindingsAccessor) {
var shouldBeOpen = ko.utils.unwrapObservable(allBindingsAccessor().dialogVisible),
hideTitelBar = ko.utils.unwrapObservable(allBindingsAccessor().hideTitelBar),
mouseOverElement = ko.utils.unwrapObservable(allBindingsAccessor().mouseOverElement),
$el = $(element),
dialog = $el.data("uiDialog") || $el.data("dialog");
var options = valueAccessor();
//don't call open/close before initilization
if (dialog) {
var isOpen = $el.dialog("isOpen");
$el.dialog(shouldBeOpen === true ? "open" : "close");
if (hideTitelBar === true) {
$el.dialog('widget').find(".ui-dialog-titlebar").hide();
} else if (hideTitelBar === false) {
$el.dialog('widget').find(".ui-dialog-titlebar").show();
}
for (var key in options) {
if (ko.isObservable(options[key])) {
$el.dialog("option", key, options[key]());
}
}
if (options.title != undefined) {
$el.dialog({ title: options.title });
}
if (shouldBeOpen === true && !isOpen) {
$("input").blur();
}
if ($Render != null && shouldBeOpen) {
$Render.renderUpdate();
}
if (options['type']) {
if (options['type'] == 'warning') {
$el.dialog("option", "width", 400);
$el.dialog("option", "height", 'auto');
$el.dialog("option", "position", "center");
}
else if (options['type'] == 'bookmarks') {
$el.dialog("option", "width", 250);
$el.dialog("option", "minHeight", 100);
}
else if (options['type'] == 'mediumDialog') {
$el.dialog("option", "width", $(window).innerWidth() * 0.6);
$el.dialog("option", "height", $(window).innerHeight() * 0.4);
$el.dialog("option", "position", "center");
}
}
else {
$el.dialog("option", "width", $(window).innerWidth() * 0.8);
$el.dialog("option", "height", $(window).innerHeight() * 0.8);
$el.dialog("option", "position", "center");
}
}
else {
if (ko.isWriteableObservable(allBindingsAccessor().dialogVisible)) {
allBindingsAccessor().dialogVisible(false);
}
}
}
};
You'll probably want to use the visible binding. Note the documentation on the if binding:
if plays a similar role to the visible binding. The difference is
that, with visible, the contained markup always remains in the DOM and
always has its data-bind attributes applied - the visible binding just
uses CSS to toggle the container element’s visiblity. The if binding,
however, physically adds or removes the contained markup in your DOM,
and only applies bindings to descendants if the expression is true.
So your div is removed and re-added each time -- causing the init binding to be processed again and again.

Selectindex change event is not firing using asp.net web application

In the below code i have a searchable dropdown using javascript.when i search and select a value from the dropdown it is not firing the selectedindexchange event.i tried but i have not found a solution pls anyone help me to solve the issue.
js:
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<script>
(function ($) {
$.widget("custom.combobox", {
_create: function () {
this.wrapper = $("<span>")
.addClass("custom-combobox")
.insertAfter(this.element);
this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
},
_createAutocomplete: function () {
var selected = this.element.children(":selected"),
value = selected.val() ? selected.text() : "";
this.input = $("<input>")
.appendTo(this.wrapper)
.val(value)
.attr("title", "")
.addClass("custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left")
.autocomplete({
delay: 0,
minLength: 0,
source: $.proxy(this, "_source")
})
.tooltip({
tooltipClass: "ui-state-highlight"
});
this._on(this.input, {
autocompleteselect: function (event, ui) {
ui.item.option.selected = true;
this._trigger("select", event, {
item: ui.item.option
});
},
autocompletechange: "_removeIfInvalid"
});
},
_createShowAllButton: function () {
var input = this.input,
wasOpen = false;
$("<a>")
.attr("tabIndex", -1)
.attr("title", "Show All Items")
.tooltip()
.appendTo(this.wrapper)
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass("ui-corner-all")
.addClass("custom-combobox-toggle ui-corner-right")
.mousedown(function () {
wasOpen = input.autocomplete("widget").is(":visible");
})
.click(function () {
input.focus();
// Close if already visible
if (wasOpen) {
return;
}
// Pass empty string as value to search for, displaying all results
input.autocomplete("search", "");
});
},
_source: function (request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response(this.element.children("option").map(function () {
var text = $(this).text();
if (this.value && (!request.term || matcher.test(text)))
return {
label: text,
value: text,
option: this
};
}));
},
_removeIfInvalid: function (event, ui) {
// Selected an item, nothing to do
if (ui.item) {
return;
}
// Search for a match (case-insensitive)
var value = this.input.val(),
valueLowerCase = value.toLowerCase(),
valid = false;
this.element.children("option").each(function () {
if ($(this).text().toLowerCase() === valueLowerCase) {
this.selected = valid = true;
return false;
}
});
// Found a match, nothing to do
if (valid) {
return;
}
// Remove invalid value
this.input
.val("")
.attr("title", value + " didn't match any item")
.tooltip("open");
this.element.val("");
this._delay(function () {
this.input.tooltip("close").attr("title", "");
}, 2500);
this.input.data("ui-autocomplete").term = "";
},
_destroy: function () {
this.wrapper.remove();
this.element.show();
}
});
})(jQuery);
$(function () {
$(".cbAutoList1").combobox();
$("#toggle").click(function () {
$(".cbAutoList1").toggle();
});
});
</script>
<asp:DropDownList ID="cbAutoList" runat="server" CssClass="cbAutoList1" AutoPostBack="true" EnableViewState="True" OnSelectedIndexChanged="cbAutoList_SelectedIndexChanged" >
<asp:ListItem Value="hai1" >hai1</asp:ListItem>
<asp:ListItem Value="hello2" >hello2</asp:ListItem>
</asp:DropDownList>
codebehind
public delegate void LeavingFocusHandler(int CurrentIndex);
public event LeavingFocusHandler LeavingFocus;
public string strValue { get; set; }
public int ItemIndex { get; set; }
protected void cbAutoList_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (cbAutoList.Items.Count > 0)
this.strValue = cbAutoList.Items[cbAutoList.SelectedIndex].ToString();
else
this.strValue = string.Empty;
if (this.LeavingFocus != null)
{
this.LeavingFocus(this.ItemIndex);
}
}
catch (Exception ex)
{
throw ex;
}
}
To access the value selected in the DropDownList you can just use SelectedValue:
this.strValue = cbAutoList.SelectedValue;
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listcontrol.selectedvalue.aspx

jqueryUi autocomplete - custom data and display

My full code is here: http://jsfiddle.net/HfNk9/13/
I am looking to this example jqueryUi autocomplete - custom data and display.
Let's suppose the object projects is different and it looks like this:
project = [
{
name: 'bar',
value: 'foo',
imgage: 'img.png'
}
]
If I set source = project the autocomplete refers to project.value and not project.name.
How should I change this behaviour?
var autocomplete = function(element, data) {
var fixtures = [
{
avatar: "http://www.placekitten.com/20/20",
name: 'aaaaaaaaa',
value: 'bbbbbbbbb'}
];
element.autocomplete({
minLength: 3,
source: function(request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response($.grep(fixtures, function(value) {
return matcher.test(value.name);
}));
},
create: function() {
console.log(fixtures)
element.val(fixtures.name);
},
focus: function(event, ui) {
element.val(ui.item.name);
return false;
},
select: function(event, ui) {
element.val(ui.item.name);
return false;
}
}).data('autocomplete')._renderItem = function(ul, item) {
return $('<li></li>')
.data('item.autocomplete', item)
.append('<a><img src="' + item.avatar + '" />' + item.name + '<br></a>')
.appendTo(ul);
};
};
autocomplete($('#auto'));
My full code: http://jsfiddle.net/HfNk9/13/
You need to filter on a different property than the autocomplete widget searches on by default (as you've noticed it's name or value when using a source array with objects).
You can use a function instead of an array as the source and perform your own filtering that way:
element.autocomplete({
minLength: 3,
source: function(request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response($.grep(fixtures, function(value) {
return matcher.test(value.name);
}));
},
create: function() {
console.log(fixtures)
element.val(fixtures.name);
},
focus: function(event, ui) {
element.val(ui.item.name);
return false;
},
select: function(event, ui) {
element.val(ui.item.name);
return false;
}
}).data('autocomplete')._renderItem = function(ul, item) {
return $('<li></li>')
.data('item.autocomplete', item)
.append('<a><img src="' + item.avatar + '" />' + item.name + '<br></a>')
.appendTo(ul);
};
Example: http://jsfiddle.net/QzJzW/
You should use the select property:
$("...").autocomplete({
source: ...,
select: function( event, ui ) { //when an item is selected
//use the ui.item object
alert(ui.item.name)
return false;
}
});
The answer is in the source code to the page you've linked to. If you want to use the value of name instead of value then you would do something like this:
$( "#input" ).autocomplete({
minLength: 0,
source: projects,
focus: function( event, ui ) {
$( "#input" ).val( ui.item.value );
return false;
},
select: function( event, ui ) {
$( "#input" ).val( ui.item.value );
return false;
}
})
.data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.name + "</a>" )
.appendTo( ul );
};

Categories