• 0

[JS] Need help with two items.


Question

Okay, I'm not the greatest with JavaScript, but I can modify and make minor changes, but not create custom ones.

So my two tasks I need to complete are this:

  • When you select a preset of items from a drop down menu, the second drop down menu must change to display (a pre-termined) list of items.
  • Add a "Add more fields" button that copies a row of five (5) boxes, including the item above

For the first item, I have a list of colours (e.g. Black, White, Red, Green, Yellow..) and when I select say, Black, the second drop down menu can only show 1, 2, 3, 4, 5, 6 but when I select Red, Green or Yellow, the drop down box shows 3, 4, 5, 6 (removing 1 and 2).

Once this is accomplished, I have 5 boxes:

Order #(text) | Colour(drop down) | Number(drop down) | Quantity(Text) | Yes/No (Radio Buttons)

I need to copy this row of items, duplicating it each time, so I can enter either 1 or 20 items at a time.

I've tried a couple of scripts, but can't seem to get them to work in harmony with one another, so rather than modifying these 2 scripts, I was wondering if Neowin could help me out :)

Thanks!

Link to comment
Share on other sites

19 answers to this question

Recommended Posts

  • 0

Could you provide us with the HTML/Javascript that you currently have that draws your 5 boxes?

Adding an onclick method to the first dropdown and then filtering the values in the second can satisfy your 1st requirement (I can specify the code to do so if you show me what you already have :))

For the second requirement, is your entire order row in a table? if so, it can easily be done by using the createElement function to create the new row & controls, then using the appendChild to add the controls to the row, but that will work differently dependent upon how you currently have it set up (Again, I can specify the code if you show me what you have).

Link to comment
Share on other sites

  • 0

Hey, thanks for the help in advance, Matty.

This is the row I want to clone, and included inside of this is the second drop down I need to manipulate.

<tr>
                 <td>#1</td>
                 <td><input type="text=" name="SKU" id="SKU"></td>
                 <td><select name="ShirtColour" id="ShirtColour">
                    <option value="Black">Black</option>
                    <option value="White">White</option>
                    <option value="Daisy">Daisy</option>
                    <option value="Dark Chocolate">Dark Chocolate</option>
                    <option value="Forest Green">Forest Green</option>
                    <option value="Gold">Gold</option>
                    <option value="Irish Green">Irish Green</option>
                    <option value="Light Blue">Light Blue</option>
                    <option value="Light Pink">Light Pink</option>
                    <option value="Military Green">Military Green</option>
                    <option value="Navy">Navy</option>
                    <option value="Orange">Orange</option>
                    <option value="Purple">Purple</option>
                    <option value="Red">Red</option>
                    <option value="Royal Blue">Royal Blue</option>
                    <option value="Sport Grey">Sport Grey</option>
                    <option value="Navy Ringer">Navy Ringer</option>
                    <option value="Black Ringer">Black Ringer</option>
                    <option value="Red Ringer">Red Ringer</option>
                    <option value="Other">Other</option>
                </select></td>
                 <td><select name="ShirtSize" id="ShirtSize" size="1">
                    <option value="Size_XSmall-Youth">X-Small (Youth)</option>
                    <option value="Size_Small-Youth">Small (Youth)</option>
                    <option value="Size_Medium-Youth">Medium (Youth)</option>
                    <option value="Size_Small">Small</option>
                    <option value="Size_Medium">Medium</option>
                    <option value="Size_Large">Large</option>
                    <option value="Size_XLarge" selected>X-Large</option>
                    <option value="Size_2XLarge">2 X-Large</option>
                    <option value="Size_3XLarge">3-X-Large</option>
                    <option value="Size_4XLarge">4 X-Large</option>
                    <option value="Size_5XLarge">5 X-Large</option>
                </select></td>
                 <td><input type="text" name="Quantity" id="Quantity" value="1" size="2"></td>
                 <td><label>No<input type="radio" name="PriorityShipping" id="PriorityShipping" value="0" checked></label>  
                 <label>Yes<input type="radio" name="PriorityShipping" id="PriorityShipping" value="1"></label></td>
                </tr>

