Target parent div, but not if it includes a nest class - javascript

I want to target a parent div using document.querySelectorAll. But not if the div contains a nested div, with a particular class.
For example, in the example below, I want to grab the parent first and last floatContainer divs. But not this second, because it contains dropdown-container class.
document.querySelectorAll(".ej-form-field:not([dropdown-container])") does not seem to be working.
console.log(document.querySelectorAll(".ej-form-field:not([dropdown-container])"))
<!-- GRAB THIS -->
<div id="floatContainer" class="ej-form-field">
<label for="floatField">First name</label>
<div class="input-container">
<input id="floatField" class="ej-form-field-input-textbox" type="text">
</div>
</div>
<!-- NOT THIS -->
<div id="floatContainer" class="ej-form-field">
<label for="floatField">Last name</label>
<div class="dropdown-container input-container">
<input id="floatField" class="ej-form-field-input-textbox" type="text">
</div>
</div>
<!-- GRAB THIS -->
<div id="floatContainer" class="ej-form-field">
<label for="floatField">Telephone</label>
<div class="input-container">
<input id="floatField" class="ej-form-field-input-textbox" type="text">
</div>
</div>

this code solve your problem.
console.log(document.querySelectorAll(".ej-form-field>div:not(.dropdown-container)"))

you must target a specific class not an attribute, ie:
document.querySelectorAll(".ej-form-field:not(.dropdown-container))

I also found this option, which seemed to work as well:
document.querySelectorAll("div.ej-form-field + :not(.dropdown-container)")

Related

Choose between ids that only meet some conditions

I'm facing a problem with my project. My user can create a new div by clicking a button, but he can remove whatever div he wants, expect the first one. So if he create 2 new divs here is what the code will look like:
<div id="container1">
<input type="text" id="title1"><br />
<input type="text" id="description1">
</div>
<div id="container2">
<input type="text" id="title2"><br />
<input type="text" id="description2">
</div>
<div id="container3">
<input type="text" id="title3"><br />
<input type="text" id="description3">
</div>
If the user remove the second div my code will look like this.
<div id="container1">
<input type="text" id="title1"><br />
<input type="text" id="description1">
</div>
<div id="container3">
<input type="text" id="title3"><br />
<input type="text" id="description3">
</div>
Pretty simple. Now I want to use the information entered by the user in the text inputs, but I don't know how to select the active divs. Is there a way to select the container1 and container3 in the example above?
Keep in mind that the user can use up to 99 new div.
Your help is appreciated. Thank you,
Just apply a CSS selector:
<div id="parent">
<div id="container1">
<input type="text" id="title"><br />
<input type="text" id="description">
</div>
<div id="container3">
<input type="text" id="title1"><br />
<input type="text" id="description1">
</div>
</div>
$('#parent > div')
See here for more information: https://api.jquery.com/category/selectors/
You can add a class to each item. You would need to amend your code that is called when the button is clicked to handle this.
Let's say you gave all titles a class of "myTitle" and you gave all descriptions a class of "myDescription". Your div created would look something like this:
<div id="container1">
<input type="text" id="title" class="myTitle">
<br />
<input type="text" id="description" class="myDescription">
</div>
Now, in order to get all titles and descriptions you'd use jQuery and say:
$('.myTitle').each(function () {
console.log($(this).val());
});
$('.myDescription').each(function () {
console.log($(this).val());
});
First of all, you have multiple divs with the id "title" and "description", so change those to class. You can select the nth div with jquery: $("#container" + n)
you can select the title of the nth div: `$("#container" + n).children(".title");
you can select all of the divs by adding a class to them, such as .container

jQuery Clone and select2 events

I have created two hidden fields where I am adding array to make dropdown. select2 array are depending on the first select2. So when I select in first select2 I will call select2 event to filter another select2.
All this is working correct. But I am cloning also same. But I don't know how to clone event of select2. I could not filter also. Somebody can help
My Sample code
My jsbin https://jsbin.com/monusupuni/edit?html,js,output
<div class="midcontainer pad20">
<div class="content-area fullWidth whiteBg">
<div class="pad15">
<div class="flightRows">
<div class="row flightRow">
<p><strong><span id="lbFlight">Flight 1</span></strong></p>
<div class="depCol1">
<label for="seldcity1" id="lbDeptCity"></label><br>
<input type="hidden" id="seldcity1" name="seldcity1" class="styled wth190 seldcity" />
</div>
<div class="depCol2">
<label for="selacity1" id="lbArrivalCity"></label><br>
<input type="hidden" id="selacity1" name="selacity1" style="width: 210px;" class="styled wth190 selacity" />
</div>
<div class="depCol1">
<label for="selddate1" id="lbDeptDate"></label><br />
<input name="selddate1" type="text" id="selddate1" autocomplete="off" class="datepicker calIcon">
</div>
<div class="searchBtnHolder">Add another Flight</div>
<div class="clear"></div>
<hr />
</div>
</div>
</div>
I'm not sure to understand your exact desire. Still, did you know that jQuery clone() method takes 2 arguments: withDataAndEvent and deepWithDataAndEvent.
So when you use .clone(), it will only clone the element, not the event associated with. You'll need to use .clone(true,true) to copy all events attached.
http://api.jquery.com/clone/

JQuery .addClass and .removeClass not working on Chrome or Safari

I'm trying to show and hide divs using a button. This code works just fine in Firefox and IE, but for some reason it's not working in Chrome or Safari. The site is using Bootstrap.
function newAdd(addId, rowId) {
var add = "#" + addId.id;
var row = "#" + rowId.id;
var nextNum = Number(add.charAt(4));
nextNum++;
var next = "#add" + nextNum;
$(add).addClass("dontShow");
$(next).removeClass("dontShow");
$(row).removeClass("dontShow");
}
.dontShow {
display: none;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row" id="row1">
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label for="000-000">Item Name:</label>
<br />
<input type="text" class="form-control" value="">
</div>
</div>
</div>
<div class="row" id="add1">
<div class="col-sm-1 col-md-1"> </div>
<div class="col-sm-2 col-md-2">
<a onclick="newAdd(add1,row2)">
<button class="btn" style="text-decoration: none; color: #ffffff;" id="add1" type="button">Add another item?</button>
</a>
</div>
<div class="col-sm-9 col-md-9"> </div>
</div>
<div class="row" id="row2">
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label for="000-000">Item Name:</label>
<br />
<input type="text" class="form-control" value="">
</div>
</div>
</div>
<div class="row" id="add2">
<div class="col-sm-1 col-md-1"> </div>
<div class="col-sm-2 col-md-2">
<a onclick="newAdd(add1,row2)">
<button class="btn" style="text-decoration: none; color: #ffffff;" id="add1" type="button">Add another item?</button>
</a>
</div>
<div class="col-sm-9 col-md-9"> </div>
</div>
<div class="row" id="row3">
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label for="000-000">Item Name:</label>
<br />
<input type="text" class="form-control" value="">
</div>
</div>
</div>
So what should happen is, the user sees the first row and first button and everything else is hidden. They fill out the first row, then click on the button. When clicked, the button goes away and the next row and next button appear showing two rows with one add button at the bottom. If they click it again, then the last row should appear and the add button goes away completely.
There are 2 solutions possible to achieve the result.
Solution 1
There are 2 updates that need to be done in your code
In HTML
There should be quotes for stirngs like newAdd('add1','row2')
In JS, no need for addId.id
var add = "#" + addId;
Solution 2
No html update. Only in JS, update
var add = "#" + addId.id;
to
var add = "#" + addId[0].id;
Solution 1 - You are passing the id of the element and accessing it in javascript.
Solution 2 - You are passing the HTML Object Collection and then accessing the element and its id property.
Now which solution to go for?
In case you only need Id, you can go for solution 1, as it makes no sense to pass the complete collection just to extract the id which can otherwise be send with the same parameters with just quotes around them.
However, if you need to get some other properties of the element, then go for solution 2.
The reason why it doesn't work in Chrome or Safari is that add1, which you are passing to the function, i.e.
addNew(add1, row1);
does not refer to a single element, but to an element collection:
Why? Because you have multiple elements with the same ID. IDs have to be unique!
Firefox on the other hand simply takes the first element with that ID (which is what I would have expected).
There are a couple of ways to solve this, one of them shown in the other answer, but you should definitely ensure that you are only using unique IDs. I highly recommend to read up on binding event handlers with jQuery: http://learn.jquery.com/events/event-basics/

Wrap children elements of parent elements without class only if they contain text inputs

Consider the following HTML
I am trying to wrap the child elements (label/input) where the label text says 'This one'. Basically, I need to select the full elements without class partial if they contain input text elements and not number uinput elements. One the full elements are selected, their children elements need to be completely wrapped entirely with <div class="wrapped"></div>
<div class="group">
<div class="full">
<label>This one</label>
<input type="text"/>
</div>
<div class="full partial">
<label>Foo</label>
<input type="text"/>
</div>
<div class="full">
<label>Foo</label>
<input type="number"/>
</div>
<div class="full">
<label>This one</label>
<input type="text"/>
</div>
<div class="full">
<label>Foo</label>
</div>
<div class="full partial">
<label>Foo</label>
<input type="text"/>
</div>
<div class="full partial">
<label>Foo</label>
<input type="number"/>
</div>
</div>
Like this:
<div class="wrapped">
<div class="full">
<label>This one</label>
<input type="text"/>
</div>
</div>
You could use a combination of the :not()/:has() selectors to select the desired .full elements. Iterate over the selected elements, and wrap the children elements using a combination of the methods .children()/.wrapAll():
Example Here
$('.group .full:not(.partial):has(input[type="text"])').each(function () {
$(this).children().wrapAll('<div class="wrapped"/>');
});
Alternatively, you could also use the following:
Example Here
$('.group input[type="text"]').closest('.full:not(.partial)').each(function () {
$(this).children().wrapAll('<div class="wrapped"/>');
});
I'm not sure where approach is faster.. probably the first one.

Copy element with its properties in mootools

The Following is the code I am using in Mootools,
var company_name = $('company_name-wrapper').clone();
company_name.inject($('wmd-button-bar'));
The HTML is as follows,
<div id="company_name-wrapper" class="form-wrapper" style='float:left;'>
<div id="company_name-label" class="form-label">
<label for="company_name" class="required">
Company
</label>
</div>
<div id="company_name-element" class="form-element">
<input type="text" name="company_name[]" id="company_name" value="">
</div>
</div>
..............
..............
<div id='wmd-button-bar'></div>
The Output I am getting after executing the code is,
<div id='wmd-button-bar'>
<div class="form-wrapper">
<div class="form-label">
<label for="company_name" class="required">
Company
</label>
</div>
<div class="form-element">
<input type="text" name="company_name[]" id="company_name" value="">
</div>
</div>
</div>
The Id's or the style of any elements is not getting cloned.
Any help or suggestion is appreciated,
thanks in advance.
Mootools avoids copying ID's to avoid getting double ID's, but you can override that using .clone([contents, keepid]) keepid function paramenters.
So try using: var company_name = $('company_name-wrapper').clone(true, true);
Demo
Notice that doing so you will have duplicate ID's and that is invalid HTML, it will give you problems when you try to refer to different elements with the same ID.

Categories