I have two multiple selects in a page (select-cities & chosen-cities), and I can transfer options to and fro. I have given the search functionality to select-cities list. Everything functions as I need.
The problem is when i search in one searchbox and select a few options from the list and move on two the other search box with deleting the typed letters from the first search box, the second search box doesn't function. I am a neophyte hence don't know how to eradicate this problem. I guess it has to do something with the "keyup()" function.
I did the following steps:
1. first I typed e in #someinput box, and selected three options. 2. the values are now in chosen cities list. 3. Now i tried searching the second search box without deleting the content i typed in the first searchbox. this where the problem starts. It won't work.
here it the demo: http://jsfiddle.net/cs6Xb/131/
html:
<input id="someinput">
<br/>
<select class="select-cities" name="city" id="optlist" multiple="multiple">
<option>Frederiksberg</option>
<option>Vanløse</option>
<option>Glostrup</option>
<option>Brøndby</option>
<option>Roskilde</option>
<option>Køge</option>
<option>Gentofte</option>
<option>Hillerød</option>
<option>Tårnby</option>
<option>Vallensbæk</option>
</select>
</input>
<br/>
<input id="someinput1"/><br/>
<select class="chosen-cities" name="chosen-cities-name" id="optlist1" multiple="multiple"></select>
jQuery:
$(function () {
opts = $('#optlist option').map(function () {
return [[this.value, $(this).text()]];
});
opts1 = $('#optlist1 option').map(function () {
return [[this.value, $(this).text()]];
});
$('#someinput').keyup(function () {
var rxp = new RegExp($('#someinput').val(), 'i');
var optlist = $('#optlist').empty();
opts.each(function () {
if (rxp.test(this[1])) {
optlist.append($('<option/>').attr('value', this[0]).text(this[1]));
} else{
optlist.append($('<option/>').attr('value', this[0]).text(this[1]).addClass("hidden"));
}
});
$(".hidden").toggleOption(false);
});
$('#someinput1').keyup(function () {
var rxp = new RegExp($('#someinput1').val(), 'i');
var optlist = $('#optlist1').empty();
opts1.each(function () {
if (rxp.test(this[1])) {
optlist.append($('<option/>').attr('value', this[0]).text(this[1]));
} else{
optlist.append($('<option/>').attr('value', this[0]).text(this[1]).addClass("hidden"));
}
});
$(".hidden").toggleOption(false);
});
$('.select-cities').click(function () {
$('.select-cities option:selected').remove().appendTo('.chosen-cities');
opts = $('#optlist option').map(function () {
return [[this.value, $(this).text()]];
});
opts1 = $('#optlist1 option').map(function () {
return [[this.value, $(this).text()]];
});
});
$('.chosen-cities').click(function () {
$('.chosen-cities option:selected').remove().appendTo('.select-cities');
opts = $('#optlist option').map(function () {
return [[this.value, $(this).text()]];
});
opts1 = $('#optlist1 option').map(function () {
return [[this.value, $(this).text()]];
});
});
});
jQuery.fn.toggleOption = function( show ) {
jQuery( this ).toggle( show );
if( show ) {
if( jQuery( this ).parent( 'span.toggleOption' ).length )
jQuery( this ).unwrap( );
} else {
if( jQuery( this ).parent( 'span.toggleOption' ).length == 0 )
jQuery( this ).wrap( '<span class="toggleOption" style="display: none;" />' );
}
};
Issue was with
$(".hidden").toggleOption(false);
I changed the $(".hidden") selector based on corresponding optlist
$("#optlist .hidden").toggleOption(false);
and
$("#optlist1 .hidden").toggleOption(false);
Working Fiddle
Related
Following is Html for Drop down
<select name="fancySelect" onchange="test()" class="makeMeFancy" id="drop1">
<option value="0" selected="selected" data-skip="1" data-icon="assets/images/large/bitcoin.png" data-html-text="BTC<i>">BTC<span class="select_coin_button_arrow">▾</span></option>
<option value="1" data-icon="assets/images/small/bitcoin.png" data-html-text="BTC<i>" >BTC</option>
<option value="17" data-icon="assets/images/small/ether.png" data-html-text="ETH<i>">ETH</option>
</select>
and following is js function test()
function test() {
var e = document.getElementById("drop1");
var strUser = e.options[e.selectedIndex].value;
console.dir(strUser)
}
How to Print
Follwing is Jquery Script working on Dropdown
As code is working without Jquery Script,There seems to be problem
in following JQuery
$(document).ready(function () {
// The select element to be replaced:
var select = $('select.makeMeFancy');
var selectBoxContainer = $('<div>', {
width: select.outerWidth(),
className: 'tzSelect',
html: '<div class="selectBox"></div>'
});
var dropDown = $('<ul>', {className: 'dropDown'});
var selectBox = selectBoxContainer.find('.selectBox');
// Looping though the options of the original select element
select.find('option').each(function (i) {
var option = $(this);
if (i == select.attr('selectedIndex')) {
selectBox.html(option.text());
}
// As of jQuery 1.4.3 we can access HTML5
// data attributes with the data() method.
if (option.data('skip')) {
return true;
}
// Creating a dropdown item according to the
// data-icon and data-html-text HTML5 attributes:
var li = $('<li>', {
html: '<img src="' + option.data('icon') + '" /><span>' +
option.data('html-text') + '</span>'
});
li.click(function () {
selectBox.html(option.text());
dropDown.trigger('hide');
// When a click occurs, we are also reflecting
// the change on the original select element:
select.val(option.val());
return false;
});
dropDown.append(li);
});
selectBoxContainer.append(dropDown.hide());
select.hide().after(selectBoxContainer);
// Binding custom show and hide events on the dropDown:
dropDown.bind('show', function () {
if (dropDown.is(':animated')) {
return false;
}
selectBox.addClass('expanded');
dropDown.slideDown();
}).bind('hide', function () {
if (dropDown.is(':animated')) {
return false;
}
selectBox.removeClass('expanded');
dropDown.slideUp();
}).bind('toggle', function () {
if (selectBox.hasClass('expanded')) {
dropDown.trigger('hide');
}
else dropDown.trigger('show');
});
selectBox.click(function () {
dropDown.trigger('toggle');
return false;
});
// If we click anywhere on the page, while the
// dropdown is shown, it is going to be hidden:
$(document).click(function () {
dropDown.trigger('hide');
});
});
$(document).ready(function () {
// The select element to be replaced:
var select = $('select.makeMeFancydrop');
var selectBoxContainer = $('<div>', {
width: select.outerWidth(),
className: 'tzSelect',
html: '<div class="selectBox"></div>'
});
var dropDown = $('<ul>', {className: 'dropDown'});
var selectBox = selectBoxContainer.find('.selectBox');
// Looping though the options of the original select element
select.find('option').each(function (i) {
var option = $(this);
if (i == select.attr('selectedIndex')) {
selectBox.html(option.text());
}
// As of jQuery 1.4.3 we can access HTML5
// data attributes with the data() method.
if (option.data('skip')) {
return true;
}
// Creating a dropdown item according to the
// data-icon and data-html-text HTML5 attributes:
var li = $('<li>', {
html: '<img src="' + option.data('icon') + '" /><span>' +
option.data('html-text') + '</span>'
});
li.click(function () {
selectBox.html(option.text());
dropDown.trigger('hide');
// When a click occurs, we are also reflecting
// the change on the original select element:
select.val(option.val());
return false;
});
dropDown.append(li);
});
selectBoxContainer.append(dropDown.hide());
select.hide().after(selectBoxContainer);
// Binding custom show and hide events on the dropDown:
dropDown.bind('show', function () {
if (dropDown.is(':animated')) {
return false;
}
selectBox.addClass('expanded');
dropDown.slideDown();
}).bind('hide', function () {
if (dropDown.is(':animated')) {
return false;
}
selectBox.removeClass('expanded');
dropDown.slideUp();
}).bind('toggle', function () {
if (selectBox.hasClass('expanded')) {
dropDown.trigger('hide');
}
else dropDown.trigger('show');
});
selectBox.click(function () {
dropDown.trigger('toggle');
return false;
});
// If we click anywhere on the page, while the
// dropdown is shown, it is going to be hidden:
$(document).click(function () {
dropDown.trigger('hide');
});
});
$(document).ready(function () {
$("#drop1").click(function () {
});
});
As mentioned in comments, your HTML is completelly changed, by jQuery script you use. Btw, it is very old script, and seems compatible just with older versions of jQuery.... However, instead <select> element which is removed, now you have <ul> with .dropDown class. To get selected value, you can do something like this:
$(".dropDown li").click(function () {
console.log($(this).text())
});
Demo:
$(document).ready(function () {
// The select element to be replaced:
var select = $('select.makeMeFancy');
var selectBoxContainer = $('<div>', {
width: select.outerWidth(),
className: 'tzSelect',
html: '<div class="selectBox"></div>'
});
var dropDown = $('<ul>', {className: 'dropDown'});
var selectBox = selectBoxContainer.find('.selectBox');
// Looping though the options of the original select element
select.find('option').each(function (i) {
var option = $(this);
if (i == select.attr('selectedIndex')) {
selectBox.html(option.text());
}
// As of jQuery 1.4.3 we can access HTML5
// data attributes with the data() method.
if (option.data('skip')) {
return true;
}
// Creating a dropdown item according to the
// data-icon and data-html-text HTML5 attributes:
var li = $('<li>', {
html: '<img src="' + option.data('icon') + '" /><span>' +
option.data('html-text') + '</span>'
});
li.click(function () {
selectBox.html(option.text());
dropDown.trigger('hide');
// When a click occurs, we are also reflecting
// the change on the original select element:
select.val(option.val());
return false;
});
dropDown.append(li);
});
selectBoxContainer.append(dropDown.hide());
select.hide().after(selectBoxContainer);
// Binding custom show and hide events on the dropDown:
dropDown.bind('show', function () {
if (dropDown.is(':animated')) {
return false;
}
selectBox.addClass('expanded');
dropDown.slideDown();
}).bind('hide', function () {
if (dropDown.is(':animated')) {
return false;
}
selectBox.removeClass('expanded');
dropDown.slideUp();
}).bind('toggle', function () {
if (selectBox.hasClass('expanded')) {
dropDown.trigger('hide');
}
else dropDown.trigger('show');
});
selectBox.click(function () {
dropDown.trigger('toggle');
return false;
});
// If we click anywhere on the page, while the
// dropdown is shown, it is going to be hidden:
$(document).click(function () {
dropDown.trigger('hide');
});
});
$(document).ready(function () {
$(".dropDown li").click(function () {
console.log($(this).text())
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<select name="fancySelect" onchange="test()" class="makeMeFancy" id="drop1">
<option value="0" selected="selected" data-skip="1" data-icon="assets/images/large/bitcoin.png" data-html-text="BTC<i>">BTC<span class="select_coin_button_arrow">▾</span></option>
<option value="1" data-icon="assets/images/small/bitcoin.png" data-html-text="BTC<i>" >BTC</option>
<option value="17" data-icon="assets/images/small/ether.png" data-html-text="ETH<i>">ETH</option>
</select>
I have implemented infinite scroll with isotope on my website and I am having a problem with loading posts. The posts load fine, but lets say I scroll down to load more posts but I am still viewing the posts already there, infinite scroll jumps to the bottom of the page whenever new posts are loaded. How can I stop this behavior and maintain the position on the page even when more posts are loaded?
My script --
$(function () {
var selectChoice, updatePageState, updateFiltersFromObject,
$container = $('.isotope');
////////////////////////////////////////////////////////////////////////////////////
/// EVENT HANDLERS
////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// Mark filtering element as active/inactive and trigger filters update
$('.js-filter').on( 'click', '[data-filter]', function (event) {
event.preventDefault();
selectChoice($(this), {click: true});
$container.trigger('filter-update');
});
//////////////////////////////////////////////////////
// Sort filtered (or not) elements
$('.js-sort').on('click', '[data-sort]', function (event) {
event.preventDefault();
selectChoice($(this), {click: true});
$container.trigger('filter-update');
});
//////////////////////////////////////////////////////
// Listen to filters update event and update Isotope filters based on the marked elements
$container.on('filter-update', function (event, opts) {
var filters, sorting, push;
opts = opts || {};
filters = $('.js-filter li.active a:not([data-filter="all"])').map(function () {
return $(this).data('filter');
}).toArray();
sorting = $('.js-sort li.active a').map(function () {
return $(this).data('sort');
}).toArray();
if (typeof opts.pushState == 'undefined' || opts.pushState) {
updatePageState(filters, sorting);
}
$container.isotope({
filter: filters.join(''),
sortBy: sorting
});
});
//////////////////////////////////////////////////////
// Set a handler for history state change
History.Adapter.bind(window, 'statechange', function () {
var state = History.getState();
updateFiltersFromObject(state.data);
$container.trigger('filter-update', {pushState: false});
});
////////////////////////////////////////////////////////////////////////////////////
/// HELPERS FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// Build an URI to get the query string to update the page history state
updatePageState = function (filters, sorting) {
var uri = new URI('');
$.each(filters, function (idx, filter) {
var match = /^\.([^-]+)-(.*)$/.exec(filter);
if (match && match.length == 3) {
uri.addSearch(match[1], match[2]);
}
});
$.each(sorting, function (idx, sort) {
uri.addSearch('sort', sort);
});
History.pushState(uri.search(true), null, uri.search() || '?');
};
//////////////////////////////////////////////////////
// Select the clicked (or from URL) choice in the dropdown menu
selectChoice = function ($link, opts) {
var $group = $link.closest('.btn-group'),
$li = $link.closest('li'),
mediumFilter = $group.length == 0;
if (mediumFilter) {
$group = $link.closest('.js-filter');
}
if (opts.click) {
$li.toggleClass('active');
} else {
$li.addClass('active');
}
$group.find('.active').not($li).removeClass('active');
if (!mediumFilter) {
if ($group.find('li.active').length == 0) {
$group.find('li:first-child').addClass('active');
}
$group.find('.selection').html($group.find('li.active a').first().html());
}
};
//////////////////////////////////////////////////////
// Update filters by the values in the current URL
updateFiltersFromObject = function (values) {
if ($.isEmptyObject(values)) {
$('.js-filter').each(function () {
selectChoice($(this).find('li').first(), {click: false});
});
selectChoice($('.js-sort').find('li').first(), {click: false});
} else {
$.each(values, function (key, val) {
val = typeof val == 'string' ? [val] : val;
$.each(val, function (idx, v) {
var $filter = $('[data-filter=".' + key + '-' + v + '"]'),
$sort = $('[data-sort="' + v + '"]');
if ($filter.length > 0) {
selectChoice($filter, {click: false});
} else if ($sort.length > 0) {
selectChoice($sort, {click: false});
}
});
});
}
};
////////////////////////////////////////////////////////////////////////////////////
/// Initialization
////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// Initialize Isotope
$container.imagesLoaded( function(){
$container.isotope({
masonry: { resizesContainer: true },
itemSelector: '.item',
getSortData: {
date: function ( itemElem ) {
var date = $( itemElem ).find('.thedate').text();
return parseInt( date.replace( /[\(\)]/g, '') );
},
area: function( itemElem ) { // function
var area = $( itemElem ).find('.thearea').text();
return parseInt( area.replace( /[\(\)]/g, '') );
},
price: function( itemElem ) { // function
var price = $( itemElem ).find('.theprice').text();
return parseInt( price.replace( /[\(\)]/g, '') );
}
}
});
var total = $(".next a:last").html();
var pgCount = 1;
var numPg = total;
// jQuery InfiniteScroll Plugin.
$container.infinitescroll({
contentSelector : '.isotope',
speed : 'fast',
behavior: 'simplyrecipes',
navSelector : '#pagi', // selector for the paged navigation
nextSelector : '#pagi a.next', // selector for the NEXT link (to page 2)
itemSelector : '.item', // selector for all items you'll retrieve
animate: true,
debug: true,
loading: {
selector: '#infscr-loading',
finishedMsg: 'No more content to load.'
}
},
// Trigger Masonry as a callback.
function( newElements ) {
pgCount++;
if(pgCount == numPg) {
$(window).unbind('.infscr');
$container.isotope('reload');
$container.append( newElements ).isotope( 'appended', newElements, true );
$('#infscr-loading').find('em').text('No more content to load.');
$('#infscr-loading').animate({
opacity: 1
}, 200);
setTimeout(function() {
$('#infscr-loading').animate({
opacity: 0
}, 300);
});
} else {
loadPosts(newElements);
}
});
});
function loadPosts(newElements) {
// Hide new posts while they are still loading.
var newElems = $( newElements ).css({ opacity: 0 });
// Ensure that images load before adding to masonry layout.
newElems.imagesLoaded(function() {
// Show new elements now that they're loaded.
newElems.animate({ opacity: 1 });
$container.isotope( 'appended', newElems, true );
});
}
//////////////////////////////////////////////////////
// Initialize counters
$('.stat-count').each(function () {
var $count = $(this),
filter = $count.closest('[data-filter]').data('filter');
$count.html($(filter).length);
});
//////////////////////////////////////////////////////
// Set initial filters from URL
updateFiltersFromObject(new URI().search(true));
$container.trigger('filter-update', {pushState: false});
});
});
You can start by overriding the default animate property of infinite-scroll
$container.infinitescroll({
animate:false, //this does just that
});
And about your dublicate entry for every request (or perhaps some requests ),
It has something to do with your backend i.e the way you are offseting the data
Infinite Scroll works great with page numbers i.e it
Sends 2,3,4,5,6 ... So For every request its sends that request.
I think you are using page offset instead , and you will probably end up with duplicate entries .
If you are using php as your receiving end ... this might help
//In your Controller
$temp = ( $page_offset * $per_page );
$offset = $temp - $per_page ;
//In your model
$this->db->query("SELECT * FROM GALLERY OFFSET $offset limit 10");
This is just a rough idea , I hope it helps.
If it does , Care to Check out Sticky Bubble ? - A game available for free on Google Play .
Cheers :)
I am having an issue with a custom select box using a script. It is working but for instance if you start at the bottom select box and click it, then click the middle, then the top it works as it is supposed to by closing the previous box.
However, if you click the middle box after the top one, the top box will also open and this will happen with all of the boxes.
Is there any solution to this?
Here is my jsFiddle
function tamingselect()
{
if(!document.getElementById && !document.createTextNode){return;}
var ts_selectclass='turnintodropdown'; // class to identify selects
var ts_listclass='turnintoselect'; // class to identify ULs
var ts_boxclass='dropcontainer'; // parent element
var ts_triggeron='activetrigger'; // class for the active trigger link
var ts_triggeroff='trigger'; // class for the inactive trigger link
var ts_dropdownclosed='dropdownhidden'; // closed dropdown
var ts_dropdownopen='dropdownvisible'; // open dropdown
var count=0;
var toreplace=new Array();
var sels=document.getElementsByTagName('select');
for(var i=0;i<sels.length;i++){
if (ts_check(sels[i],ts_selectclass))
{
var hiddenfield=document.createElement('input');
hiddenfield.name=sels[i].name;
hiddenfield.type='hidden';
hiddenfield.id=sels[i].id;
hiddenfield.value=sels[i].options[0].value;
sels[i].parentNode.insertBefore(hiddenfield,sels[i])
var trigger=document.createElement('a');
ts_addclass(trigger,ts_triggeroff);
trigger.href='#';
trigger.onclick=function(){
ts_swapclass(this,ts_triggeroff,ts_triggeron)
ts_swapclass(this.parentNode.getElementsByTagName('ul')[0],ts_dropdownclosed,ts_dropdownopen);
return false;
}
trigger.appendChild(document.createTextNode(sels[i].options[0].text));
sels[i].parentNode.insertBefore(trigger,sels[i]);
var replaceUL=document.createElement('ul');
for(var j=0;j<sels[i].getElementsByTagName('option').length;j++)
{
var newli=document.createElement('li');
var newa=document.createElement('a');
newli.v=sels[i].getElementsByTagName('option')[j].value;
newli.elm=hiddenfield;
newli.istrigger=trigger;
newa.href='#';
newa.appendChild(document.createTextNode(
sels[i].getElementsByTagName('option')[j].text));
newli.onclick=function(){
this.elm.value=this.v;
ts_swapclass(this.istrigger,ts_triggeron,ts_triggeroff);
ts_swapclass(this.parentNode,ts_dropdownopen,ts_dropdownclosed)
this.istrigger.firstChild.nodeValue=this.firstChild.firstChild.nodeValue;
return false;
}
newli.appendChild(newa);
replaceUL.appendChild(newli);
}
ts_addclass(replaceUL,ts_dropdownclosed);
var div=document.createElement('div');
div.appendChild(replaceUL);
ts_addclass(div,ts_boxclass);
sels[i].parentNode.insertBefore(div,sels[i])
toreplace[count]=sels[i];
count++;
}
}
var uls=document.getElementsByTagName('ul');
for(var i=0;i<uls.length;i++)
{
if(ts_check(uls[i],ts_listclass))
{
var newform=document.createElement('form');
var newselect=document.createElement('select');
for(j=0;j<uls[i].getElementsByTagName('a').length;j++)
{
var newopt=document.createElement('option');
newopt.value=uls[i].getElementsByTagName('a')[j].href;
newopt.appendChild(document.createTextNode(uls[i].getElementsByTagName('a')[j].innerHTML));
newselect.appendChild(newopt);
}
newselect.onchange=function()
{
window.location=this.options[this.selectedIndex].value;
}
newform.appendChild(newselect);
uls[i].parentNode.insertBefore(newform,uls[i]);
toreplace[count]=uls[i];
count++;
}
}
for(i=0;i<count;i++){
toreplace[i].parentNode.removeChild(toreplace[i]);
}
function ts_check(o,c)
{
return new RegExp('\\b'+c+'\\b').test(o.className);
}
function ts_swapclass(o,c1,c2)
{
var cn=o.className
if (o.nodeName.toUpperCase()=='A'&&ts_check(o,c1)){
if (ts_swapclass.lst&&ts_swapclass.lst!=o){
ts_swapclass(ts_swapclass.lst,ts_triggeroff,ts_triggeron);
ts_swapclass(ts_swapclass.lst.parentNode.getElementsByTagName('ul') [0],ts_dropdownclosed,ts_dropdownopen);
}
ts_swapclass.lst=o;
}
o.className=!ts_check(o,c1)?cn.replace(c2,c1):cn.replace(c1,c2);
}
function ts_addclass(o,c)
{
if(!ts_check(o,c)){o.className+=o.className==''?c:' '+c;}
}
}
window.onload=function()
{
tamingselect();
}
I was unable to fix the code so I found a quick work around that works perfect.
Thanks to everyone that tried.
*Fix
$( ".d2" ).click(function() {
$('.d3 .dropcontainer').css("display", "none");
});
$( ".d1" ).click(function() {
$('.d2 .dropcontainer').css("display", "none");
});
$( ".d1" ).click(function() {
$('.d3 .dropcontainer').css("display", "none");
});
$( ".d3" ).click(function() {
$('.d1 .dropcontainer').css("display", "none");
});
$( ".d3" ).click(function() {
$('.d2 .dropcontainer').css("display", "none");
});
$('.d3').click(function() {
$('.d3 .dropcontainer').css("display", "block");
});
$('.d2').click(function() {
$('.d2 .dropcontainer').css("display", "block");
});
$('.d1').click(function() {
$('.d1 .dropcontainer').css("display", "block");
});
$(document).mouseup(function (e){
div_cld = $('.dropcontainer');
div_par = $('.activetrigger');
if (!div_cld.is(e.target) && !div_par.is(e.target) && div_cld.has(e.target).length === 0) {
div_cld.find('ul').removeClass('dropdownvisible');
div_cld.find('ul').addClass('dropdownhidden');
}
});
I have written a small JQuery plugin that creates a dropdown box based on bootstrap. I have written it to where a data attribute supplies a url that produces the list items. After the ajax call, Jquery loops through the list items and inserts them into the dropdown menu. Here is what I do not understand, the plugin takes a div with the class of .combobox and appends the required html to make the combobox. It uses two functions, _create() and _listItems(). _create() actually adds the html and calls on _listItems() to make the ajax call and it returns the list items to be appended. Looks like this:
;(function ( $, window, document, undefined ) {
var Combobox = function(element,options) {
this.$element = $(element);
this.$options = $.extend({}, $.fn.combobox.defaults, options);
this.$html = {
input: $('<input type="text" placeholder="[SELECT]" />').addClass('form-control'),
button: $('<div id="test"/>').addClass('input-group-btn')
.append($('<button />')
.addClass('btn btn-default input-sm')
.append('<span class="caret"></span>'))
}
this.$list_type = this.$element.attr('data-type');
this.$url = this.$element.attr('data-url');
this.$defaultValue = this.$element.attr('data-default');
this._create();
this.$input = this.$element.find('input');
this.$button = this.$element.find('button');
this.$list = this.$element.find('ul')
this.$button.on('click',$.proxy(this._toggleList,this));
this.$element.on('click','li',$.proxy(this._itemClicked,this));
this.$element.on('mouseleave',$.proxy(this._toggleList,this));
if(this.$defaultValue) {
this.selectByValue(this.$defaultValue);
}
}
Combobox.prototype = {
constructor: Combobox,
_create: function() {
this.$element.addClass('input-group input-group-sm')
.append(this.$html.input)
.append(this._listItems())
.append(this.$html.button);
},
_itemClicked: function(e){
this.$selectedItem = $(e.target).parent();
this.$input.val(this.$selectedItem.text());
console.log(this.$element.find('[data-value="W"]'))
this._toggleList(e);
e.preventDefault();
},
_listItems: function() {
var list = $('<ul />').addClass('dropdown-menu');
$.ajax({
url: this.$url,
type: 'POST',
data: {opt: this.$list_type},
success:function(data){
$.each(data,function(key,text){
list.append($('<li class="listObjItem" data-value="'+text.id+'">'+text.value+'</li>'));
})
}
})
return list
},
selectedItem: function() {
var item = this.$selectedItem;
var data = {};
if (item) {
var txt = this.$selectedItem.text();
data = $.extend({ text: txt }, this.$selectedItem.data());
}
else {
data = { text: this.$input.val()};
}
return data;
},
selectByValue: function(value) {
var selector = '[data-value="'+value+'"]';
this.selectBySelector(selector);
},
selectBySelector: function (selector) {
var $item = this.$element.find(selector);
if (typeof $item[0] !== 'undefined') {
this.$selectedItem = $item;
this.$input.val(this.$selectedItem.text());
}
else {
this.$selectedItem = null;
}
},
enable: function () {
this.$input.removeAttr('disabled');
this.$button.children().removeClass('disabled');
this.$button.on('click',$.proxy(this._toggleList,this));
},
disable: function () {
this.$input.attr('disabled', true);
this.$button.children().addClass('disabled');
this.$button.off('click',$.proxy(this._toggleList,this));
},
_toggleList: function(e) {
if(e.type == 'mouseleave') {
if(this.$list.is(':hidden')) {
return false;
} else {
this.$list.hide();
}
} else {
this.$list.toggle();
e.preventDefault();
}
}
}
$.fn.combobox = function (option) {
return this.each(function () {
if (!$.data(this, 'combobox')) {
$.data(this, 'combobox',
new Combobox( this, option ));
}
});
};
$.fn.combobox.defaults = {};
$.fn.combobox.Constructor = Combobox;
})( jQuery, window, document );
The problem is that after the items are appended to the DOM, everything is selectable accept the list items. I currently have an .on() statement that binds the click event with the list item. To test this out I have used console.log(this.$element.find('[data-value="W"]') and it does not return an element, however if I place that same console log in the click callback of the list item it will return the element and it is selectable. Am I doing something wrong?
EDIT
I have pasted the entire plugin to save on confusion.
Hi I have a JQuery plugin that takes an array of Orders and creates rows for each Order in the array. No issues here. However if one of these Orders meets a condition it should add a textbox in one of the TD cells. When I debug I can see it adding the textBox but when the next row is created which requires a textBox the previous textbox gets removed. i have this inside a close so not sure what to do. So the result is I only get textboxes in the last row.
If I add the textBox as html it works fine but I want it as a plugin as I need to bind several events KeyUp/Down MouseWheel, Click. etc
The textbox plugin control (gep_inputcontrol) just creates the html and binds events, nothing fancy.
Any help appreciated.
var _table = $('#orderTable', this);
for (var i = 0; i < params.orders.length; i++) {
var row = createRow(params.orders[i]);
_table.append(row);
}
function createRow(order){
var unmatchedStake = (order.requestedStake - order.matchedStake);
var partMatched = (unmatchedStake > 0);
var tr = $(String.format('<tr id="order_{0}" class="{1}"/>' ,order.orderId, ((i % 2) == 0) ? 'gep-altrow' : 'gep-row'));
tr.append(String.format('<td class="gep-icon gep-status">{0}</td>', order.orderStatusId));
tr.append(String.format('<td class="gep-selectionname">{0} {1} {2}</td>', GBEUtils.getEventName(order.eventClassifierFullName()), gep._settings.resources.general.polarity[order.polarityId], order.selectionName()));
tr.append(String.format('<td class="gep-odds betSlipRowPrice">{0}</td>', order.averageMatchedPrice));
tr.append(String.format('<td class="gep-unmatched betSlipRowStake">{0}</td>', com.base.formatDecimal(order.requestedStake - order.matchedStake,2)));
tr.append(String.format('<td class="gep-matched">{0}</td>', com.base.formatDecimal(order.matchedStake,2)));
tr.append(String.format('<td class="gep-action"><span class="gep-icon"/></td>', order.orderStatusId));
//var tablerow = $(String.format('#order_{0}',order.orderId), _table);
//(function (_table, tr, i, unmatchedStake, tablerow) {
if(unmatchedStake > 0)//part matched
{
$('.gep-unmatched', tr).gep_inputcontrol({
type:'STAKE',
ccSymbol:clientObject.state.ccSymbol,
value: unmatchedStake,
decimalValue:unmatchedStake,
onMouseWheeled: function(e, ev){
gep.inputControlWheeled(e, ev);
gep.calculateRowProfit(e, false);
return false;
},
onArrowClicked: function(e){
gep.onArrowClick(e);
return false;
}
});
//$('.gep-unmatched', tr).html($('.gep-unmatched', tr).html());
$('.gep-odds', tr).gep_inputcontrol({
type:'PRICE',
value:order.requestedPrice,
decimalValue:order.requestedPrice,
onMouseWheeled: function(e, ev){
gep.inputControlWheeled(e, ev);
gep.calculateRowProfit(e, false);
return false;
},
onArrowClicked: function(e){
gep.onArrowClick(e);
return false;
}
});
$('.gep-action .gep-icon', tr).addClass("gep-icon-delete");
$('.gep-icon-delete', tr).bind("click", function(){
alert("delete");
toggleCurrentBetSlipBet(this);
return false;
});
}
// })(_table, tr, i, unmatchedStake, tablerow);
return tr;
}
The textbox plugin creates a table with input box and two anchor tags.
/********************
GEP.gep_inputcontrol // stake input, price input box
********************/
(function ($) {
var _templatePrice = $('<table class="gep-inputcontrol" cellpadding="0" cellspacing="0"><tr><td rowspan="2"><input type="text" size="5" class="gep-inputcontrol-price" /></td><td><a tabindex="-1" href="javascript:void(0);" class="gep-inputup"></a></td></tr><tr><td> <a tabindex="-1" href="javascript:void(0);" class="gep-inputdown"></a> </td></tr></table>');
var _templateStake = $('<table class="gep-inputcontrol" cellpadding="0" cellspacing="0"><tr><td rowspan="2"><span class="gep-ccsymbol" /> <input type="text" size="5" class="gep-inputcontrol-stake" /> </td> <td> <a tabindex="-1" href="javascript:void(0);" class="gep-inputup"></a></td></tr><tr><td> <a tabindex="-1" href="javascript:void(0);" class="gep-inputdown"></a> </td></tr> </table>');
var _template;
var _settings = null;
var _instance;
var methods = {
init: function (options) {
_settings = options;
//options.type = 'STAKE'or 'PRICE'
_template = (options.type == 'STAKE')? _templateStake: _templatePrice;
$('.gep-ccsymbol',_template).html(options.ccSymbol);
this.html(_template);
$('input', this).attr('value', options.value);
$('input', this).attr('initialvalue', options.decimalValue);
$('input', this).attr('decimalValue', options.decimalValue);
$('input', this).bind("mousewheel", function (ev) {
_settings.onMouseWheeled.call(null, this, ev.originalEvent);
});
$('.gep-inputup', this).bind("click", function (e) {
_settings.onArrowClicked.call(null, this);
});
$('.gep-inputdown', this).bind("click", function (e) {
_settings.onArrowClicked.call(null, this);
});
_instance = this;
return this;
},
show: function (params) {
alert("show" + params);
},
hide: function () {
// GOOD
},
update: function (content) {
// !!!
}
};
$.fn.gep_inputcontrol = function (method) {
// Method calling logic
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.gep_inputcontrol');
}
};
})(jQuery);
To elaborate a bit more, I did some small unit tests
This works..
$('.gep-odds', clientObject.liveBetsPane).gep_inputcontrol({
type: 'PRICE',
value: 5,
decimalValue: 5,
onMouseWheeled: function (e, ev) {
gep.inputControlWheeled(e, ev);
gep.calculateRowProfit(e, false);
return false;
},
onArrowClicked: function (e) {
gep.onArrowClick(e);
return false;
}
});
This does NOT work...(Only puts TEXT box in last row) But I need to do it this way as I need values of each row.
$('.gep-odds', clientObject.liveBetsPane).each(function () {
$(this).gep_inputcontrol({
type: 'PRICE',
value: 5,
decimalValue: 5,
onMouseWheeled: function (e, ev) {
gep.inputControlWheeled(e, ev);
gep.calculateRowProfit(e, false);
return false;
},
onArrowClicked: function (e) {
gep.onArrowClick(e);
return false;
}
});
});
I removed dollar from the template and it worked fine.
var _templatePrice = $('<table cla...
is now
var _templatePrice = '<table cla...
Although it sets the html for the last row it was moving for the other rows.
Thanks to me.... :)