Knockout asyncCommand - hit from a method - asynchronous

I want to alter how an asyncCommand is being hit (currently from a button), so I would need to access the asyncCommand from code. I don't want to have to alter what this asyncCommand is doing, it is dealing with payment details.
I have tried Googling but I cant find anything, I am also new to KO.
This is what I'm trying to achieve:
Click on a button (a separate button with its own asyncCommand method
which checks a flag) The 'execute' will do the following:
If (flag) - show modal
modal has two options - Continue / Cancel
If continue - hit asyncCommand command for original button (card payment one).
If cancel - go back to form
If (!flag)
Hit asyncCommand command for original button (card payment one).
Can this be done?
Thanks in advance for any help.
Clare
This is what I have tried:
FIRST BUTTON
model.checkAddress = ko.asyncCommand({
execute: function (complete)
{
makePayment.execute();
if (data.shippingOutOfArea === true || (data.shippingOutOfArea === null && data.billingOutOfArea === true)) {
model.OutOfArea.show(true);
}
complete();
},
canExecute: function (isExecuting) {
return !isExecuting;
}
});
ORIGINAL BUTTON
model.makePayment = ko.asyncCommand({
execute: function (complete) {
}})
MODAL
model.OutOfArea = {
header: ko.observable("Out of area"),
template: "modalOutOfArea",
closeLabel: "Close",
primaryLabel: "Continue",
cancelLabel: "Change Address",
show: ko.observable(false), /* Set to true to show initially */
sending: ko.observable(false),
onClose: function ()
{
model.EditEmailModel.show(false);
},
onAction: function () {
makePayment.execute();
},
onCancel: function ()
{
model.EditEmailModel.show(false);
}
};

You will have two async commands actually for this scenario. One to open up the modal and another one for the modal.
Eg:
showPaymentPromptCmd = ko.asyncCommand({
execute: function(complete) {
if (modalRequired) {
showModal();
} else {
makePayement();
}
complete();
},
canExecute: function(isExecuting) {
return !isExecuting;
}
});
//Called by Continue button on your modal.
makePaymentCmd = ko.asyncCommand({
execute: function(complete) {
makePayement();
complete();
},
canExecute: function(isExecuting) {
return !isExecuting;
}
});
var
function makePayement() {
//some logic
}

Related

Fullcalendar using resources as a function with select menu