Thanks again for the help!

Link to comment
Share on other sites

  • 0

Thanks! Just a quick question, how are you going to determine what's in stock and what isn't? I was starting to put them all in as static data like if you have selected gold, show only XLarge etc. This can become very difficult to maintain if these values are changing constantly. Are they going to? It would require a different approach if so.

If you just want me to show you it as a static version, with the values and their options hard coded, let me know either way :)

Link to comment
Share on other sites

  • 0

The items never change. There might be a new colour, or size added once every year or two. And keeping stock isn't the problem, they always have hundreds of shirts in stock :yes:

Hardcoded is the best way to go about this. If I really need to, i'll stick the items in a DB and call them, but that is way in the future, if it's ever needed.

Link to comment
Share on other sites

  • 0

Hi Andrew,

Please see attached.

I've made so that when you add a new colour, you put it in the colour array, that's it. If you need a new size, add it to the size array, if you need a new size for a colour, just look at the way i've done it for the ones I listed, it's a multi dimensional array like coloursize[colour], which then is used to determine which sizes are in what colours.

For your row creations, I've added an input box and a button for you to specify how many rows to add, then it will dynamically generate all the HTML for it, whilst giving a unique ID to all the controls in the row (based on the new row number).

Is that what you were looking for?

EDIT: I'm not permitted to post attachments, so here's the entire markup:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Stocker</title>
</head>
<body>
<table id="ProductTable">
    <tr id="1">
        <td>#1</td>
        <td>
            <input type="text" name="SKU" id="SKU1" />
        </td>
        <td>
            <select name="ShirtColour" id="ShirtColour1" onchange="ShirtColour_Changed(this);" style="width: 150px;">
            <option value="PleaseSelect" selected="selected">Please Select...</option>
            </select>
        </td>
        <td>
            <select name="ShirtSize" id="ShirtSize1" size="1" style="width: 150px;">
            </select>
        </td>
        <td>
            <input type="text" name="Quantity" id="Quantity1" value="1" style="width: 100px;" />
        </td>
        <td>
            <label>No</label><input type="radio" name="PriorityShipping" id="PriorityShippingNo1" value="0" checked="checked" /><label>Yes</label><input type="radio" name="PriorityShipping" id="PriorityShippingYes1" value="1" />
        </td>
        <td>
            <input type="text" name="Row Quantity" id="RowQuantity" value="1" size="2" />
            <input type="button" value="Add Rows" name="Add More Rows" id="AddRows" onclick="AddRows();" />
        </td>
    </tr>
