jquery address change not being triggered with different URL? - javascript

I've hit a wall. My scenario simply doesn't make sense. I'm using the jquery address pluglin
Here is my issue:
A user enters a url with an argument like so:
http://localhost/#view_profile=1
The jquery address change function sees it fine and calls the appropriate method:
$.address.change(function(e) {
var urlAux = e.value.split('=');
var page = urlAux[0];
var arg = urlAux[1];
alert("page: " + page);
alert("arg: " + arg);
if (page == "/view_profile") {
$.address.title("Profile");
$('#main').load("view_profile.php?id=" + arg, function () {
alert("FUNCTION CALLED");
});
}
....
Now, here's my issue; a user enters a new URL like so:
http://localhost/#view_profile=2
The address change is triggered but it never gets inside my if block. If I enter the same address a second time it does trigger the code in my if block.
Is this a known issue or does it have something to do with page caching somehow?
output from first URL:
page: /view_profile
arg: 1
FUNCTION CALLED
output from second URL:
page: /view_profile
arg: 2
**** Why is the if block not being triggered? ***
output from second URL (agian):
page: /view_profile
arg: 2
FUNCTION CALLED
I'm stumped...

Related

AJAX GET Call Will work on the first call but not after other clicks

I have an ajax call in my javascript that returns and loads a partial view into a div. This function used to work but then all the sudden it stopped. I do not think I changed any code or anything that would cause issue but obviously something is going on. The Ajax call will work on the first time when you click on the button in which it is called but never again until you reload the page. I have tried adding more parameters and moving the javascript around but it still did not work. Is there any reason why this could happen?
I have tried moving the javascript out of the onOpen event and the same thing still happens. I have also put an alert call to make sure it is getting to the success call and the alert is called. I have also installed fiddler to check the call and the call is never made except on the first click of the button. This is a very frustrating error and all help is much appreciated.
Here is my Javascript:
#section scripts
{
<script type="text/javascript">
$(document).ready(function () {
$("#assets-button").on("click", function ()
{
$('#assets-container').bPopup(
{
modal: true,
onOpen: function () {
$.ajax({
type: 'GET',
url: '#Url.Action("EmployeeAssets", "Employee",new { id = Model.ID, empNo = Model.EmployeeNumber, username = Model.UserName })',
success: function (data) {
$('#assets-container').html(data);
}
});
},
onClose: function () {
var f = $('#assets-container').children('form');
var serializedForm = f.serialize();
var action = '#Url.Action("EmployeeAssets","Employee",new {empNo = Model.EmployeeNumber})';
$.post(action, serializedForm);
}
});
});
});
</script>
}
Here is the action that I am trying to call:
[HttpGet]
public ActionResult EmployeeAssets(int id, int empNo, string username = null)
{
var assets = _employeeDb.EmployeeAssets.FirstOrDefault(e => e.EmpNo == empNo);
if (assets == null)
{
var firstOrDefault = _employeeDb.EmployeeMasters.FirstOrDefault(e => e.EmployeeNumber == empNo);
if (firstOrDefault != null)
{
username = firstOrDefault.UserName;
}
var newasset = new EmployeeAsset()
{
EmpNo = empNo,
UserName = username
};
_employeeDb.EmployeeAssets.Add(newasset);
_employeeDb.SaveChanges();
assets = newasset;
}
return PartialView(assets);
}
You may try using the cache property of the settings object you are passing to the AJAX call. According to the jQuery documentation for .ajax the default for cache is set to true, so I wonder whether your browser is accessing a cached copy of the result after the first request. Looks like you could also set the dataType, and that will default the cache back to false.
Also, I would suggest putting your alert inside of the onOpen event handler in addition to the success handler just to be sure that's also being called. So that may help you debug a bit further.

Load Javascript into ajax loaded content

I am new to working with AJAX and have some experience with Java/Jquery. I have been looking around for an solution to my problem but i cant seem to find any.
I am trying to build a function in a webshop where the product will appear in a popup window instead of loading a new page.
I got it working by using this code:
$(".product-slot a").live('click', function() {
var myUrl = $(this).attr("href") + " #product-content";
$("#product-overlay-inner").load(myUrl, function() {
});
$("#product-overlay").fadeIn();
return false;
});
product-slot a = Link to the product in the category page.
product-content = the div i want to insert in the popup from the product page.
product-overlay-inner = The popup window.
product-overlay = The popup wrapper.
The problem that i now have is that my Javascript/Jquery isnt working in the productpopup. For example the lightbox for the product image or the button to add product to shoppingcart doesnt work. Is there anyway to make the javascript work inside the loaded content or to load javascript into the popup?
I hope you can understand what my problem is!
Thank you in advance!
EDIT: The platform im using has jquery-ui-1.7.2
I know this is an old thread but I've been working on a similar process with the same script loading problem and thought I'd share my version as another option.
I have a basic route handler for when a user clicks an anchor/button etc that I use to swap out the main content area of the site, in this example it's the ".page" class.
I then use a function to make an ajax call to get the html content as a partial, at the moment they are php files and they do some preliminary rendering server side to build the html but this isn't necessary.
The callback handles placing the new html and as I know what script I need I just append it to the bottom in a script tag created on the fly. If I have an error at the server I pass this back as content which may be just a key word that I can use to trigger a custom js method to print something more meaningful to the page.
here's a basic implementation based on the register route handler:
var register = function(){
$(".page").html("");
// use the getText ajax function to get the page content:
getText('partials/register.php', function(content) {
$(".page").html(content);
var script = document.createElement('script');
script.src = "js/register.js";
$(".page").append(script);
});
};
/******************************************
* Ajax helpers
******************************************/
// Issue a Http GET request for the contents of the specified Url.
// when the response arrives successfully, verify it's plain text
// and if so, pass it to the specified callback function
function getText(url, callback) {
var request = new XMLHttpRequest();
request.open("GET", url);
request.onreadystatechange = function() {
// if the request is complete and was successful -
if (request.readyState === 4 && request.status === 200) {
// check the content type:
var type = request.getResponseHeader("Content-Type");
if (type.match(/^text/)) {
callback(request.responseText);
}
}
};
// send it:
request.send(null); // nothing to send on GET requests.
}
I find this a good way to 'module-ize' my code into partial views and separated JavaScript files that can be swapped in/out of the page easily.
I will be working on a way to make this more dynamic and even cache these 'modules' for repeated use in an SPA scenario.
I'm relatively new to web dev so if you can see any problems with this or a safer/better way to do it I'm all ears :)
Yes you can load Javascript from a dynamic page, but not with load() as load strips any Javascript and inserts the raw HTML.
Solution: pull down raw page with a get and reattach any Javascript blocks.
Apologies that this is in Typescript, but you should get the idea (if anything, strongly-typed TypeScript is easier to read than plain Javascript):
_loadIntoPanel(panel: JQuery, url: string, callback?: { (): void; })
{
// Regular expression to match <script>...</script> block
var re = /<script\b[^>]*>([\s\S]*?)<\/script>/gm;
var scripts: string = "";
var match;
// Do an async AJAX get
$.ajax({
url: url,
type: "get",
success: function (data: string, status: string, xhr)
{
while (match = re.exec(data))
{
if (match[1] != "")
{
// TODO: Any extra work here to eliminate existing scripts from being inserted
scripts += match[0];
}
}
// Replace the contents of the panel
//panel.html(data);
// If you only want part of the loaded view (assuming it is not a partial view)
// using something like
panel.html($(data).find('#product-content'));
// Add the scripts - will evaluate immediately - beware of any onload code
panel.append(scripts);
if (callback) { callback(); }
},
error: function (xhr, status, error)
{
alert(error);
}
});
}
Plain JQuery/Javascript version with hooks:
It will go something like:
var _loadFormIntoPanel = function (panel, url, callback) {
var that = this;
var re = /<script\b[^>]*>([\s\S]*?)<\/script>/gm;
var scripts = "";
var match;
$.ajax({
url: url,
type: "get",
success: function (data, status, xhr) {
while(match = re.exec(data)) {
if(match[1] != "") {
// TODO: Any extra work here to eliminate existing scripts from being inserted
scripts += match[0];
}
}
panel.html(data);
panel.append(scripts);
if(callback) {
callback();
}
},
error: function (xhr, status, error) {
alert(error);
}
});
};
$(".product-slot a").live('click', function() {
var myUrl = $(this).attr("href") + " #product-content";
_loadFormIntoPanel($("#product-overlay-inner"), myUrl, function() {
// Now do extra stuff to loaded panel here
});
$("#product-overlay").fadeIn();
return false;
});

Writing to a webpage's textfield from chrome extension

I want to create a chrome extension that takes in some text, then opens a website, and tries to write that text to the textfield.
This is what I have:
chrome.omnibox.onInputEntered.addListener(
function(text) {
chrome.tabs.create({url:"http://www.editpad.org/"});
document.getElementById("text").value = txt; //.innerHTML = txt
alert('You just typed "' + text + '"');
});
I got the ID from just inspecting the element.
What do I need to do so it writes?
Your code runs in the context of the (invisible) background or event page. In order to "switch" to the execution context of the page you've just opened, you need to use a content script (programatically, "on the fly", using chrome.tabs.executeScript).
The annotated code below shows how to achieve the result you want.
chrome.omnibox.onInputEntered.addListener(function(text) {
chrome.tabs.create({
url: 'http://www.editpad.org/'
}, function(tab) {
// chrome.tabs.executeScript takes a string that will be parsed and run
// as JavaScript code. To pass a string, you need to make sure that it
// does not contain any invalid characters. This can easily be achieved
// by serializing the input string to JSON.
var serializedValue = JSON.stringify(text);
chrome.tabs.executeScript(tab.id, {
code: 'document.getElementById("text").value = ' + serializedValue,
}, function(result) {
if (!result) {
// This usually happens when you do not have the permission to
// run code in the page. Add the site to the "permissions"
// section manifest.json.
alert('Failed to run content script.\n' +
chrome.runtime.lastError.message);
return;
}
// The value of the last expression is passed to the callback of
// chrome.tabs.executeScript, for each frame. The code runs only in
// the top-level frame (because `allFrames: true` is not specified),
// so the result is an array with only one element.
alert('You just typed: "' + result[0] + '"');
});
});
});

jQuery/Javascript: How to get anonymous function to reference variable declare outside?

I have some jQuery code that doesn't work as expected.
$('a[href^="http://"]').not('[href^="http://mydomain.com"], [href^="http://itunes.apple.com"]').click(function (e) {
e.preventDefault();
console.log("external: " + this.getAttribute('href'));
var url = this.getAttribute('href');
foo.track(
"External",
{ 'URL': url },
function (url) {
location.href = url
}
);
});
For this example, I'm tracking all external clicks from my domain, except for iTunes apps store. Assume foo.track() is a 3rd party method I'm using to track some events for reporting. The last parameter to it is an anonymous function that is executed once the tracking call successfully returns.
The code above is trying to navigate everything to http://mydomain.com/1 for some reason. However, the console.log statement succesfully logs the expected values. It's as if the url variable isn't referencing the value I expect. I've also tried replacing location.href = url with window.location = url but I get the same result.
What am I doing wrong?
Just remove the parameter from the navigation function. Like this:
$('a[href^="http://"]').not('[href^="http://mydomain.com"],
[href^="http://itunes.apple.com"]').click(function (e) {
e.preventDefault();
console.log("external: " + this.getAttribute('href'));
var url = this.getAttribute('href');
foo.track("External", { 'URL': url }, function (/*url*/) { location.href = url });
});

