Function that will only push value of most recent inputs - javascript

I have 3 groups of inputs, in chronological order (manufacturer info, repair info, test info). When the user hits the "confirm button", I want an if statement to iterate through each input, compare if (input.val() !== ""), and then make sure it is the most recent data (ie. repair info will supercede mfg info) before pushing that value to the #asreceived fields.
I have manually done an if statement for each set of inputs to iterate through, however I would have to add to the function if I wanted to enter more fields.
This is what I have currently:
$("#model-received").val(function() {
if ($("#model-test").val() != "") {
return $("#model-testonly").val();
} else if ($("#model-repair").val() != "") {
return $("#model-repair").val();
} else {
return $("#model-initial").val();
}
});
I have used this code for each set of inputs (roughly 50)
I have tried to compare groups using the .each(), but I am stuck here.
let $inputMfg = $("#manufacturers-tag").find("input , select").each(function() {
if ($(this).attr("name").indexOf("-initial") > -1) {
return
}
});
let $inputRep = $("#repairtag-old").find("input , select").each(function() {
if ($(this).attr("name").indexOf("-repair") > -1) {
return
}
});
let $inputTO = $("#testonlytag-old").find("input , select").each(function() {
if ($(this).attr("name").indexOf("-testonly") > -1) {
return
}
});
let $inputAsRec = $("#asreceived").find("input , select").each(function() {
if ($(this).attr("name").indexOf("-received") > -1) {
return
}
});
$("#asreceived"),$("#testonlytag-old"),$("#repairtag-old"),$("#manufacturers-tag") are all the same HTML, minus the name suffix on each input ("-initial")
HTML
<div id="repairtag-old" hidden>
<div class="entry-col3">
<div class="entry-line">
<label class="entry-label">Company: </label>
<input class="entry-input" type="text" name="company-repair">
</div>
</div>
<div class="entry-col3">
<div class="entry-line">
<label class="entry-label">Date: </label>
<input class="entry-date" type="date" name="date-repair">
</div>
</div>
<div class="entry-col3">
<div class="entry-line">
<label class="entry-label">VR Stamp: </label>
<select class="entry-select" id="vrstamp-old" name="vrstamp-old">
<option></option>
<option>Yes</option>
<option>No</option>
</select>
<label class="entry-bylabel">VR: </label>
<input class="entry-input" type="text" name="vrnumber-old">
</div>
</div>
<div class="entry-col2">
<div class="entry-line">
<label class="entry-label">Job Number: </label>
<input class="entry-input" type="text" name="jobnumber-repair">
</div>
</div>
<div class="entry-col2">
<div class="entry-line">
<label class="entry-label">Model Number: </label>
<input class="entry-input" id="model-repair" type="text" name="model-repair">
</div>
</div>
<div class="entry-col3">
<div class="entry-line">
<label class="entry-label">Set Pressure: </label>
<input class="entry-input" id="setpressure-repair" type="text" name="setpressure-repair">
<select class="entry-select" name="setunit-repair">
<option>psig</option>
</select>
</div>
</div>
<div class="entry-col3">
<div class="entry-line">
<label class="entry-label">Cold Test Pressure: </label>
<input class="entry-input" type="text" name="coldpressure-repair">
<select class="entry-select" name="coldunit-repair">
<option>psig</option>
</select>
</div>
</div>
<div class="entry-col3">
<div class="entry-line">
<label class="entry-label">Capacity: </label>
<input class="entry-input" type="text" name="capacity-repair">
<select class="entry-select" name="capacityunit-repair">
<option>scfm</option>
</select>
</div>
</div>
<br>
</div>
The final result should push the value of the most important value (test only 1st, repair 2nd, mfg 3rd). If the (input.val === ""), it should use the older values.
---UPDATED---
I figured it out. Code snippet below. Thank you for the responses, I was a little intimated in trying to implement them (I am new at coding). However, Mark Meyer's response got me on the right track. This works exactly as intended.
$("#copybtn-received").click(function(i) {
$("#asreceived").find("input, select").each(function() {
let $output = $(this).attr("name").split("-received")[0];
let $inputTO = $("#testonlytag-old").find("[name^=" + $output + "]");
let $inputRep = $("#repairtag-old").find("[name^=" + $output + "]");
let $inputMfg = $("#manufacturers-tag").find("[name^=" + $output + "]");
if ($inputTO.val() !== "") {
$(this).val($inputTO.val());
} else if ($inputRep.val() !== "") {
$(this).val($inputRep.val());
} else if ($inputMfg.val() !== "") {
$(this).val($inputMfg.val());
} else {
$(this).val("");
}
});
});

