Why is this bit of javascript making my checkboxes difficult to check? - javascript

My app has a form which uses checkboxes to sort results by type and area. There are 2 fieldsets, one for the types and one for the areas.
The area checkboxes are linked to areas of an imagemap so it too can be used to select multiple areas to sort by.
I have this javascript:
This links the area checkboxes and the areas of the imagemap so they both act as form inputs
var $area = $('area');
$area.click(function(){
var $checkbox = $('#' + $(this).data("areanum"));
$checkbox.attr('checked', !$checkbox.attr('checked')).button('refresh');
});
$('label').click(function () {
$area.filter('[data-areanum="' + $(this).attr('for') + '"]').trigger('click');
return true;
});
This breaks the type checkboxes (they won't register as being checked when the form is submitted), unless I change the bit:
$('label').click(function () {
$area.filter('[data-areanum="' + $(this).attr('for') + '"]').trigger('click');
return false;
});
to
$('label').click(function () {
$area.filter('[data-areanum="' + $(this).attr('for') + '"]').trigger('click');
return true;
});
(changed the last line to return true)
But this makes the checkboxes difficult to select, they respond to a single click if the tick area is clicked but only respond to a double click if the checkbox label is clicked.
I hope this makes sense, if any clarification is needed I'll try to word the problem better.
Thanks for any help.

I think you don't need the label click handler at all because you are just toggling the checkbox checked property by triggering the area click handler which will be taken care by label's default behavior itself when it's for attribute is set to the checkbox id.

Related

Combine javascript functions to work together

I am building a search form that filters the results based on the a text input as well as select options from four separate drop-downs (category, sub-category, location, etc).
The following two functions work well, but I just realized that if I type a search term in the input, make my drop-down selections and then go back and type a different search term, my drop-downs are ignored.
I've found solutions for similar problems across this site, but nothing that pertains to my particular situation.
This is the filter for the drop-downs:
$("select.filterby").change(function(){
var filters = $.map($("select.filterby").toArray(), function(e){
return $(e).val();
}).join(".");
$("div#flatdiv").find("article").hide();
$("div#flatdiv").find("article." + filters).show();
});
and Here is the one the filters based on the search input:
$(document).ready(function(){
$("#title").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#flatdiv article").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
One is using true .filter() and the other is using .find to show() and hide().
I'm not sure where to go from here. I've made various attempts but each results in neither working so I'm hoping someone can help me out.
UPDATE:
Here is the final that ended up working beautifully!
//apply selection form any drop down forms
$("select.filterby").change(function(){
var filters = $.map($("select.filterby").toArray(), function(e){
return $(e).val();
}).join(".");
$("div#flatdiv").find("article").addClass("hidden-by-category-filter");
$("div#flatdiv").find("article." + filters).removeClass("hidden-by-category-filter");
});
//apply text input from search form
$("#title").blur(function(){
var textFilters = $(this).val().toLowerCase();
$("article:contains(" + textFilters +")").removeClass("hidden-by-text-filter");
$("article:not(:contains(" + textFilters +"))").addClass("hidden-by-text-filter");
});
In such cases, instead of using .hide() and .show(), it is often better to just add CSS classes to elements to hide them.
I would create classes such as .hidden-by-text-filter and .hidden-by-category-filter, each would individually hide the elements:
.hidden-by-text-filter, .hidden-by-category-filter {
display: none;
}
Then in the event handler just add or remove a specific class. For example, the event handler on text input would add/remove the class .hidden-by-text-filter, while the category drop-down would add/remove the class .hidden-by-category-filter.
$("select.filterby").change(function() {
var filters = $.map($("select.filterby").toArray(), function(e) {
return $(e).val();
}).join(".");
$("div#flatdiv").find("article").addClass(".hidden-by-text-filter");
$("div#flatdiv").find("article." + filters).removeClass(".hidden-by-text-filter");
});
This way both those filters wouldn't interfere with each other. If an element is meant to be hidden through both criteria, it would have both those classes, and still remain hidden. If one such element is made visible by one of the filters, it would still have the other class, and will remain hidden.

problem with a jQuery function repetition

I'm trying to make a form generator but I'm stuck. With this code below I make a form (id=formLabel) visible to type the label of the generated form and submit this formLabel move the label typed in another block where the generated form will be.
My problem is: the first time I submit the label, one label is created but the second time, the new label typed is created twice, and third the third time...
Thanks for your help !
//Hide the 3 forms
$("#formLabel,#formTxt,#formButton").hide();
//Clic on button label= form visible
$("#label").on("click", function() {
$("#formLabel").show();
$("#formTxt,#formButton").hide();
//submit the form=move the label in a block named left, where the generated form will be.
$("#formLabel").submit(function(e) {
var labelEntre = $(".zone").val();
$("<span style='margin:50px;' id='span' style='float:left;'>" + labelEntre + "</span>").appendTo($("#left"));
e.preventDefault();
});
});

Html select not changes option on click after jquery instant filter in jsp

I have 3 select tags on one page, generated from struts2 select tag. I am using a jQuery filter function that filters the select. One textfield for every select, but all of them use the same filter function. I have another js function that is called on onChange event.
The problem is that before adding this jQuery function i was filtering the lists with form submit and reload the page and now the filtration happens instant, but when i write a filtration criteria the select somehow the select loses focus and when i click an element no select happens, or better lets say is a kind of select: the element is circled with a dotted line, not selected with a blue filled square. The js is called, the form submitted, but with the old value. However, if i first click in the select where are no elements (empty zone) and then i select an element everything is ok. How can i jump over the firs click?
And now my code:
I. The jQuery filter function and the binding to the selects and textfields.
jQuery.fn.filterByText = function(textbox) {
return this.each(function() {
var select = this;
var options = [];
$(select).find('option').each(function() {
options.push({value: $(this).val(), text: $(this).text()});
});
$(select).data('options', options);
$(textbox).bind('change keyup', function() {
var options = $(select).empty().scrollTop(0).data('options');
var search = $.trim($(this).val());
var regex = new RegExp(search,'gi');
$.each(options, function(i) {
var option = options[i];
if(option.text.match(regex) !== null) {
$(select).append($('<option>').text(option.text).val(option.value));
}
});
});
});
};
$(function() {
$('#selectedClientId').filterByText($('#filterClient'));
$('#selectedLocationId').filterByText($('#filterLocation'));
$('#selectedViewPointId').filterByText($('#filterViewpoint'));
});
II. One of the selects:
<s:select size="10" cssStyle="width:220px;"
label="Select a client"
listKey="id" listValue="name"
list="clientSelectList"
name="selectedClientId" id="selectedClientId"
headerKey="-1" headerValue="Client List"
onchange="onChangeSelect()"
/>
III. The select's textfield:
Filter:<s:textfield name="filterClient" id="filterClient" size="15" autocomplete="off"/>
IV. The onChangeSelect():
function onChangeSelect() {
document.getElementById('deviceListForm').action = '<s:url value="/admin/displayDeviceListPage.action"/>';
document.getElementById('deviceListForm').submit();
}
In the image: in the first select is how looks the selected option after jquery filter and in the other 2 selects are "the good" selected options.
http://i.stack.imgur.com/TAJeY.png
EDIT: So, after the first response to this post (Thanks Amit1992) I started digging further. In Mozilla after the first click (after the frame or dotted line appears) a request is made to the server with the old selected item (or null if none selected), the page refreshes as nothing happened.
In Chrome, on the other hand, the first click does not make any request. It just selects (let's say) the select tag. And the second select makes a good request.
Short story:
mozilla: click 1 -> request with old selected value ->refresh -> no changes
chrome: click 1 -> selects the select tag and no request is made -> click 2 -> request as it should happen
IE - works ok. 1 click-> select and load page as it should . OK this really surprises me. at first I thought is useless to look in IE what happens.
EDIT2
After some digging i concluded that the problem is that when typing in the textfield the select loses focus. If I put $('#selectedClientId').focus();
in the filterByText function at the end of the $(textbox).bind('change keyup', function() the fist select is focused after every char written. But this gives me another problem. I can't write more than 1 char at a time. I have to click the textfield, write a char, click again, write a char etc.
May be this will help you. i did some modification in your code.
$(function() {
$('#selectedClientId').filterByText($('#textbox'), false);
$("#selectedClientId").change(function(){
alert("you have selected ++ " + $(this).val());
});
});
I used change() event of jquery instead of javascript onChange().
you can refer this link http://jsfiddle.net/amitv1093/q55k97yc/ and I recommend you to use jquery fully if you are using it.
kindly let me know if it will work.
I solved the problem by changing the whole filter function. The function with problem was taken from a stack overflow question response (How to dynamic filter options of <select > with jQuery?). The problem is, from what I concluded, that the $(textbox).bind('change keyup', function() line was changing the focus on the textfield, so the first click was changing the focus to the select tag. The new function, the one that works was taken from the same post, John Magnolia's answer:
$(document).ready(function() {
filterClient();
filterLocation(); //same as filterClient
filterViewpoint(); //same as filterClient
});
function filterClient(){
var $this, filter,
$input = $('#filterClient'),
$options = $('#selectedClientId').find('option');
$input.keyup(function(){
filter = $(this).val();
$options.each(function(){
$this = $(this);
$this.removeAttr('selected');
if ($this.text().toLowerCase().indexOf(filter.toLowerCase()) != -1) {
$this.show();
} else {
$this.hide();
}
});
});
}

jQuery: set / reset form fields with certain class (improve code)

I am new to jQuery and hope someone here can help me with this.
I have a large HTML form with a hidden div ('#requestDetails').
Within this div there are checkboxes, radio buttons and selects with a certain class on a specific value ('.hiddenDefault') which is used to only apply a default value when they are visible.
Now I have a certain event that shows this div and another one that hides it again.
When showing the div I want to set the above default values.
When hiding it I want to reset the fields, incl. all input fields within that div (i.e. uncheck / unselect them and remove any default or entered values).
I have the following code which looks ok to me at first glance but I would like to know if this is proper / valid code, if I am missing anything here and if there is a better / faster way to achieve the same.
My jQuery:
$('[name=requestType]').on('change', function(){
if($(this).hasClass('triggerDiv')){
$('#requestDetails').find('.hiddenDefault').each(function(){
// set default values + show div
$(this).not('select').prop('checked', true);
$(this).not('input[type=checkbox], input[type=radio]').prop('selected', true);
});
$('#requestDetails').show();
}else{
$('#requestDetails').find('input, select').each(function(){
// empty / reset fields + hide div
$(this).find('input[type=checkbox], input[type=radio]').prop('checked', false);
$(this).find('input').not(':button, :checkbox, :hidden, :radio, :reset, :submit').val('');
$(this).find('select').prop('selected', false);
});
$('#requestDetails').hide();
}
});
Many thanks in advance for any help with this,
Mike
Just improving syntax or style of code you have written:
$('[name=requestType]').on('change', function(){
if($(this).hasClass('triggerDiv')){
// show div + set default values
$(this).not('select').prop('checked', true);
$(this).not('input[type=checkbox], input[type=radio]').prop('selected', true);
$('#requestDetails').show();
}else{
// hide div + reset fields
$('#requestDetails').find('input[type=checkbox], input[type=radio], input, select').not(':button, :checkbox, :hidden, :radio, :reset, :submit').val('').prop('checked', false);
$('#requestDetails').hide();
}
});
Sorry have not checked syntax, so correct me if I am wrong at it.
Not this will improve performance as well as you have written inside each.

Radio button REQUIRED if input field has content

I have a a reasonably quick problem to solve (I think). I have a form online and it validates the required content for the user's data, but has no validation on the first part of the form.
I've been asked however if I can make a radio button REQUIRED depending on whether an input field has been filled in.
The form can be found here:
http://www.elcorteingles.pt/reservas/livros_escolares/form.asp
So if the person start's filling in the input fields on the first line, that the radio buttons in the group become REQUIRED (for either the CDROM ou CADERNO but not both)
You can handle the focusout and blur events for the input:
$(function () {
// Handle every input type text.
// To select specific inputs, give them a common class and change the
// selector accordingly.
$("input[type=text]").on("focusout blur", function () {
// Check for inputs with class radio_btns which are in
// the parent element (li).
// Set their required property.
$(this).parent().find("input.radio_btns")
.prop("required", $(this).val().trim().length > 0);
});
});
Demo
jQuery reference (Tree Traversal)
jQuery reference (.prop())
jQuery reference (.focusout())
jQuery reference (.blur())
This will work. You can include the following JQuery code in the script tag, and also the JQuery cdn link in the head tag.
$(document).ready(function(){
$('#01titulo').focusout(function(){
if ($(this).val() !== "") {
$('[name="01caderno"]').prop('required', true);
} else {
$('[name="01caderno"]').prop('required', false);
}
alert($('[name="01caderno"]').attr('required'));
});
});
Try using the following js code its working:
$(document).ready(function(){
$(".titulo_books").each(function(){
$(this).focus(function(){
var radioChecked=0;
var currElemId = parseInt($(this).attr('id'));
var radioSelecterId = (currElemId>9) ? currElemId : "0"+currElemId;
$("input:radio[name="+radioSelecterId+"caderno]").each(function(){
if(radioChecked==0)
{
radioChecked==1;
$(this).attr("checked","checked");
}
});
});
});
});
I have checked it by executing this from console on your site and it seems to work fine. You can alter this in the way you want. I have checked one of the four available radio button. User can change the input value if required. Or you can also change the default radio button selected through my code.

Categories