CFML 变量名称不能以“.”结尾。 字符错误

发布于 2024-07-17 03:05:56 字数 17135 浏览 5 评论 0原文

我在发布表单时收到此错误。 但最奇怪的是,这个错误只发生在 Chrome 和 Safari 中。 FF、IE 和 Opera 都可以毫无问题地发布表单。

堆栈跟踪不指向发生此错误的文件。 cfcatch 的 cfdump 让我对问题所在有了一些了解,但我找不到问题实际存在的任何实例。 这是部分转储:

Column     1
Detail     The variable attributes. ends with a "." character. You must supply an additional structure key or delete the "." character.
KnownColumn  -1
KnownLine   -1
KnownText   "unknown"
Line         1
Message   A CFML variable name cannot end with a "." character.

这是处理发布数据的代码。 所有内容都包含在 cftransaction 内,并且有一个循环,不知道为什么它没有被显示。 (感谢彼得·鲍顿澄清这一点)

<!--- Delete out the old category ties --->
<cfquery name="deleteCategory" datasource="#request.dsnWrite#">
DELETE FROM
    ProductListings_categories
WHERE
    listingID = <cfqueryparam value="#attributes.listingID#">
</cfquery>

<!--- Loop through the list --->
<cfloop list="#attributes.taginput#" index="idx" delimiters=".">

<!--- check to see if tag exists --->
    <cfquery name="checkTag" datasource="#request.dsnWrite#">
    SELECT
        categoryID
    FROM
        categories
    WHERE
        CategoryName = <cfqueryparam value="#idx#" cfsqltype="cf_sql_varchar">
    </cfquery>

    <!--- If it does not then add the tag --->
    <cfif not(checkTag.recordCount)>
        <cfquery name="insertTag" datasource="#request.dsnWrite#">
        INSERT into Categories
        (
        categoryname,
        dateCreated
        )
        VALUES
        (
        <cfqueryparam value="#idx#" cfsqltype="cf_sql_varchar">,
        <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">
        )
        </cfquery>

        <cfquery name="insertTag" datasource="#request.dsnWrite#">
        SELECT
            LAST_INSERT_ID() as newID
        FROM
            Categories
        </cfquery>

        <cfset variables.categoryID = insertTag.newID>
    <cfelse>
        <cfset variables.categoryID = checkTag.categoryID>
    </cfif>

    <cftry>
        <!--- Tie the tag to the listing --->
        <cfquery name="insertCategory" datasource="#request.dsnWrite#">
        INSERT into ProductListings_categories
        (
        listingID,
        CategoryID
        )
        VALUES
        (
        <cfqueryparam value="#attributes.listingID#" cfsqltype="cf_sql_bigint">,
        <cfqueryparam value="#variables.categoryID#" cfsqltype="cf_sql_bigint">
        )
        </cfquery>
        <cfcatch></cfcatch>
    </cftry>
</cfloop>

<cflocation url="/sell/add_listing/step/3/listingID/#attributes.listingID#" addtoken="false">

任何见解都会很棒。 谢谢!

这是表单和 Javascript。 我还没有机会重写以前的开发人员的代码(到目前为止,它正在工作,因此不需要首先访问代码),但是没有使用 CFFORM,也没有使用其他CF 表单项。 各种 JS 函数用于 AJAX 调用,也包含在内。

<form action="/sell/add_listing/step/2/listingID/#attributes.listingId#" method="post">
    <div id="formFields"><input name="tagInput" id="tagInput" value="#variables.tagInput#" type="hidden"/></div>

    <h3>Step 2: <span id="instructions">First, choose a top-level category</span></h3>
    <p id="instructions2">This category will show up as the first tag on your listing.</p>

    <div id="tagLand">
        <div>
            1. <select onchange="mainCategorySelector(this.value)">
                <cfloop query="getTopCats">
                <option value="#getTopCats.categoryName#" <cfif ListFirst(variables.tagInput,".") EQ getTopCats.categoryName>selected="selected"</cfif>>#capFirstTitle(ReplaceNoCase(getTopCats.categoryName, "_"," ", "all"))#</option>
                </cfloop>
            </select>
        </div>

        <div id="inputDiv" style="visibility: hidden;">
            <div>Add a tag</div>

            <div>2.
                <input type="text" onkeypress="return disableEnterKey(event)" name="newTag" id="newTag" maxlength="18"/>
                <input type="button" value="add" onclick="addTag(document.getElementById('newTag').value)" class="small_button" />
            </div>

            <div class="error"></div>
        </div>
    </div>

    <a href="/sell/add_listing/step/1/listingID/#attributes.listingId#"><img src="/resources/img/layoutV3/button_prev.gif" alt="prev"/></a>
    <input type="image" name="btnSubmit" src="/resources/img/layoutV3/button_next.gif" />
