onchange javascript click event cancels the other one out - javascript

Here is the essencial part of my custom code. I believe the onchange function is in confict with the function with the 3rd party plugin im using which also targets the same "option" tag.
jQuery(document).ready(function(e) {
var t = e("#filter-container");
t.imagesLoaded(function() {
t.isotope({
itemSelector: "figure",
filter: "*",
resizable: false,
animationEngine: "jquery"
})
});
$("select").on("change", function() {
var select = $(this);
var selectedOption = select.find("option:selected");
var r = selectedOption.attr("data-filter");
t.isotope({
filter: r
});
return false
});
e(window).resize(function() {
var n = e(window).width();
t.isotope("reLayout")
}).trigger("resize")
})
and here the probable culprit from the dropdown plugin im using. It is much longer than that but here the function that worries me which probably blocks my script:
$("select").on("change", function() {
var select = $(this);
var selectedOption = select.find("option:selected");
var n = select.parents(".filter-buttons");
var r = selectedOption.attr("data-filter");
t.isotope({
filter: r
});
return false
});
both function are part of seperate scripts so I cant join them together. Is there any way to make the second function not cancel the first one out?
http://jsfiddle.net/snz0gkkk/10/

I tried to use your fiddle, but it didn't seem to work.
Try adding a unique namespace to your change event.
$("select").on("change.optionChange", function() {
var select = $(this);
var selectedOption = select.find("option:selected");
var r = selectedOption.attr("data-filter");
t.isotope({
filter: r
});
return false
});

Related

How to change fancytree SelectMode on a button click event?

I am using the a tree view/tree grid plugin which is called fancytree (Here is the link)
I initially (when the page loads) set the selectMode to 2 which allows the users to select multiple options.
// Init
$("#Organizations .OrgTree").each(function () {
var $this = $(this);
var organizationUnitId = $this.data("orgid");
//var treeData = JSON.parse($("#treeData_" + organizationUnitId).val());
$this.fancytree({
extensions: ["persist"],
selectMode: 2,
persist: {
expandLazy: true
store: "auto" 'session': sessionStore
},
icons: false,
checkbox: true,
toggleEffect: null, //disable animations
source: window["treeData_" + organizationUnitId], // treeData
lazyLoad: function (event, data) {
var node = data.node;
data.result = {
// Some data
};
}
});
});
What I want to do is, when I click on a button, I want to change the selectMode and set it to 1 or 3.
I have tried to read through the documentation and found this as well
But I won't work. Here is some code:
//Bind click to search button
$("#changeSelectModeBtn").click(function () {
debugger;
$("#Organizations .OrgTree").fancytree("getTree").visit(function (node) {
node.setSelected(false);
});
$("#Organizations .OrgTree").fancytree({ selectMode: 3 });
var selectedKeys = [];
$("#Organizations .OrgTree").each(function () {
var $this = $(this);
var orgTree = $(this).fancytree("getTree");
var selectedParentNodes = orgTree.getSelectedNodes();
for (node in selectedParentNodes) {
selectedKeys.push(selectedParentNodes[node].key)
}
// Save orgtree in hidden fields
var organizationUnitId = $this.data("orgid");
var treeData = orgTree.toDict(true);
window["treeData_" + organizationUnitId] = treeData.children; //$("#treeData_" + organizationUnitId).val(JSON.stringify(treeData.children))
});
if (selectedKeys) {
$("#HiddenOrganizationUnitIds").val(selectedKeys.join(","));
}
})
Can someone please help me?
Thanks in advance!
All options can be set dynamically using the jQuery widget pattern.
For example, you can use
$("#tree").fancytree("option", "selectMode", 3);
See also https://github.com/mar10/fancytree/wiki#configure-options

Dynamic dropdowns filtering options with jquery

I am trying to filter one dropdown from the selection of another in a Rails 4 app with jquery. As of now, I have:
$(document).ready(function(){
$('#task_id').change(function (){
var subtasks = $('#subtask_id').html(); //works
var tasks = $(this).find(:selected).text(); //works
var options = $(subtasks).filter("optgroup[label ='#{task}']").html(); // returns undefined in console.log
if(options != '')
$('#subtask_id').html(options);
else
$('#subtask_id').empty();
});
});
The task list is a regular collection_select and the subtask list is a grouped_collection_select. Both which work as expected. The problem is that even with this code listed above I can't get the correct subtasks to display for the selected task.
NOTE: I also tried var tasks=$(this).find(:selected).val() that return the correct number but the options filtering still didn't work.
Try something like this instead (untested but should work).
$(function () {
var $parent = $('#task_id'),
$child = $('#subtask_id'),
$cloned = $child.clone().css('display', 'none');
function getParentOption() {
return $parent.find('option:selected');
}
function updateChildOptions($options) {
$child.empty();
$child.append($options);
}
$parent.change(function (e) {
var $option = getParentOption();
var label = $option.prop('value'); // could use $option.text() instead for your case
var $options = $cloned.find('optgroup[label="' + label + '"]');
updateChildOptions($options);
});
});

How to combine 2 isotope filter javascript functions?

