I have not been able to find any discussion of what I'm struggling with on this site or any other, but perhaps I'm not asking the right question. I'm working on a web interface for a wireless speaker powered by the raspberry pi, and (as I inherited it) almost all the POST requests are done with calls to $.ajax. $().ready() is as follows:
$().ready(function (){
$(document).ajaxStart(function (){
$.blockUI({ message: '<img id="loadimg" src="img/loading.gif" width="64" />'});
}).ajaxStop($.unblockUI);
$("nav.setup-nav a").not("[target='_blank']").on("click", function (event){
event.preventDefault();
var href=$(this).attr('href');
$.ajax({
type:"POST",
url:href,
success:function (data){
$(".contentPanel").html(data);
$(this).blur();
$("html, body").animate({ scrollTop:100, scrollLeft:400}, 600);
},
});
return false;
});
});
Which forces all the content of the linked-to pages in the nav menu to load inside a div in the center of the page. That is, except for pages with target="_blank" attribute. This is so event.preventDefault and the UI blocking stuff doesn't get called when linking to an external page that we want to load in a new window. I'll try to concisely describe my issue: One of the menu items is (conditionally) a link to a web-based MPD client, which we definitely do NOT want to load inside a div on the same page, and thus has target="_blank" attribute. The problem is the user can also choose to enable or disable the MPD daemon through the web-interface. PHP handles the setting of all these kinds of state variables. Basically like this:
if ($config->is_flag_set($MPD_FLAG))
{
echo '<li><a target="_blank" id="mpd" href="rompr/">Local Playback Web Interface</a></li>';
}
else
{
echo '<li><a id="mpd" href="local-disabled.php">Local Playback Web Interface</a></li>';
}
and so when the page first loads, if the MPD daemon is not running the link to the web interface is pointed to a page that explains MPD is not enabled. This link does NOT contain the target="_blank" attribute. However, if one navigates to the settings form and switches on MPD, there is logic to replace the href and target attributes of that particular link, so theoretically all should work as if the page had loaded initially with the MPD flag on (if that is clear!). The problem is that when the "replaced" link with target="_blank" (set by .prop() or .attr(), I've tried both and it doesn't seem to make a difference) is clicked, the page still loads inside the div!I tried duplicating the click handler that's defined within $().ready and putting it in another function which I call after the link attributes are set, but it still doesn't work as I imagine it should! Just to verify that I wasn't crazy, I used .each() to print all the links that did and did not have the target="_blank" attribute and that all corresponds to what I believe it should be. Why is the replaced link not getting treated as if it has a target="_blank" attribute in the click handler? By the way, Going the other way and removing the target="_blank" attribute if MPD is turned off, works like a charm. Thanks so much in advance for any answers, and my apologies if I have duplicated a previous question!
Cheers,
Events are always tricky anytime you have to reload elements with ajax. The best way I've found is to attach the event to some container element that will not reload:
$('#always_present_container').on('click', "nav.setup-nav a", function (event){
if($(this).attr('target') != '_blank'){
...
}
});
that way the element is checked for the attribute when its container is clicked. When you set up $('element').click() the selector is checked on the page load and the events attached then, so when you reload something via ajax the new element doesn't get this event attached.
Note: normally you could avoid the conditional statement in the function, but I didn't know of an easy way to filter by target in a css selector.
Related
I'm working on a web application which is a traditional aspx (asp.net) web forms app but has had some angular 6 apps incorporated into it.
I've been tasked with fixing a bug that causes the browser to refresh when clicking on an anchor element with a href="#".
I'm not sure what's causing the whole page to reload.
Strangely when I open dev tools in Chrome, choose the network tab and select disable cache the page only refreshes the first time I click a link and any other subsequent clicks work fine. This might be to do with the fact that after the first time I click it the browser url now contains the # at the end of it.
I know this seems a bit random but I wondered whether anyone had any theories on what may cause the reload in the first place.
It's hard to tell what could be causing this without seeing any code. The most common solution I've used when I get this behavior is a prevent default. You can do something like
<a href="#" (click)="$event.preventDefault()">
Or if you already have a click event then pass in $event as a parameter to your function then preventDefault in the function you are calling. This would look like:
Html
<a href="#" (click)="someFunc($event)">
and in your ts:
someFunc(event) {
event.preventDefault();
// rest of your code here
}
This answer is related to the question and it's the first one that comes up in Google so I hope this is useful.
I have some external web components that use regular anchor tags with hrefs that point to routes in my angular app. Clicking the href causes a full page reload. This is because I'm not using routerLink - but, in my case, I can't.
So, my work around is:
#HostListener('window:click', ['$event'])
onClick(e: any) {
const path = e.composedPath() as Array<any>;
const firstAnchor = path.find(p => p.tagName.toLowerCase() === 'a');
if (firstAnchor && !firstAnchor.hasAttribute('routerlink')) {
const href = firstAnchor.getAttribute('href');
this.router.navigateByUrl(href);
e.preventDefault();
}
}
Depending on your application, you might need to make some other checks e.g. is the target _blank, is it an external url etc.
change your a tag code as below
A Tag
this will invoke yourClickEvent(); without page reload
check the stackblitz here stackblitz
If you don't want to reload the page use $event.preventDefault()
<a href="#" (click)="$event.preventDefault()">
Try using debug tools to select the element, then click Event Listeners and then the Click event to see what is listening. Perhaps you can track it down that way.
You could also simply paste this into the console to trigger a break, and then click any of the offending elements:
['unload', 'beforeunload'].forEach(function (evName) {
window.addEventListener(evName, function () {
debugger; // Chance to check everything right before the redirect occurs
});
});
source: Break when window.location changes?
As you are using angular routes, try to use this notation:
<a [routerLink]="['./']" fragment="Test">
As explain by this comment: https://stackoverflow.com/a/38159597/4916355
use href="javascript:void(0);"
The reason you’d want to do this with the href of a link is that normally, a javascript: URL will redirect the browser to a plain text version of the result of evaluating that JavaScript. But if the result is undefined, then the browser stays on the same page. void(0) is just a short and simple script that evaluates to undefined.
Use [routerLink] instead of using href = "", and use click event to call your calling method in the typescript file.
ex:
// downloading the file based on file name
<a [routerLink]="'file://' + 'path'" (click)="downloadFile(templateDocument.fileName)">{{downloadDocuments.fileName}}</a>
Since you have mentioned the web app is asp.net webforms, can you please let us know
Whether the link is asp.net hyperlink control. If so,
AutoEventWireUp could cause the link to be automatically submitted:
Please have a look at this link
If you do have asp.net server controls on the page, then you could disable by setting
#Page AutoEventWireup="false"
For the entire project, this can be disabled by setting in web.config:
I'm trying to change the size of a pop-up and give it the same width than the screen, sent from an iframe.
var screen_width = parent.screen.width;
Then I got the html:
<a href="#" onClick="window.open('https://www.google.com','popup', 'width='"+screen_width+"',height=400px')">
I've tryed all possible convinations with the ' " or whatever I know, but I think it should work lie this.
Sorry if it's obvious, my coding skills are not so developed, but I think, it's possible, html it's loading before javascript?
P.D.: One more thing, I want to use a variable, because I want to change a bit the real size of the screen.
One problem you might be having is that in your window.open() options, you shouldn't specify px... just put the number for your height.
In any case, here's a better implementation of what you're trying to do. In your HTML:
<a href="http://example.com" target="_blank" data-fullpopup>Click me!</a>
This way, your link will work, and will even open in a new tab/window if your JavaScript doesn't run for some reason. This is a good fallback. The key here is the data-fullpopup attribute, which we'll look for in your JavaScript:
document.addEventListener('DOMContentLoaded', (e) => {
document.querySelector('body').addEventListener('click', (e) => {
if (!e.target.matches('a[data-fullpopup]')) {
return;
}
window.open(e.target.href, 'popup', 'width=' + window.screen.width + ',height=400');
e.preventDefault();
});
});
Basically, we wait for the document to fully load so that we can attach a click handler to the body element. (Note: If you're only doing this for a couple links, it's better to attach the click handler directly to them. I'm attaching it to body here, assuming that you'll have a lot of these sorts of links... it's more efficient to have one click handler in those cases. Remember though that then this click handler has to run for every click for any element on the page. Choose your tradeoff for your use case.)
Once the link is clicked, we confirm that it's a link with our data-fullpopup attribute. If it is, we treat it like a full-width popup. We get the target (the element) href on the fly, as well as the current screen width. Finally, we prevent the default action so that it also doesn't navigate to the page on its own.
https://jsfiddle.net/L5p0xk98/3/
As mentioned in the comments, you can do this without setting a variable first:
Click Me
I'm using jQuery mobile and my page is generated from an index.php file. When I click on links referring to another option of my php file (index.php?action=other_action) it loads in Ajax so the previous content is still kept in the code. This causes problems as nothing is dynamic anymore, because I'm using specific ids, so it breaks everything. Of course disabling Ajax works but I loose all the beauty of jQuery Mobile.
I guess a solution would be to create an onclick function on the <a>, that will prevent the page from keeping the previous content or delete the old page.
So is there a way to keep using ajax in a way that it doesn't break my dynamic elements ?
You can see it in action here, you can filter names if everything's good. Then click on the top left panel and click something, notice what happens in the inspector...
Thanks for any help.
Hi you have missed enclosing the selector within qoutes...
your jQuery
$(document).ready(function() {
//bind a listener to "click" event on links with class "markviewed"
$('a.ui-btn-present').click(function(event) {
$('ul.listlist').listview('refresh');
$(#pageone).remove(); //<-- selector should be within quotes
// get ids from clicked <a>
var id = $(this).attr('data-id');
$(this).attr({
"class" : "ui-btn ui-btn-icon-notext-ok ui-icon-check ui-btn-a"
});
After much more research I wasn't looking in the right direction: the problem was that the listview had to be refreshed. So I created a new function
<script>
function refreshlist() {
$('.listlist').listview("refresh");
$('#pageone').remove();
};
</script>
And then I added onclick= "refreshlist()"to all my links and now it works.
This is pretty much an add on to a question I posted before about loading an external page without ajax, but keeping it an iOS web app window. What I came up with for that example was this
<script>
$(document).bind('pageinit', function() {
$("#test").click(function (event) {
event.preventDefault();
window.location.assign("test.html");
});
});
</script>
But now what I want to do is to set this up for every link I would have on that page. Seeing as I don't know how many links I could have, it would be very tedious to do this every time I add a new link. So I found this snippet and thought I could combined the two some how, I just need some direction on how.
$('a').each(function(index){
var elementId=$(this). attr("id");
elementId='#'=elementId;
So for each a tag or href on my page, it will automatically grab the link and load it in that particular manner automatically.
Of course you can combine your codes. Anyway I haven't tried your code but you have to wrap an .each() function around your click events. Also you should give every clickable link a the same class. Should look like this:
$('.class').each(function(){
$(this).click(function(){
event.preventDefault();
window.location.assign("test.html");
})
});
if you now want those links to link on different pages you can define a data-href attribute on each link. like this: data-href="test2.html" in your html.
You can now use
$(this).data("href");
and put the output into a variable. Afterwards you can place it in your window.location.assign thing dynamically.
Hope I understood your problem and it helped.
Because this topic turn out to interdisciplinary (but still is about user experience) I'm curiuos what think about this an javacript developers.
My site handling a tags with href starting with # as ajax request. If request was successfully then it's change document hash to appropiate. Now I want to implement action links that call internal js function like going to site top, but I don't want javascript:myAction() reference, because most browsers is showing hint with referencing url when you're over the link. Probably I can use and successfully handle own url schema like action:myAction, but it's not enough solution - user was still hinted about magic url. Another option is using custom attribute like action="myAction" with href as custom string e.g. href="Go to top", but what with browsers compatibility? Last solution is to using a span styled as link to perfom action - user is not hinted about any url, but this is a part of link functionality what suggest that perform an action (going to url default).
What is better and why?
<script>
if(window.addEventListener)//Chrome, Firefox and Safari
document.getElementById('myLink').addEventListener('click',function(e){
var e = e || event;
e.preventDefault();
window.location = destiny;
});
else//IE and Opera
document.getElementById('myLink').attachEvent('onclick',function(e){
var e = e || event;
e.preventDefault();
window.location = destiny;
});
</script>
Link
You should make your links work first without JavaScript. Then you don't have to worry about someone clicking <a href='/customers'>Customers!</a>. It works nicely and is accessible. Once you've reached this point you put the JavaScript on top to enhance the user experience. How you hook all of these up is up to you - say you want to handle deletes in a generic way, you might have links that look like this:
<a href='/customers/2' class='delete'>Delete customer</a>
<a href='/customers/2' data-action='delete'>Delete customer</a>
Or if it's specific per link, you set the id and wire it up that way:
<a href='/customers/2' id='delete'>Delete customer</a>
All of this wiring up should be done in an external JavaScript file.
I would do this by first writing everything in a way users without JS can use it, like
Go to top
Then I would take JS to enhance it immediatly after the DOM is loaded. First by adding the onclick event, then removing the href, to avoid any link hint (any other content than links probably not pass any validator) and finally a new style attribute that the cursor becomes a pointer on hover.
It is part of the very useful programmatic progressive enhancement structure. This way I get valid and compatible code as well as a comfortable behaviour.