I'm building a simple asp page on which I have list of peoples with checkbox on left of every name.
I've managed to create a simple jQuery script that allows hiding and showing rows of table based on input:
http://jsfiddle.net/Tq97v/ (first part)
As You can see I can enter part of name and then specific row are hidden.
Using red "x" I can uncheck all checkboxes.
What I'm trying to do now is to change that static red "x" into tristate checkbox.
Don't have idea how to even start.
Do I must add change listener to every checkbox in my list?
Second thing - how to create multiple instances of the same "plugin" on site.
Right now I'm identifying input by it, but it would be nice to call function with that input as param, and it would fine table after that input and create necessary logic.
This way I could call function multiple times on page to have more than one list.
I'm not asking for whole solution (of course it is always welcome :) ) but what I need is idea how to accomplish this in efficient way and as optimized as possible, because sometimes my list has 500+ elements.
P.S. don't look at HTML code, it is ASP generated.
I found this plugin: https://github.com/bcollins/jquery.tristate, but I have no idea how to use it with my list.
UPDATE:
I've managed to turn my code into functions, but right now I must call 3 functions for every list.
Here is my updated code: http://jsfiddle.net/65MEV/4/
How can I change it to one function? Will it be better?
This is my updated code. Still thinking about way of doing that Indeterminate Checkbox instead of my remove image.
UPDATE2
I build working code :)
http://jsfiddle.net/65MEV/9/
But I would like to improve it as much as possible.
Any suggestions are welcome!
A tristate checkbox is like the Three-Portal Device: an illusion.
What you actually want is to make the checkbox indeterminate (by setting the property of the same name to true). To implement this, you will need a change (or click) handler on each checkbox, then you'll need to check if all of them are in the same state, and if not then you set the indeterminate property. It's a hassle, really, because you rarely see indeterminate checkboxes and so most users don't know what to do with them. To be avoided, if possible.
To create multiple instances of the same plugin access elements relatively to an other element.
For example: in your case instead of keeping the item in a jQuery object var $tableRows = $('table.myList tr'); access them in the event.
$('#user_name').keyup(function () {
var sValue = $.trim($('input#user_name').val());
if(lastInput==sValue) return;
var $tableRows = $(this).next().next().find("table.myList tr");
if (sValue == '') {
$tableRows.show();
} else {
$tableRows.each(function () {
var oLabel = $(this).find('label');
if (oLabel.length > 0) {
if (oLabel.text().toLowerCase().indexOf(sValue.toLowerCase()) >= 0) {
$(this).show();
} else {
$(this).hide();
}
}
});
lastInput=sValue;
}
});
and you only have your actual list.
And for the tree state checkbox you don t need a plugin just add a button or link and every click check it status you can keep the status by jQuery data and change the element image according to this data.
Related
I am new to jQuery so please go easy, I have a form that will represent an Advanced Search. Users will be able to add rows to refine their specific search.
Each row has 3 elements: A Checkbox & 2 x Select boxes.
As can be seen in the fiddle I am using jquery to clone the row and place the cloned row after the last row.
Everything is working fine except visually I would like the checkbox to use Bootstrap-Switch http://www.bootstrap-switch.org/
And the select boxes to use Selectize https://github.com/brianreavis/selectize.js
Now, when I clone the row with these plugins not active, everything works.
I have NO idea how to re-render or re activate them once a new row is inserted.
Is this something that is plugin specific? Or kind of universal to jquery?
I have read HEAPS of answers on here about similar things but I cannot seem to get it right.
Here is the jquery snippet:
$adSearchForm = $('#adSearchForm');
$adSearchForm.on('click', 'button, input, select, option', function (event) {
console.log("Button Clicked", event)
});
$('#addSearchRow').click(function(event){
$('[data-content=adSearch-3]:first').clone().insertAfter('[data-content=adSearch-3]:last');
// $('.searchByField,.searchOperator').selectize({refreshItems: true});
// $('[data-toggle=switch]').bootstrapSwitch({refreshItems: true});
});
Here is the fiddle, hope its ok. http://jsfiddle.net/CkVQr/6/
Thankyou very much for your help.
Cheers
Plugins change your HTML
There are two major problems you may not be fully aware of with your code:
Whenever you do a .clone() it merely deep clones your DOM element subtree, but not any event handlers bound to cloned elements.
Your .selectize() plugin changes HTML of your form quite considerably, converting input elements to other things. So whenever you clone your already converted select filter row, and subsequently want to run .selectize() on it again, this particular plugin won't find any suitable input elements to convert. Hence it won't work. Everything will just look as it should but won't work.
What can be done?
The main idea is that whenever you clone your search filter row, you have to clone your original HTML and not after it was converted using your plugins.
HTML Templates to the rescue
One of the possibilities is to change you page (and functionality) a bit and put your search filter row in a template and always use that. When you create your first row, you should read the template (and cache it) and add+convert it on your page. When you'd add an additional row, just use the same cached template and add+convert it again.
HTML template
<script id="filterRow" type="text/x-template">
<!-- Your filter rown HTML goes in here -->
</script>
Some Javascript
var cachedTemplate = cachedTemplate || $("#filterRow").html();
...
$('#addSearchRow').click(function(evt) {
var newRow = cachedTemplate.clone(); // clone for reusability
newRow.insertAfter('[data-content=adSearch-3]:last');
newRow.selectize();
...
});
I'm fairly new to JS and am trying to write my own library using this blog post, and would like a hand. (Apologies if this is too vague for an SO question)
I'm trying to write a function that shows or hides a queried element based on the status of a queried checkbox (and another for a radio button if I can't do it in one method) on a form.
So I'm looking to end up with something like this:
$(divId).checkToggle(checkBoxId);
So the div will start as hidden. When the checkbox is clicked, the div will toggle to visible. When the checkbox is unchecked, I'd like the div to hide again and any input fields inside it to be cleared (the probably will be only one input field).
I know that this function isn't really going to be very combine-able or reusable, but I would use it so often for just that one thing that I'm going to overlook it.
Okay, enough preamble. Here's what I have so far.
Could I have some suggestions on how to change/finish my checkToggle method? Thanks!
This worked for me:
$(document).ready(function(){
$('#checkbox1').change(function() {
if($(this).attr('checked')) {
$("#myDiv").slideDown(1000);
}
else
{
$('#myDiv').slideUp(1000);
}
});
});
please run this jsfiddle as an example.
http://jsfiddle.net/AFzqt/11/
in my example, i have a link saying same as above, if you fill out the first box it will copy the value in the second box. look at the code, and look at the display. theres a reiteration of the code just to have the boxes appear twice. well... in my real use of this, i ideally want there to be about 40 of these buttons.
is there a way to do this without copying the code 40 times?
i am new to jquery, usually in another language i would just pass in arguments, but with this syntax I don't see how i can do that? how can i handle this?
feel free to dabble around on my jsfiddle, and hopefully link a new revision, with the goal of reducing the handling of those 2 'same as above' buttons into just one function with the entry id's as parameters
If you add the changeButton class to each of the buttons it will be easier to select each of them to bind the event handler:
Same as Above
Then we can select each of the elements like so:
$(".changeButton").on("click", function(e) {
//select the previous jQuery Mobile select widgets, we will use just the previous two
var $allPrev = $(this).prevAll('.ui-select').find('select');
//change the value of the immediate previous select widget to the value of the one preceding it
$($allPrev[0]).val($($allPrev[1]).val()).selectmenu("refresh");
e.preventDefault();
});
Here is a demo: http://jsfiddle.net/AFzqt/12/
This code will work for umpteen buttons since it works by using intuitive knowledge of the HTML structure (each link uses the previous two select widgets, no matter where on the page the link resides).
What about something like this?
function bind_click(button_id, target_id, origin_id) {
$(button_id).on("click", function(e) {
$(target_id).val($(origin_id).val());
$(target_id).selectmenu("refresh");
e.preventDefault();
});
}
$(function() {
bind_click("#changeButton2", "#entry_20", "#entry_18");
bind_click("#another", "#entry", "#entry2");
// More binding declarations
});
I am new to JavaScript and jQuery, but have used HTML and CSS before. In any case, I appreciate the help. I have implemented the script discussed here http://net.tutsplus.com/tutorials/javascript-ajax/using-jquery-to-manipulate-and-filter-data/ for filtering data and the one discussed here http://www.dustindiaz.com/check-one-check-all-javascript/ for a check one to check all script. The problem is, when I filter the list of items and then use the check all box, it is checking even the JS items that are hidden from the user due to filtering. Does this make sense?
I have been trying to figure out how to edit the check all script so that only items with the "visible" class (as added to visible checkboxes with the filtering script) are checked with the checkAll button. The original script had:
var checks = document.getElementsByName('del[]');
I was trying to do something like this (it wasn't working, of course):
var visiblechecks = $('input:del[]:checked.visible');
among other things.
Thank you! Also, if you have a recommended resource, I would appreciate it.
var visiblechecks = $('input[name="del[]"]:checked:visible');
Your selector just needs a bit of refinement. Try:
$(".myCheckAllSelector").change(function () {
$("input[name='del[]']:visible").attr("checked", $(this).is(":checked"));
});
This should set the checked attribute of all currently visible checkboxes with the name del[] to the checked status of the check all box. You simply need to update the check all selector appropriately to target your master checkbox element.
You don't necessarily "need" to add a visible class as there is a :visible filter you can use to make that determination for you. However, just change your selector from input to input.visible if you still wish to use the class and remove the :visible filter..
I have set up the following JSFiddle to demonstrate what I am doing. As you can see, I have various inputs. Each input has a checkbox to add an additional row. If a checkbox is checked, it should add a new input underneath the checked input.
Now what I have seems to do that without any problems - although it could probably be improved.
At the moment I am having issues with
$(this).closest(".labelAndInput").remove();
So each section (I have given them different background colours to show the sections) should only be allowed to have one additional input. At the moment, if I check the box, uncheck it, then check it again, it adds a third input.
The above problem can probably be solved with the following. If a checkbox is unchecked, it should remove the cloned div. This is where I am having issues at the moment. How can I remove the clone if the checkbox is unchecked? It should remove the div it is related too, and not a random clone.
Any information appreciated.
Thanks
Simply give your clone a class to identify it exactly. jsfiddle
$(function() {
$('input:checkbox[name="labelNewline"]').change(function() {
if ( $(this).is(':checked') ){
var clone = $(this).parent().siblings(".labelAndInput").first().clone().insertAfter($(this).parent());
clone.addClass('clone');
} else {
$(this).parent().siblings(".clone").remove();
}
});
});