Ok, so I want an autocomplete dropdown with linkbuttons as selections. So, the user puts the cursor in the "text box" and is greated with a list of options. They can either start typing to narrow down the list, or select one of the options on the list. As soon as they click (or press enter) the dataset this is linked to will be filtered by the selection.
Ok, is this as easy as wrapping an AJAX autocomplete around a dropdown? No? (Please?)
This widget can be made with three items: a text input, button input, and an unordered list to hold the results.
__________ _
|__________||v|__ <-- text and button
| | <-- ul (styled to appear relative to text input)
| |
| |
|______________|
ul shown on:
'keyUp' event of the text input (if value is non-empty)
'click' event of the button input (if currently not visible)
ul hidden on:
'click' event of the button input (if currently visible)
'click' event of list items
When the ul is shown or the 'keyUp' event of the text input is triggered an AJAX call to the server needs to be made to update the list.
On success the results should be placed in the ul. When creating the list items they should have a 'click' event attached to them that sets the text input value and hides the ul (may have to add a link inside the li to attach the event to).
The hardest part is really the CSS. The JavaScript is simple especially with a solid library like prototype that supports multiple browsers.
You will probably want to support some IDs for the items, so you can add some hidden inputs to each list item with the id and next to the text input to store the selected items ID.
You'll have to handle the OnSelectedIndexChanged event of your drop down list to rebind your dataset based on the users selection. If you want the filtering to happen in an asynch postback, wrap the dataset (or datagrid I'm assuming) and your drop down in an UpdatePanel. That is one way to do it anyhow.
I am not entirely sure what you want, but the Ra-Ajax AutoCompleter definitely have support for having "controls" within itself. You can see that in the search box at Stacked in fact (upper right corner) where we're using links. But this could also be LinkButtons if you wish...
Disclaimer; I work with Ra-Ajax...
In my opinion, you shouldn't use AJAX for this at all.
here's why:
(1) On focus: ALL the options that he can select are shown in the dropdown. This means that all possible options are already sent to the client.
(2) If the user types something in, the number of entries in the drop down are filtered down to match. This can easily be done on the client side. Being ajax'y and going back to the server at this point will just slow things down.
phpguru.org has a control which is 'almost exactly' what you need:
http://www.phpguru.org/static/AutoComplete.html#demo
It differs slightly from what you need in that it shows the dropdown on double-click instead of on focus. That should be fairly easy to modify.
I hope this helps.
Related
I'm using Primefaces' selectManyMenu to display a list of hundreds of items. I've also included a filter on top. The issue is that when I select, say, the 200th item in the list, I have to manually scroll down to the 200th item each time to see if it has been checked.
I want it so that whenever I select an item, it moves to the top of the menu, so that it is easy to view all the selected items from that list at the top without having to scroll down and up all the time.
Any suggestions?
Looks like your component is getting updated when selecting or unselecting an item, and that's the reason you're reloading the list and losing your scroll position.
Else, it looks like you could use a workround for this. Something like
Catch the select/unselect/change event and trigger a backing Bean function where
You rearrange you list of items sot that the selected ones will be pushed first
oncomplete, you will update your selectManyMenu component.
By the way, maybe it's time to think again if you're using the right component and UX practice. and I have the impression that selectManyMenu is not meant to be used with lists of 200+ items. Personally I think you should avoid using a list that will have to scroll down, for selectMany components. For example you could use another component like a pickList
I want to create a dynamic action, that will set a value to an item on the page, when the value of another item (autocomplete text field) is set.
So the proccess goes like this:
Click on the autocomplete field
type some letters
choose one of the suggested values
I cannot find an event that will be executed when the selection of one of the suggested values happens. This way, I cannot see how I can read the value of the autocomplete field, once a suggested value is selected.
The change event doesn't fit my needs, it doesn't execute when one suggested value is selected.
I had the same problem, found this link: https://community.oracle.com/thread/2130716?tstart=0 and modified my dynamic action as follows to get the desired behaviour:
Event = Custom
Custom Event = result
From the link:
the problem seems to be the default behavior of the browser. When you
enter some text into the autocomplete and the list is displayed, the
focus is still in the text field. Also if you use the keyboard cursors
to pick an entry the focus will still be in the textfield. That's why
the change event of the textfield doesn't fire. It only fires if you
leave the field.
On the other side if you pick an entry with the mouse, the browser
will remove the focus from the text field for a moment (before the
JavaScript code puts the focus back), because you clicked outside of
the field. But that's enough so that the browser fires the change
event.
I had a look into documentation of the underlaying jQuery Autocomplete
widget
(http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/) and
there is actually an event called "result" which can be captures if an
entry is selected from the drop down list.
Try "Lose Focus" as event. It will trigger your dynamic action when you leave the autocomplete field, i.e. your curosr is moved to another field.
This probably depends on the APEX version you are using.
In case of 18.2, because the underlying component is based on Oracle JET's "inputSearch" component, you need to use following configure to capture the select change event for text with autocomplete:
event: Custom
custom event: ojupdate
Reference:
https://docs.oracle.com/cd/E87657_01/jet/reference-jet/oj.ojInputSearch.html#event:optionChange
I turned on the browser console, then turned ApEx Developer toolbar debug, and found that, on the contrary, the "Change" event does fire upon user clicking with the mouse on one of the selections. However if the user uses keyboard (type a few letters to narrow the list down, then use down arrow key to arrive at desired value, then press enter) then the Change event does not fire, just as you say.
Moreover: even when you do get the value sent back via mouse-click initiated Change event, the value isn't the autocomplete's complete and valid value, but instead the possibly partial and wrong-case value just as typed by the user. I.e., the the change event's submission of the value precedes the autocomplete's substitution.
The answer that #VincentDeelen gave is the best alternative that I can see, although it doesn't quite give that "instantantenous synchronicity" feel. You could maybe use the "Key Down" event, but be careful with that. You could get a really excessive amount of web and db traffic as each and every keystroke (including corrections) results in another firing of the dynamic action.
Testing environment: ApEx 4.2.3 with Chrome 33 as well as IE 9.
p.s. This might be worth a mention to the ApEx development team as well.
It's not really ideal, but you could use onfocus(). I'm looking for the same thing you are, I think, a custom event that fires when the selection of a suggested value happens. I haven't found it yet though and that is my work-around for now. It will run whatever function you've created for this initially with no value, but once the selection is made it will return focus and run the function again with the right value. Like I said, not ideal but it works.
Jeffrey Kemp is right. You can set it up through a dynamic action using the custom event, result. You can also register it on page load using document.getElementById("{id}").addEventListener("result", {function}); or $("#{id}").result( function( event, data, formatted ) { //something here });.
Oracle apex 19 now added a "component event" when you create a dynamic action called "Update [Text Field with autocomplete]" - this action is fired when you select a value from the list, but not when you leave the field (similar to adding the custom event "ojupdate").
I have a bit of a unique challenge today. I have a client that wants to be able to search for multiple items based on inserts into a cfgrid. Suppose we have the following web form:
A Country selection dropdown
A State Selection dependent AJAX dropdown
A city Selection dependent AJAX dropdown
An ADD Button
----------------------------------------------------
A CFGRID that will populate a row with selections when the user clicks the add button
----------------------------------------------------
And finally, a CLEAR button, and a GO button on the bottom.
The resulting page will then query the database and get some statistics about the cities selected. So, suppose an individual picks USA > Arizona > Scottsdale and USA > Arizona > Flagstaff. The grid below the options will 'save' each selection and reset to their default options, waiting for a user to pick additional options or click on 'GO'.
The resulting page will then generate columns that list some statistics about the communities and highlight the 'best of' between each selected community.
Each time a user selects the ADD button (assuming three criteria are selected) I want the information to be added into a CFGRID that displays the options selected. Then, After the user selects at least one country/city/state option, have all of the data in the CFGRID get passed to another page that does a query from the data selected. In theory, the user could pick as many communities as they want, assuming they are willing to let the database sludge through enough data to get what they want and wait through a 'loading' screen to get it.
I'm having these challenges, in no particular order:
- I have an HTML grid that I must use per client spec (No Java or Flash, must be HTML)
- I have no idea how to get the selected options into the CFGRID. I assume there is some JavaScript I can write that uses some sort of AddRow function to add data into the grid with the add button but cannot seem to find how to it on the interwebs
- After we conquer the above challenge, how do I pass the data from the grid into the results page? I thought about passing one big string or a structure, but I'm not sure how to do that through the URL or posting, nor how to get the data out of the grid. I wonder if I am better off coding some sort of string that gets passed from the options page to the results page with a get method instead of dealing with the stuff in the CFGRID and have the CFGRID serve only as a 'dummy' display container.
- Finally, after the pass is complete, I would need to loop through through the structure and perform a CFQUERY or CFSTOREDPROC on each row of data, then get the statistics I need to display on the results page. I assume this would depend on how I am getting the data from the options selection page to the results page.
THANK YOU ALL!
CFGRID is great to start, but it can be b*tch to customize and extend... Have you tried editable CFGRID with bind? See how far off it is from what you want first. If it turns out to be very far, then you might want to go for a jqGrid and code up some jQuery.
To start, read Using HTML grids and make the cfgrid editable.
http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec22c24-7a01.html#WSc3ff6d0ea77859461172e0811cbec22c24-72e0
Once you got that working, look at these provided JS functions that you can use with CFGRID
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WS0ef8c004658c1089-6262c847120f1a3b244-8000.html
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSd160b5fdf5100e8f-4439fdac128193edfd6-7f5f.html
If you still demand a bit more, you might need to dig into the underlying ExtJS component. At that point I would rather use jqGrid
I found out that the best way to handle this was by using a SerializeJSON call and a Deserialize JSON call back and forth. By using JavaScript notation we are able to pass a complex JavaScript object (array) between one page and another. This has the value add of not having to worry about sessions timing out and making URLs clickable from one solution to the next.
In MVC-3/Razor, I need to create a page which will have five set of controls. Each set will have a drop-down and a text box. User will select an option from drop-down and then provide some feedback on text box.
When the view is shown very first time, I only have to enable controls in first set. Whereas all controls in 4 other sets should be disabled. Once user perform action in first set of controls (select optino from drop-down and enter in text box), the second set should become enable now, whereas other set of controls should still be disbaled. The data shown in this second drop-down is dependent upon what user has selected in first drop-down. Once user complete action in this second set, the data in third drop-down will depend upon whatever user selected in first and second drop-down etc.
I am a web-form aspx developer and not sure what will be the best way of designing this in MVC-razor world (because there is not view state etc).
Step 1)
What needs to be clarified is what will cause the other “sets” to be enabled?
Is it after the user has selected an item in the dropdown
OR
Is it after they have entered some text in the textbox?
What also needs to be clarified is if you have a dropdown AND a textbox are they both enabled at the same time or is the textbox only enabled after you’ve selected an item in the dropdown?
Once you’ve got that figured out, move on to the next step.
Step 2)
Do the users need to visually see the 4 sets from the beginning (disabling the 3 other sets) or can you simply show the other sets (on the fly) once the previous one has been successfully filled?
Depending on the answers, this may vary your approach.
As for me, the way I’d do it is simply have/show one set that loads at the beginning.
Once the user has selected an item from the dropdown, I would make an AJAX call passing along the selected item and get back a list of values for the second dropdown.
Then, using jQuery, I would duplicate the row (or div) of the first set all while changing the values in the second dropdown box.
Repeat process for when an item is selected in the second dropdown.
But wait! There’s more!!!
Let’s assume you’ve reached the third set. What if the user decides to change the value in the first dropdown? What are your requirements if that happens? Should you remove all other sets and start back at square one? I guess so…
Since we are not aware of the full set of specs for your tasks, we can only assume stuff and this may (or not) be the best path to take.
Duplicating a row (or a div) using jQuery is quite fun and performance wise, it’s nice.
Keep in mind, you will have to give a different ID to your controls (dropdown + textbox) so when you submit the form, you could use the FormCollection to get those dynamically generated controls.
I'm working on an InfoPath 2007 form. I have two drop-down lists and i need the second to be populated with items bases on the value chosen in the first list. I use c# to populate the drop-dpwn lists from external sources. I've tried to use the OnChange event to make all this, but the second list is still empty.
If anyone knows, please tell me.
You can filter the entries for the second drop-down list based on your first list (but only if the entries are based on a data source, not manually entered).
Bring up the properties window for
your second drop-down list.
Select your data source.
Click on the button to the right of the Entries text box.
Select the repeating node you wish to use for the basis of your list entry.
Click the Filter Data button. From here you can enter a filter to limit the entries displayed based on the value of your first drop-down list.
Your question was a bit ambiguous. You may be trying to populate a secondary data source based off of your first drop-down list. This should work fine with an OnChange event. Can you post the code you are using to do this?
Some additional tips that may help:
The change event will not fire until focus moves off of the list box. So, for the second drop down to populate, you will need to set the first drop-down then hit tab or click elsewhere in the form.
I don't know the size or nature of the data source you are using for the second drop-down list, but you may consider downloading the entire data source and filter it using the method I described above. This may be a better solution as you won't need to make a database query between entering the first list box and the second one.