I'm not even sure I'm asking or going about this the right way but it's probably easier if I just show it. Basically, I'm trying to have run an attr of each div as a parameter through a function and have it return a different result based on that div's attr.
The example, as you can see, is a group of dropdowns that appear when you click on a link in the container div. If you make a selection it saves that as a attr in the parent div. The problem arises when you click out, then back in on the container ... instead of reshowing each dropdown with the appropriate default or selection showing, it just mirrors the result of the a next to it.
http://jsfiddle.net/nosfan1019/b7F6x/5/
TIA
I inserted some console.log() statements to see what was happening with your various jQuery selectors. I observe the following:
when I click in the first "click" node, _container is "top one"
thus in your iteration of the three divs, you select both divs with class 'dd' contained in the div with class 'top one'
the parameters _attr and _parent that you pass to your function select() are the same for each node that is processed, giving the same result for both 'dd' boxes.
I think you want to change the selectors you use to locate the nodes to modify.
foo = foo.find('.dropdown-toggle').html(_new + '<b class="caret"></b>');
with this line you get two divs and hence you've change both values(in case the value was chosen from the droplist).
To restore selected values correctly:
function modified(_select) {
console.log("modify");
foo = $('#box').html();
foo = $(_select).html(foo);
// iterate on collection to restore selected value from selection tag;
foo.filter("div[selection]").each(function(i, v){
var selected = $(v).attr('selection');
$(v).find('.dropdown-toggle').html(selected + '<b class="caret"></b>');
});
}
Then, it's needed to be checked if any of parentDiv has [selection] attr:
if($(y).filter("div[selection]").length > 0){
return modified(y);
}
http://jsfiddle.net/b7F6x/50/
Related
I am grabbing a copy of some info from a page, but I do not want to include certain <option> elements that appear inside <select> elements on the page.
Therefore, while I grab all the elements I want and am storing them in the variable fields, I check to see if each element is a <select> and if they have the specific <option> that I don't want.
var field = allFields[i].innerHTML; //allFields is the raw HTML I'm iterating through
if ($(field).find("select").length > 0) { //If the element we're looking at contains a select
console.log("Found a select. It is in " + field);
console.log($(field).find(".bad-option");
field = $(field).not(".bad-option").prop("outerHTML"); //Use .not() to remove the elements which have the .bad-option class
// (and .prop("outerHTML") is just there to convert it back to a String instead of a jQuery object)
}
console.log("Adding " + field);
fields[i] = field; //Add the HTML, free of any unwanted options, to the `fields` variable
Based on jQuery's documentation, I would expect the .not() function to remove any elements out of field which have the bad-option class. Yet that is not the case at all. When I log field before and after using .not(), it prints out the same thing. See the console output from the code above:
Found a select. It is in <label>Description: <select><option>thing1</option><option class="bad-option">thing2</option></select></label>
-----------------
[jQuery list object size 1, containing an object called option.bad-option]
-----------------
Adding <label>Description: <select><option>thing1</option><option class="bad-option">thing2</option></select></label>
So what's going on? How do I remove an option with a certain class from from within a jQuery object? Why isn't .not() working?
If I need to clarify anything, please let me know. I tried to make this question as specific as possible and would be happy to elaborate on any details further.
The documentation is perhaps a bit confusing: not removes elements from the selection, not the DOM. If you want to remove the elements, then just filter and remove:
const processed = $(field);
processed.filter(".bad-option").remove();
field = processed.prop("outerHTML");
JSFiddle: https://jsfiddle.net/coh1xr77/5/
I need to delete an <LI> DOM Element correctly selected with a Selector based on its exact content. My list contains a set of Time LI's and my choice is to delete the first one in the list, 12:15am, based on the exact text match, when I click the button.
I can see that my selection is correct because I'm getting an [Object] reference in the alert box, rather than "Undefined".
However, the subsequent remove() on this element does nothing: the element remains.
var myselection = '12:15am';
$('#remove').click(function() {
var current = $('.ui-timepicker-list li').filter(function() {
return $(this).text() === myselection;
});
alert('current = ' + current); // This works, element found
$(current).remove(); // This does nothing (or doesn't remove properly)
});
You need to change the condition to check if the li's innerText starts with the selected time string. Like: $(this).text().indexOf(myselection) == 0
Here's the updated fiddle: https://jsfiddle.net/coh1xr77/11/
Update
Considering that all time values have the bracketed relative time strings at the end, you could try splitting based on that bracket (, and compare with the first part of that string. Like: $(this).text().split('(')[0].trim() == myselection
Here's the fiddle with that: https://jsfiddle.net/coh1xr77/12/
Update 2
If you are absolutely certain that the structure of li elements will not change, you could access the text using the childNodes. Like: $(this)[0].childNodes[0].textContent == myselection;
Here's the updated fiddle: https://jsfiddle.net/coh1xr77/14/
I have a div with a class .display_noti and inside it I have append another div with class .palnotific by jquery.I have fetched data from database and i converted that fetched data into json_encode.I used that json format data and made some information which were append on that div with class .palnotific.
my first jquery code which append data inside that div with class .display_noti looks like :-
$.getJSON("notification.php",function(data){
// you can do checking here
if ( data.result && data.result.length > 0 ) {
$(".display_noti").empty(); // Clear out the div
$.each(data.result,function(){
$(".display_noti").append("<div class='palnotific'>You got a pal requet from <strong>"+this['from_user']+"</strong><br><span class='date'>"+this['notification_date']+"<form method='post'><input type='text' class='palid' value='"+this['pals_id']+"'></form></div>");
});
done();
}
else {
$(".display_noti").append("<div class='palnotific' style='background-color:white;'>You have no notification to view.</div>");
}
Above I first get the json format data and I did some validation and then at last I append that second div with class .palnotific inside that first div with a class .display_noti.I have a form inside that append div which I use to take value from a input for use.
As we know .palnotific is an appended div.I wanted to use some Onclick event function on it so, I used below code :-
$('body').on('click','.palnotific',function(){
var x = $(this).closest('.display_noti').find('.palid');
var pid=x.val();
$.ajax({
url:'notifipro.php',
type:'post',
data:"palid="+pid,
success: function(data){
if(data==1)
{
$(window).load('oldpage.php');
}
if(data==2)
{
$(window).load('newpage.php');
}
}
});
});
Above code takes the input value from that form which was inside that .palnotific div which was appended from jquery at previous.As you know those appended div carry data from database via json_encode.It will take value as much as available in database which mean if there's 2 data in database json_encode will also have 2 data and those append div class which takes data from json_encode will append 2 time that div with a class palnotific.Now my problem is that if i have two div with class palnotifi origin from that append my click function work for first div only and when i click on second div onclick function doesn't work.No matter I have 2 or more then two div if I click any one div first div click function takes action.How can I make work onclick function to those div only which have been clicked?
The easiest way to have jquery react on an element that is dynamically created, is to attach the event to that element itself. Another way would be using on on a the container div with a subfilter, but since you are already creating the html, you can encapsulate it in $('yourhtml') and attach the click directly to that created element. In combination with appendTo instead of append, you can also chain the append and click:
//mock data:
var data={result: [
{from_user: 'A', notification_date: new Date(), pals_id: 1},
{from_user: 'B', notification_date: new Date(), pals_id: 2},
{from_user: 'C', notification_date: new Date(), pals_id: 3}
]};
$.each(data.result,function(){
var id = this.pals_id;
$("<div class='palnotific'>You got a pal request from <strong>"+this['from_user']+"</strong><br><span class='date'>"+this['notification_date']+"<form method='post'><input type='text' class='palid' value='"+ id +"'></form></div>")
.appendTo(".display_noti")
.click(function(){
//attach pre existing function or assign your logic here
alert('You clicked ' + id);
})
});
Example fiddle
In this example, the id was also stored before hand and reused inside the attached click. If you need to use the raw value, you can use $(this).find('.palid').val() (as done in this fiddle )
From the code you paste, the problem should be this line:
var pid=x.val();
as you can find in jQuery docs (http://api.jquery.com/val/)
.val() Get the current value of the first element in the set of matched elements or set the value of every matched element.
You can use a more specific CSS3 Selector in the on() function. I'm not entirely sure this is going to solve your overall problem, but it might lead you in the right direction.
$(".display_noti").on("click", ".palnotific:first", function(event) {
console.log("You Clicked: ", event.target.id);
});
Here is an example JSFiddle;
I am trying to use the following code to reference anything focused inside my contenteditable div, which has an id of rt:
var lastfocused;
$("#rt *").focus(function () {
lastfocused = $(this);
});
For some reason, lastfocused always equals $("#rt");, but never anything else which may be inside the contenteditable div. How do I make it so that anything focused inside the contenteditable div will be stored in the lastfocused variable?
Looks like your problem is elsewhere. The above code perfectly works for me:
http://jsfiddle.net/8hZWq/
EDIT
If the children elements aren't inputs as you said, but divs - the focus() method is not applicable to them, as it works only for input, textareas, select etc.
You can also use .click() instead of focus() to store the reference to the last clicked element. Bear in mind though, it also depends to the structure of your elements.
For example if you have multiple levels of containers within children divs, the #ID * selector will actually trigger multiple times each level of children starting from the #ID.
If you like to store reference to only the first level of children of the #ID, you should use #ID > * selector to refer only direct children.
If you like to store the reference to only the very element that was clicked upon regardless of it's level in relation to the container, you should use click event target reference instead:
var clicked;
$('#ID').click(function(event){
clicked = $(event.target);
});
Indeed your problem is because of variable declaration out of the function. Setting it in, in each focus event the 'lastfocused' variable will be re-assigned.
I came later, but if i arrive here someone else can.
Do this:
$("#rt *").focus(function () {
var lastfocused = $(this);
});
I have two <div> elements, and the following JavaScript code:
var myObject = {
$input: $('<input />'),
insert: function () {
$('div').append(this.$input);
$('div').append(' ');
}
};
myObject.insert();
This, as I expect, produces an <input> element within each of the two <div> elements.
Now when I create a new instance of myObject and call insert() again I will be expecting 4 <input> elements, two in each <div>. Weirdly, I only get 3 <input> elements!
See example code here:
http://jsfiddle.net/FNEax/
You're creating 1 input explicitly:
$input: $('<input />',{value:i}),
...but cloning it implicitly when you try to append it to multiple divs
// 2 divs
$('div').append(this.$input);
Then Object.create doesn't create a new $input, so on the second pass, it appends (moves) the input from the second div (which is actually the original) to the first div, and then does the implicit clone to populate the second.
Here's a jsFiddle example that increments an i variable whenever insert() is called, and adds it as the value of the input. Notice that it is always set at 0.
I also modified it to pass a string to insert so you can see which call each input came from.
The two inputs from the second call both still have the string passed to the first call.
EDIT:
I flipped it around mid explanation, but the concept is the same.
When the second insert() is called, the clone is first created of the original and added to the first div, then the original is appended to the second div (where it already is).
jQuery makes the clones first, then appends the original last.
Here's another jsFiddle example that adds a custom property to the original, then adds some text next to the element with that custom property after each insert(). The text is always added next to that original in the second div.
This is what is happening. From the jQuery docs:
If an element selected this way is inserted elsewhere, it will be moved into the target (not cloned)
If there is more than one target element, however, cloned copies of the inserted element will be created for each target after the first.
So the first time around, since your input isn't anywhere in the DOM it is cloned and inserted into both divs. But, the second time it is called it is removed from the second div, before being cloned and added back into both divs.
At the end of your code, the first div contains both inputs, but the second div only contains the most recent input, since each input was removed from your last div.
http://jsfiddle.net/hePwM/
Once an element is inserted into the DOM, another .append() call with it as the appended content causes it to move within the DOM (docs). Your code creates a jQuery collection with a single input therein, which input has yet to be appended to the DOM. So the first call to insert() appends it to each (using the cloning or copying mechanism internal to jQ).
In the second call, however, this.$input references something which is already in the DOM (due to the first call). Internally, jQuery is each-ing the collection of DIVs and appending the input which lives inside of this.$input. So it adds it, the moves it.
The primary issue is that you're re-appending the same input over and over. Remember that JavaScript generally references existing objects rather than make new ones. That same input element keeps getting re-referenced.
If you want a method to add an input to every DIV, you should simply pass the input markup into append:
$( 'div' ).append( '<input />' );
The wierd behavior is due to the fact you are using a JQuery collection where you shouldn't be. How it even worked in the first place is beyond my skillset.
var myObject = {
input: '<input />',
insert: function () {
$('div').append(this.input);
//$('div').append(' ');
}
};
try each():
var myObject = {
insert: function () {
$('div').each(function(index) {
$(this).append($('<input />'));
$(this).append(' ');
});
}
};
myObject.insert();
myObject.insert();