// plays a card into table.
// this code works. rendered card is appending into the table.
var playCard = function(card){
var renderedCard = renderCard(card);
$('#'+renderedCard.id).appendTo('#flop');
// but this one does not work.
var playCom = function(){
$.post('/api/comPlay', function(data){
var renderedCard = renderCard(data.card);
$('#'+renderedCard.id).appendTo('#flop');
});
};
I check the returned value from $.post. data.card gives the correct value. I create a div html with my renderCard function. That function works correctly as you see. But under $.post not.
I am stuck. Is there something special that i must know about $.post?
Thank you.
update :
var renderCard = function(card){
var create = document.createElement('div');
create.className = 'cardBig';
create.id = card;
return create;
};
You don't need to "find" your newly-created DOM element.
$(renderedCard).appendTo('#flop');
should do it.
Also, since you're using jQuery anyway:
$('#flop').append($('<div/>', {
className: 'cardBig',
id: data.card
}));
will save you the extra function.
In renderCard() method you are just creating a new html element but it is not rendered to the dom.
So your element lookup $('#'+renderedCard.id) will not work
$(renderedCard).appendTo('#flop');
have you tried selecting the id element first, like so:
$(renderedCard).appendTo( $('#flop')[0] )
Related
I have this class in Javascript: call it Caption:
function Caption
{
var ...
function get...()
{ }
function set...(...)
{ ... }
return( { get...: get...
, set...: set...
});
}
This is only one component of a larger system and is part of an outer class called Filter. I would love to be able to when creating the jQuery for the object to be able to say:
tblFilter.append(getCaption())
which would get the Caption class instance variable and append the jQuery representation of it. Do I need to inherit from jQuery to make that happen? Like this?
function Caption
{
var ...
function get...()
{ }
function set...(...)
{ ... }
var that = jQuery();
that.get... = get...;
that.set... = set...;
return(that);
}
?
If that's true, what I'm not sure of is what function/method I need to write to produce the jQuery that is produced to be appended to the outer jQuery. Does this make sense and if so, what am I missing?
Edit:
Let me elaborate - Ok I'm creating my own version of a Data Table. Yes I know jQueryUI has but with this, I pass the data and it renders the data. There's a Filter component that really can't be created/constructed publicly but just accessed by a getFilter() method. Every time the Filter instance is changed, thanks to a home grown listener/observer/observable pattern, the filter is erased and re-rendered. As of now much of it is hard coded. When I first wrote it it was more loosely written as it was for a programming assignment to get a job and I did it within 2 days I had. Now that it's done I'm trying to implement it more generically into a library. When I get to appending the Caption and trying to make it render it based on the Caption object, I have no ID for a Caption or a parent object to remove. Ideally I'd love to be able to do:
var objDataTable = new DataTable(/*parameters*/);
$(/*parent selector/*).append(objDataTable);
I'm self taught so my Object Oriented Programming is a bit all over the place, but if I had a class, that I wanted to 'HTMLize' and insert values from into the dom, I would do it like this:
var Caption = {
'amount':10,
'word':'Hello!',
'getCaption': function(appendToObject){
var div = $('<div />');
var ul = $('<ul />');
var li = $('<li />', {
'text' : this.word
});
li.appendTo(ul);
var li2 = $('<li />', {
'text' : this.amount
});
li2.appendTo(ul);
ul.appendTo(div);
div.appendTo(appendToObject);
}
};
var caption_instance = Caption;
caption_instance.getCaption('#wrapper');
var second_caption = Caption;
second_caption.amount = 13;
second_caption.word = 'Goodbye';
caption_instance.getCaption('#wrapper');
You can see it in action here:
http://codepen.io/EightArmsHQ/pen/bVrapW
If you are including jQuery globally you don't need to pass anything to the function, you can just get going.
The important part here is the var xxx = $('<DOM_TAG />'); which lets you create elements to append to the DOM. This can be found here: http://api.jquery.com/jquery/#jQuery2
If I've misunderstood the question just let me know and I'll remove the answer.
I know that there is a really simple jQuery way to to this, but now I would like to understand why my code is not working properly:
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
var menuHelp = document.querySelector(".menu_help");
for (var i = 0;i<menuHelp.length;i++){
menuHelp[i].onmouseenter = function(){
menuHelpPopup = document.createElement("div");
menuHelpPopup.setAttribute('class','menu_help_popup');
menuHelpPopup.innerHTML = "test";
insertAfter(menuHelp[i], menuHelpPopup);
}
menuHelp[i].onmouseleave = function(){
menuHelpPopup.remove();
}
}
What I'm trying to do is to create a popup and insert it after elements with a certain class when mouseover on them..
DEMO http://jsfiddle.net/r5e8rvkg/
Please make sure menuHelp is a nodeList, so you should use document.querySelectorAll;
When the mouse enter, the value of i is menuHelp.length. so you should use this, like insertAfter(this, menuHelpPopup)
I used getElementsByClassName and it seemed to have worked.
var menuHelp = document.getElementsByClassName('menu_help');
Please checkout here: http://jsfiddle.net/r5e8rvkg/1/
First, use querySelectorAll instead of querySelector.
More importantly, you need to take care that in your code:
menuHelp[i].onmouseenter = function(){
menuHelpPopup = document.createElement("div");
menuHelpPopup.setAttribute('class','menu_help_popup');
menuHelpPopup.innerHTML = "test";
insertAfter(menuHelp[i], menuHelpPopup);
}
The value i would not be passed in correctly because the event onmouseenter is Async. When the function is called, the value of i is actually i === menuHelp.length, which results in menuHelp[i] === undefined.
You need to use Closure, as shown in my JSFiddle code.
The document.querySelector() method returns only the first element with the specified selector. To get each element with class 'menu_help', you need to use the document.querySelectorAll() method.
In other words, replace:
var menuHelp = document.querySelector(".menu_help");
With
var menuHelp = document.querySelectorAll(".menu_help");
I know the question sounds strange, but it's really very simple. I have the following function which isn't working:
function start40Counter(counter40_set){console.log(counter40_set);
var gid = counter40_set[0];
var seat = counter40_set[1];
var suits = counter40_set[2];
var cont = "";
$.each(suits, function (num, suit) {
cont += "<a class='suitpick' onClick='pickSuit(counter40_set);'><img src='"+base+"images/someimg.png' title='Odaberi' /></a>";
});
$('#game40_picks').html(cont);
}
counter40_set is [10, 3, ["H", "S"]]. The part of the function that fails is the part this:
onClick='pickSuit(counter40_set);'
It says that counter40_set is not defined. I understand that. This wouldn't even work if counter40_set was a simple string instead of an array. If I try onClick='pickSuit("+counter40_set+");' I get a different error, saying H is not defined. I get this too, the array is rendered and JS doesn't know what H and S are.
I also tried passing the array elements (counter40_set[0] etc) individually but it still fails with the last element (["H", "S"]).
So, how do I pass this data to the onClick function in this case? There must be a more elegant way than concatenating the whole thing into a string and passing that to the function?
Btw, this is a simplified version. What I should really be passing in every iteration is [suit, counter40_set] so that each link chooses a different suit. I'm asking the simplified question because that will be enough to send me down the right path.
It cannot work,because the context is lost and thus "counter40_set" is not set.
To fix it simply use jquery for the onlick as well:
$('#game40_picks').empty(); // get rid of everything
$.each(suits, function (num, suit) {
var line = $("<a class='suitpick'><img src='"+base+"images/"+cardsuits[suit].img+"' title='Odaberi "+cardsuits[suit].name+"' /></a>");
line.click(function(ev){
ev.preventDefault(); // prevent default click handler on "a"
pickSuit(counter40_set);
});
$('#game40_picks').append(line);
});
this way the "counter40_set" is available for the click function.
You shouldn't use the onClick HTML attribute. Also, using DOM functions to build nodes saves the time it takes jQuery to parse strings, but basically the method below is to create the element and attach a click event listener and then append it to the specified element.
function start40Counter(event){console.log(event.data.counter40_set);
var counter40_set = event.data.counter40_set;
var gid = counter40_set[0];
var seat = counter40_set[1];
var suits = counter40_set[2];
var cont = "";
$.each(suits, function (num, suit) {
var link = document.createElement('a');
link.className = 'suitpick';
$(link).on('click', {counter40_set: counter40_set}, start40Counter);
var img = document.createElement('img');
img.src= base + "images/" + cardsuits[suit].img;
img.title = 'Odaberi ' + cardsuits[suit].name;
link.appendChild(img);
$('#game40_picks').append(link);
});
}
Not tested but it might work out of the box.
I create a div element dynamically and associate data() to it. When accessing it again via selector it does not return the data. As result of below snippet I see first alert with data '1' and another with 'null' value. Can someone please help.
var dc = 0;
$("#attachData").click(function () {
dc++;
var newDiv = jQuery('#oldid').clone();
newDiv.attr('id', 'dt'+dc);
jQuery.data(newDiv, "dd", '1')
alert(jQuery.data(newDiv, "dd"));
var divFromSelector = $('#dt'+dc);
alert(jQuery.data(divFromSelector, "dd"));
});
Sorry, I did not add it in the snippet but its attached to the tree:
newDiv.attr('id', 'dt'+dc).
appendTo('#workspace-container');
Also when I try to access it using selector the element is returned correctly - but no data found.
Try:
var dc = 0;
$("#attachData").click(function () {
dc++;
var newDiv = jQuery('#oldid').clone();
newDiv.attr('id', 'dt'+dc).appendTo('#workspace-container');
jQuery.data(newDiv[0], "dd", '1')
alert(jQuery.data(newDiv[0], "dd"));
var divFromSelector = $('#dt'+dc);
alert(jQuery.data(divFromSelector[0], "dd"));
});
From the docs it seems that the JQuery.data method expects a DOM element, not a JQuery object. Appending [0] to a JQuery object gives the DOM element it is wrapping.
It'd probably be better if you used newDiv.data(...) and divFromSelector.data(...).
Demo here.
It looks like you haven't attached the new node in the DOM your accessing. http://api.jquery.com/clone/
I want to loop over the elements of an HTML form, and store the values of the <input> fields in an object. The following code doesn't work, though:
function config() {
$("#frmMain").children().map(function() {
var child = $("this");
if (child.is(":checkbox"))
this[child.attr("name")] = child.attr("checked");
if (child.is(":radio, checked"))
this[child.attr("name")] = child.val();
if (child.is(":text"))
this[child.attr("name")] = child.val();
return null;
});
Neither does the following (inspired by jobscry's answer):
function config() {
$("#frmMain").children().each(function() {
var child = $("this");
alert(child.length);
if (child.is(":checkbox")) {
this[child.attr("name")] = child.attr("checked");
}
if (child.is(":radio, checked"))
this[child.attr("name")] = child.val();
if (child.is(":text"))
this[child.attr("name")] = child.val();
});
}
The alert always shows that child.length == 0. Manually selecting the elements works:
>>> $("#frmMain").children()
Object length=42
>>> $("#frmMain").children().filter(":checkbox")
Object length=3
Any hints on how to do the loop correctly?
don't think you need quotations on this:
var child = $("this");
try:
var child = $(this);
jQuery has an excellent function for looping through a set of elements: .each()
$('#formId').children().each(
function(){
//access to form element via $(this)
}
);
Depending on what you need each child for (if you're looking to post it somewhere via AJAX) you can just do...
$("#formID").serialize()
It creates a string for you with all of the values automatically.
As for looping through objects, you can also do this.
$.each($("input, select, textarea"), function(i,v) {
var theTag = v.tagName;
var theElement = $(v);
var theValue = theElement.val();
});
I have used the following before:
var my_form = $('#form-id');
var data = {};
$('input:not([type=checkbox]), input[type=checkbox]:selected, select, textarea', my_form).each(
function() {
var name = $(this).attr('name');
var val = $(this).val();
if (!data.hasOwnProperty(name)) {
data[name] = new Array;
}
data[name].push(val);
}
);
This is just written from memory, so might contain mistakes, but this should make an object called data that contains the values for all your inputs.
Note that you have to deal with checkboxes in a special way, to avoid getting the values of unchecked checkboxes. The same is probably true of radio inputs.
Also note using arrays for storing the values, as for one input name, you might have values from several inputs (checkboxes in particular).
if you want to use the each function, it should look like this:
$('#formId').children().each(
function(){
//access to form element via $(this)
}
);
Just switch out the closing curly bracket for a close paren. Thanks for pointing it out, jobscry, you saved me some time.
for me all these didn't work. What worked for me was something really simple:
$("#formID input[type=text]").each(function() {
alert($(this).val());
});
This is the simplest way to loop through a form accessing only the form elements. Inside the each function you can check and build whatever you want. When building objects note that you will want to declare it outside of the each function.
EDIT
JSFIDDLE
The below will work
$('form[name=formName]').find('input, textarea, select').each(function() {
alert($(this).attr('name'));
});