Error in IE when looping - javascript

Lets clarify my question,
I want to make an element which the element contains 5 fields so I dont want the user should be able to put in a new element if the old one is null, so I made the alert when looping through the old element and see if there is some strings, if not then dont put a new element and make an alert please fill out all fields
Here again my code
function addEvent() {
var ni = document.getElementById('discount'); // Takes the a div named discount
var discountForm = document.getElementById('discountForm'); // Takes the a form named discountForm
var numi = document.getElementById('theValue'); // Takes the a hidden input field named theValue
var num = (document.getElementById("theValue").value -1)+ 2; // Start counting to set the new divs form numbers
numi.value = num;
var divIdName = "my"+num+"Div"; // the new divs will be named
var allDivTags = discountForm.getElementsByTagName('div'); // take all div tags
var numOfDivs = (allDivTags.length -1); // take the number of the old div
var oldDivIdName = document.getElementById(allDivTags[numOfDivs].id); // old div id
var newdiv = document.createElement('div'); //the new div
newdiv.setAttribute("id",divIdName);
newdiv.innerHTML = "Company <select name=\"company[]\"><option value=\"\"></option><option value=\"ZI\">Avis</option><option value=\"ET\">Enterprise</option><option value=\"ZE\">Hertz</option><option value=\"ZD\">Budget</option><option value=\"ZR\">National</option><option value=\"AL\">Alamo</option></select> Discount Type <select name=\"type[]\"><option value=\"CD\">Discount Number</option><option value=\"PC\">Coupon Number</option></select> Code <input name=\"code[]\" type=\"text\"> Title <input name=\"title[]\" type=\"text\"> Remove"; // creating the fileds in the new div
ni.appendChild(newdiv);
for(i=0; i<discountForm.elements.length;i++){ // loop through the divs
if(numOfDivs != i-1){ // if tho old div exist and if the old div fields are empty
if(oldDivIdName.children[i].value.length == 0){
removeElement(divIdName); // then dont put the new one
alert('Please enter all fields');
}
}
}
}
But my problem is that in IE comes out an error children[...].value.length is null or not an object so I trying to figure how to fix it,
I hope its more clearly for you now.

It's very hard to tell from the information you've given us. But my first guess is the following:
for(i=0; i<discountForm.elements.length;i++){
if(numOfDivs != i-1){
if(oldDivIdName.children[i].value.length == 0){
removeElement(divIdName);
alert('Please enter all fields');
}
}
}
Above you're doing:
oldDivIdName.children[i]
But i is defined as the number of elements in the form from what I can see... not the number of children of the oldDivIdName. If there are more elements in the form than there are in oldDivIdName then the value of oldDivIdName.children[i] will be null. And "value" is not defined on null.

It's very hard to tell from the information you've given us. But my first guess is the following:
When you first call this method, allDivTags.length whether is null or negative, and results
not got element:
var oldDivIdName = document.getElementById(allDivTags[numOfDivs].id);

Related

Loop array until matches the value of the item clicked

