jQuery get children for selected object - javascript

I have a selected object that was clicked. When this happens, i would like to retrieve the object and then find the children with a specific class value so i can disable them.
I am able to get the object but when i access the children i always get "undefined" even though i can see the children.
I browsed the object and i can see the class attributes values i am looking for.
Can somebody please tell me if i am referencing this correctly?
Below is my code,
The specific line with the issue is,
var kids = clicked_obj.children('.ui-selected');
// manually trigger the "select" of clicked elements
$(".page").click(function (e) {
console.log(e);
//var selected_divs = $(".page").find("div[class*='ui-selected']");
var selected_divs = $(".page").find(".existingFieldItem.ui-selected");
selected_divs.each(function () {
if (e.ctrlKey == true) {
var clicked_obj = e.target.parentElement;
var kids = clicked_obj.children('.ui-selected');
console.log("Ctrl clicked");
console.log($(this).attr("id"));
kids.each(function () {
$(this).removeClass("ui-selected");
});
// if command key is pressed don't deselect existing elements
$(this).removeClass("ui-selected");
$(this).addClass("ui-selecting");
}
else {
if ($(this).hasClass("ui-selected")) {
// remove selected class from element if already selected
$(this).removeClass("ui-selected");
}
else {
// add selecting class if not
$(this).addClass("ui-selecting");
}
}
});
$(".page").data("ui-selectable")._mouseStop(null);
});
});

You're missing a jQuery selection:
var clicked_obj = $(e.target.parentElement);
e.target.parentElement is a DOM element object, not a jQuery selection.

Related

Call script from another script

In HTML5 I have a dropdown menu . When choosing different options I hide or show different parts of my page. Here is that script:
document
.getElementById('target')
.addEventListener('change', function () {
'use strict';
var vis = document.querySelector('.vis'),
target = document.getElementById(this.value);
if (vis !== null) {
vis.className = 'inv';
}
if (target !== null ) {
target.className = 'vis';
}
});
However what I want to do now, in another script is to preload an option from the dropdown. I can do it easily with this script:
setSelectedIndex(document.getElementById('target'),'content_1');
function setSelectedIndex(s, valsearch)
{
// Loop through all the items in drop down list
for (i = 0; i< s.options.length; i++)
{
if (s.options[i].value == valsearch)
{
// Item is found. Set its property and exit
s.options[i].selected = true;
break;
}
}
return;
}
This is where my problem comes up, my dropdow will get the value I want, but the part that I want to be shown when choosing that option won't come up.
That is because change events need to happen from the browser.
When the user commits the change explicitly (e.g. by selecting a value
from a 's dropdown with a mouse click, by selecting a date
from a date picker for , by selecting a file in the
file picker for , etc.);
If your using Jquery you can:
$("#id").val("value").trigger('change');
or you can use javascript if your not worried about building the event object:
if ("createEvent" in document) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
element.dispatchEvent(evt);
}
else
element.fireEvent("onchange");
I would recommend moving your anonymous onchange function into a named function that you can call once onload, and again onchange.
Here is the function I wrote:
function setContent(id) {
//get the current visible content
var vis = document.querySelector('.vis');
//get the target element by id
var target = document.getElementById(id);
//make current vis element inv
if (vis) vis.className = "inv";
//make target element vis
if (target) target.className = 'vis';
}
and a fiddle
edited: got rid of querySelectorAll to stick closer to OP original code and updated fiddle. clarified and commented code.
The problem you have is changing a vale or the selected value of an input with JavaScript does not trigger any change event. So you would need to manually trigger the event.
function setSelectedIndex(s, valsearch)
{
// Loop through all the items in drop down list
for (i = 0; i< s.options.length; i++)
{
if (s.options[i].value == valsearch)
{
// Item is found. Set its property and exit
s.options[i].selected = true;
break;
}
}
//Setting the selected value with JavaScript does not trigger the change event so you need to manually trigger the change event
if ("createEvent" in document) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
s.dispatchEvent(evt);
} else {
s.fireEvent("onchange");
}
return;
}

Nestable / sortable serialized list without removing the original item from list

