Create a data-persistent select option - html

I am dynamically populating a select tag with cities in the US.
Depending on which state the user selects, a city select tag gets dynamically populated with cities from that state. The options for the city are created via a js function which does its job just fine. This function is called on the 'onchange' event within the state select html tag.
As it currently works, the entirety of these fields are within a form. Every field is required to be data-persistent, ie the data you type into these fields must be "filled out" after the form has been submitted. All fields currently on the page, except the dynamically filled city field are persistent and work as intended. This is accomplished by creating CF variables in a format like so:
<cfparam name="form.highschoolstate" default="" />
<cfparam name="form.highschoolcity" default="" />
<cfparam name="form.highschool" default="" />
and at each input, a format similar to this:
<select name="highschoolstate" id="highschoolstate" required="required" onchange="stateswitch('highschoolstate')" value="#form.highschoolstate#">
However, there is one kink in the form, the cities that populate my "High school city" field are not data-persistent. I have, for each state, a list of all of the cities in a format like so:
<option value=\"akiachak\">Akiachak</option>
But when (please see the below picture for result) I try to make the data-persistent, using innerHTML (by replacing the contents of the select tag) I get this code that is undesireable.
<option value=\"akiachak\" <cfif form.highschoolcity EQ \"akiachak\">selected=\"selected\"</cfif>>Akiachak</option>
Is there an option available to put this conditional CF statement within my dynamically generated html such that I can have persistent data throughout my entire form?
Function that dynamically changes the select tag:
//Dynamically changes the drop down list when selecting a city/state pair
function stateswitch(id)
{
var myId = id; //ID of the html element we are changing
var stateFlag = false; //This flag turns true when we have selected a state
var highschoolStateFlag = false; //This flag turns true when we have selected a highschool state
var indexInSelect; //Index selected in the select tag
var selectTag1; //Select tag # 1
var selectTag2; //Select tag # 2 that becomes available after select tag # 1 is selected
if(myId == "state")
{
indexInSelect = document.getElementById("state").selectedIndex;
selectTag1 = document.getElementById("state").options;
selectTag2 = document.getElementById("city");
state = selectTag1[indexInSelect].value;
if(selectTag1[0] == "") //If we haven't selected an option before
{
document.getElementById("state").remove(0); //remove the default/null case
stateFlag = true;
}
if(stateFlag)
indexInSelect = indexInSelect - 1; //accounts for offset of default case in indecees to select from
}
else
{
indexInSelect = document.getElementById("highschoolstate").selectedIndex;
selectTag1 = document.getElementById("highschoolstate").options;
selectTag2 = document.getElementById("highschoolcity");
document.getElementById("highschool").disabled = false;
document.getElementById("highschool").placeholder = "Required";
highschoolstate = selectTag1[indexInSelect].value;
if(selectTag1[0] == "") //If we haven't selected an option before
{
document.getElementById("highschoolstate").remove(0); //remove the default/null case
highschoolStateFlag = true;
}
if(highschoolStateFlag)
indexInSelect = indexInSelect - 1; //accounts for offset of default case in indecees to select from
}
selectTag2.disabled = false; //Disable the second select box (because we know at this point we have selected an option for the first one)
switch(selectTag1[indexInSelect].value)
{
case "alabama":
selectTag2.innerHTML="<option value=\"abbeville\" <cfif form.highschoolcity EQ \"abbeville\">selected=\"selected\"</cfif>>Abbeville</option><option value=\"abernant\" <cfif form.highschoolcity EQ \"abernant\">selected=\"selected\"</cfif>>Abernant</option>";
break;
case "ANOTHER_STATE":
selectTag2.innerHTML="etc...<option value=\"...</option>"
break;
//..
}
}
EDIT - SOLUTION:
What I was trying to do was not possible, so I decided on another approach

From the information that you provided I think the problem is with the \ character in the ColdFusion code. You need that to escape the quotation marks for the JavaScript code but not for the ColdFusion code. Try removing those characters from the <cfif> statements in the JavaScript code.
Instead of this:
<cfif form.highschoolcity EQ \"abbeville\">selected=\"selected\"</cfif>
Try this:
<cfif form.highschoolcity EQ "abbeville">selected=\"selected\"</cfif>
You do not need to escape the quotation marks in the ColdFusion code because the ColdFusion server will process that code before it is output to the user's browser.

