Query Script Datasource not updating on change - google-app-maker

I have a table that has a button on each row to assign a arrival boolean and timestamp on the record in the row. When I click the button that record is not showing as updated on the client. If I refresh the browser or use a button to reload the datasource, the changes are seen.
The datasource model is Guests with a query script datasource of Guests_unchecked. The query script only displays guests that have not arrived, thus widget.datasource.item.arrived = false.
When I click the check in button this script is fired.
widget.datasource.item.arrived = true;
widget.datasource.item.arrival_timestamp = new Date();
widget.datasource.load();
No updates to the datasource appear until I reload the page.
Any help would be appreciated.
Thanks

Related

Appmaker Reloading datasource on onInputChange event issue

I have a table with a search bar above it. The content of the search bar filters the query for the table. I want the data in the table to be reloaded each time the user inputs a letter.
If I set the onValueEdit event to Reload the Datasource, it reloads the data just right, but if I set the onInputChange event to do the reloading, it reloads the table without filtering the query, displaying all of the records. No matter what I type in, it does not filter at all (altough it does seem to reload the datasource), unless I hit enter, fireing the onValueEdit event, when it does the filtering. Any ideas why can't I filter the query with the onInputChange event?
Thank you in advance!
The onInputChange event does not appear to support the value binding of a particular widget. Whether this is a bug or the intended behavior is unknown. There are two options to circumvent this behavior however and they are as follows:
Change your code in the onInputChange event to:
Option 1:
widget.value = widget.value;
widget.datasource.load();
Option 2:
widget.value = event.target.value;
widget.datasource.load();

How to set current item in App Maker datasource?

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!

Programmatically created RadioButtonList needs 2 clicks

I have a page (using MS Ajax). depending on other options, I may need to create a radio Button List inside a Panel.
This is done as per below.
RadioButtonList rbl = new RadioButtonList();
rbl.SelectedIndexChanged += new EventHandler(answer_Click);
rbl.AutoPostBack = true;
foreach (KeyValuePair<string, int> d in _answers)
{
ListItem li = new ListItem(d.Key.ToString(), d.Key.ToString());
li.Attributes.Add("class", "radio");
rbl.Items.Add(li);
}
p.Controls.Add(rbl);
this works fine, unless after the postback I need another RadioButton List. The list is drawn correctly, with all the correct options, but now when I click on an option the first time, it fills in and then resets. It takes a second click to get it to set and trigger the SelectedIndexChanged Event.
Im destroying and recreating the rbl once answer_Click is triggered (I know this as the next question that is created has different answers and options).
So, any ideas as to why it is I need to click twice on the second List?
Matt!
Looks like you have a ViewState issue. Controls are created after the LoadViewState trigger, so they doesn't get their values from the browser to load. You must save this value somewhere, using JS, ViewState, QueryString, Session, DB to persiste the state, and then load the selected value into each one.
Hopes this help you! Take a look here for more info about ASP.NET Page Life Cycle.

ASP.NET: Find which element had focus before postback?

I have a series of controls on a page, including some textboxes that serve to record employee timesheet. When OnTextChanged fires, the page postback and update the overall working hours and minutes.
The problem is, when the user clicks the save button, a postback happens, but it is not because of save button's action but because OnTextChanged has fired. The user believes that the saving has gone well until he/she access the page again and doesn't find his/her data. It's next to the impossible to explain to user that they need to click twice because the first time the textbox loses focus and the second time it's the right one.
Is there a way to store the value of the last element that had the focus before the postback occured? I've tried to access the value of __LASTFOCUS, but I'm getting an empty string.
string lastFocus = Page.Request.Params.Get("__LASTFOCUS");
Thanks for helping
If you are trying to grab the last control that lost focus which has AutoPostBack="true", I believe you can get the Name of this control from Request.Form.Get("__EVENTTARGET"). This form variable contains the ID of any control invoking postback (in most, if not all, scenarios).
I have a similar situation with a GridView with an arbitrary amount of textboxes, each with AutoPostBack on and OnTextChanged event handlers. What I wanted to do was be able to tab out of a textbox, postback, then restore focus to the textbox that had focus before postback e.g. the textbox that I tabbed to.
This is what I ended up with:
function RestoreFocus(source, args) {
var val = $("#<%=postbackFocusID.ClientID %>").attr("value");
var el = document.getElementById(val);
if (el != null)
el.focus();
}
function PersistElementThatHasFocus(source, args) {
$("#<%=postbackFocusID.ClientID %>").attr("value", document.activeElement.id);
}
function AddRequestHandler() {
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(RestoreFocus);
prm.add_beginRequest(PersistElementThatHasFocus);
}
The postbackFocusID is just an asp:HiddenField.

Combo box refresh after click button event

I have a combobox binded to a stored procedure which pulls in Years
the click event button deletes whichever year is selected and that works as I can confirm the record is actually deleted on the back end in the database. But after the delete the combo box doesnt refresh and still shows the old record. Any ideas?
You need to query the data again and call combo.DataBind() or delete the item yourself.

Resources