I would answer, but looks like you're already being helped on the adobe forums :P
I would answer, but looks like you're already being helped on the adobe forums :P
... or it makes you "smart", me "smarter" and them "friggin geniuses". It's all in the spin ;-)
I actually went to houseoffusion.com
Smarter brains than mine live there. So hopefully you'll have better luck. lol
Btw ... if you're going to open another question on this, I'd suggest including *exactly* what you happen, with specific variable and field names, etc.. Don't make the reader guess ;-)
If I knew more jquery I'd say change it make the field names unique. Then you could process it easily as product1,product2, etc.. But that's beyond my skills for now ;)
Yeah, there's an art to asking a "good" question. I'm fine with small stuff. But I really suck asking about big conceptual stuff. lol. Usually people have no clue what I mean. Some people are amazing at it. Their descriptions simple and concise. They get great answers ... when I couldn't even form the question...let alone the answer. lol
Well I tried that.,...I think...lol. I clicked the ajax function button which outputted the "list" as needed, but then when I click my page submit button, I still got a data undefined error.
Right. Because that variable doesn't exist... The ajax function and your <form> *don't* send the same data the same way
Ajax uses-> URL scope
Your <form> uses-> FORM scope
Ajax sends a complex structure -> URL.data[ItemName].vendorName ...etc...
Your <form> sends simple strings -> FORM.vendor, FORM.product, etc..
ie exactly what's in your <form>
<input type="text" class="vendor-input" name="vendor" />
<input type="text" class="product-input" name="product" />
You can't just plug the ajax into a larger <form>, POST it have it work right out of the box. You won't get an error, but your code isn't set up to handle it. It's something you have to add.
At this point I'm totally lost ;-/ ... I thought you were trying to do a simple preview of JUST the vendor/product stuff. But it's starting to sound like much more than that ... There's a lotta stuff on that page you linked. If you're trying to incorporate this section (vendors/products) with that whole big form .. you've got your work cut out for you. I'm sure it's possible, but it's beyond my skills. And with my brain mainly focused on my work, I've kinda lost track of what you're trying to do at this point ;-)
Now one thing I will mention is that I have other form elements on this page.
Yeah, but they're not inside the same <form> right? So you could process that form data separately, like have a "preview" and "submit" button for just that form.
You shouldn't need a query. Just use string functions as you loop through #GetFiles#. Either use left() to get X characters, or if there's always a space after the client name, use list functions. Then grab the file extension and create the new file name
<!-- split for readability --->
<cfset clientName = listFirst("abc xxxxx.pdf", " ")>
<cfset ext = listLast("abc xxxxx.pdf", ".")>
<cfset theDate = DateFormat(DateAdd('d', -1, MyDateTime),'mmmm dd, yyyy'))>
<cfset newName = theDate & clientName &"."& ext>
It should never run across a file that already exist as it uses the date as part of the file name when it renamed. And if it does it will make it unique when it renames
Well date alone isn't as unique as date + timestamp. As far as renaming, it'll overwrite any existing file. If you don't want that, you have to handle the making it unique yourself.
It's doable with string and date functions. But do the files always follow a standard pattern
ie file name = {clientName}_xxxxxx.pdf?
In your example they don't. abc_activity.pdf and client ABCInc. Also, if the file name already exists in the client directory, how do you want to handle it?
Your question's a little confusing. What's your real goal in plain english, not code? To identify files by client, or somethin else ...?
Also, what is a #Property# in this context?
lol. I didn't mean to sound like you don't know how ajax works. Just that you weren't using the form as it was intended to work. ie You were using a submit button to do a plain form post the old way. Instead of a plain button to do an ajax call (method=get) and display the content on the same page.
So, why then couldnt I take the code...jquery/ajax...out of that page, paste it into my template, using the same builderAction.cfm "action" within the ajax function, and display it that way.
Sorry .. I'm brain dead today. Not sure what you mean by template. ie Are you talking about having everything (jquery and action) on the same page? That should work as long as you structure it correctly.
Your choice. I think you're totally misunderstanding how the example's supposed to work, lol. Forget about the code for a sec and think about what the 2 pieces of code are doing conceptually.
You're trying to do it old style
page1.cfm => go to => page2.cfm to see preview
The whole point of ajax is to avoid leaving the page. So users can see preview changes quickly, and you don't have to worry about maintaining the state form page to page. Technically you still send data to page2.cfm. But you display the results on the original page. It's no more complex than updating the content of an element with javascript.
document.getElement('myDiv').innerHTML = "See I just changed the content!";
Well think about it :) Your code isn't doing the same thing as the example. The example sends data via ajax and displays the results w/out even leaving the current page. You're doing a form post, which obviously leaves the page. Not to mention sends the data in the FORM, not URL, scope. So obviously the sample code won't work.
I've no idea what your final code looks like. So I'm not sure what to suggest :)
It's actually pretty easy. Just deserialize the results.
<cfset results = deserializeJSON(url.data)>
Each "item" is a structure. They "key" is the item name, and the "value" are the details (category, vendors, etc..). So loop through it like in the sitepoint article.
<cfloop collection="#results#" item="itemName">
<cfset item = results[itemName]>
<cfdump var="#item#" label="Item Name #itemName#">
</cfloop>
If you look at the dump of each "item", that structure contains 2 keys: "category" and "vendors". Category name is a simple string you can access using #item.category#
Now "Vendors" is another structure. The "key" is a vendor name and the "value" is an array of products. To extract the values, loop through it the same way
<cfloop ....>
...
<cfloop collection="#item.vendors#" item="vendorName">
<cfset productArray = item.vendors[vendorName]>
<cfdump var="#productArray #" label="Products for vendor: #vendorName#">
</cfloop>
...
</cfloop>
Then loop through the product array to get each value. For CF8+ it's a simple "array" loop
....
<cfloop array="#productArray #" index="productName">
...do something with #productName#....
</cfloop>
....
Obviously you have to *do* something with the values. But now that you see how to extract them, the rest is easy.
Hey, I just tried it .. and that's a fantastic example! I'm not smart enough to write it, but it's great. Everything's organized into a structures and arrays. Just loop through it and extract what you need.
lol. The confusion is spreading ;-)
But I guess I took his response as him being highminded. I said I wasnt mad, and I'm not, but just felt like if someone tells you your doing something wrong and then offers some code for you to "use", then they ought to be willing to help you further long if you've already said "it's over my head".
Yeah, but you have to articulate "what specifically" you need help with :-) ie "I've tried X code and expected Y results. But instead I'm getting Z results." Otherwise people don't know how to answer you. Or worse it sounds like saying "write the code for me". I admit the guy was definitely blunt. But I don't think he was trying to be a jerk. Otherwise, he wouldn't have bothered putting together a custom example for you in the first place :-)
I'm not a jquery guru. So I don't completely understand his sample either. But if it were me, I'd run the example and post it to an action page. Then dump the results and go from there. If it's just structures and arrays, which I think it is, it might not be so bad and I might actually be able to help!
I hope you didn't take my remarks the wrong way. I just didn't have a clue where to begin with your question on the other forum. As strange as it sounds, it was as overwhelming to me as jquery probably is to you right now ;-)
Yeah, I saw that thread. Being fair that's not what he was saying :P I think the questions were just to broad/ambiguous to be answered. I know some of the background, and even I was intimidated by the sheer scope of it ;-) No joke, I wasn't even sure what the question was .. let alone where to begin trying to answer it.
I think we both love learning and teaching. But there's only so much you can do in a forum post. Forums are good for small, specific questions. Broad comments like "how do I make it work" or "tried everything, and nothing works" aren't questions that can be answered. They just sound like someone is asking others to write the code for them. I know that not's what you were doing. I'm just trying to explain why they responded the way they did. I think if you'd tried the code, and come back with a specific problem (however small), the response would have been better.
1) <cfset myBook.author = "Teed Younger">
... or ....
2) <cfset myBook["author"] = "Teed Younger">
Personally, I prefer syntax 1 (dot notation). Either is okay unless your key name isn't a valid variable name. Like it has spaces or dashes in it ie myBook["some-author"]. Then you must use syntax 2.
Figures the back slashes are actually in the code. lol. That one must have gotten past the editor.
Yeah, the article is definitely outdated. Most of it still applies. But StructInsert isn't as commonly used now as it was in 2003 Nowadays most people just use array notation. Simpler and more intuitive.
For the lazy, there's even shortcuts in CF8+. So instead of doing
<cfset myBook = structNew()>
<cfset myBook.publishYear = "2005">
<cfset myBook.ISBN= "ABCD123456">
You can do it all in one line
<cfset myBook = {publishYear = "2005", ISBN= "ABCD123456"}>
But it's mostly personal preference. For long structures, the line by line approach is perfectly fine.
Btw, where is this tutorial? It sounds outdated.
I followed the code exactly
I hope not ... because that code is wrong :) Two things are messing it up
1) Assuming the \\ is not a typo. Get rid of them.
2) The function is StructInsert ... not StructureInsert
But that function isn't used as much as it used to be. Most times it's simpler to just use array notion. That's my preference. But all of these are valid
<cfset StructInsert(myBook, "author", "Teed Younger", true)>
... or ....
<cfset myBook.author = "Teed Younger">
... or ....
<cfset myBook["author"] = "Teed Younger">
<cfset a = StructureInsert(myBook, "author", "Teed Younger", 1)>
It's not the cause of the error, but there's no need to capture the result if you're not using it.
<cfset StructInsert(myBook, "author", "Teed Younger", true)>
Whether you trash the existing code or not is up to you. I suspect their point was that doing all this parsing and html coding manually is... well somewhat unusual ;-)
Not separately. I've only used a few cftextarea's which have the editor baked in. It'd probably be easier than trying to write the your own page builder. But your best bet is to try it out. See how well it fits in w/your app.
I guess what I would need would be a way to tell the code that here is the beginning of a heading tag word(or new list basically)
Yup. I suppose you could assume the 1st line is always a header, and every other line is a "detail" line. But like the previous method, it's only as solid as the data ;-)
There's one potential problem though. If the "detail" line doesn't have at least 1 "|", there'd be no way to distinguish it from the produce name headers
ie
Product Name
33244
Second Product Name
33990
If every line has a hard carriage return at the end, that code won't work. The only way I can think of is to split the values on the carriage return, then check for a "|". If the line contains a "|" then it's NOT a header. Does that make sense?
<h3>Cross References</h3>
<cfoutput>
<cfloop index="brandGroup" list="#FORM.crossRefList#" delimiters="#chr(13)##chr(10)#">
<!--- header --->
<cfif NOT find("|", brandGroup)>
<h3>#brandGroup#</h3>
<!--- detail line --->
<cfelse>
<ul>
<cfloop index="productGroup" list="#brandGroup#" delimiters="|">
<li>#productGroup#</li>
</cfloop>
</ul>
</cfif>
</cfloop>
</cfoutput>
Got some good help at adobe forums...lol
... among others ;-)
Maybe it's lack of caffeine. But I've read the question twice and still don't understand what the data looks like. Could you give a sample of
A) the values you're using (FORM.crossRefList, SESSION.crossRefList, productGroup)
B) what the output SHOULD look like?
<cfloop index="productGroup" list="#listLast([/b]productGroup[/b],";")#" delimiters=";">
It's probably not a good idea to reuse the same name for your index variable.
lol. That's one of my favorite expressions: "Make it idiot proof and they'll make a better idiot." ;-)
Don't you hate it when programs try to be "helpful" ;-)
A windows shortcut? Just go to Desktop > right click > New > Shortcut and enter the url.
Also, I was asking about what happens when you run the SQL directly in your db, *not* using cfquery. Using your IDE (Management Studio, etc..) you can easily view what tables and column exist.
The error message is pretty clear. The db can't find the object (ie Table) "Language". Run the query against directly against your db in MS SQL. Does it work?
Found the code on another site. It's this:
<cfmail to="#Form.Email#" [B]from=""[/B] subject="Blah Blah - New Account Confirmation" type="html">
The FROM address shouldn't be blank. Most mail servers would probably reject it anyway. Just put a valid email address in there.
Attribute validation error for CFMAIL.
The value of the FROM attribute is invalid. The length of the string, 0 character(s), must be greater than or equal to 1 character(s).
It's an error from cfmail. It's just saying the sender address cannot be empty. Where in your code are you using CFMAIL?
It'll work. But cfschedule takes some getting used to. I'd start out slow. Just create a small task that writes something to a log file first. Once you know it's working you can plug in your real page (after testing it separately of course).
Sounds like a good job for a scheduled task. Just create a cfm page that queries your db for the desired records. Then send a cfmail to each one. Once the page is set up, create a scheduled task using the CF Administrator, or cfschedule. Schedule the task to run your cfm script daily (or however frequently you need).
Grab it from the #CFFILE# scope. After you do a CFFILE upload, that scope will contain all kinds of information about the uploaded file like: cffile.serverFile, cffile.serverFileExt, etc..
See the reference docs for a full list
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-738f.html
... or just cfdump the whole scope after your upload. So you can see examples of all of the values :-)
<cffile action="upload" ...>
<cfdump var="#CFFILE#">
You mean store the file content in the db, not just the file path (ie "c:\path\myImage.gif")? While you can do it, it can drastically bloat your database. But if you really want to do it, here is an example. It's for Oracle but the overall process is the same for any db.
http://awads.net/wp/2006/01/25/savingdownloading-files-tofrom-oracle-using-coldfusion/
Just upload the file as usual ie using <cffile action="upload" ...>. But instead of storing the file path, you read the *contents* of the file into a variable. Then insert the variable's binary data into the database instead of the path. When you're done, you can delete the uploaded file.
<cffile action="readBinary"
file="#cffile.serverDirectory#/#cffile.serverFile#"
variable="fileContents">
<cfquery name="addFile" ....>
INSERT INTO Table ( FileName )
VALUES (
<cfqueryparam value="#fileContents#" cfsqltype="cf_sql_blob">
)
</cfquery>
<!--- once done, delete the physic. file --->
<cffile action="delete"
file="#cffile.serverDirectory#/#cffile.serverFile#" >
Retrieving the file from the db is the same as any SELECT. Just retrieve the record, and use CFCONTENT, with the proper mime type to display it in the browser. If you need any help with that part, just let me know.
One thing to watch out for is your CF datasource settings. If you have files that bigger than 64K, CF will only return the 1st 64K bytes unless you enabled the "BLOB" setting in your datasource.
http://awads.net/wp/2006/02/21/lobs-gotcha-in-coldfusion/
CF has a built in tag for that. You can use cfzip with a "source" directory
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7695.html
The problem is dynamic sql. Save yourself some headaches and don't use dynamic sql. It's never as easy as it looks ;-) Plus it's hard to debug and is a big sql injection risk if done wrong ...
But .. it doesn't look like you even need to return the query. You can just return the count. But dont' forget to VAR your cfquery's and use cfqueryparam
...
<cfset var qry = "">
<cfquery name="qry" ...>
SELECT count(status) AS Result
FROM table
WHERE status = <cfqueryparam value="#arguments.status#" cfsqltype="cf_sql_varchar">
</cfquery>
<cfreturn qry.Result>
...
I didnt know why it has 3 apostrophes
CF escapes single quotes to protect you from sql injection. The only way around it is to use PreserveSingleQuotes(). But then you're at risk for sql injection. Since you don't seem to need dynamic sql anyway, my advice is to avoid it altogether.
I don't know about onRequestEnd.CFM. But with Application.cfc the "targetPage" is passed into the onRequestEnd function. You could use string functions to determine if you should include the analytics. Maybe onRequestEnd.cfm has something similar?
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d42.html
What part? :) Ignoring the startrow/maxRow part, it's just saying "do something every 5th row". Try it with a plain cfoutput and you'll see how easy it is.
<table>
<tr>
<cfoutput query="someQuery">
<td>#CurrentRow# #CurrentRow# #SomeColumn#</td>
<cfif CurrentRow MOD 5 EQ 0>
<!--- close the old row and start a new one --->
</tr><tr>
</cfif>
</cfoutput>
</tr></table>
Taking your eyes and mind off the code for a little while always does the trick ;-)
Unless there's a typo, you're not showing any text in the list ;-)
ie <option>there should be something here </option>
I even tried adding a size attribute.
That applies to vertical size. ie Display x items (or rows). To set the width, use CSS and the "width" attribute. Select lists also have a "width" attribute too. But IIRC it's deprecated.
http://www.blooberry.com/indexdot/html/topics/selectwidth.htm
I'm too brain dead right now to explain it well. But most techniques use the MOD operator to determine when to create a new row. ie if the current index is divisible by 5, create a new row
<cfif CurrentRow MOD 5 EQ 0>
<!--- close the old row and start a new one --->
</tr><tr>
</cfif>
BUT ... since you're using startRow/maxRows your #CurrentRow# won't start at 1. So you'll probably need to create your own row counter instead.
<cfif #URL.get#> or <cfif isDefined(URL.get)>
First and foremost, you have to make sure that variable is defined before using it. In the current code, you're checking the value 1st, then seeing if it's defined. That's probably why you're getting an error. Solution: your IsDefined() statement must be first.
Second, IsDefined() works a little different than other functions. You need to pass it the name of a variable - in quotes. If you don't put it inside quotes, CF assumes you want to evaluate that variable and you get an error. It should be like this.
<cfif IsDefined("URL.get")>
do stuff here ...
</cfif>
It can be confusing at first. Keep in mind there's different ways you can call functions, and reasons why you'd use 1 way versus another way. But let's ignore that for now and get back to your question.
In order to use the function, you have to create an instance of the component first. The simplest way to do that is using CFINVOKE. The "component" value is normally a dot-notation path to your component. But if both your files are in the same directory, you can just use the component name: ie "_component" without the .cfc extension. Use "returnVariable" to capture the results of your function.
<cfinvoke component="_component"
method="myFunction"
myArgument="some value here"
returnVariable="result" >
BUT ... you could also call it like brettskiii showed in the previous post. You could also call it a 3rd way (my personal preference). I find it less bulky:
<!--- create an instance of the component --->
<cfset myObj = createObject("component", "_component")>
<!--- then call the function --->
<cfset result = myObj.myFunction( "some value here ")>
For uber-clarity you could use the argument names when you call the function. But it's not strictly needed here.
ie <cfset result = myObj.myFunction( myArgument="some value here ")>
Anyway, those are the 3 main ways you can call a function within a component