How can I rewrite this without using JQuery library just with JavaScript? - javascript

I have a couple of lines of code in JQuery:
var central = $('#townid option:contains("Central")');
if (central.length){
central.insertAfter('select option:first-child');
}
How can I rewrite it without using JQuery library just with JavaScript?

A correct translation would be something like:
var selects = document.getElementsByTagName('select'),
options = document.getElementById('townid').getElementsByTagName('option'),
options = Array.prototype.slice.call(options), //2 lines only for readability
tmp = document.createDocumentFragment();
for(var i = 0, l = options.length; i < l; i++) {
var option = options[i],
text = option.innerText || option.textContent;
if(text.indexOf('Central') > -1) {
tmp.appendChild(option);
}
}
for(var i = 0, l = selects.length; i < l; i++) {
var select = selects[i],
opts = select.getElementsByTagName('option');
if(opts.length > 1) {
select.insertBefore(tmp.cloneNode(true), opts[1]);
}
else {
select.appendChild(tmp.cloneNode(true));
}
}
DEMO
This could be simplified a lot depending on the markup (and optimized depending on the browser (e.g. support for querySelectorAll)). E.g. if you know that there will always only be one option that contains "Central" and whether there exists only one select element or not.
Here is a stripped down version for one select element, known size of the list (i.e. > 1) and only one option that contains Central. So basically just reordering the option:
var options = document.getElementById('townid').getElementsByTagName('option');
for (var i = 0, l = options.length; i < l; i++) {
var option = options[i],
text = option.innerText || option.textContent;
if (text.indexOf('Central') > -1) {
if (i > 1) {
option.parentNode.insertBefore(option, options[1]);
}
break;
}
}
DEMO
Update:
If the option's text should be exactly Central, compare the text normally:
if(text === 'Central')

Related

Strange behaviour in the if statement

I have a piece of code that is meant to hide table elements depending on given array. I am running loops to compare innerText of one of the cells and the given array.
However, my if statement is statement is acting weird, once i set the operator to === the operation is successful and table rows that match the array are hidden. But i need my if to hide the elements that are not a part of the array, so naturally I set my operator to !== but once i do it it just executes anyway and of course hides all of the elements in the table.
Any idea why this is happening here is the code:
var td1 = document.querySelectorAll("#course");
var rowss = document.querySelectorAll("#rows");
var courseNames1 = [td1.innerText];
var diff = _.difference(soretedArray, courseNames1)
console.log(diff);
for (var i = 0; i < rowss.length; i++) {
for (var j = 0; j < diff.length; j++) {
if (td1[i].innerText === diff[j]) { // if i set the logic operator to !== it hides all of the elements rather the ones that don't match
console.log(rowss[i]);
rowss[i].style.display = "none";
break;
}
}
}
I added the code as I have understood your request: You want the negation of "contains" to hide the element. This is as complete as possible based on the information you gave.
var soretedArray = [];//initialized elsewhere
var td1 = document.querySelectorAll("#course");
var rowss = document.querySelectorAll("#rows");
function tdContains(td) {
for(var j= 0 ; j< soretedArray.length; j++){
if(td.innerText === soretedArray[j]){
return true;
}
}
return false;
}
for(var i = 0 ; i < rowss.length; i++){
if(!tdContains(td1[i])) {
console.log(rowss[i]);
rowss[i].style.display= "none";
}
}

How to perform a series of searches but skip a search if value is blank, in Google Sheets?

