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

时间:2009-04-22 22:25:03

标签: coldfusion fusebox

发布表单时出现此错误。但最奇怪的是,此错误仅发生在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中,并且有一个循环,不知道为什么它没有被显示。 (感谢Peter Boughton清理它)

<!--- 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(".");
}

2 个答案:

答案 0 :(得分:3)

问题已解决:选择列表没有定义name属性,因此,属性变量确实有一个空字段名称,从而导致错误。在我的例子中,选择列表不在CF中使用,而只在JS中使用。即使字段缺少名称,Chrome和Safari也会传递字段的值,而IE,FF和Opera则不会。感谢您指导我朝着正确的方向前进。

答案 1 :(得分:2)

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