Jquery simple function

The aim of this code is to delete a comment with AJAX. The function is called as follows:
DeleteComment(166);
And the code that runs is:
// Each delete button
function DeleteComment(CommentID) {
$.ajax({
url: AJAXURL + "?action=del&id=" + CommentID,
success: function (data) {
// Parse the data
if (data.substring(0, 1) == "1") {
$('#cid' + CommentID).hide();
} else {
alert(data.substring(2, data.length));
}
}
});
}
However the $('#cid' + CommentID).hide(); line never fires as CommentID isn't retained, I'm new to Jquery, could someone show me how to change this so the comments ID is retained when the ajax success is called?
put the $('#cid' + CommentID).hide(); before $.ajax({ and then add $('#cid' + CommentID).show(); to your else condition..
Hide it first and then reshow it if deletion fails...
Not the most graceful solution, but the path of least resistance from where you are.
Can you post more of the surrounding code? As is, your code looks like it should work. But I see a troublesome comment: // Each delete button. The way you are binding the DeleteComment function to the buttons must not be working the way you assume.
Try this instead:
// Iterate over each delete button.
// The .each(...) provides you a function, a.k.a. local scope, for each button.
$(".deleteButtons").each(function (idx, el) {
// This is very important: you must create a local variable to hold the ID.
// How to get the ID is up to you.
var id = getTheCorrespondingCommentId(idx, el);
// Now you can safely pass the local variable to the DeleteComment function:
$(el).click(function() { DeleteComment(id); });
});

Categories