You could put your values in an array that is in the order of precedence you want then use find() which returns the first value found. In the find callback just return whether the value is truth, which "" isn't. This will allow you to decide arbitrary orders without all the if/else statements.
Here's a simplified example. It will log the highest value filled in.
function getBest(){
/* values in the order values will be found */
let values = [
document.getElementById("one").value,
document.getElementById("two").value,
document.getElementById("three").value,
document.getElementById("four").value
]
/* find the first truthy value */
let best = values.find(val => val)
console.log(best)
}
<input id="one" type ="text"><br />
<input id="two" type ="text"><br />
<input id="three" type ="text"><br />
<input id="four" type ="text"><br />
<button onclick="getBest()">Go</button>

I'm not sure I understand the question correctly, so this is a bit of a guess. Perhaps something like this would do?:
const findFirst = (ids, idx = ids.find(id => $(`#${id}`).val() !== '')) =>
idx > -1 ? $(`#${id}`).val() : 'not found'
$("#model-received").val(findFirst(
['model-testonly', 'model-repair', 'model-initial']
))
You can then update the list by simply appending to that array. And if the 'model-' prefix is universal, you can include that in the function and only pass ['testonly', 'repair', 'initial'] in the call.
I don't know if you have a better default than the 'not found' here.

Related

What is an efficient way to check if an HTML input is right or wrong?

I'm creating a quiz with <input type="text"> and <input type="number">.
I find that making a bunch of if / else statements is extremely inefficient, due to the bulk of the JavaScript code.
Here is my HTML code:
<!--Question 1-->
<label for="a">A cow says =</label>
<input type="text" id="a"/>
<!--Question 2-->
<label for="a">1 + 1 =</label>
<input type="number" id="b"/>
<button onclick="checkQuiz()">Check Quiz</button>
Here is my JavaScript code:
var a = document.getElementById("a")
var b = document.getElementById("b")
function checkQuiz() {
// Question 2
if (a.value == "moo") {
console.log("correct")
}
else {
console.log("wrong")
}
// Question 2
if (b.value == "2") {
console.log("correct")
}
else {
console.log("wrong")
}
}
I'm down for some Jquery code answers, just I'm also don't know much about it.
Make an array of correct answers, and look up the index of the question input in the answer array to compare the appropriate value.
// tweak the selector as needed
// you'll probably want something more precise
const questionInputs = document.querySelectorAll('input');
const correctAnswers = ['moo', '2'];
function checkQuiz() {
questionInputs.forEach((input, i) => {
console.log(`Question ${i + 1}: ${input.value === correctAnswers[i] ? 'Correct' : 'Wrong'}`);
});
}
<!--Question 1-->
<label for="a">A cow says =</label>
<input type="text" id="a"/>
<!--Question 2-->
<label for="a">1 + 1 =</label>
<input type="number" id="b"/>
<button onclick="checkQuiz()">Check Quiz</button>

How to responsively get Javascript to validate information from HTML5 form textboxes?

