How can I subscribe only once to the app-db in re-frame? - clojurescript

I need to subscribe to the app-db for a value that I want to check only once when the parent component is rendered. For example, when I click a button "Click me", and there's a certain on-click event being processed, whose status I have saved on the app-db with the list of processes that are being done, I just want to check against that value once, and display two different components based on that value.
If the value is empty, I want to proceed with the normal event. If not, I'd like to show something else to the user, a popup for example.
Now the thing is that, because it's actively listening to the app-db, and the value is changing almost every second (or in a matter of milliseconds), the said popup appears, disappears, reappears, and disappears again super fast with each change to the app-db, which isn't helpful at all.
I would like to just subscribe once, get the value, and do the checks based on the value when the parent was first rendered. And then I'll do something to make that go away.
If I click the "Click me" button once again, that's only when I'd like for it to re-render.
I haven't quite been able to achieve this. I tried numerous methods such as introducing a delay during the dispatch of popup as well as after introducing processing states to the app-db in the first place hoping that since the data will already be in a steady state, it might not change as much, but now that I realize it's actively listening to it, it's expected that the values would change.
I did try using the subscription without the deref, but that only introduced an error to my frontend, so I'm not sure which way to go now.

My error with the component diappearing/reappearing turned out to be triggered by something else. A conflict/mismatch with popup-ids and a dispatch to clear one popup leading to destroying all of them.
But to answer the question, it works when you introduce a (fn []) block after the let binding where you actually do the subscription, and calling the components from inside the fn.

Related

How do I automate tab selection on a website

Here is the website I am trying to access. I dont want the default tab (Day) though, I want to select the Season tab
https://www.eex.com/en/market-data/power/futures/uk-financial-futures#!/2017/05/23
The link appears to be exactly the same whichever tab is chose making differentiation impossible as far as I can tell.
Any help on this would be much appreciated, using whichever programming method and language is appropriate.
Kind Regards
Barry Walsh
The URL does not change since this is an ajax request, which you can see from MarketDataTableAController's getPageData function. You can read about them here https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started
Ive inspected your html and you seem to be using angular. On further inpection you can see that the tabs have ng-click="setActiveTab(tab)" attribute on them. So whenever user clicks, this function gets executed. It is a matter of using this function with the appropriate tab object to get the content to change. You for example could put setActiveTab(tab) into your controller init method since setActiveTab() calls the forementioned getPageData() function to update the page.
Also the tab you are looking for is page.tabs[5] ($parent.page.tabs[5] if referring from TabController) since this is the tab with the label of season. Pass that to setActiveTab() and it should show you the season instead.
However this might not be a good solution since the tab array ordering might change. Then you would need to loop over all objects in page.tabs and see if tab.label === "Season" and pass that in the function instead or better yet use the $filter service provided by angular which would look more cleaner.
Your code source also seems to be minimized and its not very easy to read.

How to use one textbox value to call two ajax fuctions