Using Fullcalendar 4, I am trying to show/hide my resources using a select menu. When the user selects one of the providers from a menu, I want to only show that one resourc's events.
Above my fullcalendar I have my select menu:
<select id="toggle_providers_calendar" class="form-control" >
<option value="1" selected>Screech Powers</option>
<option value="2">Slater</option>
</select>
I am gathering the resources I need using an ajax call on my included fullcalendar.php page. I am storing them in an object and then trying to control which resources are shown onscreen:
document.addEventListener('DOMContentLoaded', function() {
var resourceData = [];
$.getJSON('ajax_get_json.php?what=schedule_providers_at_location',
function(data) {
$.each(data, function(index) {
resourceData.push({
id: data[index].value,
title: data[index].text
});
});
console.log(resourceData);
});
//below, set the visible resources to whatever is selected in the menu
//using 1 in order for that to show at start
var visibleResourceIds = ["1"];
//below, get the selected id when the the menu is changed and use that in the toggle resource function
$('#toggle_providers_calendar').change(function() {
toggleResource($('#toggle_providers_calendar').val());
});
var calendar_full = document.getElementById('calendar_full');
var calendar = new FullCalendar.Calendar(calendar_full, {
events: {
url: 'ajax_get_json.php?what=location_appointments'
},
height: 700,
resources: function(fetchInfo, successCallback, failureCallback) {
// below, I am trying to filter resources by whether their id is in visibleResourceIds.
var filteredResources = [];
filteredResources = resourceData.filter(function(x) {
return visibleResourceIds.indexOf(x.id) !== -1;
});
successCallback(filteredResources);
},
...
});
// below, my toggle_providers_calendar will trigger this function. Feed it resourceId.
function toggleResource(resourceId) {
var index = visibleResourceIds.indexOf(resourceId);
if (index !== -1) {
visibleResourceIds.splice(index, 1);
} else {
visibleResourceIds.push(resourceId);
}
calendar.refetchResources();
}
To make sure the getJSON is working, I have console.log(resourceData). The information in the console once it's gathered is:
[{id: '1', title: 'Screech Powers'}, {id: '2', title: 'Slater}]
... the above are the correct resources that can be chosen/rendered. So that seems to be okay.
On page load, no resources show at all, when resource id of '1' (Screech Powers) should be shown per my code. Well, at least, that's what I am trying to do right now.
When the menu changes, resources will show/hide, but not based on what's selected; the logic of only showing what is selected in the menu doesn't seem to be working.
I used to use a URL request for my resources: 'ajax_get_json.php?what=schedule_providers_at_location', and it worked fine! All resources show then their events properly. I am just trying to modify it by using a menu to show/hide the resources as needed.
Here's what I'm doing to make it happen so far! In case someone comes across this post ever, this will help.
Here's my code before my fullcalendar code.
var resourceData = [];
var visibleResourceIds = [];
$.getJSON('ajax_get_json.php?what=schedule_providers_at_location',
function(data) {
$.each(data, function(index) {
resourceData.push({
id: data[index].value,
title: data[index].text
});
});
});
$('#toggle_providers_calendar').change(function() {
toggleResource($('#toggle_providers_calendar').val());
});
My select menu with id 'toggle_providers_calendar' is the same as my original post. My fullcalendar resources as a function is the same too.
After the calendar is rendered, here are the changes I made to my toggle resources function:
// menu button/dropdown will trigger this function. Feed it resourceId.
function toggleResource(resourceId) {
visibleResourceIds = [];
//if select all... see if undefined from loading on initial load = true
if ((resourceId == '') || (resourceId === undefined)) {
$.map( resourceData, function( value, index ) {
visibleResourceIds.push(value.id);
});
}
var index = visibleResourceIds.indexOf(resourceId);
if (index !== -1) {
visibleResourceIds.splice(index, 1);
} else {
visibleResourceIds.push(resourceId);
}
calendar.refetchResources();
}
This causes the resources to show and hide properly. If the user selects "Show All" that works too!
In order to have a default resource show on load, I add this to my fullcalendar script:
loading: function(bool) {
if (bool) {
//insert code if still loading
$('.loader').show();
} else {
$('.loader').hide();
if (initial_load) {
initial_load = false;
//code here once done loading and initial_load = true
var default_resource_to_show = "<?php echo $default_provider; ?>";
if (default_resource_to_show) {
//set the menu to that provider and trigger the change event to toggleresrource()
$('#toggle_providers_calendar').val(default_provider).change();
} else {
//pass in nothing meaning 'select all' providers for scheduler to see
toggleResource();
}
}
}
},
I am using a bool variable of initial_load to see if the page was just loaded (basically not loading data without a page refresh). The bool of initial_load = true is set outside of DOMContentLoaded
<script>
//show selected date in title box
var initial_load = true;
document.addEventListener('DOMContentLoaded', function() {
My only current problem is that when toggleResource function is called, the all day vertical time block boundaries don't line up with the rest of the scheduler. Once I start navigating, they do, but I don't understand why it looks like this on initial load or when toggleResource() is called:
Any thoughts on how to correct the alignment of the allday vertical blocks?

Why I can see view1 after I triggering navigation to view2 (integration testing)

I have some questions about integration testing (OPA5, sapui5): I have created simple project which has 2 views (View1.view.xml and View2.view.xml), and I have sap.m.Button on the first view. After I press this button I'll navigate to the second view. So I have implemented OPA5 tests to check this functionality. So now I'm simulating user's click at button and Navigation is working properly. But If I want to check visibility View1.view.xml after triggering navigation I will get "test passed" result! I guess that tests are executed asynchronously that is why I have had this results. And how can I catch moment when test will finish to execute next?
UnexpectedbehaviorJourney.js
QUnit.module("Unexpected behavior");
opaTest("Why do I see View1.view after Navigation was pressed?",
function (Given, When, Then) {
// Arrangements
Given.iStartMyApp();
//Actions
When.onTheAppView.iLookAtTheScreen().
and.iPressNavigateButton();
// Assertions
Then.onTheAppView.iShouldSeeView1AfterTriggeringNavigation();
// and.iTeardownMyAppFrame();
});
UnexpectedBehavior.js
actions : {
iPressNavigateButton : function () {
return this.waitFor({
id : "idButton",
viewName : "View1",
actions: new Press(),
errorMessage : "Button control wasn't pressed"
});
}
},
assertions : {
iShouldSeeView1AfterTriggeringNavigation : function () {
return this.waitFor({
id : "idView1",
viewName : "View1",
success : function () {
ok( true, "Why I can see View1.view?");
},
errorMessage : "Navigation has worked as expected!"
});
}
}
View1.controller.js
return Controller.extend("InvestigateOPA.controller.View1", {
onPress: function() {
this.getOwnerComponent().getRouter().navTo("appView2");
}
});
Do you have any idea how can I prevent this behavior?
Shouldn't the assertion be a check for View2 visibility?
else try something like below
nb. you can use Qunit and Sinon functions like a delay/timer or a native promise etc.
iShouldNotSeeView1AfterTriggeringNavigation : function () {
return this.waitFor({
id: "app",
viewName: "App",
check: function(oApp) {
return oApp.getCurrentPage().getId() !== "__component0---View1"
},
success: function() {
ok( true, "View1 not current page");
},
errorMessage: "Navigation has not worked as expected!"
});
I have found that the one way to solve my problem is set "transition" property to "show":
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"viewType": "XML",
"transition": "show",
"viewPath": "InvestigateOPA.view",
"controlAggregation": "pages",
"controlId": "app"
},
In this case there is no visual delay when one view change another, so my OPA tests will work correctly.
p.s. thx a lot for your ideas!

SemanticUI: how to trigger a form validation maually / in modal

When a modal window is started, there will be no form validation if you use the default way:
$('#someModalWindow')
.modal({
inline: true,
onDeny: function () {
// someting
},
onApprove: function () {
// some action
}
})
.modal('show');
How can a form validation be triggered manually or automatically in the modal window.
I am using meteor below SemanticUI
thanks
I figured out how to do it:
$('#someModalWindow')
.modal({
onDeny: function () {
// someting
},
onApprove: function () {
var validated = $('#myFormId').form('validate form');
if(!validated){
return false;
}
// some action
}
})
.modal('show');
hopefully this can help you.

JQuery-Button not pressed when executed through dialog button

Here's my function:
function confirmFamilyMemDelete()
{
$('#dialog').attr('title', 'Warning').text('Are you sure?').dialog({ buttons:
[{
text: 'Yes',
click: function ()
{
$('#MainContent_cph_btnConfirmDelete').click();
$(this).dialog('close');
alert('Hello');
}
},
{
text: 'No',
click: function ()
{
$(this).dialog('close');
}
}
]
});
return false;
}
I've got a very weird problem. In my aspx page there's a button that gets an id 'MainContent_cph_btnConfirmDelete' after it gets rendered. I want to click it if Yes button is clicked in the jQuery UI dialog. However, I fail to do it. It just skips over that command and alerts 'Hello'. This means the rest of the code inside my Yes button gets executed. And if I take
$('#MainContent_cph_btnConfirmDelete').click();
out and put it just before return false; the button gets clicked. Is this a know issue with jQuery because I can't think of any logical explanation. If so, what is the workaround?
Here is what I think you need:
function confirmFamilyMemDelete()
{
$('#dialog').attr('title', 'Warning').text('Are you sure?').dialog({ buttons:
{
"Yes": function ()
{
$('#MainContent_cph_btnConfirmDelete').trigger('click');
$(this).dialog('close');
alert('Hello');
},
"No": function ()
{
$(this).dialog('close');
}
}
});
return false;
}

Conditionally load jquery throbber plugin

I have the code below that shows a throbber and makes a getJSON call to an MVC action when the user changes an entry in a select. This all works great except there is a default -- select -- element in the list for which I don't want the getJSON to run.
However, I can't work out how to apply conditional logic to hooking this event. The conditional logic is shown as the if(selectedValue == -1) But the throbber still runs as I've hooked it in the first line. I've tried removing the first line that hooks the change event and use $.throbberShow(..) inline just prior to the getJSON call but for some reason this doesn't show the throbber.
Any help greatly appreciated.
$("#selectlist").throbber("change", { ajax: false, image: "images/ajax-loader-line.gif" });
$("#selectlist").change(
function () {
var selectedValue = $("#selectlist").val();
if (selectedValue != -1) {
//Tried doing $.throbberShow(...) here without success
$.getJSON("/Candidate/GetAddress", { id: selectedValue }, function (data, textStatus) {
if (textStatus == "success") {
$("#selectlist").val(data.Line1)
$("#selectlist").val(data.Line2)
$("#selectlist").val(data.Line3)
$("#selectlist").val(data.Town)
}
$.throbberHide();
});
}
}
);
It is more a hack than a solution as throbber doesn't support conditions but this should work:
$("#selectlist").throbber("change", { ajax: false, image: "images/ajax-loader-line.gif", delay: "500" });
$("#selectlist").change(
function () {
var selectedValue = $("#selectlist").val();
if (selectedValue != -1) {
$.getJSON("/Candidate/GetAddress", { id: selectedValue }, function (data, textStatus) {
if (textStatus == "success") {
$("#selectlist").val(data.Line1)
$("#selectlist").val(data.Line2)
$("#selectlist").val(data.Line3)
$("#selectlist").val(data.Town)
}
$.throbberHide();
});
} else {
$.throbberHide();
}
}
);

Resources