Related

Is there a simple way to have a local webpage display a variable passed in the URL?

I am experimenting with a Firefox extension that will load an arbitrary URL (only via HTTP or HTTPS) when certain conditions are met.
With certain conditions, I just want to display a message instead of requesting a URL from the internet.
I was thinking about simply hosting a local webpage that would display the message. The catch is that the message needs to include a variable.
Is there a simple way to craft a local web page so that it can display a variable passed to it in the URL? I would prefer to just use HTML and CSS, but adding a little inline javascript would be okay if absolutely needed.
As a simple example, when the extension calls something like:
folder/messageoutput.html?t=Text%20to%20display
I would like to see:
Message: Text to display
shown in the browser's viewport.
You can use the "search" property of the Location object to extract the variables from the end of your URL:
var a = window.location.search;
In your example, a will equal "?t=Text%20to%20display".
Next, you will want to strip the leading question mark from the beginning of the string. The if statement is just in case the browser doesn't include it in the search property:
var s = a.substr(0, 1);
if(s == "?"){s = substr(1);}
Just in case you get a URL with more than one variable, you may want to split the query string at ampersands to produce an array of name-value pair strings:
var R = s.split("&");
Next, split the name-value pair strings at the equal sign to separate the name from the value. Store the name as the key to an array, and the value as the array value corresponding to the key:
var L = R.length;
var NVP = new Array();
var temp = new Array();
for(var i = 0; i < L; i++){
temp = R[i].split("=");
NVP[temp[0]] = temp[1];
}
Almost done. Get the value with the name "t":
var t = NVP['t'];
Last, insert the variable text into the document. A simple example (that will need to be tweaked to match your document structure) is:
var containingDiv = document.getElementById("divToShowMessage");
var tn = document.createTextNode(t);
containingDiv.appendChild(tn);
getArg('t');
function getArg(param) {
var vars = {};
window.location.href.replace( location.hash, '' ).replace(
/[?&]+([^=&]+)=?([^&]*)?/gi, // regexp
function( m, key, value ) { // callback
vars[key] = value !== undefined ? value : '';
}
);
if ( param ) {
return vars[param] ? vars[param] : null;
}
return vars;
}

Search HTML5 Datalist by Value and inner text (or some other property)

