What does unescape() function returns? - javascript

I have to use unescape() function in an if-else statement. In my website I have two pages, one with a form that the user fills and the second page have to get the information from the filled form by unescape function. I need the if-else statement because in the form I put two radio buttons that each one adds different text areas with different ids' and names so I want to check in the second page what text fields are are filled. (all the fields created by clicking on a radio button which starts a javascript function so in the next page I must check if the field was created and not just to check if it is an unfilled text field).
It is a little bit hard for me to explain so just check the code. In the code you will see params["placeName"] and so on, so placeName for example like all the others is a text field name from the previous page.
So the question is - what does unescape function returns if the component name I insert as a paramater does exist in the previous page?
<script type="text/javascript">
function getParams() {
var idx = document.URL.indexOf('?');
var params = new Array();
if (idx != -1) {
var pairs = document.URL.substring(idx + 1, document.URL.length).split('&');
for (var i = 0; i < pairs.length; i++) {
nameVal = pairs[i].split('=');
params[nameVal[0]] = nameVal[1];
}
}
return params;
}
params = getParams();
//from here it is what I want to do (I don't know if this condition in the if statement is correct, this is what I ask)
// if (unescape(params["placeName"]) == false) {
// }
// else {
var place = unescape(params["placeName"]);
var country = unescape(params["country"]);
var city = unescape(params["city"]);
var address = unescape(params["address"]);
var type = unescape(params["type"]);
var rate = unescape(params["rate"]);
// }
</script>
It can also work if I could check what radio button is checked