</form>

<script src="/resources/js/listing_2.js" type="text/javascript"></script>

//some variables
var listCount=1;
var tagLimit=14;
var maxSuggestions=100;
var allTags=new Array();
var allTags=new Array();
var allTagPointers=new Array();
var currentTags=0;

// XML document
var xmlDoc;
var req;

//this function will run anything upon page load
function addLoadEvent(func)
{
    var oldonload = window.onload;
    if (typeof window.onload != 'function')
    {
        if(func)window.onload = func;
    }
    else
    {
        window.onload = function() 
        {
            oldonload();
            func();
        }
    }
}

//let's rebuild the page!
addLoadEvent(rebuildTags());

function rebuildTags()
{
    //grab the tag tree left for us by PHP
    var passedTags=document.getElementById('tagInput').value;

    //only run if we got a value
    if(passedTags.replace(/^\s+|\s+$/g, ""))
    {
        //split the string into an array
        passedTags=passedTags.split(".");

        //run functions to rebuild the world
        mainCategorySelector(passedTags[0]);
        for(var i=1;i<passedTags.length;i++)
        {
            addTag(passedTags[i]);
        }
    }
}

function addTag(tagName)
{
    tagName=trim(tagName);
    tagName=tagName.toLowerCase();
    if(tagName)
    {
        //remove underscores from tags, replace with spaces so we can validate
        tagName=tagName.replace(/_/g," ");

        //clear out error message if it's there
        var errorDiv=document.getElementById('errorDiv');
        errorDiv.innerHTML="";

        //only run if we're not at the limit and tag has not been used already
        if(currentTags<=tagLimit && !getArrayIndex(allTags,tagName))
        {
            //if not alphanumeric, error
            var myRegxp = /^[0-9a-zA-Z\s]*$/;
            if(myRegxp.test(tagName)==false)
            {
                var errorDiv=document.getElementById('errorDiv');
                errorDiv.innerHTML="You may only use letters and numbers in your tags.";
            }
            //if it error checks fine, move on
            else
            {
                //let's replace all spaces with underscores for DB storage
                //tagName=tagName.replace(/ /g,"_");

                //query server and get list of related tags

                //random number to kill the cache
                var cacheKiller=Math.random();
                //get all children tags
                xmlDoc=ajaxRequest("/sell/get_categories_xml/tag/"+tagName.replace(/ /g,"_")+"/random/"+cacheKiller);
                relatedTags=new Array;

                var root=xmlDoc.getElementsByTagName('root')[0];
                var tags=root.getElementsByTagName('tag');

                //now get all sibling tags
                xmlDoc=ajaxRequest("/sell/get_categories_siblings_xml/tag/"+tagName.replace(/ /g,"_")+"/random/"+cacheKiller);
                root=xmlDoc.getElementsByTagName('root')[0];

                var siblingTags=root.getElementsByTagName('tag');

                //first compile child tags into an array
                for(var i=0;(i<tags.length && i<maxSuggestions);i++)
                {
                    relatedTags[i]=tags[i].firstChild.nodeValue;
                }

                //now add sibling tags to the same array
                tags=root.getElementsByTagName('tag');
                for(i;(i<tags.length && i<maxSuggestions);i++)
                {    
                    relatedTags[i]=tags[i].firstChild.nodeValue;
                }


                var tagLand=document.getElementById('tagLand');
                var newNumberDiv=document.createElement('div');
                var newDiv=document.createElement('div');

                //add to counter and master tag array
                listCount++;
                allTags[allTags.length]=tagName.replace(/ /g,"_");
                allTagPointers[allTagPointers.length]=listCount;
                updateForm();

                newNumberDiv.setAttribute('id','number_'+listCount);
                newNumberDiv.className='listing_number';
                newNumberDiv.innerHTML=listCount+".";

                newDiv.innerHTML=tagName+' <span  onclick="removeTag(\''+listCount+'\');" class="list_dynamic_link">x</span>';
                newDiv.className='list_tag';

                var newReccomendDiv=makeRelatedDiv(relatedTags);

                //let's give IDs to all of the new divs so we can't kill 'em later
                newDiv.setAttribute('id','tagDiv'+listCount);
                newReccomendDiv.setAttribute('id','reccomendDiv'+listCount);

                //add new divs to the master list
                tagLand.appendChild(newNumberDiv);
                tagLand.appendChild(newDiv);
                tagLand.appendChild(newReccomendDiv);

                //remove and re-append the input div to keep it at the end
                var inputDiv=document.getElementById('inputDiv');
                tagLand.removeChild(inputDiv);
                tagLand.appendChild(inputDiv);


                //make the inputDiv visible if it is not already
                inputDiv.style.visibility='visible';

                //run the reorderizer 
                reorderizer();

                //clear input field
                document.getElementById('newTag').value="";

                document.getElementById('newTag').focus();
            }
        }
    }
}


