Chaining jquery functions - Beginner - javascript

I am trying to set the name and ID of an element when a radio button is clicked on. To avoid duplicating the selector, I attempted to set it up like this:
$( "#selectOther" ).click(function() {
$( "[field=primaryInput]" ).attr('id', "modifiedId", function() {
$(this).attr('name', "modifiedName");
if ($(this).attr('visible') == "False") {
$(this).slideDown('fast');
$(this).attr("visible", "True");
}
});
});
However, it isn't working. It seems that the ID is changed, but the Name is not, nor is the rest of the function executed. Could someone help me understand how to express this correctly?
Here's a JFiddle.
EDIT: In my final case I will have a couple of buttons that reveal the field if it is hidden, and others that will hide it if it is visible. That is why I am not using .slideToggle()

See this fiddle:
$('input[type="radio"]').click(function() {
$('input[data="primaryInput"]')
.prop('id', this.id)
.prop('name', this.name)
.val(this.value)
.css('display', 'inline-block');
});
Number of points:
You didn't set an external resource (namely jQuery) in your fiddle - so you wouldn't ever get jQuery functions to execute
Use the data attribute for custom attributes. You can access them the way I have done or by selecting the $(element).data('field')
This example might help you understand how chaining works. One other piece of advise is that chaining only works if the method invoked next receives the same element the previous method returns. If it ever changes, you can use end() to get the previous state.

Related

How to set an element that I am toggling to be collapsed on load

