Dynamically add text into body as I click <Select> indexes in coldfusion - dynamic

On my cold fusion page what I want to do is click one of the options from my <Select> statement. After doing so I want to see a richtextbox be dynamically filled with a matching record in my database from the value of the item I clicked. I also want it to do the same for a checkbox, and authors object.
Each object already has a column in my database, what is left is to add this dynamic feature to fill in my data for editing a post.
My code looks like this:
<!--- Query --->
<cfquery name="Posts" datasource="Postings">
Select *
from BlogPosts
</cfquery>
<!--- Fill Listbox --->
<cfselect name="LoopPosts" size="12">
<cfoutput query="Posts"><option value="#PostID#">
#PostTitle#</option></cfoutput>
</cfselect>
<!--- Secondary Query --->
<cfquery name="PostsQuery" datasource="Postings">
Select *
from BlogPosts
</cfquery>
<!--- Fill --->
<cftextarea style="width: 1000px; height: 600px;" name="PostBody" id="blog"><cfoutput query="Postquery">#PostBody#</cfoutput></cftextarea>
<input name="ActivePost" type="checkbox" value="<cfoutput query="Postquery">#Active#</cfoutput>">

Let me try to redeem myself with a modified answer:
You can dynamically reapply options to elements using ajax calls to your cfc file (since cfc bind is apparently a no-no) by adding an event listener to the first select field and calling the method in the cfc file via an AJAX get request. In the success function, you can then update the response to the textarea field.
Every time a selection is made from the select box, the text box will refresh the data with the appropriate query result.
The HTML page could look something like this:
<script type="text/javascript">
document.forms['yourformname'].elements['LoopPosts'].addEventListener('click', function(){
$.ajax({
type:"GET",
url: "yourcfcfilename.cfc?method=GetSelectedPost",
data: {selectedPost : this.value},
success: function(response) {
document.forms['yourformname'].elements['PostBody'].innerHTML = response;
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
alert("Status: " + textStatus); alert("Error: " + errorThrown);
}
});
});
</script>
And the cfc page could look something like this:
<cfcomponent displayname="Post Functions" output="true">
<!--- Secondary Query --->
<cffunction name="GetSelectedPost" access="remote" returntype="String">
<cfargument name="selectedPost" type="string" required="true">
<cfquery name="PostsQuery" datasource="Postings">
SELECT PostBody
FROM BlogPosts
WHERE PostID = <cfqueryparam value="ARGUMENTS.selectedPost">
</cfquery>
<cfreturn PostsQuery.PostBody>
</cffunction>
</cfcomponent>
Every time a selection is made from the select box, the text box will refresh the data with the appropriate query result.

Related

Getting Place ID based on Place Name, City Name and Address from Google Places API service