//removes a tag from the list -- called through the "x" link on each tag
function removeTag(tagNumber)
{
    //get master div
    var tagLand=document.getElementById('tagLand');

    //get reference to all three divs that make up a tag listing
    var deathRowNumberDiv=document.getElementById('number_'+tagNumber);
    var deathRowTagDiv=document.getElementById('tagDiv'+tagNumber);
    var deathRowReccomendDiv=document.getElementById('reccomendDiv'+tagNumber);

    //any last words, boys?
    tagLand.removeChild(deathRowNumberDiv);
    tagLand.removeChild(deathRowTagDiv);
    tagLand.removeChild(deathRowReccomendDiv);

    //find where we are in the master array
    var tagIndex=getArrayIndex(allTagPointers,tagNumber);
    //splice this tag out of master tag array
    allTags.splice(tagIndex,1);
    allTagPointers.splice(tagIndex,1);
    updateForm();

    //alert(allTags.join("."));

    //since we just changed the page structure, let's run reorderizer
    //run the reorderizer 
    reorderizer();

    //make the inputDiv visible if we're below the tag limit
    var inputDiv=document.getElementById('inputDiv');
    if(currentTags<=tagLimit)
    {
        inputDiv.style.visibility='visible';
    }
}


//this function displays the formatted div for related tags
function makeRelatedDiv(relatedTags)
{
    //let's prepare the recommended tags div
    var newReccomendDiv=document.createElement('div');
    newReccomendDiv.className='list_suggested_tags';
    newReccomendDiv.innerHTML='<span>Add related tags: </span> ';
    var numTags=0;

    //loop through suggested tag array
    for ( keyVar in relatedTags )
    {
        //add comma if necessary
        if(numTags)
        {
            newReccomendDiv.innerHTML+=", ";
        }
        newReccomendDiv.innerHTML+='<span  onclick="addTag(\''+relatedTags[keyVar]+'\');" class="list_dynamic_link">'+relatedTags[keyVar]+'</span>';
        numTags++;
    }

    return newReccomendDiv;
}


