I know this is probably a very simple question, but can someone please walk me through how to take what a user inputs into a s:TextInput and use that as a variable in a JSON data request?
Basically, I want to have a user enter a search term, like "math" and then have that placed into a variable so I can use it in a JSON request.
Something like public var q:String, except that my search box (and hence user input) is on another "view" of the application.
I've just started with Flex Mobile applications and I might be way out of my league. Does anyone know how to do this?
The containing view should still be able to access teh child view's properties (and therefore controls); you just need the control(s) to have a unique ID, which then becomes a property name. That said, I would consider the whole search feature to be self-contained, so it'd have its own controller (action script class for handling actions) wired up to the search button, adn have a reference to the view that it can extract the info from, etc.
Related
I created a click event in adobe launch which will capture the value of the link and send it to analytics. I have created a data element for saving the value and in my DOM I am saving value in local storage.
Local storage code:
$('.card').click(function() {
var name = $(this).text();
localStorage.setItem('productName', name);
});
My problem is when I click the first link no value got saved, but after when I click second link it saves the value of first link and on third link saves value of second link and so on. I want to save current link value in evar3 variable.
Data element:
Rule:
Set variables:
Thanks,
Harshit
I'm scratching my head a little bit about why your jQuery selector doesn't match your Rule selector, but that's probably not immediately related or relevant, considering you said you are seeing data pop, in general, so at face value, I'm going to ignore that.
But in general, it sounds like your jQuery code is getting executed after the Rule is evaluated, so it's effectively one step behind. I'm not sure there's much if anything you can do about that if you aim to keep two separate click event listeners like this.
You're going to have to restructure to have one chain off the other (which I don't think is actually feasible with jQuery > Launch as-is. Maybe if you write two separate custom code blocks with promise chaining but that kind of sidesteps Launch and IMO is over-complicating things to begin with (see below)). Better yet, merge them into a single click event listener. On that note..
Why do you have two separate click event listeners? Is the sole reason for this to pass off the link text? Because you can reference the clicked element in the Launch Rule itself.
You should be able to reference %this.innerText% in the Set Variables fields. Or you can reference this object in custom code boxes within the Rule.
IOW at face value I don't see why you need or should be creating/using that jQuery listener or pushing to local storage like that.
Update:
You commented the following:
I tried with %this.innerText% it is also not showing current values. I
am pushing the value first to local storage because my link values are
generating on runtime through an API. They are not hardcoded. I am
also trying to figure out why my rule is getting fired before my
jquery is evaluated. But when I check in console using
_satellite.getVar('Product Name'); it shows me the correct value, but in debugger console value is wrong. Can you show me the way you want
to create rule to getting it fired correctly ? Thanks,
Okay so your link values are generated runtime through an API call? Well okay now that sounds like where the (timing) issue is, and it's the same issue in principle I mentioned you prolly had between the jQuery and Launch code. Assuming you can't change this dynamic link functionality, you have two options:
1. Explicitly trigger a launch rule (direct call rule) in a callback from the API code that's generating the link values.
This is the better method, because you won't have race condition issues with your API vs. link tracking code. The biggest caveat about this method though is that it requires requires you to actively add code to the site, which may or may not be feasible for you.
I have no idea what your code for generating the link looks like, but presumably it's some ajax call and generated from the success callback. So in the callback, you'd add a line of code something like this:
_satellite.track('product_image_click', {
text : elem.innerText
});
Again, I don't know what your API code that generates the link looks like, but presumably you have within it some element object you append to or update the DOM, so for this example, I will refer to that as elem.
'product_image_click' - This is the value you use for the direct call rule identifier in the interface, e.g. :
And then _satellite.track() call also includes an object payload in 2nd argument that you can pass to the direct call rule. So in the code above, I set a property named text and give it a value of elem.innerText.
Then, within the direct call rule, where you set variables, the data you passed can be referenced from event.details object within custom code box (e.g. event.details.text), or using % syntax within the interface fields (e.g. %event.details.text%).
2. Make use of setTimeout to delay evaluating the link click.
The one advantage of this method over option #1 is that it is passive. You don't have to add code directly to your site to make it work.
However, this is the shadier option, because you don't really know how long it will take for your link to be generated. But generally speaking, if you can determine it takes on average say 250ms for the link generation API to do its thing, and you set the timeout to be called at say 300-500ms, then you will probably be okay most of the time. However, it's never a 100% guarantee.
In addition, if clicking on the link ultimately redirects the visitor to another page, then this solution will likely not work for you at all, since the browser will almost certainly have navigated before this has a chance to execute. Because of this, I normally I wouldn't even mention this as an option, but since you mentioned this link involves an API that generates the link values when clicked, I figured maybe this isn't a navigation / redirect link, so maybe this is an option you can go for, if you can't do option #1.
First, create a direct call rule the same as shown in option #1. This will be the rule that receives the link text and makes the Adobe Analytics (or whatever other marketing tag) calls.
Then, create a separate rule as a click event, similar to what you are currently trying to do (listening for the link click, based on your css selector). In this rule, you won't be setting any AA variables. Instead, add a custom js box with code like this:
var elem = this;
(function (elem) {
window.setTimeout(function() {
_satellite.track('product_image_click', {
text : elem.innerText
});
}, 500);
})(elem);
So when the rule is triggered, it will create a setTimeout callback to call the first rule, passing the link text in the payload. And.. hopefully the 500ms timeout shown in the code example is enough time for the API to do its thing. You may be able to adjust it up or down.
Rather than defining it in Data Element I would say its better to keep it directly in the Rule itself. Please try with this %this.#text%.
Let me know if this helped.
I want to open all component-dialogs in a new windows or tabs. Is that possible and if yes, how can I do this?
I was thinking of modifying the edit handler of the component. How and where would I do this?
TL;DR:
Depending on what you want to do, it might not make sense, but, you could start here:
info.magnolia.ui.contentapp.detail.action.EditItemActionDefinition
info.magnolia.ui.dialog.formdialog.FormDialogPresenterImpl
maybe even https://www.magnolia-cms.com/blogs/boris-kraft/detail~&headless-or-full-bodied-cms--magnolia-provides-all-the-solutions~.html
Longer answer:
It depends on what you are trying to do - we can get to any state in Magnolia by re-using location fragments like this one: #app:contacts:detail;/ldavinci:edit
That tells me we are in edit mode on a particular path (from root of some workspace) in the detail subapp of the contacts app. What that means in this case is, we've opened a dialog in a tab.
Likewise: #app:contacts:browser;/ldavinci:treeview: represents another state.
So we can programmatically move to new locations if we know the parts of those location fragments. But these are locations (app,subapp,path) within Magnolia, not within a web browser.
A browser tab is not the same thing as a Magnolia tab; the latter represents a tab within a Magnolia form, and hasn't anything to do with a web browser - so it would not open.
Even if we did hijack that action, what you'll get in this case is the whole Magnolia rig, not just the dialog, standalone, in a new browser tab or window, which is not what I suspect you are interested in. If you are interested in the dialog, by itself, independent of the rest of the Magnolia UI, you might have to start looking at
info.magnolia.ui.dialog.formdialog.FormDialogPresenterImpl
146 public DialogView start(..
which calls
165 private void buildView(..
and sets up overlays, etc.
(sepcifically through 167 formPresenter.presentView(..)
...
so then if we look in here:
info.magnolia.ui.dialog.formdialog.FormPresenterImpl:
123 buildForm((FormView) this.formView, formDefinition, item, parent, activeLocale);
which eventually calls this guy
198 private void buildReducedForm(..
and it adds it to existing FormViewReduced (info.magnolia.ui.vaadin.form.FormViewReduced) with a certain modality.
FVR is implemented by
info.magnolia.ui.vaadin.form.Form
which is what should actually display the form.
and the form gets displayed on a
info.magnolia.ui.vaadin.tabsheet.MagnoliaTabSheet
So in info.magnolia.ui.vaadin.gwt.client.tabsheet.widget.MagnoliaTabSheetViewImpl:
...etc. and further on down the rabbit hole, and what would this stuff mean outside the context of Magnolia anyway?
I guess you could also look here:
info.magnolia.ui.contentapp.detail.action.EditItemActionDefinition
You can edit these data over our REST API anyway, so maybe you're trying to move the dialogs out of Magnolia to accomplish something along that line?
So if I have a customer lookup fragment form (i.e. name to lookup and displays address), then need a page with a from and to customer, is there a way to isolate the data binding so that both can be individual?
Currently I can only get the same data to show up in either and so changing one effects the other.
You can override page fragment's datasource:
Once you check 'Override page fragment datasource' checkbox, datasource property will become editable.
Ah got it! In part to what #Pavel responded with....
So in the fragment, the data source is set up pretty much normally:
In the inserted fragments, settings are as follows:
- over-ride checked
- datasource: #Datasources.Addresses.items
Both fragments now act individually on selected name.
I have a web application with a form that has disabled fields in it. It allows a "Save As" function which basically means the settings can be copied into a new configuration (without being modified) and in the new configuration they can be changed to something else. The problem I am running into with this is that since the fields are disabled, they are not getting posted through and do not appear in the context object on the server side.
When I removed the logic to disable the fields, that part works fine. So the remaining problem is, how to "disable" the fields (not allow any change of the data in any of the entry fields) without really "disabling" them (so that the data gets posted through when saving)?
I was originally looking for a way to do this in CSS but not sure if it exists. The best solution is of course, the simplest one. Thanks in advance!
(Note: by 'disabled' I mean "The textboxes display but none of the text inside of them can be modified at all". It does not matter to me whether the cursor appears when you click inside it, though if I had a preference it would be no cursor...)
http://www.w3schools.com/TAGS/att_input_readonly.asp
readonly attribute is what you want.
i would suggest that instead of using the non-updateable field values from the page's inputs, you retrieve the original object from the DB and copy them from there. It's pretty trivial using something like Firebug to modify the contents of the page whose form will be posted back to modify the values, even if they are marked as readonly. Since you really want the values from the original, I would simply reget the object and copy them. Then you don't need to worry about whether the original (and non-updateable) properties get posted back at all.
I have 2 components for example (editor.mxml using mx:windows), when I click an edit button, I want to get the current value from the other component's datafield? (datagrid.mxml using mx:window)
I do know how to access the main MXML's datagrid by parentDocument or Application.application method, but stumped block if I want to access other way as mentioned above. Keep the code as simple as possible.
You could either do dependency injection, that is, give component A a reference to component B so that they can communicate directly (example of tighter coupling,) or have both components communicate through a common mediator using events (example of more loose coupling.)
Both of those options would be implemented wherever it is that you're creating those components (A and B in this example) and adding them to the display list.
This might be more complicated than it deserves, and it smacks of Pattern-Fever, but you could use a mediator class that listens for the CLICK event from the button and knows enough about the other component to query its property. It could even transmit that data using a custom event, which the button listens for.
While this involves three classes instead of two, it often turns out to be easier to have two components that focus on looking good and one that worries about coordination.
Cheers
Try this:
FlexGlobals.topLevelApplication
This points Your root. From the root You can grab every element You want.
You can also add an id to the custom component like this,
<custom:Editor id="myCustomComponent">
</Editor:AddressForm>
and
access your datagrid's value like this,
var data:ArrayCollection = myCustomComponent.DatagridID.dataProvider;