I have an input field in html.
I want to invoke two ajax functions when text is entered into the field.
How to do it by passing events in html?
When I pass
onblur="function(this.value);another fun(this.value) "
only one ajax functions is called
Two alternatives come to mind:
you make a single "router" function handling the event which calls whatever functions you want to execute itself. Unlimited options, since it is up to you what you do inside that function.
you attach two handlers to the event. It seems you are using the in-code onblur attribute to fire your handler function. That is a very old fashioned style. Instead you can use the more modern style to attach arbitrary handlers to arbitrary events right after loading your page (or part of a page). That way you can attach different handlers to the same event without and downside.
I have encountered a similar issue. the first function executes fine, but the second doesn't. most browsers come with a javascript console - for viewing errors and such (usually CTRL-SHIFT-J brings it up). Likely what's going on is your second function may have an error in it, whereas the first has no errors. make sure you didn't miss a semi-colon, or more likely, you may have missed a closing parenthesis. EG:
if (not banned_user("bob") {
...
}
i do this kind of typo ALL the time! Drives me nuts.
So, bottom line, check the code of the second function.

Flex TextInput with default mobile skins automatically regains focus on callout close

I'm working on a simple auto complete function for my Flex mobile app. For that I've got a CalloutButton that triggers a Callout.
The Callout holds some lists from which the user can select items. On item select, the callout gets closed (calloutButton.closeDropDown()).
The very same behavior is done for a TextInput. The user inputs text, the callout opens and according to the entered text, the lists change. Works fine so far. Now, when the user selects an item from any of the lists, the callout closes. Also fine.
Now the issue, after the callout is closed, the TextInput automatically regains focus.
On a mobile device this is more than disturbing.
I narrowed this behavior down to the mobile TextInput skin (spark.skins.mobile.TextInputSkin) since a TextInput without this skin class doesn't show this behavior.
Now you might say just use the default skin instead but unfortunately I can't. The default skin has a bug with Android devices that doesn't pass though the enter event. That I could live with since I'n not necessarily dependent on the enter event, however, the spark mobile skin allows be to continue entering text in the TextInput even after the callout has been opened, which is desperately needed as the lists change according to the entered text.
I can't provide any code as the problem has been narrowed down to the skinClass, thus should not be in my own code. Believe me, I tried every nice and not so nice method to prevent the TextInput from getting focus again, but nothing worked.
So, totally stuck here!
Hopefully you guys have some ideas on how to solve this.
Edit:
Below the steps of my application's behaviour. (to be fair, the workflow inside the callout is a little more complex, I'm working with several lists and a SplitViewNavigator here (thus can't use the Flextras autocomplete), but that doesn't affect the TextInput focus issue I'm facing).
Enter text in TextInput
On key change a Callout with two Lists is opened.
The first List receives results according to the entered text from a webservice
User selects item from list
Second list receives results according to selection from first list from webservice
User selects item on second list
Callout closes
This all works fine, except that the TextInput receives focus after the Callout closes.
I really don't know what triggers this behavior.
Edit2: Code to further illustrate the issue.
Naturally, this is stripped down to the very basics, but it mirrors the behavior of the component and focus.
First the CalloutButton and TextInput that can both control the Callout:
<ui:SearchCallout id="detailSearch"/>
<s:TextInput id="searchInput" skinClass="spark.skins.mobile.TextInputSkin"
enter="historySearch(searchInput.text)"
focusOut="searchFocusOutEvent(event)"
focusIn="searchFocusInEvent(event)"/>
The TextInput's focus handlers don't do anything related to the callout, they just set current states of another component, so I'll leave them out here.
Function historySearch closes the CallOut (I forced it to close as it wouldn't close with the usual closeDropDown()), formats the search text, handles a searchHistory and eventually triggers the search function that passes the formatted search text to the selected component.
Here are the parts that matter for this case:
private function historySearch(val:String):void {
detailSearch.forceClose=true;
detailSearch.closeDropDown();
searchEvent(_searchSyms, true);
}
Note: 'val' (the TextInput's text) is trimmed and whatnot, eventually it will result in an array of strings, represented by '_searchSyms'.
Further eventListeners are as follows:
searchInput.addEventListener(KeyboardEvent.KEY_DOWN, onKeyEvent);
searchInput.addEventListener(FlexEvent.VALUE_COMMIT, onKeyEvent);
searchInput.addEventListener(TextOperationEvent.CHANGE, onTextChange);
KEY_DOWN and VALUE_COMMIT don't have anything to do with the Callout, they are used to handle stuff for the searchHistory, hence I'll leave the onKeyEvent function out here.
onTextChange triggers the string search on the server and closes the Callout in case the TextInput's text is an empty string:
private function onTextChange(event:Event):void {
if(searchInput.text=="") {
if(detailSearch.isDropDownOpen) {
(detailSearch.rightView.activeView as RightView).clearDetailList();
detailSearch.isCloseable=true;
}
}
_searchManager.getRicsByChar(searchInput.text);
}
Eventually the server will respond and passes an array of responses. The Callout gets opened and it's lists are filled with the responses.
I won't paste all the Callout content's code here as it would be way too much. Basically, the user selects an item from any of the lists, the Callout is forced to close and the search function that passes the value to the component (not yet pasted here, be patient ;), is given the item's value. That basically looks like this (never mind the FlexGlobals stuff, this gets all refactored once the focus issue has been resolved):
var search:String = String(event.currentTarget.selectedItem);
FlexGlobals.topLevelApplication.detailSearch.forceClose=true;
FlexGlobals.topLevelApplication.detailSearch.closeDropDown();
FlexGlobals.topLevelApplication.searchEvent(new Array(search), true);
Allright, now the final step of the whole functionality, the searchEvent. As already said, this function basically only passes the formatted search value to the selected component. This either happened on 'Enter' of the TextInput (as the code above shows), or on selection of an item from one of the Callout's lists.
public function searchEvent(_searchSymbols:Array, setText:Boolean):void {
if(setText) {
var _searchString:String="";
for each (var _sym:String in _searchSymbols) {
_searchString += _sym + ", ";
}
searchInput.text = _searchString.substring(0, _searchString.length-2);
}
stage.focus=null;
if(selectedWindowContainer) {
// set the array of search items to the selected component here
selectedWindowContainer.setFocus();
} else
trace("[MAIN] no component selected");
}
And that is basically it. This function is the last step of my search routine, and the selected component (that will get the search items), is getting the focus.
Yet, it automatically loses focus again and the TextInput will receive it. I have no idea where and why this happens, and I need to get rid of this behavior asap!
Wow, what a post, anyone still reading this? ;) Well, I hope so.
Well, after hours of testing several ways to prevent the TextInput from automatically gaining focus, I (kinda) solved the issue, although I think it's more a dirty hack than anything else.
Setting the TextInput's focusEnabled to false works fine, even though the focus indication (border around the TextInput) won't work with this any more (an issue I can live with for now).
Still, I'd really like to know what exactly is going on here, especially in the mobile skin class.

How to SetFocus on a TextBox in the Form Load

Working in both A2003 & A2007.
How do we ensure that a selected TextBox gets the focus when the form loads? If we put MyTextBox.SetFocus in the Form_Load then we get the error:
can't move the focus to the control
This form is designed for rapid data entry, and the form somewhat rearranges itself based on the last used settings. So there are several different textboxes any of which may need the focus depending on the user. We can't just fix it in design time by giving MyTextBox TabIndex=0.
The help says something about calling Repaint which just doesn't make any sense at all:
You can move the focus only to a
visible control or form. A form and
controls on a form aren't visible
until the form's Load event has
finished. Therefore, if you use the
SetFocus method in a form's Load event
to move the focus to that form, you
must use the Repaint method before the
SetFocus method.
The best bet in this case, is to ensure that the textbox to get focus is numbered 0 in the Tab Index property.
You cant set the focus as the controls don’t really exist yet, try putting the code in the OnActivate event instead
Or just put a DoCmd.Repaint in the OnLoad event before trying to set the focus. Both should work but I'm not near a computer to check
In my experience, I've always gotten that error when the control I was trying to set focus to was either 1)not visible or 2)not enabled. I assume you've already checked those, but it would be worth double checking at runtime when you get the error message (especially since you said you are shuffling the controls at runtime).
I use the .SetFocus method pretty regularly without trouble. I don't recall ever getting an error message when setting focus to a control that already has it as Remou stated in his answer.
I believe there is also a third case that occurs if you try to set focus to a control in the form header/footer of a bound form that has had all of its records filtered out. I know that situation causes "disappearing" contents in an unbound combo box, but I think it may also play havoc with the SetFocus method. If you are opening the form in Data Entry mode, though, that should not be an issue.
Move SetFocus to the form's On Current event. Should work then unless perhaps the form's record source contains no records and you've set the form's Allow Additions property to No. In that case your text box will not be available to SetFocus on, but in my testing it doesn't throw an error.

Do all browser's treat enter (key 13) the same inside form?

I have a form with multiple submit buttons, each of which is relevant to how the user wants the data saved and/or loaded.
The problem is (or was) that if a user pressed enter on the last (or any other) input within the form, the submit button that seemed to be called was the "load saved formed" which is at the top of the form. All attempts to user javascript to have the return button default to the "save form" seemed useless, almost as if the browser was too busy already submitting the form to have any js interfere.
Finally, in FireFox 3.5, I actually had the server-side script echo out what it received for the post variable and discovered that none of the submit button values were being passed back to the server. As it turns out, I have hooks in the script for when the user hits "Save" or "Save and Print", etc, but if the user uses the "load page" it simply updates a variable and continues loading the page normally with that variable in context.
So with no submit button value at all, it did the same thing, it simply loaded the page.
So, on to the big question:
Is this typical browser behavior? Maybe even reliable browser behavior? Will hitting enter always submit the form as though no submit button was pressed at all, or do some browsers like to pick a button to use as the default when the user presses enter?
If it is typical behavior, what is the suggested course of action? I was going to have the script save anything no matter what, so long as there was data in the form, but then I realized that this was even more dangerous, because if the user loads one saved form, changes there mind, and changes the form dates and hits "Load Form", then it will save the form data from the pervious form for the new dates they have requested.
I considered setting it up so that changing the load form inputs (selects with dates and other particulars) would clear the form so that the server still recieved an empty form and thus would not overwrite any previous data, but this is risky as well, as many users will certainly notice and think that their data has been lost, etc, and there is always the slight chance that the user will be almost done with the form, go up to the top and fiddle with the form-load selects just to confirm they chose the right what nots and then be forced to start from scratch.
I should just have two forms, one for loading, one for the data, but the problem with that is that all of the data in the load part of the form does get used by the main form. I could write more js to combine the two on submit, or hide the data in the second form, but all of that seems clunky.
Essentially, I need a setup such that the top part of the form is independent of the main form, but not vice versa. Submitting the upper form does not submit the lower, but submitting the lower does submit the higher.
Okay,I've gone on long enough. Basically I'm wondering if a solution already exists or if anyone else has run into this and found a clever fix. I thought simply having the form save whenever the form wasn't empty was pretty clever, until it occurred to me that when the user goes to the page, it auto-loads the most applicable form given the date, and thus changing the load variables will almost always caused trouble.
Having read the possible duplicate that Artelius was good enough to draw my attention to, I'm still unclear on the consistency across browsers regarding the Enter button as submit.
It seems that almost everyone in that question assumed that hitting enter presses the first available submit, which was also my assumption until a friend suggested I hide (via CSS) another submit button at the top of the form with whatever I wanted enter to achieve. It was when this got me the same results that I finally viewed what was being passed to the server (ie nothing in terms of a submit value). So that means either
a) the "enter as no submit button just submit" is new behavior for some or all browsers,
b) the "enter as just submit" vs "enter as first submit button" is just browser choice, no trends, just typical cross-browser unreliability, or
c) Everyone just keeps assuming that the "enter as first submit button" is the case because most of us only code if (situation1) else (assume not situation1) and none of us are really sure what the browser is doing.
I highly doubt it's that last one, but then again, I also highly doubt most of us know which browsers do which. I'd sure like it if there was a straight answer I could pass along.
Oh, and finally: While I know it would be far simpler to use buttons, and I am taking that under serious consideration, I would also like to consider other options, since really the only need for less submit buttons I have is for when users hit enter instead of one of the buttons.
Actually, let me get carried away one more second:
The only thing I really need to know is whether or not they hit enter FROM one of the text inputs. If I could pass that along to the server, I'd know if I should save or reload the form. But the problem is (or at least what I've had troubles with) is that when the user hits enter in an input, it seems like there isn't any more playtime with js to capture anything, and in some cases, it seems like the browser is triggering the onclick for whichever submit button and thus not really allowing me to know the real event that triggered that. I'll play around more with jquery, but has this behavior been observeed by anyone else?
My best advise would be to only have on submit button, and let that submit what ever is the most common usage of the form. Let the rest of the buttons just be normal buttons, which you can hook click events onto.
Just make sure you make it very clear which button will be "pressed" when the user hits enter. Let the submit button be the biggest one. If you have 3 buttons that are used equally as much, I would just drop having a submit button at all...
edit: I'm pretty sure most browsers will post all the data inside a form. If you want to do some checking on the data before posting you could add a listener for onsubmit
<form onsubmit="checkData(this);" ... >
Passing in this will let you check which form is actually being submitted:
function checkData(form) {
var formName = form.id;
//check all the data based on which form is being submitted
}
The HTML5 spec specifies synthetic click activation steps for implicit form submission:
A form element’s default button is the first Submit Button in tree order whose form owner is that form element.
If the user agent supports letting the user submit a form implicitly (for example, on some platforms hitting the "enter" key while a text field is focused implicitly submits the form), then doing so for a form whose default button has a defined activation behavior must cause the user agent to run synthetic click activation steps on that default button.