function mainCategorySelector(tag)
{
    //only run if we're not the dead selection
    if(tag!="- - -")
    {
        //query server and get list of related tags

        //random number to kill the cache
        var cacheKiller=Math.random();
        xmlDoc=ajaxRequest("/sell/get_categories_xml/tag/"+tag+"/random/"+cacheKiller);

        relatedTags=new Array;

        var root=xmlDoc.getElementsByTagName('root')[0];
        var tags=root.getElementsByTagName('tag');

        for(var i=0;(i<tags.length && i<maxSuggestions);i++)
        {
            relatedTags[i]=tags[i].firstChild.nodeValue;
        }

        var tagLand=document.getElementById('tagLand');

        var newReccomendDiv=makeRelatedDiv(relatedTags);

        //replace old reccomend list if it exists
        if(document.getElementById('mainCategoryReccomendations'))
        {
            var mainCategoryReccomendations=document.getElementById('mainCategoryReccomendations');
            tagLand.appendChild(newReccomendDiv);
            tagLand.insertBefore(newReccomendDiv , mainCategoryReccomendations);
            tagLand.removeChild(mainCategoryReccomendations);
        }
        else
        {
            tagLand.appendChild(newReccomendDiv);
            //add to counter if we added a new tag
            listCount++;
        }

        newReccomendDiv.setAttribute('id' , 'mainCategoryReccomendations');

        //alert(allTags.join("."));

        //add master tag array    
        allTags[0]=tag;
        allTagPointers[0]=1;
        updateForm()

        //alert(allTags.join("."));

        //remove and re-append the input div to keep it at the end
        var inputDiv=document.getElementById('inputDiv');
        tagLand.removeChild(inputDiv);
        tagLand.appendChild(inputDiv);

        //make the inputDiv visible if we're below the tag limit
        if(currentTags<=tagLimit)
        {
            inputDiv.style.visibility='visible';

            //focus on the new field
            document.getElementById('newTag').focus();
        }

        //change up the instructions
        changeInstructions("Now, add other tags to sort your listing","You can either click the related tags or enter your own")
    }
}

//this function changes the content of the instructional div
function changeInstructions(top, bottom)
{
    var instructions=document.getElementById('instructions');
    var instructions2=document.getElementById('instructions2');
    instructions.innerHTML=top;
    instructions2.innerHTML=bottom;
}

//this function reassigns all list numbers to their proper value
function reorderizer()
{
    /*
    Here we run through all number div IDs...
    remember, the div ID number may not match the display number, due to 
    additions/removals. That's why we have a separate variable for displayNumber!
    */

    var tagLand=document.getElementById('tagLand');

    //another counting var, for the actual display number
    var displayNumber=1;

    for(var i=1; i <= listCount; i++)
    {
        if(document.getElementById('number_'+i))
        {
            var b=document.getElementById('number_'+i);
            b.innerHTML=displayNumber+".";

            //ony increment displayNumber if we've actually printed a number
            displayNumber++;
        }
    }

    //update global tag count to most current and accurate number
    currentTags=displayNumber;

    //have we hit the tag limit? If so, hidezorz input
    if(displayNumber>tagLimit)
    {
        var inputDiv=document.getElementById('inputDiv');
        inputDiv.style.visibility='hidden';
    }
    else
    {
        //after looping through dynamic list entries, let's change the submit field's number too
        var number_last=document.getElementById('number_last');
        if(number_last)
        {
            number_last.innerHTML=displayNumber+".";
        }
    }
}

function pausecomp(millis) 
{
    date = new Date();
    var curDate = null;

    do { var curDate = new Date(); } 
    while(curDate-date < millis);
}

function ajaxRequest(requestURL)
{
    var req;
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
    }

    req.open("GET", requestURL, false);
    req.send(null);
    var xmlDocument = req.responseXML;
    return(xmlDocument);
}

function disableEnterKey(e)
{
    var key;

    if(window.event)
        key = window.event.keyCode;     //IE
    else
        key = e.which;     //firefox

    if(key == 13)
    {
        addTag(document.getElementById('newTag').value);
        return false;
    }
    else
    {
        return true;
    }
}


function getArrayIndex(arr, val) 
{
    for (i = 0; i < arr.length; i++) 
    {
        if (arr[i] == val) { return i; }
    }
}

function updateForm()
{
    //this function updates the hidden field that will actually send the tag data upon form submission
    document.getElementById('tagInput').value=allTags.join(".");
}

I get this error when posting a form. The strangest thing, though, is that this error only occurs in Chrome and Safari. FF, IE and Opera all post the form without a problem.

The Stack Trace does not point to a file to where this error occurs. A cfdump of cfcatch gives me some insight as to what the problem is, but I can't find any instance of where the problem actually exists. Here's the partial dump:

Column     1
Detail     The variable attributes. ends with a "." character. You must supply an additional structure key or delete the "." character.
KnownColumn  -1
KnownLine   -1
KnownText   "unknown"
Line         1
Message   A CFML variable name cannot end with a "." character.