I am trying to build a functional Credit Card validation script for a demo assignment. I am attempting to get JavaScript to react to input as the focus() changes from text box to text box. Once I have the JavaScript reactive then I want to validate that data against specific parameters.
I've tried adding onchange methods directly into the HTML5, but something won't work correctly. I am open to all suggestions, I've spent too long at a stalemate.
HTML
<h2>Payment
<img style="visibility: hidden" class="mastercard"
src="https://img.icons8.com/color/48/000000/mastercard.png">
<img style="visibility: hidden" class="visacard"
src="https://img.icons8.com/color/48/000000/visa.png">
<img style="visibility: hidden" class="discovercard"
src="https://img.icons8.com/color/48/000000/discover.png">
<img style="visibility: hidden" class="amexcard"
src="https://img.icons8.com/color/48/000000/amex.png">
</h2>
<div class="form-group">
<label for="name-on-card">Name on Card</label>
<input class="cc_name" type="text" name="card-name" class="form-control" placeholder="">
</div>
<div class="form-group">
<label for="cc-number">Credit card number</label>
<input type="text" class="form-control" id="cc_number" name="cc_number" placeholder="" maxlength="16">
</div>
<div class="">
<select class="month_year_select" name="month" id="month">
<option value="">exp month</option>
</select>
</div>
<div class="">
<select class="month_year_select" id="year" name="year">
<option value="">exp year</option>
</select>
</div>
<div class="CVV">
<label for="cc-cvv">CVV</label>
<input type="text" class="form-control" id="cc-cvv" name="cc-cvv" placeholder="" maxlength="4">
</div>
<button type="submit" class="myButton"style = "float:right;">Place Order</button>
</form>
JavaScript
<script type="text/javascript">
var creditError="Error with Credit Card information";
var CWError="Error with CW";
document.getElementbyID("cc-cvv").onchange=function(){function CWcheck()};
document.getElementbyID("cc_number").onchange=function(){function creditCheck()};
document.getElementbyID("cc_name").onchange=function(){function upperFunction()};
function CWcheck()
{
if (document.forms["LeftCheck"]["cc-cvv"].value.length < 3 ||document.forms["LeftCheck"]["cc-cvv"].value.length>=5){
alert(CWError);
cdocument.forms["LeftCheck"]["cc-cvv"].value.value=" ";
}
else if(document.forms["LeftCheck"]["cc-cvv"].value.match(/^[A-Za-z]+$/)){
alert(CWError);
document.forms["LeftCheck"]["cc-cvv"].value=" ";
}
else if(document.forms["LeftCheck"]["cc-cvv"].value.match(/^[-+]?[0-9]+\.[0-9]+$/)) {
alert(CWError);
document.forms["LeftCheck"]["cc-cvv"].value=" ";
}
else
break;
}
function upperFunction() {
document.getElementsByClassName("cc_name").value.toUpperCase();
}
function creditCheck() {
{
if (document.forms["LeftCheck"]["cc_number"].value.length < 15 ||document.forms["LeftCheck"]["cc_number"].value.length>16){
alert(creditError);
document.forms["LeftCheck"]["cc_number"].value=" ";
}
else if(document.forms["LeftCheck"]["cc_number"].value.match(/^[A-Za-z]+$/)){
alert(creditError);
document.forms["LeftCheck"]["cc_number"].value=" ";
}
else if(document.forms["LeftCheck"]["cc_number"].value.match(/^[-+]?[0-9]+\.[0-9]+$/)) {
alert(creditError);
document.forms["LeftCheck"]["cc_number"].value=" ";
}
else
if(document.forms["LeftCheck"]["cc_number"].value.match(/^(?:3[47][0-9]{13})$/)){
document.getElementsByClassName('amexcard').style.visibility="visable";
document.forms["LeftCheck"]["cc_number"].value=" ";
}
else if(document.forms["LeftCheck"]["cc_number"].value.match(/^(?:4[0-9]{12}(?:[0-9]{3})?)$/)){
document.getElementsByClassName('visacard').style.visibility="visable";
document.forms["LeftCheck"]["cc_number"].value=" ";
}
else if(document.forms["LeftCheck"]["cc_number"].value.match(/^(?:5[1-5][0-9]{14})$/)){
document.getElementsByClassName('mastercard').style.visibility="visable";
document.forms["LeftCheck"]["cc_number"].value=" ";
}
else if(document.forms["LeftCheck"]["cc_number"].value;=.match(/^(?:6(?:011|5[0-9][0-9])[0-9]{12})$/)){
document.getElementsByClassName('discovercard').style.visibility="visable";
document.forms["LeftCheck"]["cc_number"].value=" "
}
else {
alert(creditError)
this.clear()
}
}
I would ideal like the text box to validate that when a creditcard number is entered it; it will check nothing outside of numbers were entered, the cadence of the numbers match a card type or reset the field, and display the image that the card is next to the "Payment" header.
The Checksum Validation by Alex works very well, with that portion out of the way I can streamline the image setting. So far my code has been updated to the following
Updated HTML
<form method="POST" action="/checkout" class = "LeftCheck" name="LeftCheck" id="LeftCheck">
<h2>Payment
<img style="visibility: hidden" class="mastercard"
src="https://img.icons8.com/color/48/000000/mastercard.png">
<img style="visibility: hidden" class="visacard"
src="https://img.icons8.com/color/48/000000/visa.png">
<img style="visibility: hidden" class="discovercard"
src="https://img.icons8.com/color/48/000000/discover.png">
<img style="visibility: hidden" class="amexcard"
src="https://img.icons8.com/color/48/000000/amex.png">
</h2>
<div class="form-group">
<label for="name-on-card">Name on Card</label>
<input class="cc_name" type="text" name="card-name" class="form-control" placeholder="">
</div>
<div class="form-group">
<label for="cc-number">Credit card number</label>
<input type="text" class="form-control" id="cc_number" name="cc_number" placeholder="" maxlength="16">
</div>
<div class="">
<select class="month_year_select" name="month" id="month">
<option value="">exp month</option>
</select>
</div>
<div class="">
<select class="month_year_select" id="year" name="year">
<option value="">exp year</option>
</select>
</div>
<div class="CVV">
<label for="cc-cvv">CVV</label>
<input type="text" class="form-control" id="cc-cvv" name="cc-cvv" placeholder="" maxlength="4">
</div>
<button type="submit" class="myButton"style = "float:right;">Place Order</button>
</form>
And the updated Issue area of my JavaScript
document.getElementById('cc_number').addEventListener('change',pictureCheck);
function pictureCheck()
{
var ccNum = this.value;
if (ccNum.length = 15)
{
document.getElementsById('amexcard').style.display='';
}
else if(ccNum.value.match(/^(?:4[0-9]{12}(?:[0-9]{3})?)$/))
{
document.getElementsById('visacard').style.display='';
}
else if(ccNum.value.match(/^(?:5[1-5][0-9]{14})$/))
{
document.getElementsById('mastercard').style.display='';
}
else (ccNum.value;=.match(/^(?:6(?:011|5[0-9][0-9])[0-9]{12})$/))
{
document.getElementsById('discovercard').style.display='';
}
}
Your javascript part is all wrong. Let me show how it should work.
document.getElementById('cc-cvv').addEventListener('change', CWcheck); //recommended way
document.getElementById('cc_number').onchange = creditCheck; //it is OK too
function CWcheck() { //function name should conventionally start with lower case but isn't big deal
//"this" is the element which fired the event
if (!/^\d{3,4}$/.test(this.value)) {
this.value = '';
this.focus();
alert('CVV is 3 or 4 digits');
}
}
function creditCheck() {
// hide cc logos
var ccImgs = document.querySelectorAll('h2 img');
for (var i = 0, ccImg; ccImg = ccImgs[i]; ++i) {
ccImg.style.visibility = 'hidden';
}
var ccNum = this.value.replace(/\D/g, ''); //remove all non-digits
if (ccNum.length < 15 /*15 is amex*/ || ccNum.length > 16) {
alert('CC number is 15 or 16 digits');
this.focus();
return false;
}
//implement Luhn algorithm
var check = ccNum.split('') //get array
.reverse()
.map(function(el, index) {
return el * (index % 2 + 1); //multiply even positions by 2
})
.join('') //combine array of strings
.split('')
.reduce(function(a, b) { //sum digits
return a + (b - 0);
}, 0);
if (!check || (check % 10)) { //checksum should be none-zero and dividable by 10
alert('Incorrect checksum of CC');
this.focus();
return false;
}
//test passed. show card logo
if (/^5[1-5]/.test(ccNum))
document.querySelector('h2 img.mastercard').style.visibility = 'visible';
else if (/^4/.test(ccNum))
document.querySelector('h2 img.visacard').style.visibility = 'visible';
else if (ccNum.length == 15 && /^3[47]/.test(ccNum))
document.querySelector('h2 img.amexcard').style.visibility = 'visible';
else if (/^6011/.test(ccNum))
document.querySelector('h2 img.discovercasd').style.visibility = 'visible';
//and so on
else {
alert('CC number doesn\'t match known any CC issuer');
this.focus();
return false;
}
//test passed. format the string
this.value = ccNum
.replace(/^(\d{4})(\d{4})(\d{4})(\d+)$/, '$1 $2 $3 $4');
}
<h2>Payment
<img style="visibility: hidden" class="mastercard" src="https://img.icons8.com/color/48/000000/mastercard.png">
<img style="visibility: hidden" class="visacard" src="https://img.icons8.com/color/48/000000/visa.png">
<img style="visibility: hidden" class="discovercard" src="https://img.icons8.com/color/48/000000/discover.png">
<img style="visibility: hidden" class="amexcard" src="https://img.icons8.com/color/48/000000/amex.png">
</h2>
<div class="form-group">
<label for="name-on-card">Name on Card</label>
<input class="cc_name" type="text" name="card-name" class="form-control" placeholder="">
</div>
<div class="form-group">
<label for="cc-number">Credit card number</label>
<input type="text" class="form-control" id="cc_number" name="cc_number" placeholder="" maxlength="20">
</div>
<!--<div class="">
<select class="month_year_select" name="month" id="month">
<option value="">exp month</option>
</select>
</div>
<div class="">
<select class="month_year_select" id="year" name="year">
<option value="">exp year</option>
</select>
</div>-->
<div class="CVV">
<label for="cc-cvv">CVV</label>
<input type="text" class="form-control" id="cc-cvv" name="cc-cvv" placeholder="" maxlength="4">
</div>
UPDATE: CC issuer from card number is added.
You could do this with JQuery. When you switch between input fields, you could run your validation script.
$("#id1, #id2").focus(function() {
alert("Focus changed.");
//run validator
});
I noticed that you use document.forms["LeftCheck"]["cc-cvv"] to access the fields of the form. Since you did not include your form start tag, I want to make sure that the name field of you form is set to LeftCheck, rather than the ID, since I have had this problem before.
You also use document.getElementbyID() to access the elements that you are applying the onchange listener to. The method is actually document.getElementbyId(), with the last letter not capitalized. This may be the reason your events are not firing.
The way that you attach your events to the select element is also incorrect. You can simply do this:
document.getElementbyID("cc-cvv").onchange = CWcheck;
or alternatively
document.getElementbyID("cc-cvv").onchange = function() { CWcheck();};
One last thing is that you use regex to validate the input of the credit card field. However, you do this by checking if the input matches an invalid pattern and raises an error if it does. Although this could work, it would be much better to check if the input matches a valid pattern, and if it doesn't, raise in error. This makes your validation code more robust and makes sure that you don't have invalid edge cases that may pass your validation.
Use the inline onblur event
<input type="text" onblur="CWcheck()" />

Bug in JQuery function for checking for required fields in custom dropdowns

I made a JQuery function to check for empty required fields inside a closed custom dropdown.
If a required field is empty inside one of the dropdown and if the dropdown is currently closed I want the dropdown to open and if there are no empty values in the required fields I want the dropdown to close.
The problem is that the required fields aren't accessible if the dropdowns are closed and I tried to fix that problem with this function.
For some reason, it only checks for these input fields if the form is submitted at least once and the required fields are opened at least once.
find(':input[required]') doesn't give any output if the dropdown isn't opened at least once, once u open and close the dropdown the function works.
This is the function:
function dropdown_required() {
var required = 0;
$('#visible_fields').find(':input[required]').each(function () {
if (!this.value) {
for (var i = 1; i < 15; i++) {
$('.form_' + i).find(':input[required]').each(function () {
$(this).prop('required', false);
});
}
required++;
}
});
if (required == 0) {
for (var i = 1; i < 15; i++) {
var empty = 0;
$('.form_' + i).find(':input[required]').each(function ()
{
if(!this.value) {
empty++;
}
});
if (empty !== 0) {
if ($(".arrow_" + i).hasClass("rotate_2")) {
$(".arrow_" + i).addClass("rotate_1").removeClass("rotate_2");
$(".form_" + i).fadeToggle();
}
} else if ($(".arrow_" + i).hasClass("rotate_1")) {
$(".arrow_" + i).addClass("rotate_2").removeClass("rotate_1");
$(".form_" + i).fadeToggle();
}
}
}
}
This is the html:
<form method="POST" autocomplete="off" enctype="multipart/form-data" target="_self"
action="/contacten/leveranciers/iframe{{ ($leverancier == null ? '' : '/' . $leverancier->cot_id) }}">
{{ csrf_field() }}
<div id="visible_fields">
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label for="organisatie">Organisatie</label>
<input type="text" name="organisatie" id="organisatie" blocked=",;()/" hk="a"
value="{{ ($leverancier == null ? old('organisatie') : $leverancier->cot_organisatie) }}"
class="form-control inputblocked">
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label for="postcode">Postcode</label>
<input type="text" name="postcode" id="postcode" filter="a-zA-Z0-9" maxlength="6"
value="{{ ($leverancier == null ? old('postcode') : $leverancier->cot_postcode) }}"
class="form-control inputfilter filter_postcode">
</div>
</div>
</div>
//all visible input fields outside of the dropdowns
</div>
<label class="toggle_1">Controles<span class="arrow_1 glyphicon glyphicon-menu-left"
aria-hidden="true"></span></label>
<div class="form_1">
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label for="bkr">BKR</label>
<select name="bkr" class="form-control" required>
<option selected hidden></option>
<option value="10">BKR toetsing open</option>
<option value="11">BKR toetsing accoord</option>
<option value="12">Vrijgesteld van BKR toetsing</option>
</select>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label for="bkr_bestand">BKR bestand</label>
<input type="file" name="bkr_bestand" id="bkr_bestand"
data-default-file=""
class="form-control dropify">
<input type="hidden" name="verwijder_foto" class="verwijder_foto" value="0">
</div>
</div>
</div>
</div>
<div class="form-group">
<input type="hidden" id="input_iframe" name="input_iframe" value="">
<button type="submit" onclick="dropdown_required()"
class="btn btn-primary">Toevoegen </button>
</div>
</form>
</div>
</body>
</html>
Your function checks if your arrow element has the class rotate_2. The code you pasted has neither rotate_1 or rotate_2 and no else block, so the toggle never executes.
Problem demonstration:
// This group has empty mandatory elements
var empty = 1;
$('#validate').click(function() {
if (empty !== 0) {
console.log("I have empty elements!");
// From your comments, this might be backwards
if ($(".arrow_1").hasClass("rotate_2")) {
console.log("I'm going to show them");
$(".arrow_1").addClass("rotate_1").removeClass("rotate_2");
$(".form_1").fadeToggle();
}
// This is missing in the code
else {
console.log("I wasn't invited to the party");
}
// -------
} else if ($(".arrow_1").hasClass("rotate_1")) {
console.log("I'm out, I don't have empty elements...");
$(".arrow_1").addClass("rotate_2").removeClass("rotate_1");
$(".form_1").fadeToggle();
}
});
$('#simulate').click(function() {
// Simulates manually opening and closing
// In short, add rotate_2 class as if it's been toggled
$('.arrow_1').addClass('rotate_2');
console.log("Toggled manually");
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label class="toggle_1">Controles<span class="arrow_1 glyphicon glyphicon-menu-left"
aria-hidden="true"></span></label>
<div class="form_1">
<div>Some form elements</div>
</div>
<button id="validate">Validate</button>
<button id="simulate">Simulate</button>

Jquery condition doesnt work

I must be doing some very basic mistake, because i cant get to result2, even though it checks the condition for it. it detects the counter and InpActive, but it only add up the counter once (but that should be enough to check for condition 2) nor perform the check for the test2 condition.
Edit: im presenting the full function. I want to make a mysqli query with each input, and i want to be able to add and take out each entry, preserving the query structure to be sent to the server. Its not working for some reason. In this post, im not adding the PHP part. Im only interested in making the jquery part work.
This is the jquery code:
var inpreco = ["", "", ""];
var altpreco = ["", "", ""];
var inprocess = ["", "", ""];
var altprocess = ["", "", ""];
var cpcounter8 = 0;
var cpcounter9 = 0;
$(".opcaopreco").click(function () {
SuperFun(this, "#preco", inpreco, altpreco, "altpreco2", "cpvalor",
"cpindex", "cpactivo", cpcounter9, "preco", "1 AND 5000");
});
$(".opcaopreco2").click(function () {
SuperFun(this, "#process", inprocess, altprocess, "altprocess2",
"cpvalor8", "cpindex8", "cpactivo8", cpcounter8, "process", "1 AND 11");
});
function SuperFun(element, input, inpArray, secArray, secArray2, inpValue,
secIndex, inpActive, counter, msqlip, ending) {
var inpValue = $("#" + element.id).val();
var secIndex = $("#" + element.id).data(secIndex);
var inpActive = $("#" + element.id).data(inpActive);
if (counter==0){
counter++;
$("#" + element.id + "l").addClass("activa");
$(element).data(inpActive, "primary");
inpArray[0] = (inpValue);
}else
if (inpActive=="") {
counter++;
$("#" + element.id + "l").addClass("activa");
$(element).data(inpActive, "yes");
inpArray[secIndex]=(" OR "+msqlip+" BETWEEN "+inpValue);
secArray[secIndex]=(secIndex);
}else
if (inpActive=="yes") {
counter--;
$("#" + element.id + "l").removeClass("activa");
$(element).data(inpActive, "");
inpArray[secIndex]="";
secArray[secIndex] = "";
}else
if (inpActive=="primary" && counter!==1) {
counter--;
$("#" + element.id + "l").removeClass("activa");
$(element).data(inpActive, "");
secArray2 = secArray.filter(Boolean);
inpArray[0]=$("#op" + secArray2[0]).val();
inpArray[$("#op" + secArray2[0]).data(secIndex)]="";
$("#op" + secArray2[0]).data(inpActive, "primary");
secArray[$("#op" + secArray2[0]).data(secIndex)]="";
} else
if (inpActive=="primary" && counter==1) {
counter--;
$("#" + element.id + "l").removeClass("activa");
$(element).data(inpActive, "");
inpArray[secIndex]="";
inpArray[0]=ending;
}
$(input).val(inpArray[0]+inpArray[1]+inpArray[2]);
};
This is the html code:
<input id="preco" type="text" name="preco" value='1 AND 5000'><br><br>
<input id="process" type="text" name="process" value='1 AND 11'><br><br>
<div id="op1l" class="input">
<input type="checkbox" id="op1" class="opcaopreco" value="201 AND 400" data-cpindex="1" data-cpactivo="">
<label for="op1"></label>
<span class="itext">€201 - €400</span>
</div>
<div id="op2l" class="input">
<input type="checkbox" id="op2" class="opcaopreco" value='401 AND 600' data-cpindex="2" data-cpactivo="">
<label for="op2"></label>
<span class="itext">€401 - €600</span>
</div>
<div id="op3l" class="input">
<input type="checkbox" id="op3" class="opcaopreco" value='601 AND 800' data-cpindex="3" data-cpactivo="">
<label for="op3"></label>
<span class="itext">€601 - €800</span>
</div>
<div id="op4l" class="input">
<input type="checkbox" id="op4" class="opcaopreco2" value="1 AND 1" data-cpindex8="1" data-cpactivo8="">
<label for="op4"></label>
<span class="itext">1 AND 1</span>
</div>
<div id="op5l" class="input">
<input type="checkbox" id="op5" class="opcaopreco2" value='2 AND 2' data-cpindex8="2" data-cpactivo8="">
<label for="op5"></label>
<span class="itext">2 AND 2</span>
</div>
<div id="op6l" class="input">
<input type="checkbox" id="op6" class="opcaopreco2" value='3 AND 3' data-cpindex8="3" data-cpactivo8="">
<label for="op6"></label>
<span class="itext">3 AND 3</span>
</div>
<div id="paramount">paramount</div>
You're initializing your counter to 0. It hits the if counter == 0 and wont continue to the else where you have the Test2 check
Ok let me show you much nicer solution for your problem:
https://jsfiddle.net/11jm9k7a/10/
Sorry I just couldn't work with your code so I totally reworked your logic - might be that I missed something so let me know. This solution will work on unlimited different parameter groups, as long as you put on each checkbox element 2 different attributes, first one is query before which will hold string that goes before group in your first case:
query-before="BETWEEN"
and some string to identify group of query for your first case:
query-type="opcaopreco"
there's no need for any class/id's manipulations since this is generic solution.
HTML:
<br>
<br>
<label for="process">Final Query</label>
<input id="process" type="text" name="process" value='' placeholder='1 AND 11'>
<br>
<br>
<div id="op1l" class="input">
<input type="checkbox" id="op1" query-before="BETWEEN" query-type="opcaopreco" class="opcaopreco" value="201 AND 400" data-cpindex="1" data-cpactivo="">
<label for="op1"></label>
<span class="itext">€201 - €400</span>
</div>
<div id="op2l" class="input">
<input type="checkbox" id="op2" query-before="BETWEEN" query-type="opcaopreco" class="opcaopreco" value='401 AND 600' data-cpindex="2" data-cpactivo="">
<label for="op2"></label>
<span class="itext">€401 - €600</span>
</div>
<div id="op3l" class="input">
<input type="checkbox" id="op3" query-before="BETWEEN" query-type="opcaopreco" class="opcaopreco" value='601 AND 800' data-cpindex="3" data-cpactivo="">
<label for="op3"></label>
<span class="itext">€601 - €800</span>
</div>
<div id="op4l" class="input">
<input type="checkbox" id="op4" query-before="" query-type="opcaopreco2" class="opcaopreco2" value="1 AND 1" data-cpindex8="1" data-cpactivo8="">
<label for="op4"></label>
<span class="itext">1 AND 1</span>
</div>
<div id="op5l" class="input">
<input type="checkbox" id="op5" query-before="" query-type="opcaopreco2" class="opcaopreco2" value='2 AND 2' data-cpindex8="2" data-cpactivo8="">
<label for="op5"></label>
<span class="itext">2 AND 2</span>
</div>
<div id="op6l" class="input">
<input type="checkbox" id="op6" query-before="" query-type="opcaopreco2" class="opcaopreco2" value='3 AND 3' data-cpindex8="3" data-cpactivo8="">
<label for="op6"></label>
<span class="itext">3 AND 3</span>
</div>
Javascript:
$(function() {
let query = {};
// itterate through all input elements that have query-type attribute
$('input[query-type]').each(function(value) {
query[$(this).attr('query-type')] = {
list: [],
queryBefore: $(this).attr('query-before'),
};
});
/* we first need to initialize arrays so we can get in your case:
query: {
opcaopreco: {
list: [],
queryBefore: 'BETWEEN'
},
opcaopreco2: {
list: [],
queryBefore: ''
},
}
*/
// after that attach on click even on all input elements that have query-type attribute
$('input[query-type]').on('click', function(event) {
// get query-type of $(this) - currently clicked element
let typeOfQuery = $(this).attr('query-type');
// check if this element is checked
if ($(this).is(":checked")) {
/* if it is checked, push value to object and you will get
query: {
opcaopreco: {
list: ['201 AND 400'],
queryBefore: 'BETWEEN'
},
opcaopreco2: {
list: [],
queryBefore: ''
},
}
*/
query[typeOfQuery].list.push($(this).val());
} else {
// remove - splice element from array - check index of value and remove 1 element at that index
query[typeOfQuery].list.splice(query[typeOfQuery].list.indexOf($(this).val()), 1);
}
// we also need to sort array to get remove order which people clicked
query[typeOfQuery].list.sort();
// create temporary array that will hold query
let fullQuery = [];
// loop through object keys
Object.keys(query).forEach((value, index) => {
// if there's something in array then do something otherwise don't do anything
if (query[value].list.length > 0) {
// first query join array with string ' AND ' to get ' AND ' between all values
// after that split it to get all values in correct order
let arrQuery = query[value].list.join(' AND ').split(' AND ');
// use string literal to create a string which is basically first element and last element
fullQuery.push(`${query[value].queryBefore} ${arrQuery[0]} AND ${arrQuery[arrQuery.length-1]}`);
// this is same as using + sign on each element with spaces in between like below
// fullQuery.push(query[value].queryBefore + ' '+ arrQuery[0] + ' AND '+ arrQuery[arrQuery.length-1]);
}
});
// join all query types with OR keyword
$('#process').val(fullQuery.join(' OR '));
});
});
This solution is very extendable and will work in most cases it won't cover every possible scenario and parts of it may require more work depending on your exact parameters that you need or that before part and I just join everything with 'OR', but will work very good for similar type of thing.

javascript if text box element is blank do different action

Trying to get this search form to do different searches but if the search box is empty, I want it to default to a different page. This is with the first else if. Even with the text box empty it keeps defaulting to the first action.
<script type="text/javascript">
function changeAction() {
if(document.getElementById('searchOption').value == "title" && document.getElementById('searchText').value!=null) {
document.getElementById('searchForm').action = 'catalog.com=0&term=' + escape(document.getElementById('searchText').value);
}
**else if(document.getElementById('searchOption').value == "title" && document.getElementById('searchText').value===null) {
document.action = 'differentPage.com'
}**
else if(document.getElementById('searchOption').value == "keyword") {
document.getElementById('searchForm').action = 'catalog.com?keyword=' + escape(document.getElementById('searchText').value);
}
else{
document.getElementById('searchForm').action = "mysite.com/searchResults.html";
$('#searchForm').attr('method', 'get');
$('#searchText').attr('name', 'q');
}
}
</script>
<form id="searchForm" name=search method=post>
<div class="subscribe">
<div class="text">
<input name="term" type="text" id="searchText"/>
</div>
<select id="searchOption" name="searchOption" title="search">
<option name="index" value="title" selected="selected">TITLE IN CATALOG</option>
<option name="index" value="keyword" type="hidden">CATALOG KEYWORD</option>
<option name="nothing" value="googleSearch" type="hidden">LIBRARY WEBSITE</option>
</select>
<!-- for google search appliance -->
<input value="slco_pub" name="client" type="hidden">
<input value="slco_pub" name="proxystylesheet" type="hidden">
<input value="xml_no_dtd" name="output" type="hidden">
<input value="mainSite" name="site" type="hidden">
<!-- end of necessary for google search appliance -->
<!-- for ILS -->
<INPUT name=menu value=search type=hidden>
<INPUT name=aspect value=basic_search type=hidden>
<INPUT name=profile value=maincentral type=hidden>
<!-- Left from old <INPUT name=index value=".TW" type=hidden> -->
<INPUT name=index value="PALLTI" type=hidden>
<!-- end of necessary for google search appliance-->
<!--Button Graphic-->
<input type="image" src="/sebin/m/p/btn-search.gif" alt="search button" onClick="changeAction();" />
</div>
</form>
document.getElementById('searchText').value!=null is using loose comparison, so it will be true if the value is null or undefined. In this case, it will always be a string. What you want to test is whether it is a non-empty string, like so:
var option = document.getElementById('searchOption').value,
text = document.getElementById('searchText').value,
form = document.getElementById('searchForm');
if (option === "title" && text.length > 0) {
form.action = 'catalog.com=0&term=' + escape(text);
}
else if (option === "title" && text.length === 0) {
form.action = 'differentPage.com'
}
else if (option === "keyword") {
form.action = 'catalog.com?keyword=' + escape(text);
}
else {
form.action = "mysite.com/searchResults.html";
$('#searchForm').attr('method', 'get');
$('#searchText').attr('name', 'q');
}
Note that I've used strict comparison.

Categories

Resources