I have a tab strip containing many tabs. when i make some changes in tab 2, a confirm msg pops up asking if i want to continue without saving and if i say yes, i need to reset the value of the modified field in tab 2 to its original. Please help me do this.
please find below my sample code
Html.Telerik().TabStrip().Name("TabStripEmployeeDetail")
.Items(items =>
{
items.Add()
.Text("tab1").HtmlAttributes(new { onclick = "return warnOfChanges()" })
.LoadContentFrom(......);
items.Add().HtmlAttributes(new { onclick = "return warnOfChanges()" })
.Text("tab2")
.LoadContentFrom(......);
items.Add()
.Text("tab3")
.LoadContentFrom(.......);
items.Add()
.Text("tab4")
.LoadContentFrom(....);
items.Add()
I have a javascript function
function warnOfChanges() {
if(documentmodified) {
return confirm('Changes have been made on this tab. Continue without saving?');
}
return true;
};
and i am calling this onclick of the tab. please help here
First of all I suggest you to use the select event of the TabStrip instead of attaching the same handler on the tab items.
To actually reset these settings (since you are loading them with Ajax) the easiest way would be to refresh the content of the TabFrom the server. To refresh a particular tab you could use the reload method of the Client API.
Check the documentation for examples how to use the reload method.
Related
Let's say I have the following component
function ClickButton(props) {
const history = useHistory();
const onClick = () => {
history.push('/next-page');
};
return <button onClick={onClick}>Go to next page</button>;
}
More accessible version would be to use Link from react-router as the following
function ClickButton(props) {
return (
<Link to="/next-page">
<span>Go to next page</span>
</Link>
);
}
But what if redirection depends on some http call success, like
function ClickButton(props) {
const history = useHistory();
const onClick = async () => {
try {
await axios.get('https://google.com')
history.push('/next-page');
} catch(err) {
setAlertMessage('Google can't be reached - check your internet connection');
}
};
return <button onClick={onClick}>Go to next page</button>;
}
What is equivalent (and is there some semantically meaningful way) of using Link (or something else that e.g. screen readers would treat as link-alike) here, in case of async handler of onClick event?
I'd probably opt to use the Link component since semantically it makes the most sense to. You can use button element, but then you would need to add all the appropriate accessibility attributes, i.e. role="link" and correct click and keypress event handlers, etc...
You can add an onClick handler to the Link and do the same check. The key is preventing initially the default link behavior.
const ClickButton = props => {
const history = useHistory();
const onClick = async e => {
e.preventDefault();
try {
await axios.get("https://google.com"); // NOTE *
history.push("/next-page");
} catch (err) {
alert("Google can't be reached - check your internet connection");
}
};
return (
<Link to="/next-page" onClick={onClick}>
<span>Go to next page</span>
</Link>
);
};
* NOTE: this GET request seems to just fail in codesandbox.
The simplest way to do this is with a hyperlink. (<link>) as #Drew Reese pointed out.
There is nothing wrong with intercepting the hyperlink action via JavaScript and reporting back if there is an error.
To do this you would just use a standard e.preventDefault(), make your AJAX call and redirect if it works. If it fails then create an alert that explains that the call failed.
Why use an anchor / hyperlink?
Semantics - accessibility is all about expected behaviour. If I change page then a hyperlink makes a lot more sense than a button. It also means I understand that the page will change from the element in case your description does not make sense.
JS Fallback - it could be your SPA does not function at all without JS. However if it does work in some limited fashion without JS then using a hyperlink means that if a user has JS disabled (around 2% of screen reader users don't use JS) or an error causes your JS to fail then navigation is still possible with a hyperlink.
SEO - I dare to swear on Stack Overflow and mention the forbidden term! Although search engines are very good at understanding JS they still aren't perfect. They understand hyperlinks perfectly. If SEO matters use a hyperlink.
Styling - hyperlinks have :visited and :active whereas buttons do not.
How to handle async loading.
When you click on the element you need to let the screen reader know an action is being performed.
The easiest way to do this is to have a visually hidden div located on the page that has the aria-live="polite" attribute. (You can use the same div for all actions).
Then when a function is called that contains an async action you set the contents of that div to "loading" or "waiting" (whatever is appropriate).
This will then get announced in the screen reader (you could argue aria-live="assertive" is better but I will leave that to you).
If the action fails then set your alert message (but make sure that your alert has the appropriate WAI-ARIA roles and behaviour. I would suggest role="alert" but without seeing your application that is a best guess. It could equally be role="alertdialog" if you want a confirmation from the user.
Final thought
When navigation occurs in a AJAX powered SPA, don't forget to set the focus to something on the new page. I normally recommend adding a <h1> with tabindex="-1" (so you can focus it) and setting the focus on that (as your <h1> should obviously explain what the page is about).
www.example.com/templates/create-template
I want to warn users if they leave create-template page. I mean whether they go to another page or to templates.
I use this code to warn users on a page reload and route changes should the form be dirty.
function preventPageReload() {
var warningMessage = 'Changes you made may not be saved';
if (ctrl.templateForm.$dirty && !confirm(warningMessage)) {
return false
}
}
$transitions.onStart({}, preventPageReload);
window.onbeforeunload = preventPageReload
It works as expected on a page reload and route changes if it is done by clicking on the menu or if you manually change it. However, when I click the back button, it does not fire the warning. only it does if I click the back button for the second time, reload the page, or change route manually.
I am using ui-router. When you click back button, you go from app.templates.create-template state to app.templates state.
How to warn if they press Back button?
First of all, you are using it wrong:
from https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload:
Note: To combat unwanted pop-ups, some browsers don't display prompts
created in beforeunload event handlers unless the page has been interacted
with; some don't display them at all. For a list of specific browsers, see the
Browser_compatibility section.
and
window.onbeforeunload = funcRef
funcRef is a reference to a function or a function expression.
The function should assign a string value to the returnValue property of the Event object and return the same string.
You cannot open any dialogs in onbeforeunload.
Because you don't need a confirm dialog with onbeforeunload. The browser will do that for you if the function returns a value other than null or undefined when you try to leave the page.
Now, as long as you are on the same page, onbeforeunload will not fire because technically you are still on the same page. In that case, you will need some function that fires before the state change where you can put your confirm dialog.
How you do that depends on the router that you are using. I am using ui-router in my current project and I have that check in the uiCanExit function.
Edit:
You can keep your preventPageReload for state changes in angular. But you need a different function for when the user enters a new address or tries to leave the page via link etc.
Example:
window.onbeforeunload = function(e) {
if (ctrl.templateForm.$dirty) {
// note that most broswer will not display this message, but a builtin one instead
var message = 'You have unsaved changes. Do you really want to leave the site?';
e.returnValue = message;
return message;
}
}
However, you can use this as below:(using $transitions)
$transitions.onBefore({}, function(transition) {
return confirm("Are you sure you want to leave this page?");
});
Use $transitions.onBefore insteadof $transitions.onStart.
Hope this may help you. I haven't tested the solutions. This one also can help you.
I have script, what work one time when window loaded, it work on this page, but site use some navigation links what not fully reload page (see this answer for example: Modify the URL without reloading the page). How can I detect that and run my script again?
I have one idea: storing URL (without anchor) in variable and check it periodically with current url, but I think this is bad solution. May be you know better one?
JavaScript or JQuery is possible to use.
Use window.onpopstate or window.onpushstate if u are using pushState or replaceState ( from ur given example).
ex:-
To Navigate Without reload ( you already did this )
// Your code to fetch new URL body and title
// update the DOM then use following code to update URL also (don't use location.href, otherwise the page reloads)
// sorry u already know this because u provided the example ;)
let data = { title : "Current Title",
body : document.body.innerHTML" } // to store current page data
window.history.pushState(data, 0, "newURL");
To detect navigation ( i.e., you wanna do )
window.onpushstate: when above code runs for navigation to a new url and load new content without reload ...
window.onpushstate(function() {
// detects ur navigation
})
window.onpopstate: when you press back button
window.onpopstate(function (e) {
let { data } = e.state;
// data object that u gave in pushState method when u called ur last / latest pushState method...
// use this data to retrieve previous data content and title
let { title, body } = data;
document.title = title;
document.body.innerHTML = body
})
for more detail mdn docs
That's because the new pages are either
1 ) Already at the ready and simply being brought in-sight by jQuery
2 ) Ajax called in.
If you scout for your navigation (the links you click on to go to the other page), you should find click me or so.
If you look for wherever this is is bound (i.e.: $('#navigation a').on("click", function(){});, you can simply wrap your script within a function, and trigger this function together with loading the new page every time. (after it, obviously).
I wish I could be more clear, but you did not provide any code yourself, so I have absolutely no idea of what kind of example I should be giving here.
-- the point: Those page changes are triggered by something in your javascript. Find the trigger that makes the page-change happen, and simply insert myCustomFunction();.
If you want to make your bindings update with a new DOM, you could use this:
function setBindings(){
//removing the old bindings prevents the "click" from triggering twice.
$('a').off("click");
$('a').on("click", function(){
//load page and such here
//Apply script you want to run here
setbindings(); //rerun the function to set the bindings.
});
}
I think you are looking for hashchanges you can listen to this event onhashchange
window.onhashchange = function(e) {
var sublink = window.location.hash.substring(1);
//do your thing here
}
You can also check what updated the url after the hashchange
var sublink = window.location.hash.substring(1);
I think the URL of script is cached,do you used Ajax get method?if it is,please
like this write url "wwww.baidu.com?"+Math.random();if not is ,in the firefox ,you can used pageshow event.
I'm not sure how to do a pop-up that warns when you are clicking on external links, using javascript.
I figured that it would be handy to put a class on my external links as well, but I'm not quite sure it's done correct as it is now either. This is the HTML I'm using at the moment:
<div id="commercial-container">
<img src="picture1.jpg" />
<img src="pciture2.jpg" />
<img src="picture3.jpg" />
<img src="picture4" />
</div>
I'm very new to javascript and very unsure on how to solve my problems. The pretty much only thing I figured out so far is that I will have to use window.onbeforeload but I have no clue on how to figure out how to write the function I need.
I want to keep my javascript in a separated .js document instead of in the HTML as well.
Call the confirm() function from the onClick attribute. This function returns true if the user clicks OK, which will open the link, otherwise it will return false.
<img src="picture1.jpg"/>
Hope this helps.
You can do it by adding a click event handler to each link. This saves having to use a classname.
window.onunload will run even if the user is just trying to close your site, which you may not want.
staying in site
going external
<script>
var a = document.getElementsByTagName('a');
var b = a.length;
while(b--){
a[b].onclick = function(){
if(this.href.indexOf('yourwebsitedomain.com')<0){
//They have clicked an external domain
alert('going external');
}
else{
alert('staying in your site');
}
};
}
</script>
Since you're new to Javascript I advice you to use a javascript framework to do all the "heavy work" for you.
For example with JQuery you can easily bind an onClick event to all external links by doing:
$(".external").click(function(event) {
var confirmation = confirmation("Are you sure you want to leave ?");
if (!confirmation) {
// prevents the default event for the click
// which means that in this case it won't follow the link
event.preventDefault();
}
});
This way every time a user clicks on a link with the external class, a popup message box asking for a confirmation to leave will be prompt to the user and it will only follow the link if the user says "yes".
In case you want only to notify without taking any actions you can replace the confirmation by a simple alert call:
$(".external").click(function(event) {
alert("You are leaving the site");
});
If the user click an image,div,.. you need to look for the parent node. !There could be several elements wrapped with a-tag.
document.addEventListener('click',function(event){
var eT=(event.target||event.srcElement);
if((eT.tagName.toLowerCase()==='a' && eT.href.indexOf('<mydomain>')<0)
|| (eT.parentNode!==null && eT.parentNode.tagName.toLowerCase()==='a'
&& eT.parentNode.href.indexOf('<mydomay>')<0))
{
//do someting
}
else if(eT...){
...
}
},false);
Two side notes:
If you want to keep track a user by cookie or something similar, it's good practice to check external links, set a timeout and make a synchronic get request to renew.
It's better to add the event to the document or a div containing all events and decide on target.
I want to add a confirm dialog to a delete button to ask the user whether it is ok or not deleting the selected item.
If not, nothing should happend, else a url should be executed.
I know how to realize this via some Javascript code but I am looking for a solution that has less code. I mean e.g. :
Delete
Is it possible to put the whole functionality in the onClick element without having some extra Javascript in the header?
You can return the confirm() (which returns true/false), like this:
Delete
You can test it here
Better (though far from ideal!): turn it around. Don't let the link do anything, unless you got JavaScript:
<a href="#"
onclick="if confirm('Sure?') { window.location='http://mysite.de/xy/delete';}">
Click to delete
</a>
This at least prevents the link to work without JavaScript. This also reduces the risk of the link accidentally being crawled by Google, or even by some local plugin. (Image if you had a plugin that would try to load/show as thumbnail) the target page on hover of a link!)
Still, this solution is not ideal. You will actually browse to the url, and the url might show up in the history because of that. You could actually delete Bob, create a new Bob, and then delete that one by accident by just clicking 'back' in the browser!
A better option would be to use JavaScript or a form to post the desired action. You can make a request to the server with the POST method, or arguably better, the DELETE method. That should also prevent the urls from being indexed.
Consider what happens if the user has javascript disabled, or if google comes along and spiders the link. Will your entity be deleted?
A better way would be to post a form to delete.
There is a jQuery plugin that does just that: jquery.confirm.
Example:
Go to home
JS code:
$('.confirm').confirm();
If the user confirms, he is redirected to the link of the <a>, else nothing happens.
You can use this:
Download a bootboxjs from:[1]: http://bootboxjs.com/
Create the Button (HTML)
<button type="submit" id="btn">Delete</button>
Call the Dialog:
var myBtn = document.getElementById('btn');
myBtn.addEventListener('click', function(event) {
bootbox.confirm({
size: "small",
message: "Are you sure?",
callback: function (result) {
/* result is a boolean; true = OK, false = Cancel*/
if (result == true) {
alert("ok pressed");
}
else {
alert("cancel pressed");
}
}
})
});