jQuery dynamic checkbox position, merging examples found - javascript

When dynamically adding checkboxes in jquery, the position is incorrect:
I have an example (taken from stakoverflow) in JSFiddle of adding checkboxes dynamically.
I also have a link which claims they got it right to add the position,
<!-- language: lang-js -->
var $myCheckboxLabel = $("label[for='myCheckbox']");
$myCheckboxLabel.position({my:"left", at:"right", of:$myButton });
but this does not tie up at all with the example as mentioned:
for (var i = 0; i < 40; i++) {
$("fieldset").append('<input type="checkbox" name="' + name + '" id="id' + i + '"><label for="id' + i + '">' + name + ' ' + i + '</label>');
}
Can someone please help met to set the position of the checkbox that gets added in the loop, so it does not show next to each other, but in the next row.

Your Javascript is fine for what you're trying to do - it'll generate the correct HTML. The problem is that they're being displayed "inline" which means that they all go side-by-side, as many on one line as it can fit, then it'll wrap down a line.
What you want is for them to be displayed as a "block" element which means it has its own line, and the next element will have to go underneath it. You can just use CSS to make them do this:
fieldset input[type=checkbox] { /* this can be more specific if you need it to be */
display: block;
}
Here's a fiddle demo'ing this.

Related

OnClick event that adds text to a div, removes it if it exists, and groups by description name

I'm using FullCalendar that's filled with events that's populated from a mysql database. I'm using the eventClick function of FullCalendar to send the contents of the event to a separate div so I'll be able to print out the events that I've clicked.
Using this code below, I'm able to click on the event and it adds the lines that I need to the div, but it'll add duplicates because there's nothing stopping it from doing so as I'm just appending each event when I click on one.
// FullCalendar eventClick function
eventClick:function(event){
$(document).ready(function(){
document.getElementById("event_info").innerHTML += event.description + "<br>" + event.start + "<br>" + event.end;
});
}
// div where the information will print
<div class="col-sm-3" id="event_info"></div>
So I want to be able to click on a calendar event & send it to the div, but also check to see if the event has already been added and if it has, remove it. Finally, I'm looking to group the events by the description name when clicked.
I'm not sure where to start with adding those so any help or direction would be much appreciated. Thanks for your time and feel free to yell at me if I didn't explain something very well.
Why not simply include something like a class or data-attribute once you first add the event to the div, and then check if that is present, before adding another event?
var target = document.getElementById("event_info");
var isAlreadySet = target.getAttribute('data-eventAlreadySet');
var newHTML = event.description + "<br>" + event.start + "<br>" + event.end";
if (!isAlreadySet) {
target.innerHTML += newHTML;
target.setAttribute('data-eventAlreadySet', "true");
} else {
// your code here if the event is already set
// to replace the former event, use something like :
target.innerHTML = newHTML; // replaces the HTML
//instead of :
target.innerHTML += newHTML; // adds to the existing HTML
};
you need to check the div innerHtml before appending a new text. Please try the following code:
// FullCalendar eventClick function
eventClick:function(event){
$(document).ready(function(){
if($("div#event_info:contains("+event.description+")").length <=0)
{
document.getElementById("event_info").innerHTML += event.description + "<br>" + event.start + "<br>" + event.end";
}
});
}

jquery html function isn't working