I am using the Google Places API service(https://developers.google.com/places/web-service/) to get the place id based on location name. The user types some location name and related suggestions appear from which the user can select and get the place Id. I have a requirement where I need to have three textboxes and a button. The user will enter Place Name, City Name and Address and click the button to get placeId. Right now, I don't see an option to get place Id based on more than one parameter. How can I accomplish that?
Text Search Requests accept a query string. One potential solution would be to allow your users to enter the place name, city, and address into different text fields, but then concatenate all of them into a single query string before sending your ajax request.
Your form looks something like this:
<form id="form">
<input type="text" name="place" value="">
<input type="text" name="city" value="">
<input type="text" name="address" value="">
<input type="submit" value="Locate">
</form>
Your javascript will look something like this:
$( "#form" ).submit(function( event ) {
// concatenate places into a single query string
var query = $('input[name="place"]').val() + $('input[name="city"]').val() + $('input[name="address"]').val();
// convert spaces to '+' symbol for query
query = encodeURIComponent(query);
// send ajax request
$.ajax({url: "https://maps.googleapis.com/maps/api/place/textsearch/xml?query=" + query + "&key=YOUR_API_KEY", success: function(result){
alert('success, now retrieve your id from result variable');
}});
//prevent the submit button from reloading the page
event.preventDefault();
});

CF ORM many-to-many relationship sort order

I have a many to many relationship setup, and need to control the order.
I have an entity with the property below. How do I control the order of the components when retrieved via this relationship?
property name="Components" fieldtype="many-to-many" cfc="CmsComponent"
type="array"
singularname="Component"
linktable="CMSPageComponents"
fkcolumn="page_id"
inversejoincolumn="component_id";
I've setup a column in the linktable (CMSPageComponents) called dispOrder. But when I set the orderby="dispOrder" or orderby="CMSPageComponents.dispOrder" attribute on the property above, it just seems to ignore it.
Any suggestions on how I can control the order of a many-to-many relationship?
When the relationship is many-to-many CF will apply the orderBy statement to the object table not to the link table. So in theory you could move your dispOrder column from the CMSPageComponents link table to the CmsComponent table to make it work.
But in practice I expect the ordering is specific to the many-to-many relationship (i.e. the particular page), in which case you could follow Peter's advice and create a separate entity which links the other two entities and lets you define an order property.
So you would have 3 entities:
CmsPage
CmsComponent
CmsPageComponent
CmsPageComponent might look something like this:
<cfcomponent displayname="CmsPageComponent" persistent="true" table="cmsPageComponents">
<!--- Add a primary key for the link Entity --->
<cfproperty name="ID" fieldType="id" generator="native">
<cfproperty name="dispOrder">
<cfproperty name="page" fieldType="many-to-one" cfc="CmsPage" fkColumn="pageID">
<cfproperty name="component" fieldType="many-to-one" cfc="CmsComponent" fkColumn="componentID">
<!--- init() etc --->
</cfcomponent>
CmsPage could then have a one-to-many relationship with the link entity allowing ordering using the dispOrder column:
<cfcomponent displayname="CmsPage" persistent="true" table="cmsPages">
<cfproperty name="ID" fieldType="id" generator="native">
<cfproperty name="pageComponents" singularName="pageComponent" fieldType="one-to-many" cfc="PageComponent" fkColumn="pageID" orderBy="dispOrder">
<!--- init() etc --->
</cfcomponent>
Update
The following shows how you might add and display page components. Not the only or necessarily best way, but just to give you an idea:
<cfscript>
transaction{
//load the page
page = EntityLoadByPK( "CmsPage",1 );
//load the components we want to add
component1 = EntityLoadByPK( "CmsComponent",1 );
component2 = EntityLoadByPK( "CmsComponent",2 );
//create link objects
pageComponent1 = EntityNew( "CmsPageComponent" );
pageComponent2 = EntityNew( "CmsPageComponent" );
// link them to the pages and components in the order we want
pageComponent1.setComponent( component1 );
pageComponent1.setPage( page );
pageComponent1.setDispOrder( 2 );
EntitySave( pageComponent1 );
pageComponent2.setComponent( component2 );
pageComponent2.setPage( page );
pageComponent2.setDispOrder( 1 );
EntitySave( pageComponent2 );
}
//Reload from the database so the order is applied
EntityReload( page );
</cfscript>
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<cfoutput>
<h2>Page #page.getID()#</h2>
<ol>
<cfloop array="#page.getPageComponents()#" index="pageComponent">
<cfset component = pageComponent.getComponent()>
<li>Component ID #component.getID()#, Display Order = #pageComponent.getDispOrder()#)</li>
</cfloop>
</ol>
</cfoutput>
</body>
</html>
NOTE: this assumes the ORM setting flushAtRequestEnd is true in Application.cfc

Getting properties of dojo's dijit.InlineEditBox for ajax request

In essence I have the same problem as described in this question, but the accepted answer there is not fully working for me.
I want to have the id of the record I'm processing in an HTML5 compliant data-myid attribute, then when the text in the text area is changed, I want call a function that will send an ajax request containing the new value and data-myid to the server. This is important because there can be multiple inlineEditBoxesi a single page. The ajax request part I'm fine with, is getting the proper values to send where I'm stuck.
So far, I know the end result of the HTML declaration will look something like this:
<span data-dojo-type="dijit.InlineEditBox" data-dojo-props="editor:'dijit.form.Textarea'" data-myid="123" title="some title" id="test" >
<script type="dojo/connect" event="onChange" data-dojo-args="myid,value">
console.log(myid + " changed to value " + value);
</script>1339598</span>
But I have not been able to get this to work.
You can get the myId value through
this.domNode.dataset.myid;
... in your onChange event.
Example here : http://jsfiddle.net/psoares/ycEN7/
A more portable solution is to use dojo/dom-attr instead though, like this :
*HTML
<div id="editBox" data-dojo-type="dijit/InlineEditBox"
data-dojo-props="editor:'dijit/form/Textarea'"
data-myid="123"
title="some title">1339598</div>
<div id="output"><div>`
*Javascript :
require(["dojo/dom",
"dojo/dom-attr",
"dojo/parser",
"dojo/html",
"dijit/registry",
"dijit/InlineEditBox",
"dijit/form/Textarea",
"dojo/domReady!"],
function(dom, domAttr, parser, html, registry){
var editBox;
parser.parse().then(function(instances){
editBox = registry.byId("editBox");
editBox.on("change", function(value){
var myId = domAttr.get(this.domNode, "data-myid");
html.set(dom.byId("output"), "Editor " + myId + "'s value changed to " + value);
});
});
});

Storing file name when uploading using Coldfusion

I am trying to store the filename of the selected file to be uploaded into a hidden input field on the form. my form looks like this
<form id="uploadattachment" enctype="multipart/form-data"
method="post" action="/governance/attachmentfilestore">
<cfif isDefined("fileUpload")>
<cffile action="upload"
fileField="fileUpload"
accept="application/pdf"
nameconflict="makeunique"
destination="#ExpandPath( '/files/governance/upr/' )#">
<input type="hidden" name="filename" id="filename" value="">
<input type="hidden" readonly id="uprUUID" name="uprUUID"
style="width: 400px" value="<cfoutput>#params.key#</cfoutput>"/>
<input type="hidden" readonly id="status" name="status"
style="width: 400px" value="1"/>
<input name="fileUpload" type="file" style="width: 200px;" />
<button type="submit" name="action"
class="submitBtn primary rightSubmitBtnSpace">Upload</button>
</form>
This is then sent to the controller which writes it to the database how ever I cannot work out a way to get the name of the file to store in the "filename" field.
Does anyone have a solution on how you can populate a field with the name of the file that is selected to be uploaded?
I have added the CFFILE.serverFile in and it worked once, but I'm guessing thats because it grabbed the previously uploaded files name.
Now when loading the page I get Serverfile is undefined in CFFILE and so it does not let me populate the form with the files name.
My code looks like this now to try and work around it how ever this doesn't seem to work either.
<cfif isDefined("CFFILE.serverFile")>
<cfset form.filename = CFFILE.serverFile>
<cfelse>
<cfset form.filename = "null">
</cfif>
<input type="hidden" name="filename" id="filename"
value="<cfoutput>#CFFILE.serverFile#</cfoutput>"/>
The filename does not become available until the file is uploaded. This happens after the form is posted. The only way around this is to try posting the fileupload via AJAX and then returning the filename.
Otherwise, you can assign the value to the field after the file is upload and the form is posted.
<cfset form.filename = CFFILE.serverfile>
You can find the file name before saving.
Railo:
GetPageContext().formScope().getUploadResource("myFormField").getName()
Adobe:
function getClientFileName(fieldName) {
var tmpPartsArray = Form.getPartsArray();
var clientFileName = "";
if (IsDefined("tmpPartsArray")) {
for (local.tmpPart in tmpPartsArray) {
if (local.tmpPart.isFile() AND local.tmpPart.getName() EQ arguments.fieldName) {
return local.tmpPart.getFileName();
}
}
}
return "";
}
Source: http://www.stillnetstudios.com/get-filename-before-calling-cffile/
As lvmisooners said,
GetPageContext().formScope().getUploadResource("myFormField").getName()
works for Railo (and Lucee) but I noticed an interesting wrinkle: if the browser is IE than this returns the full source path including the filename. Firefox and Chrome on the other hand, return only the filename.
For my application I need the full path, but haven't been able to find that if the browser is FireFox or Chrome. If anyone has any ideas I would be most grateful!
(Sorry for not replying to lvmisooners but I don't have the reputation points to reply.)

Pass text box value to a dojo grid's query parameter

I am trying to pass the value in a text box as a query parameter in a dojo data grid and would like to get clarified on two questions listed below. The dojo grid initiates a call to the server with the query params to initiate a search and bring back results (that is diplayed on the data grid)
Is it possible to reload the gird based on the value in the text by invoking refresh (dijit.byId("mygrid").refresh
If yes, how can I pass the value of the text box as a query parameter to the data grid.
Listed below is my relevant code
function reload(){
dijit.byId("mygrid").refresh;
}
<div class="test">
<input id="searchParam" >
<button dojoType="dijit.form.Button" type="submit" onclick=reload()>
Search
</button>
</div>
<div dojoType="dojox.grid.DataGrid"
id="mygrid"
jsid="mygrid"
store="dojox.data.JsonRestStore"
target="<c:url value='members' />">
query="{
searchCriteria: ? TODO How to pass value of text box here?,
}"
rowsPerPage="1000"
autoWidth="true"
autoHeight="true"
selectionMode="single"
selectable="true"
errorMessage="Error loading data"
noDataMessage="<span class='dojoxGridNoData'>No members found.</span>">
</div>
You should be able do something like the following:
function reload() {
var val = dojo.byId('searchParam').attr('value');
dijit.byId("mygrid").setQuery({ propName: val });
}
You will need to properly build the query { propName: val }.