Here's the code handling the posted data. Everything is wrapped inside cftransaction and there's a loop, not sure why it's not being displayed. (thanks Peter Boughton for clearing that up)

<!--- Delete out the old category ties --->
<cfquery name="deleteCategory" datasource="#request.dsnWrite#">
DELETE FROM
    ProductListings_categories
WHERE
    listingID = <cfqueryparam value="#attributes.listingID#">
</cfquery>

<!--- Loop through the list --->
<cfloop list="#attributes.taginput#" index="idx" delimiters=".">

<!--- check to see if tag exists --->
    <cfquery name="checkTag" datasource="#request.dsnWrite#">
    SELECT
        categoryID
    FROM
        categories
    WHERE
        CategoryName = <cfqueryparam value="#idx#" cfsqltype="cf_sql_varchar">
    </cfquery>

    <!--- If it does not then add the tag --->
    <cfif not(checkTag.recordCount)>
        <cfquery name="insertTag" datasource="#request.dsnWrite#">
        INSERT into Categories
        (
        categoryname,
        dateCreated
        )
        VALUES
        (
        <cfqueryparam value="#idx#" cfsqltype="cf_sql_varchar">,
        <cfqueryparam value="#now()#" cfsqltype="cf_sql_timestamp">
        )
        </cfquery>

        <cfquery name="insertTag" datasource="#request.dsnWrite#">
        SELECT
            LAST_INSERT_ID() as newID
        FROM
            Categories
        </cfquery>

        <cfset variables.categoryID = insertTag.newID>
    <cfelse>
        <cfset variables.categoryID = checkTag.categoryID>
    </cfif>

    <cftry>
        <!--- Tie the tag to the listing --->
        <cfquery name="insertCategory" datasource="#request.dsnWrite#">
        INSERT into ProductListings_categories
        (
        listingID,
        CategoryID
        )
        VALUES
        (
        <cfqueryparam value="#attributes.listingID#" cfsqltype="cf_sql_bigint">,
        <cfqueryparam value="#variables.categoryID#" cfsqltype="cf_sql_bigint">
        )
        </cfquery>
        <cfcatch></cfcatch>
    </cftry>
</cfloop>

<cflocation url="/sell/add_listing/step/3/listingID/#attributes.listingID#" addtoken="false">

Any insight would be great. Thanks!

Here's the form and the Javascript. I haven't had a chance to rewrite the code by the previous developer (up until this point, it was working, so there was no need to visit the code in the first place), but CFFORM isn't used, nor are other CF form items. Various JS functions are used for AJAX calls and are included as well.

<form action="/sell/add_listing/step/2/listingID/#attributes.listingId#" method="post">
    <div id="formFields"><input name="tagInput" id="tagInput" value="#variables.tagInput#" type="hidden"/></div>

    <h3>Step 2: <span id="instructions">First, choose a top-level category</span></h3>
    <p id="instructions2">This category will show up as the first tag on your listing.</p>

    <div id="tagLand">
        <div>
            1. <select onchange="mainCategorySelector(this.value)">
                <cfloop query="getTopCats">
                <option value="#getTopCats.categoryName#" <cfif ListFirst(variables.tagInput,".") EQ getTopCats.categoryName>selected="selected"</cfif>>#capFirstTitle(ReplaceNoCase(getTopCats.categoryName, "_"," ", "all"))#</option>
                </cfloop>
            </select>
        </div>

        <div id="inputDiv" style="visibility: hidden;">
            <div>Add a tag</div>

            <div>2.
                <input type="text" onkeypress="return disableEnterKey(event)" name="newTag" id="newTag" maxlength="18"/>
                <input type="button" value="add" onclick="addTag(document.getElementById('newTag').value)" class="small_button" />
            </div>

            <div class="error"></div>
        </div>
    </div>

    <a href="/sell/add_listing/step/1/listingID/#attributes.listingId#"><img src="/resources/img/layoutV3/button_prev.gif" alt="prev"/></a>
    <input type="image" name="btnSubmit" src="/resources/img/layoutV3/button_next.gif" />
</form>

<script src="/resources/js/listing_2.js" type="text/javascript"></script>

