JQuery checkbox with options framework and wordpress - javascript

This is a jquery question, and since I am working with WordPress and options framework in the admin panel, I have to hide certain options with a checkbox. The problem is one of the elements is a dropdown menu and it seems that I cannot hide it at the beginning (meaning if I click twice the dropdown disappears as it should) although the code works for the text input. Here is the code:
jQuery('#telephone_hidden').click(function() {
if (jQuery('#telephone_hidden').attr('checked') ? true : false) {
jQuery('#section-telephone_dropdown_icons, #section-telephone_number_hidden').show();
} else {
jQuery('#section-telephone_dropdown_icons, #section-telephone_number_hidden').fadeToggle(400);
}
});
I am not very good with jQuery but I think that this should work, or at least there is a better way to do this.

An if statement with a ternary statement ... not going to work. Try this:
if (jQuery('#telephone_hidden').prop('checked')){
jQuery('#section-telephone_dropdown_icons, #section-telephone_number_hidden').show();
} else {
jQuery('#section-telephone_dropdown_icons, #section-telephone_number_hidden').fadeToggle(400);
}
The .prop('checked') returns a boolean, which I think is what you want to validate. Also, there really isn't a need to use jQuery if you properly set up your libraries to not conflict. You can consolidate it to:
if ($('#telephone_hidden').prop('checked')){
$('#section-telephone_dropdown_icons, #section-telephone_number_hidden').show();
} else {
$('#section-telephone_dropdown_icons, #section-telephone_number_hidden').fadeToggle(400);
}
This doesn't seem like much, but over an entire script file you reduce its size and therefore improve its performance. Depending on how big your file is, it can have a huge impact.
Also, noticed you were using the .click event for $('#telephone_hidden'), so rather than query the DOM again, try this:
var $tel = $('#section-telephone_dropdown_icons, #section-telephone_number_hidden');
$('#telephone_hidden').on('click',function() {
if ($(this).prop('checked')){
$tel.show();
} else {
$tel.fadeToggle(400);
}
});
The use of $(this) prevents needing to query the DOM for the selector again, and I cache the selector used for the show / fadeToggle, providing another performance boost.
I know this is a long answer, but I figured if I showed the step-by-step process of improvement you could learn and apply it to future jQuery endeavors.