</table>
<script type="text/javascript">

    //This is where your colours & sizes are defined, they will then be picked up everywhere
    var colorArray = new Array("Black", "White", "Daisy");
    var sizesArray = new Array("X-Small (Youth)", "Small (Youth)", "Medium (Youth)", "Small", "Medium", "Large", "X-Large", "2 X-Large", "3 X-Large", "4 X-Large");
    var defaultedColours = document.getElementById("ShirtColour1");
    for (var i = 0; i < colorArray.length; i++) {
        var option = document.createElement('option');
        option.text = colorArray[i];
        option.value = colorArray[i];
        defaultedColours.add(option, defaultedColours.length);
        colorArray[i] = new Array();
    }

    //Black Sizes
    colorArray[0][0] = sizesArray[0];
    colorArray[0][1] = sizesArray[1];
    colorArray[0][2] = sizesArray[2];
    colorArray[0][3] = sizesArray[3];

    //White Sizes
    colorArray[1][0] = sizesArray[4];
    colorArray[1][1] = sizesArray[5];
    colorArray[1][2] = sizesArray[6];

    //Daisy Sizes
    colorArray[2][0] = sizesArray[7];
    colorArray[2][1] = sizesArray[8];
    colorArray[2][2] = sizesArray[9];

    function ShirtColour_Changed(sender) {
        var rowNum = sender.id.substring(11);
        var sizesDDL = document.getElementById('ShirtSize' + rowNum);
        if (sender.options.value != "Please Select") {
            ClearDropdown(sizesDDL);
            for (var i = 0; i < colorArray[sender.options.selectedIndex - 1].length; i++) {
                var option = document.createElement('option');
                //Use -1 because there is an extra element in the dropdown (the please select)
                option.text = colorArray[sender.options.selectedIndex - 1][i];
                option.value = colorArray[sender.options.selectedIndex - 1][i];
                sizesDDL.add(option, sizesDDL.length);
            }
        }
    }

    function ClearDropdown(dropdown) {
        //Standard way of clearing a dropdown
        dropdown.options.length = 1;
        dropdown.options[0] = null;
    }

    function AddRows() {
        var rownums = document.getElementById("RowQuantity").value;
        //Make sure what they typed in is a number and is less than 50 (you can change to whatever limit :)
        if (!isNaN(rownums) && rownums < 50) {
            for (var i = 1; i <= rownums; i++) {
                AddRow();
            }
        }
    }

    function AddRow() {
        var mainTable = document.getElementById("ProductTable");
        var newRow = document.createElement("tr");
        var newRowNum = mainTable.getElementsByTagName("tr").length + 1

        newRow.id = newRowNum;

        mainTable.appendChild(newRow);

        //TDs
        var rowNumTD = document.createElement("td");
        var colourTD = document.createElement("td");
        var sizeTD = document.createElement("td");
        var shippingTD = document.createElement("td");
        var skuTD = document.createElement("td");
        var quantityTD = document.createElement("td");

        newRow.appendChild(rowNumTD);
        newRow.appendChild(skuTD);
        newRow.appendChild(colourTD);
        newRow.appendChild(sizeTD);
        newRow.appendChild(quantityTD);
        newRow.appendChild(shippingTD);

        //SKU Input
        var skuInput = document.createElement("input");
        skuInput.id = "SKU" + newRowNum;
        skuInput.type = 'text';

        //Colour Dropdown
        var colourSelect = document.createElement("select");
        colourSelect.id = "ShirtColour" + newRowNum;
        colourSelect.onchange = function () { ShirtColour_Changed(this); };
        colourSelect.style.width = "150px";

        var defaultColours = document.getElementById("ShirtColour1").options;

        for (var i = 0; i < defaultColours.length; i++) {
            var defColour = document.createElement("option");
            defColour.text = defaultColours[i].text;
            defColour.value = defaultColours[i].value;
            colourSelect.add(defColour, colourSelect.options.length);
        }

        //Size Dropdown
        var sizeSelect = document.createElement("select");
        sizeSelect.id = "ShirtSize" + newRowNum;
        sizeSelect.style.width = "150px";

        //Quantity Input
        var quantityInput = document.createElement("input");
        quantityInput.id = "Quantity" + newRowNum;
        quantityInput.type = 'text';
        quantityInput.style.width = "100px";
        quantityInput.value = '1';

        //Priority Shipping Radio Buttons
        var pShipYes = document.createElement('input');
        pShipYes.id = "PriorityShippingYes" + newRowNum;
        pShipYes.type = 'radio';
        var pShipYesLBL = document.createElement('label');
        SetText(pShipYesLBL, "Yes");
        var pShipNo = document.createElement('input');
        pShipNo.id = "PriorityShippingNo" + newRowNum;
        pShipNo.type = 'radio';
        pShipNo.checked = 'checked';
        var pShipNoLBL = document.createElement('label');
        SetText(pShipNoLBL, "No");

        //we get how many rows there is already, and add one for the row number
        SetText(rowNumTD, "#" + (mainTable.getElementsByTagName("tr").length + 1));

        skuTD.appendChild(skuInput);
        colourTD.appendChild(colourSelect);
        sizeTD.appendChild(sizeSelect);
        quantityTD.appendChild(quantityInput);
        shippingTD.appendChild(pShipNoLBL);
        shippingTD.appendChild(pShipNo);
        shippingTD.appendChild(pShipYesLBL);
        shippingTD.appendChild(pShipYes);
    }

    function SetText(element, text) {
        //will set the text of an element in both IE and Firefox
        if (element.innerText != null) {
            element.innerText = text;
        }
        else {
            element.textContent = text;
        }
    }

    </script>