//some variables
var listCount=1;
var tagLimit=14;
var maxSuggestions=100;
var allTags=new Array();
var allTags=new Array();
var allTagPointers=new Array();
var currentTags=0;

// XML document
var xmlDoc;
var req;

//this function will run anything upon page load
function addLoadEvent(func)
{
    var oldonload = window.onload;
    if (typeof window.onload != 'function')
    {
        if(func)window.onload = func;
    }
    else
    {
        window.onload = function() 
        {
            oldonload();
            func();
        }
    }
}

//let's rebuild the page!
addLoadEvent(rebuildTags());

function rebuildTags()
{
    //grab the tag tree left for us by PHP
    var passedTags=document.getElementById('tagInput').value;

    //only run if we got a value
    if(passedTags.replace(/^\s+|\s+$/g, ""))
    {
        //split the string into an array
        passedTags=passedTags.split(".");

        //run functions to rebuild the world
        mainCategorySelector(passedTags[0]);
        for(var i=1;i<passedTags.length;i++)
        {
            addTag(passedTags[i]);
        }
    }
}

function addTag(tagName)
{
    tagName=trim(tagName);
    tagName=tagName.toLowerCase();
    if(tagName)
    {
        //remove underscores from tags, replace with spaces so we can validate
        tagName=tagName.replace(/_/g," ");

        //clear out error message if it's there
        var errorDiv=document.getElementById('errorDiv');
        errorDiv.innerHTML="";

        //only run if we're not at the limit and tag has not been used already
        if(currentTags<=tagLimit && !getArrayIndex(allTags,tagName))
        {
            //if not alphanumeric, error
            var myRegxp = /^[0-9a-zA-Z\s]*$/;
            if(myRegxp.test(tagName)==false)
            {
                var errorDiv=document.getElementById('errorDiv');
                errorDiv.innerHTML="You may only use letters and numbers in your tags.";
            }
            //if it error checks fine, move on
            else
            {
                //let's replace all spaces with underscores for DB storage
                //tagName=tagName.replace(/ /g,"_");

                //query server and get list of related tags

                //random number to kill the cache
                var cacheKiller=Math.random();
                //get all children tags
                xmlDoc=ajaxRequest("/sell/get_categories_xml/tag/"+tagName.replace(/ /g,"_")+"/random/"+cacheKiller);
                relatedTags=new Array;

                var root=xmlDoc.getElementsByTagName('root')[0];
                var tags=root.getElementsByTagName('tag');

                //now get all sibling tags
                xmlDoc=ajaxRequest("/sell/get_categories_siblings_xml/tag/"+tagName.replace(/ /g,"_")+"/random/"+cacheKiller);
                root=xmlDoc.getElementsByTagName('root')[0];

                var siblingTags=root.getElementsByTagName('tag');

                //first compile child tags into an array
                for(var i=0;(i<tags.length && i<maxSuggestions);i++)
                {
                    relatedTags[i]=tags[i].firstChild.nodeValue;
                }

                //now add sibling tags to the same array
                tags=root.getElementsByTagName('tag');
                for(i;(i<tags.length && i<maxSuggestions);i++)
                {    
                    relatedTags[i]=tags[i].firstChild.nodeValue;
                }


                var tagLand=document.getElementById('tagLand');
                var newNumberDiv=document.createElement('div');
                var newDiv=document.createElement('div');

                //add to counter and master tag array
                listCount++;
                allTags[allTags.length]=tagName.replace(/ /g,"_");
                allTagPointers[allTagPointers.length]=listCount;
                updateForm();

                newNumberDiv.setAttribute('id','number_'+listCount);
                newNumberDiv.className='listing_number';
                newNumberDiv.innerHTML=listCount+".";

                newDiv.innerHTML=tagName+' <span  onclick="removeTag(\''+listCount+'\');" class="list_dynamic_link">x</span>';
                newDiv.className='list_tag';

                var newReccomendDiv=makeRelatedDiv(relatedTags);

                //let's give IDs to all of the new divs so we can't kill 'em later
                newDiv.setAttribute('id','tagDiv'+listCount);
                newReccomendDiv.setAttribute('id','reccomendDiv'+listCount);

                //add new divs to the master list
                tagLand.appendChild(newNumberDiv);
                tagLand.appendChild(newDiv);
                tagLand.appendChild(newReccomendDiv);

                //remove and re-append the input div to keep it at the end
                var inputDiv=document.getElementById('inputDiv');
                tagLand.removeChild(inputDiv);
                tagLand.appendChild(inputDiv);


                //make the inputDiv visible if it is not already
                inputDiv.style.visibility='visible';

                //run the reorderizer 
                reorderizer();

                //clear input field
                document.getElementById('newTag').value="";

                document.getElementById('newTag').focus();
            }
        }
    }
}