I am struggling to figure out how to make an element that I am toggling on click with jQuery collapsed when the page initially loads. Everything is open on load at the moment - exactly the opposite of what I need.
Keeping in mind that I'm a beginner, can someone please help me? Thanks.
// Toggle
$('.togglehandle').click(function() {
$(this).toggleClass('active');
$(this).next('.toggledata').slideToggle();
});
// alert close
$('.clostalert').click(function(){
$(this).parent('.alert').fadeOut ();
$('#options').hide();
});
First off, remember to set your ".toggledata" element to display: none in the CSS.
Also, make sure that the two handlers you posted are all wrapped in $(document).ready(). In other words, make sure you have something like the below:
$(document).ready(function() {
// Toggle
$('.togglehandle').click(function() {
$(this).toggleClass('active');
$(this).next('.toggledata').slideToggle();
});
// alert close
$('.clostalert').click(function(){
$(this).parent('.alert').fadeOut ();
$('#options').hide();
});
});
And just because you mentioned that you are a beginner..........here it is with just a little code cleanup ;)
$(document).ready(function() {
// Toggle
$('.togglehandle').on('click', function() { //1: .click() -> .on('click',
var $this = $(this); //2: $(this) -> var $this = $(this)
$this.toggleClass('active');
$this.next('.toggledata').slideToggle();
});
// alert close
$('.clostalert').on('click', function(){
$(this).parent('.alert').fadeOut(); //3: No change
$('#options').hide();
});
});
Explanation of changes:
Changing .click() to .on('click'...
The .click() method is just shorthand for the .on('click'... method. Using the long form doesn't really have any benefits over the shorthand, except that it standardizes your handler bindings and has more options for parameters (like when using delegated events, which you will likely do in the future).
Changing $(this) to var $this = $(this)
This part is sometimes difficult to wrap your mind around. First and foremost, understand that jQuery, itself, is actually a function object. The developers of jQuery gave the library two names that can both be used interchangeably when coding: $ and jQuery.
In other words, both of the following are actually equivalent:
$('.toggledata').slideToggle();
and
jQuery('.toggledata').slideToggle();
This is important because it must be remembered that the $ is essentially a function name, used like any other. As such, each time you call $(this) you are essentially calling a "constructor" function to initialize a new jQuery object. As such, to make code more efficient, we store $(this) in a variable so that it can be reused.
The variable name $this is just a convention (a good one that you should make a habit of using). It is a common convention to prefix the name of any variables that hold jQuery objects with the dollar sign. For example, if we store $('.clostalert') in a variable then we would do something like:
var $clostalert = $('.clostalert');
Notice that we do not bother to store $(this) in a variable in the second handler because it is only used once and thus $(this) is only called once there.

Toggling one thing with two different elements

In my previous question I asked about how can I toggle a textarea with a paragraph. I got the answer. Now I want to do the opposite of it. First I was showing the already hidden textarea + 2 buttons by a click of a hyperlink. Now on the click of one of the buttons I want to hide the text + 2 buttons and show the paragraph that was first already shown.
I have tried this JS so far but it's not working:
$(document).ready(function () {
$(".no_link").click(function (e) {
e.preventDefault();
});
$(".edit_offer").on('click', function () {
toggleEditPanel($(this));
});
$("#cancel_edits").on('click', function () {
$(this).closest("button").hide();
$(this).closest("textarea").hide();
$(this).closest("p.content").show();
});
});
function toggleEditPanel(link) {
link.parent().parent().parent().find("textarea").toggle();
link.parent().parent().parent().find("button").toggle();
link.parent().parent().parent().find("p.content").toggle();
}
But its not working. How can I solve this error?
If I am trying to call the function toggleEditPanel() again. Its not working then aswell.
You can find the markup in the fiddle. Here's the fiddle.
UPDATE 1:
Just came up with a solution. I can use the $.siblings() function to toggle the elements beside the button. Still, is there any better solution?
Here's the code that I came up with:
$("#cancel_edits").on('click', function () {
$(this).hide();
$(this).siblings("button").hide();
$(this).siblings("textarea").hide();
$(this).siblings("p.content").show();
});
UPDATE 2:
The problem in the above code is that if there are more than one panels like this then the code is not working. How can I solve that issue aswell?
You are using Id for selector $("#cancel_edits") .
Id selectors returns only first element , so if there are multiple pannel it will work only for first.
Instead give some class name and use it for selector. Further you can use chaining and caching in your code for better performance.
$(".cancel_edits").on('click', function () {
var elm=$(this);
elm.add(elm.siblings("button,textarea")).hide();
elm.siblings("p.content").show();
});
I would recommend referencing your elements by ID:
$("#cancel_edits").on('click', function () {
$('#save_edits').hide();
$('#edited_content').hide();
$(this).hide();
$("p.content").show();
});
JSFiddle
The great thing about using IDs is that you are guaranteed they are unique - no need to use closest() to find the element you want. If, however, you're using classes instead, closest() might be necessary or helpful.

how to add id to a html tag using jquery

I have more than one links with the class of video and I want to add an id attribute, When the user clicks on a link.
My code is :
$(function () {$(".video").click(function(e){
e.preventDefault();
$(this).attr('id', 'selected');
});});
After clicking the link, if i see the code. Firebug shows the same code without any change.
Try plain JavaScript:
this.id = "selected";
If that works, then it's a jQuery-fart. If it still doesn't work, make sure you're using Firebug correctly (I don't use it, but I know in IE I have to click a button to refresh the DOM view) and if that still doesn't seem to fix it use a class instead (or a data-* attribute)
There is nothing wrong with the code you posted so you are doing something wrong elsewhere. Here are a few general points of advice:
Format your code better to understand what is going on
Always wrap in an enclosed function that defines $ as jQuery incase
it is undefined or defined as something else in the global scope
Apply things like "selected" as classes, not ids
Don't use the short hand of document ready it is not descriptive of what it is doing and not readable
e.g.
(function($) {
$(document).ready(function() {
$('.video').click(function(ev) {
ev.preventDefault();
//$(this).attr('id', 'selected');
$(this).toggleClass('selected'); // This will turn the "selected" class on and off for each click
});
);
})(jQuery);

Input:Checked jQuery vs CSS?

Unless I am mistaken. jQuery and CSS handle the :checked selector very differently. In CSS when I use :checked, styles are applied appropriately as I click around, but in jQuery it only seems to recognize what was originally in the DOM on page-load. Am I missing something?
Here is my Fiddle
In jQuery:
$('input:checked').click(function () {
$('input:checked').css('background','#FF0000');
$('input:checked+label').css('background','#ff0000');
});
In CSS:
input:checked+label {font-weight:bold;color:#5EAF1E}
UPDATE:
I should clarify that what I am looking to do is trigger behavior if a user clicks an already selected radio button.
Try setting up the handler this way:
$('body').on('click', 'input:checked', function() {
// ...
});
The way you have it, you're finding all the elements that are checked when that code runs. The above uses event bubbling so that the test is made when each "click" happens.
Inside your handler, you're updating the style for all checked elements, even though any particular click will only change one. That's not a huge deal if the number of checkboxes isn't too big.
edit — some further thought, and a helpful followup question, makes me realize that inside an event handler for a radio button "click" event, the button will always be ":checked". The value of the "checked" property is updated by the browser before the event is dispatched. (That'll be reversed if the default action of the event is prevented.)
I think it'll be necessary to add a class or use .data() to keep track of a shadow for the "checked" property. When a button is clicked, you'd see if your own flag is set; if so, that means the button was set before being clicked. If not, you set the flag. You'll also want to clear the flag of all like-named radio buttons.
You bound the event only to the inputs that were initially checked. Remove :checked from the first selector and it works as intended (but ugly.)
http://jsfiddle.net/8rDXd/19/
$('input').click(function () {
$('input:checked').css('background','#FF0000');
$('input:checked+label').css('background','#ff0000');
});
you would of course need to "undo" the css change you made with jQuery to make it go away when the input is unchecked.
$('input').click(function () {
$('input').css('background','').filter(":checked").css('background','#FF0000');
$('input+label').css('background','');
$('input:checked+label').css('background','#ff0000');
});
http://jsfiddle.net/8rDXd/20/
AFTER UPDATE
Keep track of the status of the radio buttons. For example, use .data() to keep an in-memory state of the radio buttons.
$(function () {
var $radio = $(":radio");
$radio.filter(":checked").data("checked", true);
$radio.on("click", function () {
if ($(this).data("checked")) {
alert("Already selected");
}
$radio.data("checked", false).filter(":checked").data("checked", true);
});
});
See it live here.
BEFORE UPDATE
I think you want to use .change() here.
$('input:radio').change(function () {
$('input, input+label').css('background', '');
$('input:checked, input:checked+label').css('background', '#f00');
}).change();
See it live here.

.not method fails?

I have written two jQuery functions, the simplified version of which run thus:
$('button.class').not('.selected').on('click', function() {
console.log('not selected');
console.log($(this));
$(this).addClass('selected');
}
$('button.class.selected').on('click', function() {
console.log('selected');
console.log($(this));
$(this).removeClass('selected');
}
Clicking on the button always logs the following in the console:
not selected
[<button class="someClass1 someClass2 selected">Text</button>]
The Web Inspector shows this before clicking on the button:
<button class="someClass1 someClass2">Text</button>
and this after clicking on it:
<button class="someClass1 someClass2 selected">Text</button>
Clicking on it again changes nothing.
Switching addClass() to toggleClass() succeeds in toggling 'selected' on and off, but still always logs not selected, which suggests something is going on with my selectors. Why is the first function always being called even when 'selected' is clearly one of the classes associated with the button element?
I noticed in testing some solutions that hard-coding 'selected' as a class of button results in the opposite problem: only second of the functions is ever called, even though toggleClass() works as intended. Do classes added via jQuery not "count" as classes?
The CSS selector is evaluated at the time you run it. I wouldn't expect that there are any elements matching $('button.class.selected') on page load, so your second handler is never executed, because it is never bound to anything.
What you should be doing is attaching event to some base selector such as $('button.class') and then doing filtering when event is fired.
$("button.class").on("click", function()
{
if ($(this).is(".selected"))
{
console.log('selected');
console.log($(this));
$(this).removeClass('selected');
}
else
{
console.log('not selected');
console.log($(this));
$(this).addClass('selected');
}
});
Either version works, but one might be more appropriate than the other, depending on what are you actually trying to do.
If all you are looking to do is to add/remove .selected on button click then this much simpler version will do the job
$("button.class").on("click", function() { $(this).toggleClass("selected"); });
Try changing :
$('button.class').not('.selected')
To:
$('button').not('.selected')
And :
$('button.class.selected')
To:
$('button.selected')

Categories

Resources