How to set current item in App Maker datasource? - google-app-maker

This seems basic but I can't seem to figure out how to manually set the current item to work with from the datasource?
To illustrate: I have a table and I notice that when I select a row to edit a field, the item of that row becomes the current item, so if I have a link on that row to Navigate to a page, the row of the item selected will be the datasource.item for the navigated page.
However, I also notice that if I just hover over a row, without selecting to edit a field, if then I click on a link to Navigate to a page, it loads the data of whatever row was previously selected/edited. Therefore I'm wondering how to make it so that just on a mouse:over (or click on the shortcut without a prior click on another field in the row) the datasource.item will update to the the row the mouse has gone over instead of requiring to edit a field on the row first. I hope that makes sense.
Assistance is much appreciated. Thank you!

Why it happens:
AM code: generate button click event
User code: handle button's click event
User code: navigate user to different page
AM code: destroy DOM of current page
AM code: build DOM for new page
-- dead code after this line
AM code: row click event handler
AM code: change datasource's current item
Row's click event handler never gets control, because row is destroyed by user's code.
What Morfinismo's solution does?
AM code: generate button click event
User code: handle button's click event
AM code: row click event handler
AM code: change datasource's current item
-- moved lines
User code: navigate user to different page
AM code: destroy DOM of current page
AM code: build DOM for new page
Here are more tech details: Event Loop
In App Maker this problem can be solved with
setTimeout
Force current item update in user code
// button's onClick event handler
app.datasource.ListDatasource.selectKey(widget.datasource.item._key);
CustomProperties
// button's onClick event handler
app.pages.ShowMeNext.properties.Key = widget.datasource.item._key;
app.showPage(app.pages.ShowMeNext);
// next page's onAttach event handler
app.datasources.RecordDatasource.filters._key._equals = app.currentPage.properties.Key;
app.datasources.RecordDatasource.load();
URL parameters and history - this approach is used in most template apps, because it also implements deep linking on some extent.
// button's onClick event handler
var params = {
key: widget.datasource.item._key
};
var page = app.pages.ShowMeNext;
app.showPage(page);
google.script.history.replace(null, params, page.name);
// next page's onAttach event handler
google.script.url.getLocation(function(location) {
app.datasources.RecordDatasource.filters._key._equals = location.parameters.key;
});
Passing value between pages using global scope
// button's onClick event handler
window.key = widget.datasource.item._key;
// next page's onAttach event handler
app.datasources.RecordDatasource.filters._key._equals = window.key;
ListDatasource - list/grid/table datasource
RecordDatasource - datasource dedicated for a specific record (single-record datasource)

Use a timeout function. This happens because it takes some time for appmaker to change the item in the datasource. You can use something like this on the onClick event handler of the button or link that will take you to the other page:
setTimeout(function(){
app.showPage(app.pages.pageToNavigate);
},200);
That should take care of the issue. I hope this helps!

Related

Which page event could be used for the following purpose?