//removes a tag from the list -- called through the "x" link on each tag
function removeTag(tagNumber)
{
    //get master div
    var tagLand=document.getElementById('tagLand');

    //get reference to all three divs that make up a tag listing
    var deathRowNumberDiv=document.getElementById('number_'+tagNumber);
    var deathRowTagDiv=document.getElementById('tagDiv'+tagNumber);
    var deathRowReccomendDiv=document.getElementById('reccomendDiv'+tagNumber);

    //any last words, boys?
    tagLand.removeChild(deathRowNumberDiv);
    tagLand.removeChild(deathRowTagDiv);
    tagLand.removeChild(deathRowReccomendDiv);

    //find where we are in the master array
    var tagIndex=getArrayIndex(allTagPointers,tagNumber);
    //splice this tag out of master tag array
    allTags.splice(tagIndex,1);
    allTagPointers.splice(tagIndex,1);
    updateForm();

    //alert(allTags.join("."));

    //since we just changed the page structure, let's run reorderizer
    //run the reorderizer 
    reorderizer();

    //make the inputDiv visible if we're below the tag limit
    var inputDiv=document.getElementById('inputDiv');
    if(currentTags<=tagLimit)
    {
        inputDiv.style.visibility='visible';
    }
}


//this function displays the formatted div for related tags
function makeRelatedDiv(relatedTags)
{
    //let's prepare the recommended tags div
    var newReccomendDiv=document.createElement('div');
    newReccomendDiv.className='list_suggested_tags';
    newReccomendDiv.innerHTML='<span>Add related tags: </span> ';
    var numTags=0;

    //loop through suggested tag array
    for ( keyVar in relatedTags )
    {
        //add comma if necessary
        if(numTags)
        {
            newReccomendDiv.innerHTML+=", ";
        }
        newReccomendDiv.innerHTML+='<span  onclick="addTag(\''+relatedTags[keyVar]+'\');" class="list_dynamic_link">'+relatedTags[keyVar]+'</span>';
        numTags++;
    }

    return newReccomendDiv;
}


function mainCategorySelector(tag)
{
    //only run if we're not the dead selection
    if(tag!="- - -")
    {
        //query server and get list of related tags

        //random number to kill the cache
        var cacheKiller=Math.random();
        xmlDoc=ajaxRequest("/sell/get_categories_xml/tag/"+tag+"/random/"+cacheKiller);

        relatedTags=new Array;

        var root=xmlDoc.getElementsByTagName('root')[0];
        var tags=root.getElementsByTagName('tag');

        for(var i=0;(i<tags.length && i<maxSuggestions);i++)
        {
            relatedTags[i]=tags[i].firstChild.nodeValue;
        }

        var tagLand=document.getElementById('tagLand');

        var newReccomendDiv=makeRelatedDiv(relatedTags);

        //replace old reccomend list if it exists
        if(document.getElementById('mainCategoryReccomendations'))
        {
            var mainCategoryReccomendations=document.getElementById('mainCategoryReccomendations');
            tagLand.appendChild(newReccomendDiv);
            tagLand.insertBefore(newReccomendDiv , mainCategoryReccomendations);
            tagLand.removeChild(mainCategoryReccomendations);
        }
        else
        {
            tagLand.appendChild(newReccomendDiv);
            //add to counter if we added a new tag
            listCount++;
        }

        newReccomendDiv.setAttribute('id' , 'mainCategoryReccomendations');

        //alert(allTags.join("."));

        //add master tag array    
        allTags[0]=tag;
        allTagPointers[0]=1;
        updateForm()

        //alert(allTags.join("."));

        //remove and re-append the input div to keep it at the end
        var inputDiv=document.getElementById('inputDiv');
        tagLand.removeChild(inputDiv);
        tagLand.appendChild(inputDiv);

        //make the inputDiv visible if we're below the tag limit
        if(currentTags<=tagLimit)
        {
            inputDiv.style.visibility='visible';

            //focus on the new field
            document.getElementById('newTag').focus();
        }

        //change up the instructions
        changeInstructions("Now, add other tags to sort your listing","You can either click the related tags or enter your own")
    }
}

