How to build autocomplete similar-title check like stackoverflow? - yii

Using Yii PHP framework. When you ask a question on stackoverflow, as you type the title a list appears called "Questions that may already have your answer". I want to create similar type of field so that when users enter the name of a business I can display similar business names already in my system. It doesn't necessarily need to be as sophisticated as stackoverflow's model. A simple alphabetical search should be fine.
Keep in mind unlike a normal autocomplete, this "autocomplete" won't actually fill in the field in question but rather serves as an informational tool to inform the user of data that potentially already exists.
I'm thinking Yii CJuiAutoComplete widget is the right tool for the job but how do I dissociate the autocomplete from the input field?

CJuiAutoComplete is definitely the right tool, and to disable the auto filling when selecting the suggested values, you will have to alter jQueryUI autocomplete's behavior for its select event, and also for its focus event.
The select event is triggered when a suggestion item is clicked, and focus event is triggered when a suggestion item is navigated to by keystroke (up, down arrow keys).
So to change the default behavior, which is updating the text field, you can cancel those events by returning false from their callbacks:
$this->widget('zii.widgets.jui.CJuiAutoComplete', array(
// other options
// additional javascript options for the autocomplete plugin
'options'=>array(
'select'=>'js:function( event, ui ) {
return false;
}',
'focus'=>'js:function(event, ui) {
return false;
}'
),
));

Related

Screen readers unable to read options of `vue-search-select`

I inherited a vuejs project. People using screen readers as assistive devices complain that their screen readers are unable to read the options in drop down menus that were made from vue-search-select. Here is how you can reproduce the issue:
Install a screen reader such as NVDA.
Turn on NVDA screen reader.
Go to https://vue-search-select.netlify.app/#/model
Tab to a search text field.
Confirm drop down of results appear.
Press the down arrow key to focus on any of the search result items.
Confirm the NVDA says the word "Blank" instead of actually reading out the contents of the selected item.
Here is a 10 second clip to that demonstrates steps 3 of 7.
https://www.youtube.com/watch?v=Nxx1k1oKETI
How do you modify vue-search-select such that in step 7, the screen reader will read out the contents of the selected item instead of reading out the word "Blank"?
Right now, as a temporary solution, I'm trying to write a setTimeout function that will automatically add the appropriate meta data to force screen readers to read out the content. But I'm not sure how successful this approach will be. I prefer an approach that is idiomatic to vue-search-select.
I tried adding a customAttr like so:
<model-select :custom-attr="ariaAttrs" />
function ariaAttrs() {
return function() { return '" aria-label="hello" tabindex="0'; }
}
Although the attributes do appear in my developer console's inspector, my screen reader still does not read out the options.
It seems custom-attr will not help you as it does not allow you to add any attr you want - anything the function returns is just placed as a value of data-vss-custom-attr attribute
Any decent Vue library with similar functionality would offer a slot to customize rendering of menu items, but this does not. Plus it doesn't seem to be maintained for a long time so maybe it is a time to look for an alternative....

How to get the user's new page selection in a Notebook control under Windows?

In my app, when a user has made changes to the data on one page of my notebook control, I want to prompt them to save or discard their changes when they switch to a different page. I have bound the EVT_BOOKCTRL_PAGE_CHANGING event for this, and have created a handler method.
However, I can't tell what page the user is switching to. According to the wxBookCtrlEvent docs,
under Windows, GetSelection() will return the same value as GetOldSelection() when called from the EVT_BOOKCTRL_PAGE_CHANGING handler and not the page which is going to be selected.
Is there a workaround?
I guess as a workaround, you could use a mouse handler checking for when the left button is clicked. In a handler for that event you could do a hit test to see where the click was made and store the value of the tab that was clicked. Something like this:
void MyFrame::OnLeftDown( wxMouseEvent& event )
{
long flags;
int ht = m_notebook1->HitTest( wxPoint(event.GetX(),event.GetY()), &flags);
if( (flags & wxBK_HITTEST_NOWHERE) == 0 )
{
//store the value of ht somewhere
}
event.Skip();
}
void MyFrame::OnNotebookPageChanging( wxNotebookEvent& event )
{
//use the stored value of ht here
}
under Windows, GetSelection() will return the same value as
GetOldSelection() when called from the EVT_BOOKCTRL_PAGE_CHANGING
handler and not the page which is going to be selected.
So, call GetSelection from EVT_BOOKCTRL_PAGE_CHANGED to get the new page.
No, there is no workaround (if there were a reliable way to do it, wxWidgets would have been already doing it), the underlying native control simply doesn't provide this information.
You can either ask whatever you need to ask the user about in any case, independently of the page they're switching to, or ask them after they will have already switched -- which is, of course, going to look weird if you then decide to switch back.
If you really, really need this functionality, you might use non-native wxAuiNotebook instead.

