adding custom function to bootstrap typeahead - javascript

I'm using typeahead to pull names and then updating a hidden field with the id respective to the name. In my form the name can be left blank, filling it is not a requirement.
Is there a way to add custom error checking to the typeahead function? for instance, I start filling out the form and type/select a user, then I change my mind and want to leave it blank. by this point, the user id is already added to the hidden field, so even if i leave the name field blank, the form will be passed with the user id in it.
I guess I can always do error checking on submit, but am curious if there is a way to add to the native api.
my code is:
$('#name_field').typeahead({
minLength: 3,
source: function (query, process){
$.get('/url/getsource', {query: query}, function (data) {
names = [];
map = {};
$.each(data, function (i, name) {
map[name.uName] = name;
names.push(name.uName);
});
process(names);
});
},
matcher: function (item) {
if (item.toLowerCase().indexOf(this.query.trim().toLowerCase()) != -1) {
return true;
}
},
sorter: function (items) {
return items.sort();
},
highlighter: function (item) {
var regex = new RegExp( '(' + this.query + ')', 'gi' );
return item.replace( regex, "<strong>$1</strong>" );
},
updater: function (item) {
selectedID = map[item].id;
$('#id_field').val(selectedID);
return item;
}
});
I was hoping I can add something like
$('#name_field').typeahead({
myCustom: function (){
if($('#name_field').val() == ''){
$('#id_field').val('');
},
rest,
of the,
function
});

You could bind a function to the blur event of the user field. So as soon as the user makes any changes to another form element if it is left blank you clear the typeahead field.
$('#user-field').blur(function (e) {
if(this.val() === ''){
$('#typeahead-field').val(''); // Clear typeahead
}
});

Related

Change value of first iteration input with next iteration input value

Structure Concept:-
Basically, i am trying to create the modal window containing input and that modal window currently fires when the input on index page get focused for that I have used data attribute to make a link between them by assigning them same attribute value.
Javascript Concept:-
for the modal window, I have created the modal object. and model object contains a bindModal method which takes one argument and that argument is data attribute value. after taking that value bindModal method will search dom elements containing that particular value and after the search, I iterate over them using each loop.
Problem
So basically I want whenever user starts typing on the model input it should get written automatically in input on the index page.
I will appreciate you all if guys help me out to make my code more optimized and well structured and most important thing is that let me know what mistake I have done in overall work Thanks
JavaScript Code
var modal = function () {
this.toggleModal = function () {
$('#modal').toggleClass('content--inActive').promise().done(function () {
$('#modal__close').on('click',function(){
$('#modal').addClass('content--inActive');
});
});
}
this.bindModal = function (bindVal) {
var bindValue = $(document).find('[data-modal-bind = ' + bindVal + ']');
$.each(bindValue, function (index) {
var bind1 = $(this);
if(index === 1) {
var bind2 = $(this);
$(bind1).change(function (){
$(bind2).val(bind1.val());
});
}
});
}
}
var open = new modal();
$('#input_search').on('click',function(){
open.toggleModal();
open.bindModal('input');
});
Here is one way to do what you want:
var modal = function() {
this.bindModal = function(bindVal) {
var bindValue = $('[data-modal-bind = ' + bindVal + ']');
bindValue.each(function(index) {
$(this).keyup(function() {
var value = $(this).val();
bindValue.each(function(i, e) {
$(this).val(value);
});
});
});
}
}
$('#input_search').on('click', function() {
var open = new modal();
open.bindModal('input');
});
Changes done:
I cached the inputs with same binding values in bindValue variable, and then bound the the keyup event for each of them. On keyup, the value of the current input is get in value, which is then assigned to each input using the inner loop.
This makes the inputs to be in sync while typing. Hope that solves your issue.

Flickr Api doesn't delete feeded photos when using an html input, but when changing it manually in the code

I made a little application in JavaScript with the Flickr API. It returns the ten most recent photos of a specific tag.
When Searching for a tag it brings one the photos, everything fine till here. At the next search it keeps the old photos and just adds new ones. It was planned to "delete" the older photos. Visit: https://jsfiddle.net/79uueuso/
var thread = null;
function findTags(input) {
console.log(input);
var flickerAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
// Get the vaules of the Flickr-API
$.getJSON(flickerAPI, {
tags: input, // input = value of the input text field
tagmode: "all",
format: "json"
})
// get 10 pictures
.done(function (data) {
$.each(data.items, function (i, item) { // put them in a <img> with thumbnail of bootstrap / append them to the <div> with id="images"
$("<img class='img-thumbnail'>").attr("src", item.media.m).appendTo("#images");
if (i === 9) {
return false;
}
});
});
}
// Get the Value of the text input field while you type!
// The function reads the value 500ms after your last typing (.keyup)
$('#tag').keyup(function () {
clearTimeout(thread);
var $this = $(this);
thread = setTimeout(function () {
findTags($this.val())
}, 750);
});
Originally it was like this, Visit: https://jsfiddle.net/ckdr2Lwx/
(function() {
var flickerAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
$.getJSON(flickerAPI, {
tags: "Schloss Heidelberg",
tagmode: "any",
format: "json"
})
.done(function (data) {
$.each(data.items, function (i, item) {
$("<img>").attr("src", item.media.m).appendTo("#images");
console.log("Hallo die " + [i] + ".");
if (i === 9) {
return false;
}
});
});
})();
I solved my problem. I added a function which removes the input value, after that when there is no input value the recent photos will be deleted and the search does not start from scratch. First you have to type something in the input field. Here goes the additional code I used.
// when pressing backspace once, the whole input field gets cleared.
$('html').keyup(function(e){
if(e.keyCode == 8) {
var photo = document.getElementById("tag");
photo.value = "";
var photoDel = $(".img-thumbnail"); // All pictures of the last search will be deleted.
photoDel.remove();
}
});
if(input == ""){ // The search only works now when the input field is not empty-
return false;
}else {
added on top of
var flickerAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
// Get the vaules of the Flickr-API

Running a form handled by ajax in a loaded ajax page?

Using tutorials found i'm currently loading new pages with this:
$("a.nav-link").click(function (e) {
// cancel the default behaviour
e.preventDefault();
// get the address of the link
var href = $(this).attr('href');
// getting the desired element for working with it later
var $wrap = $('#userright');
$wrap
// removing old data
.html('')
// slide it up
.hide()
// load the remote page
.load(href + ' #userright', function () {
// now slide it down
$wrap.fadeIn();
});
});
This loads the selected pages perfectly, however the pages have forms that themselves use ajax to send the following:
var frm = $('#profileform');
frm.submit(function (ev) {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
alert(data)
}
});
However this is not sending the form as it did before the page itself was called to the parent page via ajax. Am I missing something? Can you not use an ajax call in a page already called by ajax?
I also have other issues, for example I disable the submit button unless there are any changes to the form, using:
var button = $('#profile-submit');
var orig = [];
$.fn.getType = function () {
return this[0].tagName == "INPUT" ? $(this[0]).attr("type").toLowerCase() : this[0].tagName.toLowerCase();
}
$("#profileform :input").each(function () {
var type = $(this).getType();
var tmp = {
'type': type,
'value': $(this).val()
};
if (type == 'radio') {
tmp.checked = $(this).is(':checked');
}
orig[$(this).attr('id')] = tmp;
});
$('#profileform').bind('change keyup', function () {
var disable = true;
$("#profileform :input").each(function () {
var type = $(this).getType();
var id = $(this).attr('id');
if (type == 'text' || type == 'select') {
disable = (orig[id].value == $(this).val());
} else if (type == 'radio') {
disable = (orig[id].checked == $(this).is(':checked'));
}
if (!disable) {
return false; // break out of loop
}
});
button.prop('disabled', disable);});
However this also doesn't work when pulled to the parent page. Any help much appreciated! I'm really new to ajax so please point out any obvious mistakes! Many thanks in advance.
UPDATE
Just an update to what i've found. I've got one form working by using:
$(document).on('mouseenter', '#profile', function() {
However the following:
$(document).on('mouseenter', '#cancelimage', function() {
$('#cancelimage').onclick=function() {
function closePreview() {
ias.cancelSelection();
ias.update();
popup('popUpDiv');
$('#imgForm')[0].reset();
} }; });
Is not working. I understand now that I need to make it realise code was there, so I wrapped all of my code in a mouseover for the new div, but certain parts still don't work, so I gave a mouseover to the cancel button on my image form, but when clicked it doesn't do any of the things it's supposed to.
For anyone else who comes across it, if you've got a function name assigned to it, it should pass fine regardless. I was trying to update it, and there was no need. Doh!
function closePreview() {
ias.cancelSelection();
ias.update();
popup('popUpDiv');
$('#imgForm')[0].reset();
};
Works just fine.

jQuery exception, probably AJAX-related for Autocomplete fields

I have an application running with jquery-1.5.2.min.js. It works fine in IE9, 8, 7, FF and Chrome.
But there's this problem. I have a JavaScript function in a custom .js file using jQuery that rules the behaviour of a hidden field. Whenever a button is clicked, the hidden field is turned into a jQuery Autocomplete control, and loads the Autocomplete information through an Ajax call. The function is like this:
$.ajax({
type: "POST",
url: action,
dataType: "json",
data: "{type: '" + control + "', param:" + params + "}",
contentType: "application/json; charset=utf-8",
success: function (data) {
var dataTable = data;
$(selector).autocomplete({
minLength: 2,
source: dataTable,
open: function (e, ui) {
var options = $(this).data('autocomplete');
options.menu.element.find('a').each(function () {
var this_ = $(this);
var regex = new RegExp(options.term, "gi");
this_.html(this_.text().replace(regex, function (matched) {
return autocompleteTemplate.replace('%s', matched);
}));
});
},
focus: function (event, ui) {
$(selector).val(ui.item.label);
return false;
},
change: function (event, ui) {
if (!ui.item) {
var options = $(this).data('autocomplete');
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i"),
valid = false;
options.menu.element.find('a').each(function () {
if ($(this).text().match(matcher)) {
valid = true;
return false;
}
});
if (!valid) {
if (control == "ProjectType") {
$('#selector').val("...");
$('#selector').attr('disabled', 'disabled');
$('#another.selector').val("");
}
// Remueve los valores inválidos.
$(this).val("");
$(selector).val("");
$(selector).data("autocomplete").term = "";
return false;
}
}
if (control == "ProjectType") {
$('#selector').val("");
}
},
select: function (event, ui) {
$(selector).val(ui.item.label);
$(hidden).val(ui.item.value);
if (control == "ProjectType") {
Autocomplete("ProjectSubType", action, ui.item.value);
// This is a function that changes the CSS for another HTML control
ProjectSubType(false);
}
return false;
}
});
}
});
So, whenever I change the browser type from IE8 to IE7 or IE9, or from IE7 to IE8 or IE9, after activating this field, the following exception is thrown from jquery-1.5.2.min.js
Runtime error from Microsoft JScript: Cannot get value of property
'type': the object is null or undefined
FYI:
The AJAX calls work. The autocomplete works properly and fires the events it has to fire when completed, in the order they have to be fired.
There is another control that fires another AJAX event (filling a jqGrid) which produces no mistake.
The conditional clause that you see in the code, "if (control == "ProjectType")", is meant to allow another control to turn into an Autocomplete if this control being used has an Autocomplete option filled in. Otherwise, it is disabled, as you can see (I changed its name to '#selector'). This also works properly: if you fill in a value in that Autocomplete, the other control is filled with the options needed.
Thanks
UDP
The function that calls the AJAX function is the following:
function SetSearchMenu(url, local) {
$('#advancedSearch').hide();
$('#advSearch').click(function () {
if ($('#advancedSearch').css("display") == "none") {
$('#advancedSearch').show();
$('#generalSearch').val("...");
$('#generalSearch').attr('disabled', 'disabled');
ProjectSubType(true);
}
else {
$('#dAdvancedSearch').hide();
$('#General').val("");
$('#General').removeAttr('disabled');
}
if (alreadyOpen == false) {
Autocomplete("SelectorOne", url, null);
Autocomplete("ProjectType", url, null);
Autocomplete("Selector", url, local);
alreadyOpen = true;
}
});
}
The parameters url and local are sent from the $(document).ready() function, and are filled with an #Url.Action() in string format and another variable hardcoded to one.

Bootstrap Typeahead - don't autoselect first item?

I'm using this fork of the Twitter Bootstrap typeahead library, which allows asynchronous data sources as well as onselect events. It's working really well for me so far, but when a user tabs out of the field (i.e. doesn't actively select a drop down entry), the onselect event is fired (which in my case, redirects the user to another page). Is there any way I can stop the onselect event being fired if a user doesn't click? Here's what I've got so far (in CoffeeScript):
$(document).ready ->
$('#inspection_name').typeahead(
source: (typeahead, query) ->
$.ajax(
url: "/inspections/search.json?name="+query
success: (data) =>
return_list = []
$(data.results.inspections).each ->
return_list.push("<span data-url='" + this.uri + "/edit'>" + this.name + ", " + this.town + "</span>")
typeahead.process(return_list)
)
onselect: (obj) =>
window.location.href = $(obj).attr("data-url")
)
For the default Bootstrap, this will work:
$.fn.typeahead.Constructor.prototype.render = function (items) {
var that = this;
items = $(items).map(function (i, item) {
i = $(that.options.item).attr('data-value', item);
i.find('a').html(that.highlighter(item));
return i[0];
});
this.$menu.html(items);
return this;
};
Somewhere after including bootstrap.(min.)js
In the end, I answered my own question, and put the adjustments in this Gist:
https://gist.github.com/1977953
You can set the attribute in angular-bootstrap typehead
typeahead-focus-first="false"
Similar option availble for jQuery
All credit should go to #jrochkind but I wanted to put the answer from Bibliographic Wilderness: Overriding bootstrap typeahead to not initially select here for more clarity.
Add this somewhere after bootstrap.js:
/**
* Makes it so the first typeahead result isn't auto selected
*
* #author Jonathan Rochkind
* #url http://bibwild.wordpress.com/2013/04/04/overriding-bootstrap-typeahead-to-not-initially-select/
*/
$.fn.typeahead.Constructor.prototype.select = function() {
var val = this.$menu.find('.active').attr('data-value');
if (val) {
this.$element
.val(this.updater(val))
.change();
}
return this.hide()
};
var newRender = function(items) {
var that = this
items = $(items).map(function (i, item) {
i = $(that.options.item).attr('data-value', item);
i.find('a').html(that.highlighter(item));
return i[0];
});
this.$menu.html(items);
return this;
};
$.fn.typeahead.Constructor.prototype.render = newRender;

Categories

Resources