I'm trying to loop through an array until it matches the value of the object that is clicked.
When the object is created the text input box shares it's value with the object and the array. I would like to be able to loop through the array until there is a match, then find the index, after that pass the index value to a variable to be used. From there remove the object that is clicked from the webpage and the array.
Additional details are that there is an input box with a button. The user enters a line of information into the input box and selects a button to appendChild it to the list. The object created is a div with the input value as the paragraph with a span element with an X which is supposed to remove the object when clicked.
Here is the HTML Code being used
<div id="outerDiv">
<div id="taskList">
</div>
</div>
Here is the code to create the object.
var magicArray = [];
function makeOutline() {
var textValue = document.getElementById("inputBox").value;
if (textValue == "" || textValue == null){
alert("Please enter a item you want to add to the to-do list");
} else {
var inputField = document.getElementById("taskList");
var inputText = document.createTextNode(textValue);
var mainHeading = document.createElement("p");
mainHeading.setAttribute("class", "outlineBorder");
var spanText = document.createTextNode("x");
var spanBox = document.createElement("span");
spanBox.setAttribute("class", "close");
spanBox.setAttribute("onclick", "removeMe()");
var outlineList = document.createElement("div");
outlineList.setAttribute("value", textValue);
spanBox.appendChild(spanText);
mainHeading.appendChild(inputText);
mainHeading.appendChild(spanBox);
outlineList.appendChild(mainHeading);
inputField.appendChild(outlineList);
magicArray[magicArray.length] = textValue;
document.getElementById("inputBox").value = "";
}
}
Here is the code to remove the item.
I am able to have it set to a static number and work every time; however,
struggling to find a dynamic solution since there can be multiple objects.
function removeMe() {
var removeList = document.getElementById("taskList");
removeList.removeChild(removeList.childNodes[1];
}
Here is a screenshot of the family tree structure
First, you can use this to get the element. docs:
When the event handler is invoked, the this keyword inside the handler is set to the DOM element on which the handler is registered.
function removeMe()
{
// this refers to the item that invoked removeMe()
var removeList = document.getElementById("taskList");
removeList.removeChild(this.parentNode.parentNode);
}
Also, this is how you properly add event listeners
spanBox.addEventListener("click", removeMe);
Here is a working jsfiddle for you

Can't access property once selecting element

Can't get the title right. I am using jquery to create a textarea.
function build_form() {
// Clear all previous form elements
$('#form_content').html('');
// Grabs all elements that will be dynamically created
var elements = templates.types[$('#selectType')[0].selectedIndex].content.elements;
for (ele in elements){
var $div = $(document.createElement('div'));
$div.attr('class', 'div_form');
// Create description for input box
var $x = $(document.createElement('text'));
$x.html(elements[ele].description);
$div.append($x);
// Create input box itself
var $i = $(document.createElement(elements[ele].type));
$i.attr('placeholder', elements[ele].placeholder);
$i.attr('class', 'form_input');
if (elements[ele].value) {
// For textareas
$i.text(elements[ele].value);
// For input
$i.val(elements[ele].value);
}
console.log($x);
console.log($x[0]);
console.log($x[0].scrollHeight);
$div.append($i);
$('#form_content').append($div);
var $linebreak = $(document.createElement('br'));
$('#form_content').append($linebreak);
}
}
Resulting in:
This is as much an understanding problem as a problem blocking me. $x shows that there is a textarea at $x[0] and, expanding it, I see a giant list of properties. One of which is scrollHeight which I am trying to access.
However once accessing $x[0], it then gives me the HTML and $x[0].scrollHeight results in 0. The text is present.
What am I missing?
Edit: The height of the textarea is non-zero.

Error message not showing and hiding depending on if else statement

I have a function that loops through all of the inputs of my form and checks if they are filled or not. If the field is blank, it makes that specific input pink and returns false.
I'm trying to add a "Field Required" message underneath the inputs that are not filled. So i coded an extra table row after each one, with a div that holds the error message. The css for the div is set to "display:none" on page load.
Right now my function is showing "required" for every input and not just the ones that are blank, but the pink coloring is still working correctly.
How do I get the "required" div to show and hide correctly like the pink coloring does?
checkinputs = function (blockOne,blockTwo) {
inputGood = true;
blOne = $(blockOne);
blTwo = $(blockTwo);
blInput = [blOne,blTwo];
for (x = 0; x < 2; x++) {
var validators = blInput[x].find(" [id$='RequiredIndicator']").parent().parent('tr').find(':input:not(:hidden)');
var notAllFilled = validators.filter(function(){
var myInput = $(this); //.parent().parent('tr').find(':input');
var filledVal = myInput.val();
var isFilled = $.trim(filledVal).length;
if (isFilled) {
$(this).css('background-color', 'white');
$(this).closest('div').find('.required').hide();
$(this).parent('td').prev('td').find('span').text('*');
}
else {
$(this).css('background-color', 'pink');
$(this).closest('div').find('.required').show();
$(this).parent('td').prev('td').find('span').text('*');
inputGood = false;
}
return isFilled;
}).length;
var inputCount = validators.length;
};
if( !inputGood ){
$('#errorAlert').append('<span style="font-weight:bold;">"Some required information is missing. Please complete the missing fields below."</span>' + '<br><br>');
$('#errorAlertTwo').append('<span style="font-weight:bold;">"Some required credit card information is missing. Please complete the missing fields below."</span>' + '<br><br>');
}
return inputGood;
};
HERE IS A FIDDLE OF THE ISSUE:
http://jsfiddle.net/RNMM7/
Your issue is almost definitely your line to show the div:
$(this).closest('div').find('.required').show();
What this line does is:
Starting at your $(this), it finds the nearest ancestor [including $(this)] that is a div, going up the DOM tree
Finds all elements with class 'required' under that div, and shows them.
Without seeing how your HTML is structured, my guess is that the nearest div element up the DOM tree encompasses all your .required elements. You'd need to replace the 'div' in that statement with an element lower in the DOM tree that would only encompass your $(this) and the one .required element you want to show.

Mimicking "placeholder" attr with "value"

I found this online:
var x = 0; // count for array length
$("input.placeholder").each(function(){
x++; //incrementing array length
});
var _values = new Array(x); //create array to hold default values
x = 0; // reset counter to loop through array
$("input.placeholder").each(function(){ // for each input element
x++;
var the_default = $(this).val();
var default_value = $(this).val(); // get default value.
_values[x] = default_value; // create new array item with default value
});
var current_value; // create global current_value variable
$('input.placeholder').focus(function(){
current_value = $(this).val(); // set current value
var is_default = _values.indexOf(current_value); // is current value is also default value
if(is_default > -1){ //i.e false
$(this).val(''); // clear value
}
});
$('input.placeholder').focusout(function(){
if( $(this).val() == ''){ //if it is empty...
$(this).val(current_value); //re populate with global current value
}
});
As you can see, it grabs the text within a value attribute and sets it as the default_value. It then checks the current_value against the default.
I'm running into a problem.
In this example, we have an element like:
<input type="text" class="placeholder" value="potato">
If the user focuses and unfocuses the input, it works great - removing and repopulating with "potato".
However, let's say a user enters "ioqiweoiqwe", and then unfocuses the input (fills out the rest of the form"). They then go back to our input and delete all of their text, and click on another field. The input would be re-populated with "ioqiweoiqwe" - when really, we want it to be re-populated with the default_value. How do I manage to do this?
Yours sincerely,
a jQuery nub.
Note: I set up a jsfiddle here... a bit after some comments: http://jsfiddle.net/xmhCz/
I don't really know what the problem with that code is, but it looks like it was written by someone who didn't know much JavaScript. I rewrote the functionality:
$("input.placeholder").each(function() {
var me=$(this);
var defaultValue=me.val();
me.focus(function() {
if(me.val()===defaultValue) {
me.val("");
}
});
me.blur(function() {
if(me.val()==="") {
me.val(defaultValue);
}
});
});
Test it out on JSFiddle.
HTML inputs have defaultValue

jQuery removing elements from DOM put still reporting as present

I have an address finder system whereby a user enters a postcode, if postcode is validated then an address list is returned and displayed, they then select an address line, the list dissappears and then the address line is split further into some form inputs.
The issue i am facing is when they have been through the above process then cleared the postcode form field, hit the find address button and the address list re-appears.
Event though the list and parent tr have been removed from the DOM it is still reporting it is present as length 1?
My code is as follows:
jQuery
// when postcode validated display box
var $addressList = $("div#selectAddress > ul").length;
// if address list present show the address list
if ($addressList != 0) {
$("div#selectAddress").closest("tr").removeClass("hide");
}
// address list hidden by default
// if coming back to modify details then display address inputs
var $customerAddress = $("form#detailsForm input[name*='customerAddress']");
var $addressInputs = $.cookies.get('cpqbAddressInputs');
if ($addressInputs) {
if ($addressInputs == 'visible') {
$($customerAddress).closest("tr").removeClass("hide");
}
} else {
$($customerAddress).closest("tr").addClass("hide");
}
// Need to change form action URL to call post code web service
$("input.findAddress").live('click', function(){
var $postCode = encodeURI($("input#customerPostcode").val());
if ($postCode != "") {
var $formAction = "customerAction.do?searchAddress=searchAddress&custpc=" + $postCode;
$("form#detailsForm").attr("action", $formAction);
} else {
alert($addressList);}
});
// darker highlight when li is clicked
// split address string into corresponding inputs
$("div#selectAddress ul li").live('click', function(){
$(this).removeClass("addressHover");
//$("li.addressClick").removeClass("addressClick");
$(this).addClass("addressClick");
var $splitAddress = $(this).text().split(",");
$($customerAddress).each(function(){
var $inputCount = $(this).index("form#detailsForm input[name*='customerAddress']");
$(this).val($splitAddress[$inputCount]);
});
$($customerAddress).closest("tr").removeClass("hide");
$.cookies.set('cpqbAddressInputs', 'visible');
$(this).closest("tr").fadeOut(250, function() { $(this).remove(); });
});
I think you're running into the same issue I recently ran into. If you have a variable pointing to 5 DIV's (example: var divs = $('.mydivs');) and then you call jQuery's remove() on one of the DIV's, like so: divs.eq(0).remove() you'll see that divs.size() still returns 5 items. This is because remove() operates on the DOM. However... if after calling remove() you then re-set your variable: divs = $('.mydivs'); and get the size you'll now get the correct size of the array. I've added sample code displaying this below:
// get all 5 divs
var d = $('.dv');
// remove the first div
d.eq(0).remove();
// you would expect 4 but no, it's 5
alert(d.size());
// re-set the variable
d = $('.dv');
// now we get 4
alert(d.size());

Categories