jquery find logical operator inside selector - javascript

How can I search (jquery find) elements without using comma seperator. JSFiddle here.
Example:
<div id="inputs">
<input name="n1" value="v1" type="text" />
<input name="n2" value="v2" type="checkbox" />
<input name="n3" value="v3" type="button" />
<input name="n4" value="v4" type="hidden" />
<input name="n5" value="v5" type="text" />
<input name="n6" value="v6" type="text" />
<input name="n7" value="v7" type="text" />
<input name="n8" value="v8" type="text" />
<input name="n9" value="v9" type="text" />
<input name="n10" value="v10" type="text" />
</div>
1- I can do this with following code:
$('#inputs')
.find('input[type="text"][name="n7"], input[type="text"][name="n8"]')
.val("found");
2- But how I want to use this is like:
$('#inputs')
.find('input[type="text"][name="n7" || "n8"])
.val("found");
Reason: Just curious and think there might be a performance difference (second is faster).

How can I search elements without using comma seperator.
You cannot, the comma between multiple selectors is the only OR-operator available.
However, you can chain the searches and use the comma operator on a single level only:
$('#inputs input[type="text"]').filter('[name="n7"], [name="n8"]')
This is indeed more concise (no repetition) and should be more efficient as well. If you really want to match multiple values against a single attribute expression, use a custom filter function:
$('#inputs input:text').filter(function() {
var name = this.name;
return name=="n7" || name=="n8"; // or
return ~["n7","n8"].indexOf(this.name); // or
return /^n[78]$/.test(this.name); // or whatever
});

Related

How to get text-box counts in javascript

H i have a button "Add text" when on-click it creates the text-boxes,now How can i get the count of text-boxes in JavaScript i create text-boxes like
<input type="text" name="my_textbox[1]" id="my_textbox1" />
<input type="text" name="my_textbox[2]" id="my_textbox2" />
<input type="text" name="my_textbox[3]" id="my_textbox3" />
<input type="text" name="my_textbox[4]" id="my_textbox4" />
the reason why i need to count is ,i am fetching values from ajax and creating new text-box appending new text-box like :
<input type="text" name="my_textbox[5]" id="my_textbox5" value="seomthing"/>
Now I would like to know the number of text-boxes present. It would be best if I can get the count through JavaScript .
Thanks in advance.
Give your inputs a classname so you can identify them as a group:
<input class="myInputs" type="text" name="my_textbox[1]" id="my_textbox1" />
Then in your javascript select them with querySelectorAll() and look at the length of the returned collection:
var inputs = document.querySelectorAll('.myInputs')
var number_of_inputs = inputs.length
Use document.querySelectorAll() to get all the elements matching substring of id (https://www.w3.org/TR/selectors/#attribute-substrings). This '[id^="my_textbox"]' syntax means you are selecting all elements with id starting with "my_textbox" string. The just take the length of queried collection and you are done. Please see snippet below:
var textboxCount = document.querySelectorAll('[id^="my_textbox"]').length;
console.log(textboxCount);
<input type="text" name="my_textbox[1]" id="my_textbox1" />
<input type="text" name="my_textbox[2]" id="my_textbox2" />
<input type="text" name="my_textbox[3]" id="my_textbox3" />
<input type="text" name="my_textbox[4]" id="my_textbox4" />

REQUIRED || REQUIRED HTML5 Forms

I have arrived to a situation that if only one of the two required fields in the form are filled then it should submit the form. Unfortunately, if i put required on both the fields it would wait for both of them to be filled in. Can this work without using JS? I know it is nearly impossible while not knowing any of the hidden features regarding it?
Can this work without using JS?
No, you need JavaScript to do that validation client-side.
The solution requires JS, but is easy - simply toggle the .required property of the elements based on whether either of them has a value:
var t1 = document.getElementById('test1');
var t2 = document.getElementById('test2');
function toggleRequired() {
t2.required = (t1.value.trim() === '');
t1.required = (t2.value.trim() === '');
}
t1.addEventListener('change', toggleRequired, false);
t2.addEventListener('change', toggleRequired, false);
<form>
<input name="test1" id="test1" required />
<br/>
<input name="test2" id="test2" required />
<br/>
<input type="submit" />
</form>
You could also put it into one div. It did worked for me.
<form>
<div class=question>
<input id="field1_1" name="field1" required>
<input id="field1_2" name="field1" required>
<input type="submit" />
</div>
</form>

Check if n elements contains data attribute set to true

I have a website where there are five checkboxes, a div that contains another divs which each div contains five input hidden that have a value 1 or empty. That value comes from DB.
That's an example to represent the div container with the divs:
<input checkbox value="a">
<input checkbox value="b">
<input checkbox value="c">
<input checkbox value="d">
<input checkbox value="e">
<div class="container">
<div class="content" data-name="combine">
<input type="hidden" value="" data-name="a" />
<input type="hidden" value="" data-name="b" />
<input type="hidden" value="" data-name="c" />
<input type="hidden" value="" data-name="d" />
<input type="hidden" value="" data-name="e" />
</div>
<div class="content" data-name="combine">
<input type="hidden" value="1" data-name="a" />
<input type="hidden" value="" data-name="b" />
<input type="hidden" value="" data-name="c" />
<input type="hidden" value="1" data-name="d" />
<input type="hidden" value="" data-name="e" />
</div>
</div>
In the javascript code i have this snippet:
if(elementLength > 0) {
$("[data-name='combine'] div.tagsProds").each(function() {
var element = $(this);
$.each(enabledChecks,function(i, v) {
if(element.find("input[name='"+v+"']").val() == "") {
element.append("<div class='blocked'></div>");
element.unbind("click");
element.addClass("js_noSortable");
}
});
});
}
The javascript first checks if the div.container has childs and if it has childs the code iterates each child. On each child i iterate the five each checkbox (enabledChecks) and i see if the input hidden are empty. What i need if that if the five input are empty then append the `div.blocked'.
As i don't have enough reputation to write a comment i write an answer.
First, i think that your answer is quite interesting if you're looking to find a way using a jQuery function, but as i don't know any function to do this i think that you can create an array() and when you check if the input has empty value push it to the array, when the loop finishes you check the length of the array() and if it matches with the number of your checkboxes then append the .blocked
If I understand the question correctly, you want to find divs matching some selector that have no child input elements with non-empty values. The .filter method seems like a good fit here:
$("[data-name='"+name+"'] div.tagsProds")
.filter(function() {
// assert that at least one child input has a value
var $inputsWithValue = $(this).find("input[name='avail_" + v + "'][value!='']");
return $inputsWithValue.length === 0;
})
.each(function() {
// now act on those value-less divs
$(this)
.append("<div class='blocked'></div>")
.addClass("js_noSortable")
.unbind("click");
});
Another selector-only option might look like:
$("[data-name='"+name+"'] div.tagsProds:not(:has(input[name='avail_" + v + "'][value!='']))")
.each(function() {
// now act on those value-less divs
$(this)
.append("<div class='blocked'></div>")
.addClass("js_noSortable")
.unbind("click");
});
JSFiddle: http://jsfiddle.net/nrabinowitz/vrx2wk8g/
Note that the examples above follow the selectors in your sample code, but won't work against your sample markup.

Regex to detect the first set of square brackets with anything inside them

So I suck at RegExes. Still.
I'm looping over some HTML-inputs with jQuery, and, in their name attributes, I would like to replace only the first set of the square brackets with "anything" inside them.
I've got these HTML-inputs:
<fieldset id="set">
<input type="text" name="shift[305][sub_amount]" value="Snoopy" />
<input type="text" name="shift[405][price]" value="12" />
<input type="text" name="cost[insert_1392222118][amount]" value="Hoof" />
</fieldset>
And my goal is this
<fieldset id="set">
<input type="text" name="shift[replaced][sub_amount]" value="Snoopy" />
<input type="text" name="shift[replaced][price]" value="12" />
<input type="text" name="cost[replaced][amount]" value="Hoof" />
</fieldset>
So I'm looping over them like so:
$('#set').find(":input").attr("name", function(index, element) {
return element.replace(/\[[0-9]+\]/, function(match) {
return '[replaced]';
})
});
But my regex only fixes the square brackets with numeric data in them.
JSFiddle-example that only solves it when the square brackets only contain numeric data:
http://jsfiddle.net/XLnAC/
Who can tell me which RegEx to use to target the first instance of square brackets with anything inside them?
I've found similar questions, but no details on how to only find the first instances.
Regular expression for detecting round or square brackets
You may use this one :
/\[[^\]]+\]/
You also don't need to use a function here :
return element.replace(/\[[^\]]+\]/, '[replaced]')

How do I order by node depth and then by tabindex?

I've got an HTML form that's built dynamically using templates at runtime - dictated by user action.
I need to set the tab index across the form based on the tabindexing specified within each of the pieces of the form.
Given this, is there a way in jQuery to order items within a set? For instance something that follows this pseudo structure would be awesome, but I can't figure out how to achieve it:
<div name="firstTemplate" templateIndex="0">
<input type="text" name="field0" tabIndex="1" />
<input type="text" name="field1" tabIndex="2" />
<input type="text" name="field2" tabIndex="3" />
</div>
<div name="firstTemplateRpt" templateIndex="1">
<input type="text" name="field0" tabIndex="1" />
<input type="text" name="field1" tabIndex="2" />
<input type="text" name="field2" tabIndex="3" />
</div>
<div name="secondTemplate" templateIndex="2">
<input type="text" name="field0" tabIndex="1" />
<input type="text" name="field1" tabIndex="2" />
<input type="text" name="field2" tabIndex="3" />
</div>
I could then use some variation of the following concept:
$("input, textarea, select, input:checkbox, input:radio").orderBy("templateIndex, tabIndex");
Where templateIndex would be the index of the template within the form and the tabindex would be the tabindex of the control within the template. A template could be added to the form multiple times at runtime, which is causing havoc on manually specified tabindexes.
When another template is added to the form, it would be assigned the templateIndex="3" with its manually set tabIndexes starting again at 1.
Collect the divs with a templateIndex attribute into an array, then sort them like:
divArray.sort(function(a, b) {
return a.getAttribute('templateIndex') - b.getAttribute('templateIndex');
});
Then iterate over those and sort the inputs inside the array using a very similar function:
inpArray.sort(function(a, b) {
return a.tabIndex - b.tabIndex;
});
Then move the elements in the required order in the document using something like node.parentNode.insertBefore(node, firstChild).

Categories