I am attempting to find a way so that when a user enters text into the data list, they can come across the same entry by course number (E.G. "CS 101") or course name (E.G. "Intro to Computer Science).
Currently, what I have is only searchable by the value field:
<datalist id="tagList">
<option value=""></option>
<option value="CSCI 4950">Senior Software Project</option>
<option value="CSCI 5117">Developing the Interactive Web</option>
<option value="CSCI 5421">Advanced Algorithms</option>
<option value="CSCI 5980">Design Methods for Comp. Sci.</option>
</datalist>
The solution needs to work in the Android Webkit web browser (Phonegap) -- Chrome seems to handle Datalists the same as Android's native browser so if it works in Chrome I should be ok.
It needs to display both the course name and course number to the user
This needs to be generalizable and not hard-coded as I am using AngularJS to actually populate the full list of courses.
What I've tried
https://stackoverflow.com/a/22827978/2831961 -- For some reason, this didn't work.
I've also tried a similar strategy, but with the data-value attribute. That didn't work either. Unless I am responsible for some behind the scenes Javascript work that I am unaware of.
http://jsfiddle.net/rh48cgrj/3/
Here's a fiddle. I put the option values/text into key:value pairs in a javascript object. NOTE: the key is an index number and the value is the option value attribute AND the text. This makes it easier to search them for our text.
var i = 0;
var selectItems = {}
$('#tagList option').each(function() {
var listvalue = $(this).val();
var listtext = $(this).text();
selectItems[i] = listvalue + " " + listtext + ",";
i++;
});
Then I split them into rows that included both value and text.
count = i;
for(i=0; i < count;i++) {
var blockoftext = blockoftext + " " + selectItems[i].toLowerCase() + ",";
}
I then setup a search function that would search those rows to see if any returned a match, and if they did the result was outputted to a div below the search box.
var texttosplit = blockoftext.split(",");
var searchresults;
for(i=0; i < texttosplit.length; i++) {
(texttosplit[i].indexOf(searchvalue.toLowerCase()) != -1) ?
(searchresults = texttosplit[i] + "<br>") : false;
$("#searched").html(searchresults);
}
There's an example for all of the above in the fiddle.
EDIT: The below is the commented code for the loop to check if search text is in the datalist per op request.
for (i = 0; i < texttosplit.length; i++) {
//The above loops through our array of class values and titles
(texttosplit[i].indexOf(searchvalue.toLowerCase()) != -1) ?
// The above determines if our search text is in class title using a ternary operator
// our array of class values and titles is lowercase so we make
//sure our search text is lowercase as well
// if we find a match between the search text and the class title/values perform the following:
(searchresults = texttosplit[i].replace(/\b[a-z]/g, function(letter) {
return letter.toUpperCase();
})
// The above replaces the first char of every word with an uppercase char
.replace("Csci", "CSCI") + "<br>",
// The above finds Csci and changes it to CSCI since all THOSE letters should be uppercase
prevtext = $("#searched").html(),
//get current text of element with id "searched" and place it in prevtext
$("#searched").html(prevtext + searchresults))
//append "searched" by adding it's current text with the new searchresults
:
//if search text is not in the class title return false
false;
}

Static Dropdown to Dynamic Dropdown Coldfusion

I am new here at stack overflow.
I need to create a static dropdown and then create a dynamic drop down based on the values that was chosen in the static dropdown. Just coldfusion and html. NO other fancy stuff.
So from the first drop down the user would chose: color, id, officer, school and hit "continue" button
Then on the same page or different, if color is chosen it will do a query on database and give out the results for the different colors, if id is seclected it will give a list of id numbers from a query. Same thing for officer or school, if those variables are chosen.
I can do the dropdown box, and get the queries but I am stuck in getting the results from the frist dropdown box to the queries. Below is my code:
<cfform method="POST" action="">
<select name="dropDownOne" required="yes" onchange="this.form.submit()">
<option>Select Report Type</option>
<option value="color">Color</option>
<option value="id">ID</option>
<option value="officier">officier</option>
<option value="school">school</option>
</select>
<input type="Submit" name="Continue" value="Continue">
<cfif isDefined('form.selectType')><cfif form.dropDownOne eq "color">
<option>Select Color</option>
<cfloop query="colorlist">
<option value="#color_id#"
<cfif isDefined('form.selectcenter')>
<cfif form.selectcenter eq "#color_id#">selected</cfif></cfif>>#color#</option>
</cfloop>
Unless you resubmit the page after each selection and requery for the dependent dropdown values, you have to use some kind of client side js and/or ajax.
I think that is what you are sort of trying to show you are doing? It is not too clear what you are trying to do; do you want the dependent dropdown to reflect what you choose and automagically change?
So you would need to have big if wraps around all the possible drop downs depending on what they picked and submitted? And why would the user only be able to choose one of these things at a time? This seems like a very cumbersome way to code it up, and a cumbersome interface.
This will show you how to wire up using cfselect, but I think it is still a bit strange how you want to do this. Are you going to save off each piece and show that or use that somewhere? Or is this just a proof of concept?
And I would probably display all the stuff all the time. A dependent drop down makes more sense for things like Car selectors (Year, Make, Model, Trim level) where each is uniquely dependent on the previous value. I am not sure what you are trying to hook together from the question you asked.
Anyway, ColdFusion does have a <cfselect> which will wire that up for you automagically, though personally I would just use jQuery/Ajax.
Here is how you might do this using the tag:
1) Don't submit your form onChange.
2) Use cfselect to wire the dropdowns together.
3) You need to have methods to call queries that are remote accessible for the binding to work.
<cfif isDefined('Form.DropDownOne')>
<!--- Do some action here --->
<cfdump var="#form#">
</cfif>
<cfform>
<label>Select A Report</label>
<cfselect name="dropDownOne" id="dropDownOne" required="yes"
<!--- The display attribute will map the "name" column to the option display text area --->
<!--- The value attribute will map "value" column to the option value (what is submitted)--->
display='name ' value='value'
<!--- The cfc should send back a query with name and value columns. --->
<!--- The dot path should point to the location of the cfc. --->
bind="cfc:com.app.code.myDropDowns.getCategories()" bindonload="true">
<option>Select Report Type</option>
</cfselect>
<label>Select A Value</label>
<cfselect name="dropDownTwo" id="dropDownTwo" required="yes"
display='name' value='value'
<!--- This method takes the value from the other drop down. --->
<!--- CF uses {} to denote the binding of the element to pass through. --->
<!--- This binding will occur automatically on any change to the dropDownOne element (including load). --->
bind="cfc:com.app.code.myDropDowns.getDetails({dropDownOne})" >
<option>Stuff</option>
</cfselect>
<input type="Submit" name="Continue" value="Continue">
</cfform>
Here I made a myDropDowns.cfc that will return a hand-built query (I do not know how/where you are storing data, so swap out with real query as you like, just return a query to the request:
component output="false" persistent="false" displayname="myDropDowns" {
structAppend(variables, Application.Seq.Objects.oCore.injectCoreMethods() );
remote function getCategories() {
var q = queryNew('');
queryAddColumn(q,'name',['Select Report Type','Color','ID', 'Officer', 'School']);
queryAddColumn(q,'value',['Select Report Type','Colors','IDs', 'Officers', 'Schools']);
return q;
}
remote function getDetails(required string Category) {
var q = queryNew('');
if(Arguments.Category == 'Colors' ) {
queryAddColumn(q,'name',['Select Value','Red','Green','Blue', 'Yellow', 'Purple']);
queryAddColumn(q,'value',['','Red','Green','Blue', 'Yellow', 'Purple']);
} else if(Arguments.Category == 'IDs' ) {
queryAddColumn(q,'name',['Select Value','123','456','789', '1011', '978']);
queryAddColumn(q,'value',['','123','456','789', '1011', '978']);
} else if(Arguments.Category == 'Officers' ) {
queryAddColumn(q,'name',['Select Value','Johnson','Fredricks','Oppenheimer', 'Davis', 'Smith']);
queryAddColumn(q,'value',['','Johnson','Fredricks','Oppenheimer', 'Davis', 'Smith']);
} else if(Arguments.Category == 'Schools' ) {
queryAddColumn(q,'name',['Select Value','Central','Northridge','Fairview', 'Daring', 'South']);
queryAddColumn(q,'value',['','CJH','NRJH','FHS', 'DHS', 'SHS']);
} else {
queryAddColumn(q,'name',['Select A Report Type First']);
queryAddColumn(q,'value',['Yeah, do that']);
}
return q;
}
}
Here are a couple of queries wrapped in cat/list methods you could modify to point at your tables that should return the same style query as the hand coded ones. Substitute your database.tablename and column names, of course.
remote function getCats() {
var q = queryNew(''); // Create empty query, not really nec. Just to initiate as query type.
var oQ = new Query(); // Create query object to execute query against your DB
try { // I like to use try-catches, make it easier to figure out what is going on sometimes....
/* You don't have to set the datasource if you set it in the Application for CF9+*/
oQ.setDataSource('myDataSource');
// Query name is only really needed if caching or requerying as it becomes part of your cache signature
oQ.setName('qMyQueryCategories');
oQ.setCachedWithin(1); // 1 == 1 day/24 hours, .5 = 12 hours, etc)
oQ.setSQL("
SELECT
T1.Id,
T1.DisplayName AS Name,
T1.Category AS Value
FROM yourDB.yourCatTableHere T1
");
q = oQ.Execute().getResult();
return q;
} catch (any err) {
/*
* Returning the error will allow you to debug in the case you have a bad query.
* You can see the result in your F12 debug network tool.
* You could optionally call an error handler to log/email the error
* but then return the empty query to the UI request so it sort of keeps functioning...
* */
return err;
}
}
remote function getList(required string Category) {
var q = queryNew('');
var oQ = new Query();
try {
oQ.setName('qMyQuery#Arguments.Category#');
oQ.setCachedWithin(.04); // Approximately 1 hour (1/24=.0417)
oQ.setSQL("
SELECT
T1.Id,
T1.Category AS Cat,
T1.DisplayName AS Name,
T1.ValueKey AS Value
FROM [yourDB.yourDetailTableNameHere] T1
WHERE T1.Category = ? ;
");
// Parameterize your sql variable. CF will take care of quoting it properly, etc.
oQ.AddParam(value=Arguments.Category, cfsqltype='CF_SQL_VARCHAR' );
q = oQ.Execute().getResult();
return q;
} catch (any err) {
return err;
}
}
Just make sure you match the method names you call in your bindings to the ones you use for each method.

How to maintain checkbox value through pagination?

I have a list of products which are shown with pagination and I can filter the display of the products using check boxes. The problem is it can only displays the value from check box at first page, and if i go to the next page, i will lose the check box checked's value. Please help me how to solve this. I don't know where should I put input hidden and how to write Java Script. Here's my code:
<input id="checkbox_brand" type="checkbox" name="checkbox_brand[<? echo $data_brand[brand_name]; ?>]" value="<? echo $data_brand[brand_name]; ?>"/>
if (isset($_POST["checkbox_brand"])){
foreach($_POST["checkbox_brand"] as $status_a) {
$status_sql[] = '\''.$status_a.'\'';
}
$status = implode(',',$status_sql);
session_start();
$_SESSION["selected"]=$status;
}
if (session_is_registered("selected")){
-->my query
}
Each time you press a check box you'll have to use dictionary array in JavaScript
For example:
if I use the example page you gave, then when pressing a check box inside "Categories"
you'll have to put a value inside correct variable.
// Initialize Objects
var userChoice = {};
userChoice.Catagories = {};
userChoice.Brands = {};
userChoice.ScreenSize = {};
.
.
.
// Pressing check box will trigger the bellow
userChoice.Categories["LG"] = 0;
userChoice.Categories["Sharp"] = 1;
userChoice.Categories["Sony"] = 1;
userChoice.Brands["LcdTV"] = 1;
userChoice.Brands["LedTV"] = 0;
Each checkbox press will also trigger the following JavaScript
document.getElementById("userChoiceHiddenField").value = JSON.sringify("userChoice");
When submitting the page or going to the next page the hidden value will contain the JSON string, so you can parse it as JSON again.
Server Side: (.NET)
string userChoiceHiddenField = request["userChoiceHiddenField"].ToString();
and then take the value you got and place it back in the hidden field and the JavaScript value as follows:
userChoice = JSON.parse(document.getElementById("userChoiceHiddenField").value);
Hope that answers your question.

Select statement selection through URL parameters

I'm attempting to alter the contents of certain parts of a HTML form through usage of the URL. For a text field, I'm aware that this will suffice,
http://<domain>?fieldname=ping&anotherfield=pong
On the form there are multiple select braces (drop down boxes); Is it possible to pick an int or string value through the url for this?
There seems to be little documentation on this (or even people trying to do the same)...
You haven't specified how you want to do this, but I'll assume that you want to use JavaScript:
To get a value from QueryString:
getQueryStringArgument = function(key) {
var hu = window.location.search.substring(1);
var gy = hu.split("&");
for (i = 0; i < gy.length; i++) {
var ft = gy[i].split("=");
if (ft[0] == key)
return ft[1];
}
}
To set the selected value of the select list:
document.getElementById("sel").value = getQueryStringArgument("id");
For a text field, I'm aware that this will suffice
No, it won't (at least, not in a generic way).
For a text field, the default value is specified by the value attribute. There might be a server side script that populates it based on query string data, but there doesn't have to be.
On the form there are multiple select braces (drop down boxes); Is it possible to pick an int or string value through the url for this?
Again, this requires an attribute to be set (selected on <option>), and that could (again) be set by a server side script based on the query string data.