Try .is()
if (jQuery('#telephone_hidden').is(':checked')) {
or .prop
if (jQuery('#telephone_hidden').prop('checked')){

You can use the is function in conjunction with the checked selector, like so:
if ($('#telephone_hidden').is(':checked')) {
// ... do something
}

Related

kicking off ajax query to php mysql DB by use of onblur

I'm trying (and failing) to make an ajax process work when people leave a form input field. I need it to happen for each input field, of any type, on the form.
I'm trying to modify the following (which does work):
$("document").ready(function() {
$("#getcontent").click(getContent);
});
function getContent() {
$("#example").load("sampletextcontent.txt");
}
(there would be a button with id="getcontent" in the html, and a div with id="example" also in the html. When button clicked, contents of external file sampletextcontent.txt is displayed within said div)
jquery IS being used, version 2.0.3 jquery.min.js
So I am trying (and this is where I am failing) is to convert the above to become:
$("document").ready(function() {
$("#input_1_1").onblur(doSend);
$("#input_1_2").onblur(doSend);
$("#input_1_3").onblur(doSend);
$("#input_1_4").onblur(doSend);
$("#input_1_5").onblur(doSend); // etc for as many fields there are
})
function doSend() {
// Do some ajax stuff to send the entire value of all form fields in here
}
But it does not seem to like the concept of using the replacement of the ".click" to ".onblur" here. Why is this? Isn't onblur a valid JS function/item?
Sorry I'm not a JS guru, I have great problems understanding JS.
C
Edit - sorry I was not clear about the code I am trying to get working. There is no button in the version I want to work, it's just wanting to trigger by when a user clicks/tabs away from each input field. Sorry about not making that clear before.
For dynamic jQuery event binding, I would try switching out the .click and .blur functions with the .on function.
As an example, I would try the following:
$('body').on('click', '#getcontent', function(){
DoSomething();
});
and
$('body').on('blur', '#input_1_1', function(){
DoSomething();
});
The documentation for the on function can be found http://api.jquery.com/on/.
Here is another Stack Overflow article that also explains this: Event binding on dynamically created elements?.
Thanks to the comments and answer attempts. However the answer that I'm using, that actually does answer the specific question is the following. Simply change:
$("document").ready(function() {
$("#input_1_1").onblur(doSend);
$("#input_1_2").onblur(doSend);
$("#input_1_3").onblur(doSend);
$("#input_1_4").onblur(doSend);
$("#input_1_5").onblur(doSend); // etc for as many fields there are
})
To become:
$("document").ready(function() {
$("#input_1_1").blur(doSend);
$("#input_1_2").blur(doSend);
$("#input_1_3").blur(doSend);
$("#input_1_4").blur(doSend);
$("#input_1_5").blur(doSend); // etc for as many fields there are
})
And it works. This retains the ability to call different functions per field if I so wish, and is very straightforward for a JS novice like me to work with.
A better cleaner solution may be implemented later, but for now this will do and directly answers the original question.

Expanding an Accordion Pane on Invalid Validation

I have a collection of AccordionPanes containing various TextBox controls and DropDownLists, each with their own validators.
If a few server-side validations occur on form submit, is there something that can automatically expand a previously minimized pane that contains the invalid validator message? Otherwise, it will seem to the user that the form isn't submittable without reason.
Another scenario: Let's say I have multiple panes with client side validators tied to the inputs. If a pane is minimized (and therefore you can't see the validator's ErrorMessage), is there a way to expand the appropriate pane when the AJAX page validation occurs on submit?
I know there's a brute-force way to this approach, where I keep track of every validator and their associated AccordionPane, but I was hoping for a better solution that can handle my situation for a large number of inputs/validators and panes.
How about something like this (using JQuery but I'm sure it can be converted into plain javascript)...
$(document).ready(function(){
if (isPostback()){
$.each(Page_Validators, function(index, validator) {
if (!validator.isvalid) {
// do something here to locate the accordion based on the validator
// $(this) is the currently invalid validator element as a jquery object/wrapped set
// so for example...
$(this).parent().slideDown();
// This assumes that the immediate parent of of the validator is the accordion which is unlikely but if you post your emitted html I can write the appropriate selector for you.
}
});
}
});
Because you dont want it to fire on initial load you can use a technique like this How to detect/track postback in javascript? and check if you are in a postback after the document.ready - I have assumed you've used the advice in the link and your function for postback detection is called isPostback().
there is a project built for this issue try to take a look at it....you can also download the source to analysis more details or use the same code-base if you want....http://www.codeproject.com/Articles/43397/Validating-Accordion-and-RadPanelBar-using-Ajax-an
Rich beat me to it, but here's the vanilla js version (ie9+):
Page_Validators
.filter(function(v) { return !v.isvalid; })
.forEach(function (v) { console.log(v.parentNode); });
Remember to place the code beneath the </form>-tag. I've had issues with using jQuerys document.ready and window.onload, since it might execute the code before all the needed JavaScript from asp.net is loaded.
Update: A more browser compatible version
for(var i = 0; i < Page_Validators.length; i++) {
var validator = Page_Validators[i];
if (!validator.isvalid) {
console.log(validator.parentNode);
}
}

Have jquery filter inside live event

Hi I have this following code with jquery , so it will alternate colors on each row of a table:
$("tr").filter(':nth-child(2n+1)').addClass('odd').next().addClass('even');
but unfortunately it doesnt work when the table comes from an ajax call .. is there a way to put this into a $("tr").live... and make it work like that? .. I have tried different aproaches like this: ( I know the syntax may not be correct ).
$("tr").live({
$("this").filter(':nth-child(2n+1)').addClass('odd').next().addClass('even')
});
But doestn seem to work
live isn't a catch-all solution for problems that come from dynamic content. It only works with events. Normally, you listen for events with bind; when your content is dynamic, live is a way to capture events reliably. So you need another solution for styles...
The simplest solution is to define your CSS using nth-child:
tr:nth-child(2n+1) {
// whatever the odd styles are
}
tr:nth-child(2n) {
// whatever the even styles are
}
This won't work in all browsers, since it's CSS3. (In particular, it won't work in Firefox 3 or Internet Explorer before version 9.)
The other solution is to update all the tr elements on the page after every AJAX call using ajaxComplete:
$(document).ajaxComplete(function() {
$('tr:nth-child(2n+1)').addClass('odd').next().addClass('even');
});
This won't have great performance, but it probably won't be a particular drain as it will always happen asynchronously. This will, obviously, work cross-browser.
Its possible to use the :odd and :even tags for example
JSfiddle example

Help with JQuery conditional statement

I am trying to run some JQuery script on a particular page but only if a certain page loads.
The Scenario: We have one page that loads (i.e., webpage.aspx) and it loads different content based on the referring click. (i.e., webpage.aspx?contentId=1, webpage.aspx?contentId=2, webpage.aspx?contentId=3, etc). Here is my problem. I need to have a particular part of the page removed if only one specific contentId is pulled. I am trying to do this in JQuery and can't seem to figure it out.
Here's what i have been working with so far. I realize it's not correct but hopefully it gives you a starting point to work with.
Thanks.
CODE:
$(window).load(function() {
var $deleteNewRow = $("div.col.w140 tbody:first").find("td:first").parent().remove();
if($('#dealer-info h1').indexOf('Ferrari') != -1) {
$deleteNewRow
}
});
What you store in your $deleteNewRow variable isn't the jQuery method, that method will already execute. You want to do that method in your if statement, something like this (note that you are also missing the .text() in the if statement):
$(window).load(function() {
if($('#dealer-info h1').text().indexOf('Ferrari') != -1) {
$("div.col.w140 tbody:first").find("td:first").parent().remove();
}
});
You can use jQuery :contains selector to check for the existence. Here is the docs.
Then to delete find the element and then use remove.
$("div.col.w140 tbody:first").find("td:first").parent().remove();

Needing an ExtJS bug workaround

I have a web application that uses Ext-JS 2.2. In a certain component, we have an empty toolbar that we are trying to add a button to using
myPanel.getTopToolbar().insertButton(0, [...array of buttons...]);
However, in IE6/7 this fails because of lines 20241-20242 in ext-all-debug.js:
var td = document.createElement("td");
this.tr.insertBefore(td, this.tr.childNodes[index]);
Since "this.tr.childNodes([0])" does not yet exist in IE, this fails with "Invalid argument".
THE REAL QUESTION:
Can I, using CSS similar to the below add a child to every toolbar <tr> so that this.tr.childNodes[0] is found:
div.x-toolbar tr:after { content: " "; }
I totally realize this is a hack, but for legal reasons I cannot change any Javascript, not even to add an empty button ({}) to each toolbar. Major kudos to anyone that can figure this out.
What I've had to do in the past was include an empty toolbar in my element config:
tbar:[]
Then (and only after the element has completely rendered) use the .add() method for injecting buttons.
Order of events will get you every time. It takes a while to get a handle on it.
If all you are doing is adding to a empty panel
myPanel.getTopToolbar().add(buttons etc);
Or
myPanel.getTopToolbar().addButton(..);
Either should work. It looks like purpose of insertButton is for putting a button within a non-empty toolbar.
Did you look into adding the button after the panel has been rendered? Maybe something like:
myPanel.on('render', function() {
this.getTopToolbar().insertButton(0, [...array of buttons...]);
}, true);
I didn't think there was a CSS-only solution.
For the record, I ended up injecting javascript into the page that overrides the Ext.Toolbar prototype for the insertButton() function to check for the existance of "this.tr.childNodes([0])" and default to addButton() if it didn't exist.

Categories

Resources