Sencha Touch: Clear listeners on an individual list item

In a TreeStore I have a list item / record which differs from all the other records. I want to execute window.open() whenever the user clicks on this specific record. The other records should maintain their usual functionality. (leafItemTap => detailCard)
I have tried all events of NestedList that made sense to me but no success.
My basic idea is to clear all listeners on the list item and add a custom one for the window.open() task.
Try to use select event, it's preventable so you just need to return false. However, you need to do extra work to deselect previously selected item:
http://docs.sencha.com/touch/2.3.1/#!/api/Ext.dataview.List-event-select

Selecting which fields to show in address composite control

By default, when creating a new account, the composite address control displays three lines for entries (Street_1, Street_2 and Street_3). It looks really inappropriate in our scenario so I'd like to remove one of there. In fact, I'd like to gain a full control of what's shown and what's hidden.
According to this blog, we can resolve this by application of business rules. I don't like it one bit.
We need to rely on a condition from one field to affect the others for the rule to kick in. It feels like giving up to the stupid computer and cheating, without actually gaining control. And lastly - it'll be a huge number of rules bouncing around back and forth in my case. Baaad karma.
How can I control the contents of a composite control?
The article mentions that hiding a field on a form, hides it on the composite address control as well. Not sure if there is some other magic going on behind the scenes, but if there isn't, just add javascript to hide the field.
Here is a little helper function:
setVisible: function (controlName, visibility) {
// Do we need to be here?
if (!controlName) { return; }
if (!Xrm.Page.getControl(controlName)) { return; }
// Set visibility.
Xrm.Page.getControl(controlName).setVisible(visibility);
},

Selenium: Loop Through Each <option> in Drop Down List

I'm using Selenium to ease my testing burden and I have about 1,000 different drop down list combinations (spread across multiple pages and drop down lists) that need to be tested. Basically, what I would like to do is select each <option> inside of a <select>, click the Submit button, select an item (first, second, third, etc.) in the drop down list on the resulting page, click submit, and then go back and select the next item, in sequence. Each time, it should assert that a certain value (related to the drop down list value selected) is present on the final page. Does anybody know if this kind of logic is possible in Selenium?
I'm having a hard time explaining this, so hopefully this pseudo code clears things up
foreach option in select
select option
submit form
foreach option in select
select option
submit form
assert that page contains text that matches selected values
Edit: I have selected values from the drop down list while the recorder is playing, but it seems like the recorder isn't picking up the selected drop down list values. Nor have I been able to figure out how to perform the operation for each <option> in a <select>.
The first question I have is whether or not it's even possible. If it is, could somebody please point me in the right direction to get me started?
Edit 2: I'm not opposed to using another web automated testing utility. If anybody has any recommendations for a free alternative, please feel free to make that recommendation.
What language are using Selenium in? If you're just using Selenium by writing HTML, I'd recommend switching to a programming language and using Selenium RC -- bindings are available for a wide variety of languages, such as Java and Python. In Java, I believe the following would do what you want:
void test(Selenium browser, String startPageUrl,
String firstFormLocator, String firstSelectLocator,
String secondFormLocator, String secondSelectLocator) {
browser.open(startPageUrl);
for (String option : browser.getSelectOptions(firstSelectLocator)) {
browser.open(startPageUrl);
browser.select(firstSelectLocator, "label=" + option);
browser.submit(firstFormLocator); // Or click the submit button
for (String subOption : browser.getSelectOptions(secondSelectLocator) {
browser.open(startPageUrl);
browser.select(firstSelectLocator, "label=" + option);
browser.submit(firstFormLocator); // Or click the submit button
browser.select(secondSelectLocator, "label=" + subOption);
browser.submit(secondFormLocator); // Or click the submit button
// Do your assertions
}
}
}
The code isn't exactly readable, so it might be worth some time abstracting the page away slightly using the Page Object pattern. This also helps make the code more maintainable, for instance when you change the ID of an element, you only need to change it in the page object rather than every test.
Also bear in mind that doing this 1000 times isn't going to be quick. It might be worth seeing if you do similar testing just below the web interface to allow quicker feedback from tests, and then test the web interface is using the lower layer correctly. Also, do you really need 1000 tests? It seems that there's some redundancy in testing here -- is the 1000th test going to fail if the last 999 have passed?