//this function changes the content of the instructional div
function changeInstructions(top, bottom)
{
    var instructions=document.getElementById('instructions');
    var instructions2=document.getElementById('instructions2');
    instructions.innerHTML=top;
    instructions2.innerHTML=bottom;
}

//this function reassigns all list numbers to their proper value
function reorderizer()
{
    /*
    Here we run through all number div IDs...
    remember, the div ID number may not match the display number, due to 
    additions/removals. That's why we have a separate variable for displayNumber!
    */

    var tagLand=document.getElementById('tagLand');

    //another counting var, for the actual display number
    var displayNumber=1;

    for(var i=1; i <= listCount; i++)
    {
        if(document.getElementById('number_'+i))
        {
            var b=document.getElementById('number_'+i);
            b.innerHTML=displayNumber+".";

            //ony increment displayNumber if we've actually printed a number
            displayNumber++;
        }
    }

    //update global tag count to most current and accurate number
    currentTags=displayNumber;

    //have we hit the tag limit? If so, hidezorz input
    if(displayNumber>tagLimit)
    {
        var inputDiv=document.getElementById('inputDiv');
        inputDiv.style.visibility='hidden';
    }
    else
    {
        //after looping through dynamic list entries, let's change the submit field's number too
        var number_last=document.getElementById('number_last');
        if(number_last)
        {
            number_last.innerHTML=displayNumber+".";
        }
    }
}

function pausecomp(millis) 
{
    date = new Date();
    var curDate = null;

    do { var curDate = new Date(); } 
    while(curDate-date < millis);
}

function ajaxRequest(requestURL)
{
    var req;
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
    }

    req.open("GET", requestURL, false);
    req.send(null);
    var xmlDocument = req.responseXML;
    return(xmlDocument);
}

function disableEnterKey(e)
{
    var key;

    if(window.event)
        key = window.event.keyCode;     //IE
    else
        key = e.which;     //firefox

    if(key == 13)
    {
        addTag(document.getElementById('newTag').value);
        return false;
    }
    else
    {
        return true;
    }
}


function getArrayIndex(arr, val) 
{
    for (i = 0; i < arr.length; i++) 
    {
        if (arr[i] == val) { return i; }
    }
}

function updateForm()
{
    //this function updates the hidden field that will actually send the tag data upon form submission
    document.getElementById('tagInput').value=allTags.join(".");
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

云裳 2024-07-24 03:05:56

问题已解决:选择列表没有定义 name 属性,因此,attributes 变量的字段名称为空,从而导致错误。 就我而言,CF 中没有使用选择列表,而仅在 JS 中使用。 即使字段缺少名称,Chrome 和 Safari 也会传递字段的值,而 IE、FF 和 Opera 则不会。 感谢您引导我走向正确的方向。

Problem solved: select list did not have the name attribute defined, and as a result, the attributes variable did have a null field name, causing the error. In my case, the select list is not used in CF, but only in JS. Chrome and Safari will pass a field's value even if the field lacks a name, while IE, FF and Opera do not. Thanks for guiding me in the right direction.

梅窗月明清似水 2024-07-24 03:05:56

从您的描述来看,该错误似乎是由客户端中的表单本身引发的,而不是您上面发布的处理代码。 如果调用页面上有 cfform/cfgrid,您可能需要查看 CF 生成的 Javascript 并针对 Chrome/Safari 进行测试。

From your description it sounds like that the error is thrown by the form itself in the client, and not the handling code that you've posted above. If you have a cfform/cfgrid on the calling page, you may want to look at the Javascript that's generated by CF and test it against Chrome/Safari.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文