You are asking what will unescape(params["something"]) return if params["something"] is not present. The answer is undefined. So you need to check equivalence to "undefined". Meaning: if (unescape(params["placeName"]) == "undefined") (in this case params["placeName"] is not present (was not created).

The undecode function returns -as it's name indicated- a decoded string. If you enter a value that's not defined it will probably cause an error because of the indefinition. If what you want is to check whether the element was or not created or not you could use
if (params.placeName !== undefined) {
// It was created
}
instead.
Aditionally, if you want to check which radio button was checked use
if (document.getElementById('foo').checked) {
// Radio button with id 'foo' was checked
} else if (document.getElementById('bar').checked) {
// Radio button with id 'bar' was checked
} else if
...

Related

Why this function stops to work with other "get element" methods than getElementsByTagName?

i'm trying to adapt this JS form steps for my own: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_form_steps
There is a function that validates it:
function validateForm() {
// This function deals with validation of the form fields
var x, y, i, valid = true;
x = document.getElementsByClassName("tab");
y = x[currentTab].getElementsByTagName("input");
// A loop that checks every input field in the current tab:
for (i = 0; i < y.length; i++) {
// If a field is empty...
if (y[i].value == "") {
// add an "invalid" class to the field:
y[i].className += " invalid";
// and set the current valid status to false
valid = false;
}
}
But I want it to work only for specific field, so I added ID to the input and change the code to:
y = x[currentTab].getElementById("test");
But then it stops to work and console shows that x[currentTab] is not a function. Please explain me, why this function works with y = x[currentTab].getElementsByTagName("input"); but stops if I change it for ID, class or name.
It's because getElementById returns a single element instead of a NodeList. Therefore, y[i] no-longer works. You can remove the whole loop part because there's only one.
function validateForm() {
// This function deals with validation of the form fields
let valid = true;
const tabs = document.getElementsByClassName("tab"); // Do you need this?
const input = document.getElementById("test");
// A loop that checks every input field in the current tab:
if (input.value == "") {
// add an "invalid" class to the field:
input.className += " invalid";
// and set the current valid status to false
valid = false;
}
// ...
}
It should be noted that an element's ID must be unique document-wide so selecting by ID within a specific parent element doesn't make much sense. If each tab has an element with an ID of test, the HTML is invalid. You can still select a single element by class name with something like tabs[currentTab].querySelector('.test'); instead.

Javascript validation on dynamic inputs and combining inputs with some logic

In a form (named createform) many inputs are created dynamically by clicking on add button (from 0 to any number for each kind of input).
The problem I'm having is the validation of the inputs that were created dynamically, because there is a complex logic behind it.
THE SCENARIO
I can have several different inputs:
brand
model
country
region
The first of them is called brand1, model1, country1 and region1, then adding others they will be called for instance brand2... brand50
In the starting scenario there will be only brand1 and model1. The country and region inputs are added only by clicking on a button.
THE VALIDATION CONDITION
I have to submit the form only in two cases:
If there is at least one brand + one model where both of them are not empty (any brand and any model, so it can also be brand5 and model12)
If there is at least one brand + country + region not empty (all of them not empty, same logic than before)
I made the following validation function which works good if I assume that I just have the first brand,model,country and region (so brand1,model1,country1 and region1).
THE CODE
function validateForm() {
var brand = document.forms["createform"]["brand1"].value;
var model = document.forms["createform"]["model1"].value;
if (document.forms["createform"]["country1"] === undefined) {
var country = "";
} else {
var country = document.forms["createform"]["country1"].value;
}
if (document.forms["createform"]["country1"] === undefined) {
var region = "";
} else {
var region = document.forms["createform"]["region1"].value;
}
if ((brand != "") && (model != "")) {
alert("Send");
return true;
} else if ((brand != "") && (country != "") && (region != "")) {
alert("Send");
return true;
} else {
alert("Impossible to send");
return false;
}
}
For better reading of the code I added return true even if it is not necessary.
The main problem is that it is impossible to know how many inputs there will be of every different kind. I was thinking about trying by checking if the inputs are starting with brand,model,country or region but I don't know how to cross my controls in my validation function with all the possible results.
Do you guys have any idea of how to solve this?
What you need is a way to access all your brand and model elements by the start of their name.
var elements = document.querySelectorAll("form[id='createform']>input[id^='brand']");
This will give you an array (instead of your single valued variable) which you can loop through looking for your values.
The nifty querySelectorAll accepts selectors which can narrow your search to all matching elements. In the example, it gets all input elements within a form named "createform" which start with (^=) "brand".
var brandelements = document.querySelectorAll("#createform select[name^='brand'] option:checked:not([value=''])");
This is the best way to get all the values of a select (you can easily change with a normal input) that are not empty.

Filter options by reading character length inside for loop

I have a widget (the widget code in the pen linked below is not the actual code, please just pay attention to the filtering function jQuery.fn.doFilterOptions(){..}).
Use case:
I have a non-native selectbox. I need to extend its functionality to accept an onclick event which allows the user to type data into the selectbox (not targeting a traditional <select>), it should filter the .options available by simply showing or hiding them based on its inner HTML value, if no match is found at any point during the loop through the string being entered by the user, I need the options to continue not being displayed.
Issue:
Right now it works 95% of the way, the only issue is that if an invalid char is found, the loop keeps checking the rest of the users entries char by char, and if the next char is a match to any of the options in the same index, it re-display's this as a valid .option.
$('.selectbox .selected').on('keyup', function(){
var theseOptions = $(this).parent('.selectbox').find('.option');
var defaultPlaceholder = $(this).data('placeholder');
var filterOptions = (function(curSelectedVal){
if (curSelectedVal === ' ' || curSelectedVal.length === 0 || curSelectedVal === defaultPlaceholder){
theseOptions.show();
}
var optionsVal;
var doInputOptionsComparison = (function(){
var invalidOption = false;
for (var letterPos = 0; letterPos < curSelectedVal.length; letterPos++){
theseOptions.each(function(optionIteration){
var thisOption = $(this);
thisOptionsVal = thisOption.html();
if (curSelectedVal.length > thisOptionsVal.length ){ // If a longer string has been input by the user than exists in the option being iterated over, hide this option
thisOption.hide();
invalidOption = true;
}
else if ((thisOptionsVal[letterPos].toLowerCase().trim() === curSelectedVal[letterPos].toLowerCase().trim()) && invalidOption === false){ // If the input string matches this option and no invalid options have been found in the letterPos prior to it, show this option
thisOption.show();
}
else { // If the string does not match any option
invalidOptionFound = true;
thisOption.hide();
}
});
}
})();
})($(this).html());
});
Here is the demo, try selecting then typing abz you will see the filter working properly.
Now erase that input data, and now type azc. You will see the abc option comes available again because the c matches in that same index (user input[i] = optionsHtml[i] = show();), resulting the the above described undesirable effect.
http://codepen.io/nicholasabrams/pen/KwwMPG?editors=001
BONUS:
Would this be easier by using regEx to do the filtering?
I managed to use a dynamic regEx filter function it it cut the code down big time! Wow what a better solution.
$.fn.filterOptionsByUserInput = function(optionSelector){
var curInput = $(this).html().trim().replace(/ /g, '').toLowerCase();
$(optionSelector).each(function(optionIndex){
var userInputRegEx = new RegExp('^'+curInput+'.*');
if ($(this).html().toLowerCase().trim().match(userInputRegEx)){
$(this).fadeIn('slow');
}
else {
$(this).fadeOut('slow');
}
});
};
http://codepen.io/nicholasabrams/pen/LEEwrm?editors=001

How to use JavaScript to Require a Ratio of Completed Fields in a Form

I'm looking for a way to use JavaScript to require a specific ratio of fields in a form to be complete. So if I have six fields and the user has to complete any 2/6 to submit. If not then they receive an error. (The form will actually have a few different groups like this in it, so I have to be able to identify specific fields for the ratio.)
After some more research I've found something close, and realize I can count the number of a class. How would I change this to say if number of checked boxes is greater than or equal to 2, return true?
document.getElementById("test").onclick = function() {
isCountCheck("Check something");
};
function isCountCheck(helperMsg) {
var i, len, inputs = document.form1.getElementsByClassName("checkbox");
for (i = 0, len = inputs.length; i < len; i++) {
if (inputs[i].type === "checkbox" && inputs[i].checked) return true;
}
alert(helperMsg);
return false;
}
UPDATE:
My final jQuery ended up like this.
function isCountCheck(){
if($("input[class=crit1]:checked").length >= 4)
return false;
alert("Check a box");
return true;
}
Using jQuery
var numberOfInputsCompleted = 0;
var allInputs = $(":input"); // returns all input fields on the document
var numberOfInputs = allInputs.length
allInputs.each(function () {
if($(this).val() != '') {
numberOfInputsCompleted = numberOfInputsCompleted + 1;
}
});
numberOfInputsCompleted would give fields completed and numberOfInputs would total number of input fields on the form. Hope this helps
The first thing that comes to my mind: create a function that counts filled fields and returns true if the number of filled fields is enough (false otherwise). Then add it to the form as an "onsubmit" function. When the submit button is clicked the function is executed and, depending on what the function returns (true or false), the form is submitted or not.
More info about javascript form validation: http://www.w3schools.com/js/js_form_validation.asp

Javascript - making form inputs appear needed through key input

I have a form that has five text inputs, a through e. I set it though so only the first two are visible through the css:display, and I set the last three to display:none initially.
I have my javascript so that it sets the last input to 'b', and the next input to 'c', and depending on whether the other texts are empty or not changes the last and next variables.
option-a, option-b, etc. is the id of the text box in the form
answer_answera, answer_answerb, etc. is the class of the form input
<script>
var last = 'b';
var next = 'c';
if (document.getElementById('option-c').value != null) {
last = 'c';
next = 'd';
}
if (document.getElementById('option-d').value != null) {
last = 'd';
next = 'e';
}
if (document.getElementById('option-e').value != null) {
last = '';
next = '';
}
$('#answer_answer'+last).keyup(function() {
console.log('beg');
var elem = document.getElementById('option-'+next);
elem.style.display="block";
console.log('hit this');
})
</script>
This works for the first input. When I type in form input b, form input c appears. However, how do I get this to continually, I suppose, refresh itself, as form input d does not appear when I type in form input c. I thought about putting a while loop around the entire last block/keyup function, but it made the entire app slow and wouldn't load properly.
Thanks for any thoughts! :)
Before we go into solving this problem, let's quickly review some Javascript concepts. When your document first loads, everything inside the <script></script> tags will execute once. This means that the following statements will all be evaluated:
var last = 'b';
var next = 'c';
if (document.getElementById('option-c').value != null) {
last = 'c';
next = 'd';
}
if (document.getElementById('option-d').value != null) {
last = 'd';
next = 'e';
}
if (document.getElementById('option-e').value != null) {
last = '';
next = '';
}
Once they are evaluated, they will never be run again until you refresh the page. Thus, when the page is done loading last = 'b' and next = 'c' and the three if statements all evaluate to false and are not executed (I assume the text fields are empty on initial load). The following code will also be executed once:
$('#answer_answer'+last).keyup(function() {
console.log('beg');
var elem = document.getElementById('option-'+next);
elem.style.display="block";
console.log('hit this');
})
However, this code binds a 'handler' (a future promise) to execute some code given a user action.
The action is a keyup event on the '#answer_answer'+last element.
Because we know that last = 'b' when this promise is made, this
really means '#answer_answerb'
The promise is to execute the following code:
console.log('beg');
var elem = document.getElementById('option-'+next);
elem.style.display="block";
console.log('hit this');
Thus, when you begin typing in #answer_answerb the #answer_answerc field is displayed (remember that next = 'c'). And if you type some more into #answer_answerb the #answer_answerc field remains visible. And now we know everything that your code does.
So, how do we fix it? Can you guess? We can make more promises. The full code:
<script>
$('#answer_answerb).keyup(function() {
var elem = document.getElementById('option-c');
elem.style.display="block";
})
$('#answer_answerc).keyup(function() {
var elem = document.getElementById('option-d');
elem.style.display="block";
})
$('#answer_answerd).keyup(function() {
var elem = document.getElementById('option-e');
elem.style.display="block";
})
</script>
This will have the desired effect, but is hard to maintain. If you decide to add more text fields, you will have to create a promise for each one. You can find a more elegant solution to your problem here http://jsfiddle.net/tppiotrowski/GkT2g/

Categories