Hi I have successfully setup isotope filtering with multiple drop downs using this js code -
jQuery(function() {
var $container = $('#isocontent'),
$select = $('div#filterGroup select');
filters = {};
$container.isotope({
itemSelector: '.box'
});
$select.change(function() {
var $this = $(this);
var $optionSet = $this;
var group = $optionSet.attr('data-filter-group');
filters[group] = $this.find('option:selected').attr('data-filter-value');
var isoFilters = [];
for (var prop in filters) {
isoFilters.push(filters[prop])
}
var selector = isoFilters.join('');
$container.isotope({
filter: selector
});
return false;
});
});
And on the same page I was able to setup a live search input field using the quicksearch.js plugin and isotopes by using this code -
<script type="text/javascript">
$(function () {
$('input#id_search').quicksearch('#isocontent.box');
});
</script>
<script type="text/javascript">
$(function() {
var $container = $('#isocontent');
$container.isotope({
itemSelector: '.box'
});
$('input#filter').quicksearch('#isocontent .box', {
'show': function() {
$(this).addClass('quicksearch-match');
},
'hide': function() {
$(this).removeClass('quicksearch-match');
}
}).keyup(function(){
setTimeout( function() {
$container.isotope({ filter: '.quicksearch-match' }).isotope();
}, 100 );
});
});
</script>
The live search and drop downs work, except they are not working together. When doing a search, it will find the content as should - hiding the irrelevant content- but when filtering with the drop downs, it seems to reset or ignore the filtering done by the live search. Is there away to get the two functions to work together and possibly combine the script into one script??
Any help is appreciated, thanks.
Here is how i have done it.
First, I register a simple text filter.
Then in case a button is clicked, I "extend" this filter by redefining it (by passing a function to isotope's filter option).
If no button is clicked, I re-register the simple text filter.
Isotope initialization:
var qsRegex; // global variable
var $grid = $(container).isotope({
resizable: true,
masonry: {
columnWidth: columnWidth
},
filter: function() {
return qsRegex ? $(this).text().match( qsRegex ) : true;
}
});
Then my keyup event on the input:
var tabPane = $('.tab-pane.active');
var $quicksearch = tabPane.find('.quicksearch').unbind().keyup( debounce( function() {
qsRegex = new RegExp($quicksearch.val(), 'gi');
$grid.isotope();
}, 200 ) );
Then my click event on the buttons:
(simplified)
The addition of $(this).hasClass(filter) is what is important here.
$('.gender-switch').click(function() {
if ($(this).hasClass('active') == false) {
var filter = $(this).attr('data-filter');
var my_combined_filter = function() {
return qsRegex ? ($(this).text().match( qsRegex ) && $(this).hasClass(filter)) : true;
}
$('.tab-pane.active .gallery').isotope({ filter: my_combined_filter });
} else {
// none of the buttons have been selected.
// reset to the simple filter
$('.tab-pane.active .gallery').isotope({ filter: '*' });
var my_simple_filter = function() {
return qsRegex ? $(this).text().match( qsRegex ) : true;
}
$('.tab-pane.active .gallery').isotope({ filter: my_simple_filter });
}
});
Extra: the debounce function in the keyup event
// debounce so filtering doesn't happen every millisecond
function debounce( fn, threshold ) {
var timeout;
return function debounced() {
if ( timeout ) {
clearTimeout( timeout );
}
function delayed() {
fn();
timeout = null;
}
timeout = setTimeout( delayed, threshold || 100 );
}
}

jQuery click inside each loop

I want to loop my click events, to make the code shorter. I might have 30 of these values later on.
My working code
$(document).ready(function () {
var last_click = '';
$("#title").click(function() { last_click = 'title'; });
$("#subtitle").click(function() { last_click = 'subtitle'; });
$("#test").click(function() { last_click = 'test'; });
});
This is how I want it (not working)
My guess is that the each-loop runs on dom ready and then never again and that way the click-event can never be triggered?
$(document).ready(function () {
var last_click = '';
var contents = new Array();
contents = ['title', 'subtitle', 'test'];
$.each(contents , function(index, value){
$("#" + value).click(function() { last_click = value; });
});
});
If there is not solved like I would, I would be thankful for a nice workaround.
I would rather add a class to all elements you want to bind this to, eg class="last-click"
and define the binding once as:
$(".last-click").on('click', function() {
last_click = this.id;
}
If you really wanted to make it shorter, give them all a similar class.
$(document).ready(function () {
var last_click = '';
$(".theclass").click(function() {
last_click = this.id;
});
});
if you have value attribute for your buttons or elements, you can do it:
$(document).ready(function() {
var last_click = '';
$("input").click(function() {
last_click = $(this).attr('value');
alert(last_click);
});
});​
I assumed that you are using "input type="button". Also here is the demo you can see it in action: http://jsfiddle.net/rS2Gb/5/

How to get jQuery placeholder/watermark plugin to work for ajax loaded text fields?

I'm using the following placeholder plugin
(function($){
var ph = "PLACEHOLDER-INPUT";
var phl = "PLACEHOLDER-LABEL";
var boundEvents = false;
var default_options = {
labelClass: 'placeholder'
};
//check for native support for placeholder attribute, if so stub methods and return
var input = document.createElement("input");
if ('placeholder' in input) {
$.fn.placeholder = $.fn.unplaceholder = function(){}; //empty function
delete input; //cleanup IE memory
return;
};
delete input;
//bind to resize to fix placeholders when the page resizes (fields are hidden/displayed, which can change positioning).
$(window).resize(checkResize);
$.fn.placeholder = function(options) {
bindEvents();
var opts = $.extend(default_options, options)
this.each(function(){
var rnd=Math.random().toString(32).replace(/\./,'')
,input=$(this)
,label=$('<label style="position:absolute;display:none;top:0;left:0;"></label>');
if (!input.attr('placeholder') || input.data(ph) === ph) return; //already watermarked
//make sure the input tag has an ID assigned, if not, assign one.
if (!input.attr('id')) input.attr('id', 'input_' + rnd);
label .attr('id',input.attr('id') + "_placeholder")
.data(ph, '#' + input.attr('id')) //reference to the input tag
.attr('for',input.attr('id'))
.addClass(opts.labelClass)
.addClass(opts.labelClass + '-for-' + this.tagName.toLowerCase()) //ex: watermark-for-textarea
.addClass(phl)
.text(input.attr('placeholder'));
input
.data(phl, '#' + label.attr('id')) //set a reference to the label
.data(ph,ph) //set that the field is watermarked
.addClass(ph) //add the watermark class
.after(label) //add the label field to the page
//setup overlay
itemFocus.call(this);
itemBlur.call(this);
});
};
$.fn.unplaceholder = function(){
this.each(function(){
var input=$(this),
label=$(input.data(phl));
if (input.data(ph) !== ph) return;
label.remove();
input.removeData(ph).removeData(phl).removeClass(ph).unbind('change',itemChange);
});
};
function bindEvents() {
if (boundEvents) return;
//prepare live bindings if not already done.
$("form").live('reset', function(){
$(this).find('.' + ph).each(itemBlur);
});
$('.' + ph)
.live('keydown',itemFocus)
.live('mousedown',itemFocus)
.live('mouseup',itemFocus)
.live('mouseclick',itemFocus)
.live('focus',itemFocus)
.live('focusin',itemFocus)
.live('blur',itemBlur)
.live('focusout',itemBlur)
.live('change',itemChange);
;
$('.' + phl)
.live('click', function() { $($(this).data(ph)).focus(); })
.live('mouseup', function() { $($(this).data(ph)).focus(); });
bound = true;
boundEvents = true;
};
function itemChange() {
var input = $(this);
if (!!input.val()) {
$(input.data(phl)).hide();
return;
}
if (input.data(ph+'FOCUSED') != 1) {
showPHL(input);
}
}
function itemFocus() {
$($(this).data(ph+'FOCUSED',1).data(phl)).hide();
};
function itemBlur() {
var that = this;
showPHL($(this).removeData(ph+'FOCUSED'));
//use timeout to let other validators/formatters directly bound to blur/focusout work
setTimeout(function(){
var input = $(that);
//if the item wasn't refocused, test the item
if (input.data(ph+'FOCUSED') != 1) {
showPHL(input);
}
}, 200);
};
function showPHL(input, forced) {
var label = $(input.data(phl));
//if not already shown, and needs to be, show it.
if ((forced || label.css('display') == 'none') && !input.val())
label
.text(input.attr('placeholder'))
.css('top', input.position().top + 'px')
.css('left', input.position().left + 'px')
.css('display', 'block');
//console.dir({ 'input': { 'id':input.attr('id'), 'pos': input.position() }});
}
var cr;
function checkResize() {
if (cr) window.clearTimeout(cr);
cr = window.setTimeout(checkResize2, 50);
}
function checkResize2() {
$('.' + ph).each(function(){
var input = $(this);
var focused = $(this).data(ph+'FOCUSED');
if (!focused) showPHL(input, true);
});
}
}(jQuery));
It applies the placeholder attribute to form fields in browsers that do not natively support the placeholder attribute (ex. IE9). It works for statically loaded text fields, however for text fields that are loaded via ajax, the placeholder does not appear.
Is it possible to achieve this 'watermark' effect on text fields that are loaded via ajax?
What happens if you trigger the window resize function after adding in new inputs?
$(window).trigger('resize')
You could apply the plugin to newly created controls after the AJAX call completes. Forgive the pseudo-code as I'm not really sure about how your AJAX calls are working:
$.ajax({
url: "test.html",
cache: false
}).done(function( result ) {
field = $('<input>').html(result);
$("#results").append(field);
field.placeholder();
});
Another option is that you could use jQuery's .on() method to bind dynamically created controls to the function--but it wants an event (like click). I'm not sure how you would do that. Maybe something like this:
$( 'body' ).on('click','input.addField', function(e){
$(this).placeholder();
});
I know this won't work, but maybe it helps get you brainstorm solutions.

Categories