I have a page which is having the following
Some ddl's for Filter the data
A Submit button
A export Button
A GridView
In general We show/hide Export button if submit query results more than zero rows/ no rows
NOTE:
It is not only the case for one button but there would be more and i will have to check for the permission for every where i show /hide the buttons
For Example
Page_Load
showHideAsPerPermission(btnExport);
BtnSubmitClick()
if rows>0
btnExport.Visible = true;
else
btnExport.Visible = false;
But for the purpose of Permission
I want to set Export button visibility to true/false after BtnSubmit_click (or all controls events like selected index change, textChanged etc.) event has fired
A little Explanation of my problem
Say if you have permission to export then it only visible when rows>0 and if you don't have then it invisible even rows>0 but if i set the permission on page load and then i set exports visibility true for rows > 0 then it is visible even you don't have permission so is there any event which fires after control events
Is there any method which i can utilize for this purpose
I have read the following events and tried Page_Unload event which actually does nothing cause page is already rendered
So is there any method which could accomplish my task
Note:
As per my Knowledge there is no such Event so can i create a custom page event?
Just do it in Page_Load.
Keep in mind, on BtnSubmit_click, the page will post back, Page_Load is going to execute again (so you'll probably need something like if (!IsPostback)...), and then BtnSubmit_click.

jQUery Mobile - how can I pass back values on dialog close?

I have a form page that opens a dialog in order to enter new information. I open the dialog in the "standard" jQM way:
Open dialog
What I need to do is pass back some of the values that were entered so that I can update the page with those values. How do I do that?
As an added bonus, I also really need to be able to submit the values. It seems like jQuery Mobile is setup close the page on any link click. This is an ASP.NET application, and so I need for the page to last long enough to hit the Button_Click() event in the code behind.
Here's the pieces you need:
Html in the dialog:
Cancel
Submit
In pagecreate:
$("#btnSave", pagediv).live('click', function () {
var s = page.Model;
s.serverName = $("#txtName", pagediv).val();
s.Save(function () {
$('.ui-dialog').dialog('close');
});
});
s.Save is a function that writes to the datastore, updates a global model object that is accessible to all pages, then calls the callback function.
In the pageshow handler for the parent page, update the controls from the model. You can't update the parent page directly from the dialog as the parent page may not exist at that point - if data-dom-cache isn't set, it will be removed as soon as the dialog is displayed and will not be recreated until you call close.

Button click event handler before page load

I will describe my problem in simple way so it's not exactly what I'm trying to do but the idea is the same.Here is the problem:
I create dynamic buttons from code behind.I get some id from query string,create button with that id ,dynamic add event handler to click event,and add button to placeholder.I store the list of id-s in session and in page load method recreate these buttons and add to placeholder.One of the id-s is CurrentId and it's also stored in session.Buttons click handler do something like this
Button b=(Button)sender;
Session["CurrentId"]=Convert.ToInt32(b.ID);
In page load when I create buttons I want to set button text property different from others if id==Convert.ToInt32(Session["CurrentId"]) when list of id-s are gotten from session.But problem is that click event handler is called after page load,and when I create buttons in page load ,CurrentId in session hasn't been channged by click event handler.Can you suggest any solution to this situation?
It looks like you are attempting to update the buttons you have dynamically created after the click event has fired. Why not just change the button text within the click event as you have described?
i.e.
protected void button_Clicked(object sender, EventArgs e)
{
((Button)sender).Text = "Custom text for active button";
}
Also, you can always update the buttons on the PreRender event which occurs after the control click events but before the controls are served back down to the client.

One update panel updated and other one is also updated?

I have scenario, I have two update panels on the page (both have update mode='conditional'). If I update one update panel the other is automatically updated. This is first problem.
I am using UpdatePanelAnimationExtender. If one update panel is updated, that don’t have updatepanelAnimationExtender other one also updated and that have updatepanelAnimationExtender, OnUpdatingUpdatePanel(); event is fired.
As the documentation of updatepanelAnimationExtender says:
http://www.asp.net/AJAX/AjaxControlToolkit/Samples/UpdatePanelAnimation/UpdatePanelAnimation.aspx
OnUpdating - Generic animation played as when any UpdatePanel begins updating
OnUpdated - Generic animation played after the UpdatePanel has finished updating (but only if the UpdatePanel was changed)
Problem: OnUpdating fired and it worked backend and not finished because onUpdated only fired when an UpdatePanel Changed
"Add 2 update panel on page, set updatemode='conditional' for both and add load event for both updatepanel and set breakpoint for both load event and add 1 button and then add Asyn trigger for button click on 1 update panel.... you will notice when you hit button, it should load only triggered update panel and 2nd one remain unchanged, but 2nd updatepanel is load event also fired"
This will happen only if the button is inside the 2'nd updatepanel? If not, then I dont think it will update the second update panel. Could you confirm if the button is inside or outside the second updatepanel?
I just had this same issue. Two update panels on the same page that are NOT nested and have UpdateMode="Conditional". Just realize that when one update panel on a page triggers a partial postback, all update panels will get the updating event triggered. If you have an UpdatePanelAnimationExtender hooked up to UpdatePanel A, and a partial postback is triggered for an unrelated UpdatePanel B, both will get the updating event triggered, and the animation for UpdatePanel A will only run the OnUpdating part and not the OnUpdated part (so basically the animation will run half way).
This is how I fixed this issue:
Determine which update panel was triggered. This can be found by getting the value of the form variable for the script manager. The update panel in question will be mentioned in the string. Use this info to perform an action based on your needs.
// Variable to hold ScriptManager. Just slap this in the class for the page.
private ScriptManager scriptManager;
// Get the ScriptManager. Put this in Page_Init handler.
// If you have the ScriptManager on the same page, just refer to it directly.
// If you have it on the master page, you can get a reference to it like so.
// The second line shows one way you can get a reference to the ScriptManager from
// a user control.
// FYI, the same code applies to a ToolkitScriptManager.
scriptManager = ScriptManager.GetCurrent(this);
// scriptManager = ScriptManager.GetCurrent(HttpContext.Current.Handler as Page);
// This function checks whether an UpdatePanel is being updated
private Boolean IsUpdatePanelUpdating(String sUPID)
{
String sUpdateValue = Request.Form[Request.Form.AllKeys.Where(s => s.EndsWith(scriptManager.ClientID)).FirstOrDefault()] ?? String.Empty;
return sUpdateValue.Contains(sUPID);
}
// This is code you can put somewhere (say within OnLoad handler) to make an
// UpdatePanel A get updated even if an unrelated UpdatePanel B is currently being
// updated.
if (!IsUpdatePanelUpdating(upA.ClientID))
upA.Update();
I hope this helps someone.

onclick event not working after ASP.net AJAX save

I have an gridview that I am adding onclick events to a checkbox column via:
cb.InputAttributes.Add("onclick", "checkClick()");
everything works fine, but when the user clicks the save button on the form, (which is within the updatepanel), suddenly the onclick event of the checkboxes stops firing!
Is this a problem with the ASP.NET AJAX?
The weird thing is that I am seeing the onclick event on the source, it just doesn't fire.
Help!
The source will show you the state of the document when first received from the server, not the current state of the DOM. What is likely happening is the update panel content is being replaced by new HTML content. The elements to which the original click events were bound are no longer in the dom.
The onclick events will need to re-bound to wire-up to the new elements that have arrived.

Resources