I have been using the Nestable JS from Bushell (https://github.com/dbushell/Nestable) for a while and have lots of usable code to generate the menus from Mysql, but I need to drag available options from one list to another list without removing it from the source.
I just want to append it to the list second list. Is this reasonable to do with Nestable or do I need to run back to jquery draggable to get the "clone" option?
Demo I found to illustrate: http://jsfiddle.net/Aub7x/
On this demo it would be easy enough, except when you use $( ".items" ).sortable( "toArray" ); it doesn't return the nested format that I can use to identify parent child relationships. Otherwise it is a much cleaner code base to work off of than the Bushell library.
http://jsfiddle.net/trevordowdle/6CDSB/1/
Since I am linking to JSFiddle, it requires some code to be posted. In the Bushell code I was working hard to find where items were removed from the source, but didn't see it here:
list.el.on('click', 'button', function(e) {
if (list.dragEl) {
return;
}
var target = $(e.currentTarget),
action = target.data('action'),
item = target.parent(list.options.itemNodeName);
if (action === 'collapse') {
list.collapseItem(item);
}
if (action === 'expand') {
list.expandItem(item);
}
});
var onStartEvent = function(e)
{
var handle = $(e.target);
/* callback for beforeDragStart */
list.el.trigger('beforeDragStart', [handle]);
if (!handle.hasClass(list.options.handleClass)) {
if (handle.closest('.' + list.options.noDragClass).length) {
return;
}
handle = handle.closest('.' + list.options.handleClass);
}
if (!handle.length || list.dragEl) {
return;
}
list.isTouch = /^touch/.test(e.type);
if (list.isTouch && e.touches.length !== 1) {
return;
}
e.preventDefault();
list.dragStart(e.touches ? e.touches[0] : e);
/* callback for dragStart */
var item = list.dragEl.find('.'+list.options.itemClass);
list.dragRootEl.trigger('dragStart', [
item, // List item
list.el // Source list
]);
};
I was able to come up with a solution here: https://github.com/dbushell/Nestable/issues/158
You can add the class of "clone" to anything you want to drag from one list to the other.
Put this around line 325:
if ($(dragItem[0]).hasClass("clone"))
{
var cln=dragItem[0].cloneNode(true);
dragItem[0].parentNode.replaceChild(cln, dragItem[0]);
$(dragItem[0]).removeClass("clone")
dragItem.after(this.placeEl);
}else{
dragItem.after(this.placeEl);
dragItem[0].parentNode.removeChild(dragItem[0]);
}

JavaScript Function Only Working Sometimes With Same Input

I've got the following bit of code (using JQuery) that I've written for a project. The idea is to have a function that you can attach to an element within an "item" div and it will return the id of that div. In this case, the div id would be item-[some item primary key value]. This function works probably 9/10 times, but every once in a while it will get to the else else case and return false. I've verified through the console that the input for selector is the exact same JQuery $() item in both the success and fail cases.
I'm relatively new to JavaScript, so there may be something obvious I'm missing, but this is some really unusual behavior.
var recursionCounter = 0;
function getElementID(selector, recursionDepth, searchString){
console.log(selector);
var elementID = selector.attr("id");
if(elementID === undefined){
elementID = "";
}
if(elementID.indexOf(searchString) !== -1){
elementID = elementID.split("-")[1];
return elementID;
} else {
if(recursionCounter < recursionDepth){
recursionCounter++;
return getElementID(selector.parent(), recursionDepth, searchString);
} else {
recursionCounter = 0;
alert("The element clicked does not have an associated key.");
return false;
}
}
}
Here is an example of code that calls this function, for some context.
$(document).on("click", ".edit-pencil-item", function(event) {
//Use helper function to get the id of the surrounding div then pass it to the function
var itemID = getElementID($(this), 10, "item-");
jsEditItem(itemID);
return false;
});
Thanks in advance for any help!
If you want to get the encapsulating element of your clicked element, and you know it should have an id starting with "item-" you should be able to do something along the lines of
$(this).closest('[id^="item-"]').attr('id')
Which says find this elements closest parent that has an id starting with "item-" and tell me its id.

Hide/unhide table row given the row index and table ID

Currently I have this code to delete a table row:
var remove = document.getElementById(dataID); (this is the id of an object in the row I wish to hide)
if(remove!=null){
var v = remove.parentNode.parentNode.rowIndex;
document.getElementById(tid).deleteRow(v); (tid is the table id, not the row id)
}
However, instead of delete it, I'd just like to hide it. What's a good way to do this?
Also, in the future, I'm going to want to 'unhide' it at user request, so how can I check if it has been hidden? The if(remove!=null) is what checked if a row was already removed, so I'd need something similar.
Thank you for your time.
document.getElementById(tid).children[dataID].style.display = 'none';
You may need -1 on dataID
And block to show it again (or inline or whatever it originally was, for a div it's block).
JQuery:
$('#'+tid+':nth-child('+dataID+')').hide();
My own approach, in plain JavaScript:
function toggleRow(settings) {
// if there's no settings, we can do nothing, so return false:
if (!settings) {
return false;
}
// otherwise, if we have an origin,
// and that origin has a nodeType of 1 (so is an element-node):
else if (settings.origin && settings.origin.nodeType) {
// moving up through the ancestors of the origin, until
// we find a 'tr' element-node:
while (settings.origin.tagName.toLowerCase() !== 'tr') {
settings.origin = settings.origin.parentNode;
}
// if that tr element-node is hidden, we show it,
// otherwise we hide it:
settings.origin.style.display = settings.origin.style.display == 'none' ? 'table-row' : 'none';
}
// a simple test to see if we have an array, in the settings.arrayOf object,
// and that we have a relevant table to act upon:
else if ('join' in settings.arrayOf && settings.table) {
// iterate through that array:
for (var i = 0, len = settings.arrayOf.length; i < len; i++) {
// toggle the rows, of the indices supplied:
toggleRow({
origin: table.getElementsByTagName('tr')[parseInt(settings.arrayOf[i], 10)]
});
}
}
}
// you need an up-to-date browser (you could use 'document.getElementById()',
// but I'm also using 'addEventListener()', so it makes little difference:
var table = document.querySelector('#demo'),
button = document.querySelector('#toggle');
// binding a click event-handler to the 'table' element-node:
table.addEventListener('click', function (e) {
// caching the e.target node:
var t = e.target;
// making sure the element is a button, and has the class 'removeRow':
if (t.tagName.toLowerCase() === 'button' && t.classList.contains('removeRow')) {
// calling the function, setting the 'origin' property of the object:
toggleRow({
origin: t
});
}
});
// binding click-handler to the button:
button.addEventListener('click', function () {
// calling the function, setting the 'arrayOf' and 'table' properties:
toggleRow({
'arrayOf': document.querySelector('#input').value.split(/\s+/) || false,
'table': table
});
});
JS Fiddle demo.
References:
document.querySelector().
e.target.addEventListener().
Node.nodeType.
String.split().
As you've asked for a jQuery solution...how about
var $remove = $('#' + dataID);
if ($remove) {
$remove.closest('tr').closest().hide();
}
?

jQuery: Check if an element is assigned to a var

I'm trying to create a simple button manager to select and eventually unselect allready checked img elements which contains CSS class .my_class, why this doesn't work?
var last_selected;
$("img.my_class").click ( function () {
if (last_selected != null) alert ($(this) == last_selected); // returns false everytime
last_selected = $(this);
});
It doesn't work because each time you call $(this) a new jQuery wrapper object is created.
Instead, try just saving "this":
var last_selected;
$("img.my_class").click ( function () {
if (last_selected != null) alert (this === last_selected);
last_selected = this;
});
why not assign a 'selected' class to the currently selected img?
$('img.my_class').click(function()
{
// remove the selected class from the previous selected
$('img.my_class.selected').removeClass('selected');
// flag the current one as selected
$(this).addClass('selected');
});
Each time you wrap this you create a new jQuery object. Two jQuery objects are not equal to each other just because they wrap the same element ($(this) != $(this)).
Instead, assign this itself to last_selected and everything should work as expected.
var last_selected;
$("img.my_class").click ( function () {
if (last_selected != null) alert (this == last_selected);
last_selected = this;
});

Categories