I am tring to show twitter user information on my web page. I have created a div tag which is will contain user information using jquery. I want to show user information when the cursor is over this div tag. Below is my code in jquery:
var hideDelay = 500;
var currentID;
var hideTimer = null;
var container;
$(function () {
container = $('<div id="personPopupContainer" style=\"max-width:400px;\">'
+ '<table border="0" cellspacing="0" cellpadding="0" align="center" class="personPopupPopup">'
+ '<tr>'
+ ' <td class="corner topLeft"><div style="position:absolute;top:15px;left:-16px;"><img src="images/balloon_tail.png" /></div></td>'
+ ' <td class="top"></td>'
+ ' <td class="corner topRight"></td>'
+ '</tr>'
+ '<tr>'
+ ' <td class="left"></td>'
+ ' <td><div id="personPopupContent"></div></td>' //the div tag is here
+ ' <td class="right"></td>'
+ '</tr>'
+ '<tr>'
+ ' <td class="corner bottomLeft"> </td>'
+ ' <td class="bottom"></td>'
+ ' <td class="corner bottomRight"></td>'
+ '</tr>'
+ '</table>'
+ '</div>');
$('body').append(container);
$('#personPopupContainer').mouseover(function () {
if (hideTimer)
clearTimeout(hideTimer);
});
$('#personPopupContainer').mouseout(function () {
if (hideTimer)
clearTimeout(hideTimer);
hideTimer = setTimeout(function () {
container.css('display', 'none');
}, hideDelay);
});
});
That is working well. But the below code that is
$('#personPopupContent').html('<center><img src="images/loading_sm.gif" /></center>');
isn't working.
function UserMouseOver(o) {
var obj = $("#" + o);
var Settings = obj.attr('rel').split(',');
var UserID = Settings[0];
var ScreenName = Settings[1];
if (hideTimer)
clearTimeout(hideTimer);
var pos = obj.offset();
var width = obj.width();
if (pos != null && width != null) {
container.css({
left: (pos.left + width) + 20 + 'px',
top: pos.top - 23 + 'px'
});
}
$('#personPopupContent').html('<center><img src="images/loading_sm.gif" /></center>');
}
what I am doing wrong? Can someone please help me?
Note: in the actual code there is no typo ( the image tag isn't closed early ) but in the code you focus on, there is a typo, as Stian points out.
Longshot.. Is the image even available? You can use this plugin:
https://github.com/desandro/imagesloaded
..then change the HTML once the image is known to be in the DOM.
Your question does not entirely explain what you are trying to do. However, I can at least explain why your image isn't showing.
First, you need to call your function UserMouseOver(o) from inside $('#personPopupContainer').mouseover(function () {. . .}. The way you coded it, UserMouseOver(o) will never get called, and none of the logic in the function will get executed.
Second, in your $('#personPopupContainer').mouseout(function () {. . .}, the line container.css('display', 'none') is hiding your entire container object (ALL your HTML!) on mouseout. That will cause your "loading" gif to never display, because the div you are trying to display (personPopupContent) resides within the container object you just set to display: none! You should set the display to none only on the particular element you are trying to hide; for example, you could add id="balloon_tail" to your balloon image and change the Javascript line to $('#balloon_tail).css('display', 'none').
Third, you will get an error on the line var Settings = obj.attr('rel').split(','); because you did not include a rel attribute in your outermost element personPopupContainer. You will need to add a rel attribute of comma separated strings to this element for this line to work. (However, according to W3C, the only official element that uses the rel attribute is <a>, the anchor tag.)
Finally, I would add an image tag to #personPopupContent to make it something like <div id="personPopupContent"><img src="" id="loading_sm" /></div>. Then you can change
$('#personPopupContent').html('<center><img src="images/loading_sm.gif" /></center>');
to
$('#loading_sm').attr("src", "images/loading_sm.gif");
but that's just me.
I hope this helps!
If the code is working as you stated (I can't see where you are calling your mouse over method) and it's only the image that isnt showing.
Use a Web Debugger to check for any 404 errors e.g. http://www.fiddler2.com/fiddler2/ or even your browser's F12 web debugger.
Make sure your path to the image is correct.
UPDATE
Okay, now that we know it works. Try the following : Add a class to #personPopupContent e.g. class="popupContent" . Change the line of code where you set the html to call the class selector instead of the ID selector. Then to make sure that jQuery is getting the html element to add the content to, add some text to it.
//All the other code
+ ' <td><div id="personPopupContent" class="popupContent"></div></td>'
//All the other code
Change the selector in UserMouseOver() method :
$('.popupContent').html('<center><img src="images/loading_sm.gif" /></center>');
PLEASE MAKE SURE
I don't know where you are calling the UserMouseOver() method, so please add a Document Ready around the piece of jquery.
function UserMouseOver(o) {
//All the other code
$(function () {
$('.popupContent').html('<center><img src="images/loading_sm.gif" /></center>');
});
}

How to combine tags as long as they have the same class

The Html that I'm getting ideally looks like this:
<span class="RapidLink1-H">See the more detailed areas of what not</span>
Next my aim is to change the span tag into an anchor tag. With the ideal Html, I have done it this way:
// Walk through each link tag on this page and replace the content with an actual link
thisLink.each(function() {
linkRefTarget = '';
// Get only the identifier number of the link
linkId = ($(this).attr('class')).replace(/[A-Za-z$-]/g, '');
// Match this link with the list of link references
if (thisLinkRef) {
for (var key in thisLinkRef) {
if (key == 'link' + linkId) linkRefTarget = thisLinkRef[key];
}
}
output = '';
output+= '<a href="#' + linkRefTarget + '" id="link' + linkId + '" class="rapidLink">';
output+= $(this).html();
output+= '</a>';
}).replaceWith(output);
Now, the problem comes when I'm actually getting this sort of Html (please note, I can't change the Html input):
<span class="RapidLink1-H">See the</span><span class="RapidLink1-H">more detailed areas of</span><span class="RapidLink1-H">what not</span></span>
The question is:
How could I get it to work with such a broken set of spans?
I'm thinking the following:
Find an expected link span
Check whether the immediate next element is also a span with the same class
and then check whether the immediate next element is also...,
and then check...
if none is found, combine the innerHtml of each span into a single anchor tag
How could I achieve such a loop?
Thanks.
There is the + selector which selects consecutive elements: http://jsfiddle.net/NWWYC/1/.
$(".RapidLink1-H + .RapidLink1-H").each(function() {
// move contents to previous span, remove this span afterwards
$(this).prev(".RapidLink1-H").append(
$(this).contents()
).end().remove();
});

jQuery 'not' function giving spurious results

Made a fiddle: http://jsfiddle.net/n6ub3/
I'm aware that the code has a LOT of repeating in it, its on the list to refactor once functionality is correct.
The behaviour i'm trying to achieve is if there is no selectedTab on page load, set the first tab in each group to selectedTab. If there is a selectedTab present, then use this as the default shown div.
However, as you can see from the fiddle its not working as planned!
If anyone has any ideas how to refactor this code down that'd be great also!
Change
if($('.tabs1 .tabTrigger:not(.selectedTab)')){
$('.tabs1 .tabTrigger:first').addClass('selectedTab');
}
to
if ( !$('.tabs1 .tabTrigger.selectedTab').length ) {
$('.tabs1 .tabTrigger:first').addClass('selectedTab');
}
Demo at http://jsfiddle.net/n6ub3/1/
They way you are doing it (the first code part) you are adding the .selectedTab class if there is at least one of the tabs in that group that is not selected at start .. (that means always)
Update
For a shortened version look at http://jsfiddle.net/n6ub3/7/
Your selector are doing exactly what you're writing them for.
$('.tabs3 .tabTrigger:not(.selectedTab)') is true has long as there is at least one tab that has not the selected tab (so always true in your test case).
So you should change the logic to !$('.tabs3 .tabTrigger.selectedTab').length which is true only if there are no selectedTab
WORKING DEMO with simplified code
$('.tabContent').hide();
$('.tabs').each(function(){
var search = $(this).find('div.selectedTab').length;
if( search === 0){
$(this).find('.tabTrigger').eq(0).addClass('selectedTab')
}
var selectedIndex = $(this).find('.selectedTab').index();
$(this).find('.tabContent').eq(selectedIndex).show();
});
$('.tabTrigger').click(function(){
var ind = $(this).index();
$(this).addClass('selectedTab').siblings().removeClass('selectedTab');
$(this).parent().find('.tabContent').eq(ind).fadeIn(700).siblings('.tabContent').hide();
});
That's all! You don't need all that ID's all around. Look at the demo!
With a couple of very minor changes you code can be reduced to:
$('.tabContent').hide();
$('.tabs').each(function(){
if($('.tabTrigger.selectedTab',$(this)).length < 1)
$('.tabTrigger:first').addClass('selectedTab');
});
$('.tabTrigger').click(function(){
var content = $(this).data('content');
$(this).parents('div').children('.tabContent').hide();
$(this).parents('div').children('.tabTrigger').removeClass('selectedTab');
$(this).addClass('selectedTab');
$('#' + content).show();
});
$('.tabTrigger.selectedTab').click();
Those changes are
Change the class on the surrounding div to just class="tabs.
Add a data-content attribute with the name of the associated content div
Live example: http://jsfiddle.net/gsTBQ/
Well, I'm a bit behind the times obviously; but, here's my updated version of your demo...
I have updated your fiddle as in the following fiddle: http://jsfiddle.net/4y3Xp/1/.
Basically I just tidied it up a bit, and to refactor I put everything in a separate function instead of having each of the cases in their own. This is basically just putting a new function in that does similar to what yours was doing (e.g. not modifying your HTML model), but I tried to clean it up a bit, and I also just made a function that took the tab number and did each of the items that way rather than needing a separate copy for each.
The main issue with the 'not' part of your query is that the function doesn't return a boolean; like all JQuery queries, it's returning all matching nodes. I just updated that part to return whether .selected was returning more than 0 results; if not, I go ahead and call the code to select the first panel.
Glad you got your problem resolved :)
$(document).ready(function(){
var HandleOne = function (i) {
var idxString = i.toString();
var tabName = '.tabs' + idxString;
var tabContent = tabName + ' .tabContent';
$(tabContent).hide();
var hasSelected = $(tabName + ' .tabTrigger.selectedTab').length > 0;
if (!hasSelected)
$(tabName + ' .tabTrigger:first').addClass('selectedTab');
var selectedTabId =
$(tabName + ' .tabTrigger.selectedTab').attr('id');
var selectedContentId = selectedTabId.replace('tab','content');
$('#' + selectedContentId).show();
$(tabName + ' .tabTrigger').click(function() {
$(tabName + ' .tabTrigger').removeClass('selectedTab');
$(tabName + ' .tabContent').hide();
$(this).addClass('selectedTab');
var newContentId = $(this).attr('id').replace('tab','content');
$('#' + newContentId).show();
});
}
HandleOne(1);
HandleOne(2);
HandleOne(3);
});

Trouble with jquery's append and prepend

I use the following code to check whether or not a certain div exists. And if it doesn't it adds it to the dom in the proper place.
if (!($("#col"+lastSlide).length))
{
$('#schDisplay').prepend('<div id="col' + (lastSlide) + '"></div>');
}
My problem is that when this if statement checks again for a div that had already once been appended/prepended, it doesn't see the div that I added. So it will continue to add the div that was already prepended/appended.
Is there any way this issue can be fixed?
more code:
//fillin added column
function fillElement(colnum)
{
var URL = 'schedule.php';
$("#col"+colnum).text("Loading...").show();
$.post(URL,{fecolnum: colnum},
function (data)
{
$("#col"+colnum).html(data).show();
});
}
//...irrelevant code...
// Create event listeners for .arrows clicks
$('.arrows')
.bind('click', function(){
numberOfSlides++;
// Determine new position
if ($(this).attr('id')=='arrow_right')
{
lastSlide++;
currentPosition++;
if (!($("#col"+lastSlide).length))
{
$('#schDisplay').append('<div id="col' + lastSlide + '" class="schColumn" style="float: left; width: ' +slideWidth+ 'px"></div>');
fillElement(lastSlide);
}
}
else
{
lastSlide--;
currentPosition--;
if (!($("#col"+lastSlide-2).length))
{
$('#schDisplay').prepend('<div id="col' + (lastSlide-2) + '" class="schColumn" style="float: left; width: ' +slideWidth+ 'px"></div>');
fillElement(lastSlide-2);
}
}
I don't have much context to go off of, but checkout this jsfiddle I made from what you gave me.
Notice the line where I've made a comment that you can comment out the increment statement. Basically, this is how you can test what happens when "lastSlide" is the same value. (versus if "lastSlide" is indeed a different value).
You might just try debugging your actual code and make sure that lastSlide has the value you actually expect.
If I understand your question correctly, you're saying that it keeps adding the div if you do the same thing again. However, I can't reproduce this. The following code shows one div. According to you, it would show two divs.
lastSlide = 1;
if (!($("#col"+lastSlide).length))
{
$('#schDisplay').prepend('<div id="col' + (lastSlide) + '"></div>');
}
if (!($("#col"+lastSlide).length))
{
$('#schDisplay').prepend('<div id="col' + (lastSlide) + '"></div>');
}
If I didn't miss something, your problem must lie elsewhere.
This will work:
if (!($("#col"+lastSlide).length)) {
var newdiv = $('<div id="col'+lastSlide+'"/>');
$('#schDisplay').prepend(newdiv);
}
It keeps adding because your if condition is always true.
I haven't tested this though...
Can you try something like this to see if it helps?
var len = 0;
len = $("#col"+lastSlide).length;
if (len < 1)
{
$('#schDisplay').prepend('<div id="col' + (lastSlide) + '"></div>');
}
You can use jQuery filters to remove the selected div if it has already been prepended to. This should work for your particular scenario:
$('#schDisplay').filter(':not(:has(div[id^=col]))')
This says "select the div with id 'schDisplay' and then remove it from the selection if it has any descendent divs with ids start with 'col'".
In your example, you would chain on your prepend statement to this code like so (no need for an if statement):
$('#schDisplay').filter(':not(:has(div[id^=col]))').prepend('<div id="col' + (lastSlide) + '"></div>');
A special note: I believe that the :has selector is a jQuery content filter selector, meaning that it will not work without jQuery. You are clearly using jQuery, but readers with different implementations should keep this in mind.

Categories

Resources