I understand that Ext.Msg.Confirm is asynchronous, and will proceed if you do not provide a callback.
Below is my code - this is called if the user tries to navigate from the current screen while in edit mode. I'm passing in a callback to the method - fn is my callback event, but regardless of how I code this the logic continues to navigate away from the page. Is there anyway to stop propagation until the user has selected yes or no in the confirmation box?
Here is the code for the Confirmation:
displaySaveConfirmation: function(fn) {
var title = 'Do you want to Save?'
var msg = 'You are currently Editing Standard Text. Would you like to save your changes?'
var box = Ext.Msg.confirm(title, msg, function(buttonId, value) {
if (buttonId === 'no'){
fn.call();
} else {
return false;
}
}, this );
box.setZIndex(400);
box.setCls('alert-box');
var buttons = Ext.ComponentQuery.query('button', box);
for (var i=0; i<buttons.length; i++) {
if (buttons[i].getItemId()=="no")
buttons[i].addCls('blackBtn');
else if (buttons[i].getItemId()=="yes")
buttons[i].addCls('blueBtn');
this.addReleaseEvent(box, buttons[i]);
}
},
As of now you do the following:
The event is fired
You open the MessageBox
Your function returns, and it does not return "false".
The browser navigates away before the user can click "yes" or "no".
What you want to do is the following:
The event is fired
You open the MessageBox
Your function returns false.
The browser does not navigate away.
The user clicks "yes" or "no".
If the answer is "yes", you navigate to the previously requested target page manually (e.g. close the browser window, use history.back() or similar).
Alternatively, if the work to get that up and running (and tested, with all the possible cases how to navigate away and how to find the target) is too much, you can opt for the window.alert dialog instead, which does not look nearly as nice, but works synchronously.
Or you can do as I did: I just returned false after bringing up a MessageBox that says: "You cannot leave the page during edit. Please save or abort the post."
Related
I am trying to execute a fuction when a change occurs in one tab, the change should reflect in other tab too.
i write this and it is working fine in the same tab i change even i check manually browser localstorage and see it works nice.
but the problem, the change not reflect in other tab too.
I mean, i opened two tab and when i change something in one tab, in other tab it should reflect.
Whenever any change occurs in one tab, 2nd tab should execute this $scope.getAllContact(); and wait for another change, if another change occurs, $scope.getAllContact(); should be executed.
$localStorage.editedData = response.data;
$scope.editedID = $localStorage.editedData.id;
if (response.data.id == $localStorage.editedData.id) {
$localStorage.isChanged = true;
}
while ($localStorage.isChanged == true) {
$scope.getAllContact();
break
}
I write above code;
Ignore below this code if you undertand above few line, below code is fuction, when change occurs, the fuction should be executed:
$scope.getAllContact = function() {
var data = $http.get("http://127.0.0.1:8000/api/v1/contact")
.then(function(response) {
$scope.contacts = response.data;
// below two line of codes will reload in every 10 millisecond if a request succcess
// in result, you will see refleation in other browser if any change occurs in another browser
// do nothing for now
}, function(response) {
//$scope.connectionError = "Opps ! Having Trouble in loading this page ! \n It's Connection Error !!!";
// below two line as as above two commented line
// do nothing for nw
});
};
$scope.getAllContact();
You need to check your local storage at a certain time difference
setInterval(function(){
if ($localStorage.isChanged == true) {
$scope.getAllContact();
}
}
}, 500);
See below code may helpfull
$scope.$apply(function() {
$scope.contacts = response.data;
});
or
As per my assumption at a time you can see only one tab. So,call $scope.getAllContact()
whenever your clicking on second tab.
I need trigger a specific dialog in ibm-watson conversation, but without ask the user to type something (like a intent). I need to use botkit to init a specific dialog. That's is possible? I'm looking for in all possible documentation and links at Google, but not successfully :/
Sending initial empty message triggers welcome event in the dialog.
To make it do something different, you could set some variable in the context and add condition for that variable to welcome branch in the dialog.
This is how I implemented it in my bot:
function handleHelloEvent(bot, message) {
message.type = 'welcome';
const contextDelta: any = {};
if (message.intent) {
contextDelta.initialIntent = message.intent;
}
//more fields here
watsonMiddleware.sendToWatsonAsync(bot, message, contextDelta).catch((error) => {
message.watsonError = error;
}).then(() => {
//this is the same function which handles message_received events
return handleWatsonResponse(bot, message);
});
}
function handleWatsonResponse(bot, message) {
bot.reply(message, message.watsonData.output.text.join('\n'));
}
controller.on('hello', handleHelloEvent);
controller.on('message_received', handleWatsonResponse);
hello event is specific to webchat/botkit anywhere, you may need to handle different events for different platfoms.
A similar example of code handling welcome event: https://github.com/watson-developer-cloud/botkit-middleware/#dynamic-workspace
(I wrote that one too, so it is a bit too similar).
Dialog example:
I have an angularjs webpage that prompts when I perform certain action on the page. The code should ignore and continue if there is no prompt, but if a prompt appears then ensure that the javascript prompt is accepted.
When I use firebug, I get the following property of the element.
/html/body/div[2]
The div[number] changes as and when I go to this page.I am not able to use the same in XPath as everytime the test case is executed, the div element would change. Also the div has an attribute of tabindex = -1.
bool status = false;
WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(10));
IWebElement alert;
if (wait.Until(ExpectedConditions.InvisibilityOfElementLocated((By.XPath("/html/body/div[2]")
{
Console.WriteLine("I am in if loop");
status = false;
}
else
{
Console.WriteLine("I am in else loop");
alert = Browser.Driver.FindElement(By.XPath("/html/body/div[2]"));
((IJavaScriptExecutor)webDriver).ExecuteScript("arguments[0].click()", alert);
status = true;
}
return status;
How do I handle such a dialog box and ensure that the same is accepted when it appears.
Thanks.
You can derive the xpath using the title of the alert. May be like below. (I do not know the exact html, just imagining the header text is in some span tag)
alert = Browser.Driver.FindElement(By.XPath("/html/body//div/span[contains(text(),'Apply changes to controller configuration')]"));
(//) can avoid using index to your div tag.
Trying to do a simple scroll to the top of my page when the user clicks the 'edit' button. For some reason, when I try to set the $location.hash, it will not run any code following it.
It will put the value into the console, and in the browser address bar, but nothing after.
If you click 'edit' again, (the location value will be in the address bar, i.e. - sitename.com/#/send#top), and the rest of my code will run as expected.
Any ideas what I am doing wrong?
scrollToLoc = function(loc) {
$location.hash(loc);
$anchorScroll();
console.log(loc);
};
$scope.doEdit = function(item) {
scrollToLoc('top');
$scope.request = item;
};
This may be more of a question around design pattern - I hope it makes sense.
I am using backbone - am developing a relatively simple app where user can add requests (where the request model is simply heading, description and price). The only requirement to add the requests is that a user is 'logged in'.
However I wish that the user 'adds' the request before checking if the user is logged in (remove one barrier). By that I mean that the user fills the form in, if not registered they have to register and then the request is just sent, if they were logged in it would just be sent. So initially the 'add request' view is rendered, when save is triggered this will call the save on the model which calls the ajax request on the server. The response will either return true (the user was logged in and the request added) or false (the user was not logged in).
So assuming that the user was not logged in - then I would wish to render a new view 'register' which has the option for the user to switch to 'login' (another view). So User in theory could go from
Request (save) -> Register -> Login -> Request (save)
So presuming that the user then registered (filled in the form which then called the registers view save method which then called the registers model save and returned ok). I would then wish to once again call the 'request' save method once again (as now the user would be logged in). However I do not want the register/login tied to the Request view - as in theory a new view (lets say I had a sent message view) would want similar functionality e.g. try and make the request, if failed switch view to register - perform save and then call some callback.
So the question is what is the right way to do this?
1) Do I create some closure inside the request view referencing the 'save' function and store it in a global to be called by register/login onsuccess?
2) Create a closure as above and pass that to the register etc (and if so how would I pass this given register/login is a view).
3) Pass a reference to 'this' of the request view?
So far all I have is, so in the else I would render the 'register' view but would love to know best way to do this without it getting very ugly?
save : function(event){
if(this.model.isValid() == true) {
this.$("#general_error").hide();
this.model.set({'formattedPrice' : TB_H.formatPrice(this.model.get('currency'), this.model.get('price'))});
self = this;
this.model.save(this.model.toJSON(), {
success: function(m, y) {
if(y.status == true) {
self.model = new TB_BB.Request();
Backbone.ModelBinding.bind(self);
Backbone.Validation.bind(self);
$('#add-offer-button').show();
} else {
if(y.errors[0] == 'not logged in') {
this.$("#general_error").html('You are not logged in');
this.$("#general_error").show();
} else {
_.each(y.errors, function(key, val) { this.$("#general_error").html(key) });
this.$("#general_error").show();
}
}
}, error : function(m,y) {
this.$("#general_error").show();
this.$("#general_error").html("Something bad happened - please try again")
}
}
);
}
Greatly appreciate any help!
I noticed this after asking a similar question, which I just deleted. I'm thinking this isn't the way most people are doing it in backbone.
what I did instead was pass my different routes to the same method and if the ids were not null, I'd call the route.
So I have a view
base_view = Backbone.Views.extend({
initialize: function(id,a_id,b_id){
this.id = id;
this.a_id = a_id;
this.b_id = b_id;
Myapp.data = new Myapp.Model.Base();
Myapp.data.url = '/data_url/'+id;
Myapp.data.fetch(Myapp.data, {
success: function(response){
// i have some nested collections, and models so i fill those in here
Myapp.mainModel = new First_Child_Collection(response.attributes.first_child_array);
}, error: function(){
alert('oops couldn't get data');
}
});
Myapp.data.bind("fetched",this.render,this);
},
render: function(){
new Main_View();
new Sub_View_1(this.id);
new Sub_View_2(this.a_id);
new Sub_View_3(this.b_id);
}
});
Then in my routes, rather than having a new route for each, I have
routes: {
"app/new": "new",
"app/:id/edit/a/:a_id/b/:b_id": "edit"
}
edit {
new base_view(id,a_id,b_id);
}
I'm not sure if this is perfect, but I think it is DRY'r than the other options. I just check that a_id or b_id are not undefined before passing those views.
Hope it helps.