</body>
</html>

Link to comment
Share on other sites

  • 0

Hmm, I tried the script in my editor, and it works (aside from the Add Rows button) but once I upload it, the javascript stops working.

Here is an example (Uploaded to my own website) http://www.imgftw.net/test.php

That Javascript all worked for me on that link you provided? Is it throwing an error for you? Have you got script debugging enabled in IE?

I don't know if this helps but try putting it in the head section.

That won't help unfortunately :). It is better practice, the reason I moved it orignally was because I was using document.getElementById on page load, which won't work unless it's executed AFTER the markup (the element won't yet exist on the page to be able to access it).

Link to comment
Share on other sites

  • 0

Well that is very strange, looking in my IE developer toolbar and I'm running IE in IE8 Document Mode, but if I change it to IE7 (I suspect that's what yours is?), it doesn't work! The dropdown colours populate the sizes fine, but the add button does nothing!!! Let me fix that. In the meantime, to view it working you need to Press F12 (assuming you're in IE6 or higher) and set your Document Mode (top right corner) to IE8, it will all work fine!

Let me have another look.

Link to comment
Share on other sites

  • 0

In the meantime, change the ShirtColour_Changed function to the following (it handles clicking back to Please Select properly and clears the sizes DDL).

    function ShirtColour_Changed(sender) {
        var rowNum = sender.id.substring(11);
        var sizesDDL = document.getElementById('ShirtSize' + rowNum);
        if (sender.options.value != "PleaseSelect") {
            ClearDropdown(sizesDDL);
            for (var i = 0; i < colorArray[sender.options.selectedIndex - 1].length; i++) {
                var option = document.createElement('option');
                //Use -1 because there is an extra element in the dropdown (the please select)
                option.text = colorArray[sender.options.selectedIndex - 1][i];
                option.value = colorArray[sender.options.selectedIndex - 1][i];
                sizesDDL.add(option, sizesDDL.length);
            }
        }
        else {
            ClearDropdown(sizesDDL);
        }
    }

Link to comment
Share on other sites

  • 0

Hmm, I changed that, but still no luck. I wonder what is making it not load.. cause it works in my editor, but not online.

Link to comment
Share on other sites

  • 0

Hmm, I changed that, but still no luck. I wonder what is making it not load.. cause it works in my editor, but not online.

I found out why it never worked in any other mode than IE 8, it's the following line:

mainTable.appendChild(newRow)

You can't do that in anything other than IE 8 mode! You need to add the new row to the tbody, not the table itself. Replace it with the following line:

mainTable.getElementsByTagName('tbody')[0].appendChild(newRow);

That works for me in IE7 mode, IE8 mode and Chrome.

Let me know if it works for you :)

If it doesn't work, do you get the colours in the dropdown or is it just the add button that doesn't work?

Link to comment
Share on other sites

  • 0

If it doesn't work, do you get the colours in the dropdown or is it just the add button that doesn't work?