I would like to search various columns in my sheet to find matches to certain cells. The issue comes from some of these cells may be blank and as they are I would like to skip it and do the next search. In the end I want it to mark "found here" against the rows that match all the value cells that have been filled in. My script so far is
function onSearch() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Main Sheet");
var searchVal1 = sheet.getRange("AE31").getValue();
var searchVal2 = sheet.getRange("AE32").getValue();
var searchVal3 = sheet.getRange("AE33").getValue();
var searchCol1 = sheet.getRange(2,6,sheet.getLastRow()).getValues();
var searchCol2 = sheet.getRange(2,7,sheet.getLastRow()).getValues();
var searchCol3 = sheet.getRange(2,7,sheet.getLastRow()).getValues();
for (var i = 0, len = searchCol1.length; i < len; i++)
for (var i = 0, len = searchCol2.length; i < len; i++)
{if (searchVal1 === "")
(searchCol2[i][0] == searchVal2)
else if (searchCol1[i][0] == searchVal1)
{if (searchCol2[i][0] == searchVal2)
{if (searchVal2 === "")
(searchCol3[i][0] == searchVal3)
else if (searchCol2[i][0] == searchVal2)
{if (searchVal3 === "")
else if (searchCol3[i][0] == searchVal3)
{sheet.getRange(i + 2, 30).setValue("found here")
This does search and find the correct rows if all the values are in the cells (AE31,AE32,AE33) but if I take one out it produces no result.
This is an example of the data set I am using.
Why are searchCol2 and searchCol3 identical?
You have this:
for (var i = 0, len = searchCol1.length; i < len; i++)
for (var i = 0, len = searchCol2.length; i < len; i++)
Which is bad. If you want to nest for loop, use two different counter variables, typically i and j (and k)
You need to learn to properly indent your code. A good-looking code is easier to debug. Use code beautifier if you need help.
Code like getRange("AE31") will make code maintenance harder. Consider name your search term cell and use getRangeByName instead.
Here is the cleaned-up (and working) code:
function onSearch() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Main Sheet");
var searchVal1 = sheet.getRange("AE31").getValue();
var searchVal2 = sheet.getRange("AE32").getValue();
var searchVal3 = sheet.getRange("AE33").getValue();
var searchCol1 = sheet.getRange(2, 6, sheet.getLastRow()).getValues(); // F2:F (address)
var searchCol2 = sheet.getRange(2, 7, sheet.getLastRow()).getValues(); // G2:G (MIS)
var searchCol3 = sheet.getRange(2, 7, sheet.getLastRow()).getValues();
for (var i = 0; i < searchCol1.length; i++) {
if (
((searchVal1 == "") || (searchCol1[i][0] == searchVal1)) &&
((searchVal2 == "") || (searchCol2[i][0] == searchVal2)) &&
((searchVal3 == "") || (searchCol3[i][0] == searchVal3))
) {
sheet.getRange(i + 2, 30).setValue("found here")
}
}
}
The variable naming is confusing. I'd suggest searchTerm or searchTermAddress instead of searchVal1, and searchRange instead of searchCol

Looping through and updating the values in a select list

I'm trying to update the options of ALL select lists on a page and implemented a solution found on Get list of all `input` objects using JavaScript, without accessing a `form` object and other pages.
This works to an extent but only the select lists which occur AFTER the one which is triggering the javascript are updated whereas I need them ALL done, regardless of their position relative to the triggering select.
Here's a simplified version of what I have:
function chooseBon(id, value) {
var bonbonsAmount = 12;
var bonbonsCurrent = 0;
var bonbonsCount = 4;
var inputs, index;
// get all the select lists
inputs = document.getElementsByTagName('select');
// loop through all the lists
for (index = 0; index < inputs.length; ++index) {
// First disable all options
for (j = 0; j<=bonbonsAmount; ++j) {
inputs[index].options[j].disabled="disabled";
}
// Then re-enable the ones we still need
for (j = 0; j<=(bonbonsAmount - bonbonsCurrent); ++j) {
inputs[index].options[j].disabled="";
}
// add up the no of chocs selected so we know how many options to re-enabled above
bonbonsCurrent += inputs[index].selectedIndex;
}
I'm an admitted newbie and am adapting a script from one ecommerce platform for another so am hamstrung in certain areas so feel free to make other suggestions.
here is one of possible solutions and the fiddle:
function chooseBon() {
var bonbonsAmount = 12;
var bonbonsCurrent = 0;
var bonbonsRemaining; //max. is bonbonsAmount
var inputs, i, j;
inputs = document.getElementsByTagName('select');
for (i = 0; i < inputs.length; i++) {
bonbonsCurrent += parseInt(inputs[i].value, 10);
}
bonbonsRemaining = bonbonsAmount - bonbonsCurrent;
for (i = 0; i < inputs.length; i++) {
for (j = 0; j <= bonbonsAmount; j++) {
inputs[i].options[j].disabled = (j < bonbonsRemaining + parseInt(inputs[i].value, 10) + 1) ? false : true;
}
}
}

Javascript fill select box

[Code]
$.ajax
({
'method': 'GET',
'source': '/bpv-registratie/periods/show_period_list_by_year.html',
'charge': function ()
{
},
'finish': function (xmlHttp)
{
var options = new Array();
var response = eval('(' + xmlHttp.responseText + ')');
var child = document.createElement('option');
child.setAttribute('value', 'none');
child.setAttribute('checked', 'checked');
child.innerHTML = '&nbsp';
options.push(child);
for (var c = 0; c < response.length; c++)
{
var child = document.createElement('option');
child.setAttribute('value', response.data[c].periode_id);
child.innerHTML = response.data[c].periode_naam +
' (' +
response.data[c].periode_startdatum +
' t/m ' +
response.data[c].periode_einddatum +
' )';
options.push(child);
}
for (var a = 0; a < obj.childNodes.length; a++)
{
var e = obj.childNodes[a].getElementsByTagName("select");
for (var f = 0; f < e.length; f++)
{
e[f].length=0;
for (var o = 0; o < options.length; o++)
{
e[f].appendChild(options[o]);
}
}
alert('test');
}
}
});
[Problem]
Running the code above with the alert, it shows that all the select boxes do get filled with the options I want them to. However as soon as it starts filling the next select box, the previous is being cleared again.
Does anyone know why?
[Situation]
I have a bunch of select boxes generated from about the same code. These represent a class a person can be in. The class should be selected from the selectbox. However if the teacher wishes to change the person to a different period, that would most likely mean that there are different classes available in that period so what I'm trying to do is fill the select boxes with the classes from the new period.
I think your problem is that a single option object can only be in one <select> at a time. Your first trip through the loop fills the first select, then your second trip through the loop moves the options from the first <select> to the second. Rinse and repeat until your final <select> ends up with all the options.
The solution is to create the options when you're about to add them to the <select>. Your first loop should just build an array to hold the values and labels, then expand that simple data to option DOM elements and hand them over to the <select>. This will create a unique set of option objects for each <select>.
Here's a simple example that you can play with to see what's going on:
http://jsfiddle.net/ambiguous/9WuQC/
I'll include the fiddle inline for future reference; the HTML:
<select id="a"></select>
<select id="b"></select>
<button id="c">fill first</button>
<button id="d">fill second</button>
And JavaScript:
var options = [ ];
var option;
for(var i = 0; i < 10; ++i) {
option = document.createElement('option');
option.setAttribute('value', i);
option.innerHTML = i;
options.push(option);
}
$('#c').click(function() {
var s = document.getElementById('a');
for(var i = 0; i < options.length; ++i)
s.appendChild(options[i]);
});
$('#d').click(function() {
var s = document.getElementById('b');
for(var i = 0; i < options.length; ++i)
s.appendChild(options[i]);
});
I'm not sure what obj actually is, but in my mind, this is what is happening (denoted by the comments):
//loop round all the child nodes of obj (not just immediate children)
for (var a = 0; a < obj.childNodes.length; a++)
{
//get all <select> elements under the current child (a) of obj
var e = obj.childNodes[a].getElementsByTagName("select");
//loop round our selects under the current child node
for (var f = 0; f < e.length; f++)
{
e[f].length=0;
for (var o = 0; o < options.length; o++)
{
e[f].appendChild(options[o]);
}
}
alert('test');
}
The comment 'not just immediate' is pertintent here. Say you have a structure
<div id="a">
<div id="b">
<div id="c">
<select id="d"></select>
</div>
</div>
</div>
When you loop through the children of 'a' you get ALL the children, i.e. b,c,d. Next time around your child iteration you are looking at 'b' itself, so you get 'c' and 'd'.
In each of these loops, you populate the select box.
The short answer is that you have probably made a false assumption about the childNodes property.

javascript equivalent of jquery code

Can someone help what's the javascript equivalent of below jquery line.
$("#abc option[value='1']").text();
abc is the id of selectbox
var options = document.getElementById("abc").options;
for (var i = 0, j = options.length; i < j; i++) {
if (options[i].value == "1") {
alert(options[i].text);
}
}
The value and text attributes are available on the HTMLOptionElement per DOM Level 2.
(demo)
UPDATE
Updated demo with combined text, cf. comments:
var options = document.getElementById("abc").options,
text = "";
for (var i = 0, j = options.length; i < j; i++) {
if (options[i].value == "1") {
text += options[i].text;
}
}
This would be 100% equivalent to the selector:
var options = document.getElementById('abc').getElementsByTagName('option'),
text = "";
for(var i = 0, l = options.length; i < l; i++) {
var option = options[i];
if(option.value === '1') {
text += option.text;
}
}
Or if querySelectorAll is available:
var options = document.querySelectorAll('#abc option[value="1"]'),
text = "";
for(var i = 0, l = options.length; i < l; i++) {
text += options[i].text;
}
That said, you can make improvements depending on the HTML structure (e.g. if #abc is the select element etc).
In modern browsers it can be:
var option = document.querySelector('#abc option[value="1"]').textContent
The statement doesn't make sense. It gets the text from an option, and then just throws it away. I assume that you want to do something with the text, like assigning it to a variable.
// A variable for the result
var text = null;
// Get the options from the select element
var options = document.getElementById('abc').options;
// Find the option with the value "1"
for (var i = 0; i < options.length; i++) {
if (options[i].value == '1') {
// Get the text from the option
text = options[i].text;
// Exit from the loop
break;
}
}
Note: The original code would get the text from all options with the specified value, but this code only gets the text from the first option found. Having more than one option with the same value is pretty useless, so that feature of the original code is most likely unintended.
This Will Work.
document.querySelector(".producer option[value='1']").text;

Categories

Resources