It works in everything, except Firefox 3.6.11 :( - what i'm using to test in

Link to comment
Share on other sites

  • 0

I know why! when you do select.add to add an option to a select in JS, it doesn't work in FF! Please see my new solution, testing in Firefox 3.6, IE 7 & IE8 and Chrome 6 :)

Should be okay now!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Stocker</title>
</head>
<body>
<table id="ProductTable">
    <tr id="1">
        <td>#1</td>
        <td>
            <input type="text" name="SKU" id="SKU1" />
        </td>
        <td>
            <select name="ShirtColour" id="ShirtColour1" onchange="ShirtColour_Changed(this);" style="width: 150px;">
            <option value="PleaseSelect" selected="selected">Please Select...</option>
            </select>
        </td>
        <td>
            <select name="ShirtSize" id="ShirtSize1" size="1" style="width: 150px;">
            </select>
        </td>
        <td>
            <input type="text" name="Quantity" id="Quantity1" value="1" style="width: 100px;" />
        </td>
        <td>
            <label>No</label><input type="radio" name="PriorityShipping" id="PriorityShippingNo1" value="0" checked="checked" /><label>Yes</label><input type="radio" name="PriorityShipping" id="PriorityShippingYes1" value="1" />
        </td>
        <td>
            <input type="text" name="Row Quantity" id="RowQuantity" value="1" size="2" />
            <input type="button" value="Add Rows" name="Add More Rows" id="AddRows" onclick="AddRows();" />
        </td>
    </tr>
</table>
<script type="text/javascript">

    //This is where your colours & sizes are defined, they will then be picked up everywhere
    var colorArray = new Array("Black", "White", "Daisy");
    var sizesArray = new Array("X-Small (Youth)", "Small (Youth)", "Medium (Youth)", "Small", "Medium", "Large", "X-Large", "2 X-Large", "3 X-Large", "4 X-Large");
    var defaultedColours = document.getElementById("ShirtColour1");
    for (var i = 0; i < colorArray.length; i++) {
        var option = document.createElement('option');
        SetText(option, colorArray[i]);
        option.value = colorArray[i];
        defaultedColours.appendChild(option);
        colorArray[i] = new Array();
    }

    //Black Sizes
    colorArray[0][0] = sizesArray[0];
    colorArray[0][1] = sizesArray[1];
    colorArray[0][2] = sizesArray[2];
    colorArray[0][3] = sizesArray[3];

    //White Sizes
    colorArray[1][0] = sizesArray[4];
    colorArray[1][1] = sizesArray[5];
    colorArray[1][2] = sizesArray[6];

    //Daisy Sizes
    colorArray[2][0] = sizesArray[7];
    colorArray[2][1] = sizesArray[8];
    colorArray[2][2] = sizesArray[9];

    function ShirtColour_Changed(sender) {
        var rowNum = sender.id.substring(11);
        var sizesDDL = document.getElementById('ShirtSize' + rowNum);
        if (sender.options.value != "PleaseSelect") {
            ClearDropdown(sizesDDL);
            for (var i = 0; i < colorArray[sender.options.selectedIndex - 1].length; i++) {
                var option = document.createElement('option');
                //Use -1 because there is an extra element in the dropdown (the please select)
                SetText(option, colorArray[sender.options.selectedIndex - 1][i]);
                option.value = colorArray[sender.options.selectedIndex - 1][i];
                sizesDDL.appendChild(option);
            }
        }
        else {
            ClearDropdown(sizesDDL);
        }
    }

    function ClearDropdown(dropdown) {
        //Standard way of clearing a dropdown
        dropdown.options.length = 1;
        dropdown.options[0] = null;
    }

    function AddRows() {
        var rownums = document.getElementById("RowQuantity").value;
        //Make sure what they typed in is a number and is less than 50 (you can change to whatever limit :)
        if (!isNaN(rownums) && rownums < 50) {
            for (var i = 1; i <= rownums; i++) {
                AddRow();
            }
        }
    }

    function AddRow() {
        var mainTable = document.getElementById("ProductTable");
        var newRow = document.createElement("tr");
        var newRowNum = mainTable.getElementsByTagName("tr").length + 1

        newRow.id = newRowNum;

        mainTable.getElementsByTagName('tbody')[0].appendChild(newRow);

        //TDs
        var rowNumTD = document.createElement("td");
        var colourTD = document.createElement("td");
        var sizeTD = document.createElement("td");
        var shippingTD = document.createElement("td");
        var skuTD = document.createElement("td");
        var quantityTD = document.createElement("td");

        newRow.appendChild(rowNumTD);
        newRow.appendChild(skuTD);
        newRow.appendChild(colourTD);
        newRow.appendChild(sizeTD);
        newRow.appendChild(quantityTD);
        newRow.appendChild(shippingTD);

        //SKU Input
        var skuInput = document.createElement("input");
        skuInput.id = "SKU" + newRowNum;
        skuInput.type = 'text';

        //Colour Dropdown
        var colourSelect = document.createElement("select");
        colourSelect.id = "ShirtColour" + newRowNum;
        colourSelect.onchange = function () { ShirtColour_Changed(this); };
        colourSelect.style.width = "150px";

        var defaultColours = document.getElementById("ShirtColour1").options;

        for (var i = 0; i < defaultColours.length; i++) {
            var defColour = document.createElement("option");
            SetText(defColour, GetText(defaultColours[i]));
            defColour.value = defaultColours[i].value;
            colourSelect.appendChild(defColour);
        }

        //Size Dropdown
        var sizeSelect = document.createElement("select");
        sizeSelect.id = "ShirtSize" + newRowNum;
        sizeSelect.style.width = "150px";

        //Quantity Input
        var quantityInput = document.createElement("input");
        quantityInput.id = "Quantity" + newRowNum;
        quantityInput.type = 'text';
        quantityInput.style.width = "100px";
        quantityInput.value = '1';

        //Priority Shipping Radio Buttons
        var pShipYes = document.createElement('input');
        pShipYes.id = "PriorityShippingYes" + newRowNum;
        pShipYes.type = 'radio';
        var pShipYesLBL = document.createElement('label');
        SetText(pShipYesLBL, "Yes");
        var pShipNo = document.createElement('input');
        pShipNo.id = "PriorityShippingNo" + newRowNum;
        pShipNo.type = 'radio';
        pShipNo.checked = 'checked';
        var pShipNoLBL = document.createElement('label');
        SetText(pShipNoLBL, "No");

        //we get how many rows there is already, and add one for the row number
        SetText(rowNumTD, "#" + (mainTable.getElementsByTagName("tr").length + 1));

        skuTD.appendChild(skuInput);
        colourTD.appendChild(colourSelect);
        sizeTD.appendChild(sizeSelect);
        quantityTD.appendChild(quantityInput);
        shippingTD.appendChild(pShipNoLBL);
        shippingTD.appendChild(pShipNo);
        shippingTD.appendChild(pShipYesLBL);
        shippingTD.appendChild(pShipYes);
    }

    function SetText(element, text) {
        //will set the text of an element in both IE and Firefox
        if (element.innerText != null) {
            element.innerText = text;
        }
        else {
            element.textContent = text;
        }
    }

    function GetText(element) {
        //will get the text of an element in both IE and Firefox
        if (element.innerText != null) {
            return element.innerText;
        }
        else {
            return element.textContent;
        }
    }

    </script>
</body>
</html>

Link to comment
Share on other sites

  • 0

DUDE! You are amazing! I can not thank you enough!!

I just need to implement this into my working model and pray everything is working well! You have just saved me hours of time and a massive headache!

Again, THANK YOU!

Link to comment
Share on other sites

  • 0

Another strange one this one! It seems when you put it all inside a form, the Add Rows button throws the JS error because the ID of the button matches the name of the JS function the onclick calls (I think it thinks that you are trying to call the element, not the function).

Here is the line in question: (line 31)

<input type="button" value="Add Rows" name="Add More Rows" id="AddRows" onclick="AddRows();" />

See how the ID matches the onclick? Adding the form tag must have confused the browser as to what the onclick was trying to call. Changing the ID solves it, as shown below:

<input type="button" value="Add Rows" name="Add More Rows" id="AddMoreRows" onclick="AddRows();" />

All I have added is the word "More" in the ID, which removes the ambiguity!

Hope this helps :)

Link to comment
Share on other sites

  • 0

Again Matty, thank you very much :D Everything seems to be working, I just need to work on the POST data, which I should be able to handle easily :p

Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.