How to reference html element from included js-file - javascript

I created this test case which works as expected:
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="site.js"></script>
<script>
function click_me() {
deActivateButton("Please wait ..", "#btnX");
activateButton("Click me 2", "#btnX");
}
</script>
<button type="button" id="btnX" onclick="click_me(); return false;">Click me
</button>
And then two small functions kept in site.js to deactivate/activate my buttons:
function deActivateButton(btnText, id) {
$(id).text(btnText);
$(id).prop("disabled", true);
}
function activateButton(btnText, id) {
$(id).text(btnText);
$(id).prop("disabled", false);
}
This works fine, but fails when I use the code in my application. I'm using web forms with a master page. The master page loads include file:
<%Response.WriteFile("Content/Files/master_include_head.html");%>
And then in master_include_head.html I include the actual javascript functions like this:
<script src="site.js"></script>
What can I be doing wrong here? There are no error messages, it just dies. Shouldn't I be able to reference the id of the clicked button with this design, or is the reference to the button lost because of the way I include files? Can it be a cache problem?

Are you not just setting and then clearing then immediately clearing the value in your code?
So you are activating then immediately de-activating your button?
Just a little note. Why not use jQuery to attach your click events as follows:
$("#btnX").click(function(e) {
// Do stuff
});
Side note. I'm not sure there's any need for the return false; statement in your onclick. Typically this would just contain the function name. return false; can be used in functions to prevent event bubbling, as you've set it I'm not sure it will have any effec

Related

check if dynamically inserted input field exists

I have a script that adds a button that will open up a window that allows us to design t shirts. All i have top do is include their script and the button gets automatically added.
Below is the code which is dynamically added to the page.
<input id="design_edit_btn" class=" btn btn-success btn-block" value="Edit the design" type="button">
What i need to do is that, if that button is available then show a message saying its customizable or else display cannot be customized.
I tried the below code
if($("#design_edit_btn").length) {
alert("exists");
}
I did a bit of research but couldn't find a way to achieve this. Can someone please let me know how this can be done?
Thanks
You probably need to wait until the script has been loaded and executed.
Try waiting when the document is finished and do something like this:
jQuery(($) => {
if($("#design_edit_btn").length) {
alert("exists");
}
} );
jQuery triggers a given callback as soon as the document is ready. If that doesn't work either you could try adding a setTimeout as well.
Since the button you look for is create by an external script, that script is likely not finished by the time the DOM is ready, hence you won't find it, not even at $(document).ready()
What you can try is to use the script tag's onload, and when it fires, check for the button, like I do here, fire a console.log when jQuery have loaded.
Note, the order of the script is important
Stack snippet
<script>
function checkForjQuery() {
console.log('jQuery loaded');
}
function checkForButton() {
if ($("#design_edit_btn").length) {
alert("exists");
}
}
</script>
<script onload="checkForjQuery()" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- temp. commented out
<script onload="checkForButton()" src="your_script_path"></script>
-->
have you tried something like this:
if(document.getElementById('design_edit_btn') != null)
{
alert("exists");
}
This should do the trick
if ($("#design_edit_btn").length > 0) {
alert("exists");
}

How to run a function on a page with Capybara/Poltergeist?

I have a page with JS functions (which are called on mouse click) within <script> ... </script> tags. While I was testing I had encountered problems with .click method not working many times. Therefore I decided to simply call that function manually. However I found no source on the Internet which taught to do this.
I want to avoid clicking the links and simply call for doSumbit('5').
Thank you!
The JS functions are:
<script language="javascript">
function doSubmit(infoTypeId) {
document.forms[1].INFOTYPEID.value = infoTypeId;
document.forms[1].action = document.forms[1].action + "#" + infoTypeId;
document.forms[1].submit();
document.forms[0].INFOTYPEID.value = infoTypeId;
document.forms[0].submit();
}
function doSubmitOne(infoTypeId) {
document.forms[0].INFOTYPEID.value = infoTypeId;
document.forms[0].submit();
}
</script>
and the on-click links are:
<a href="javascript:doSubmit('11')" >Engine News<br></A>
<a href="javascript:doSubmit('5')" >Parts Identification<br></A>
You can run arbitrary JS with execute_script
page.execute_script("doSubmit('5')")
if you expect a return value use evaluate_script - it's all documented here - http://www.rubydoc.info/gems/capybara/Capybara/Session#evaluate_script-instance_method
Of course if you're actually testing an app, you'd be much better off figuring out why click isn't working for you and fixing that, since by just calling JS functions you're not actually testing that your app works.
EDIT: typo doSubit changed to doSubmit

OnClick works only works after reload, using jquerymobile

I know it's an often asked question, but no answer (till now) fits for me.
I wrote a mobile app with Cordova. I'm also testing apps in browser (Firefox). I'm using jQuery and jq mobile.
The problem is: my OnClick events on work only after refresh, which isn't possible on mobile and even on pc not really an solution.
Update: I read about, that the ehader isn't loaded again in jQuery mobile. So I treid it as described in thsi solution: page loaded differently with jQuery-mobile transition
didn't work.
And with alert(); you see, that the script runs once but before the site is totally build.
My html:
<div data-role="main" class="ui-content" id="container" >
<div id="container0">
<a data-role="button" id="anchor0" >Neuen Termin Hinzufügen</a>
</div>
</div>
originally the <a> had an onclick (<a onClick>="doStuff()")
Here a are my different attempts:
$(function () {
// Assign the click handler on DOM-ready
$('a').on('click', function () {
dateElementClicked(this);
});
});
$(document).ready($(function () {
// Assign the click handler on DOM-ready
$('a').on('click', function () {
dateElementClicked(this);
});
})
);
$("#anchor0").live("click", dateElementClicked($("#anchor0")));
$("a").click( dateElementClicked(this));
$("a").bind("click", function (event, ui){
dateElementClicked(this);
});
They all work only after an refresh. or the first one runs the function instant and interupts everything because "this" is undefined.
Edit:
I even tried it with button and inpute type button and made extra js file. but my javascript only runs after an refresh... Putted an console log and alert in the script. So the whole script is stuck somehow
The dateelement clicked function (I cleared this too for testing and just put an alert() in it)
Here is the git link to the project: https://github.com/LosKartoflos/Apoll.git
function dateElementClicked(clickedAnchor) {
//anchor is clicked the first time(the id number equals numberOfAppointments)
if (clickedAnchor.id.slice(-1) == numberOfAppointments) {
dateElementClickedFirstTime(clickedAnchor);
}
else if (appointmentList[getDateElementNumber(clickedAnchor)]["RolledOut"] == true)
{
hideContent(getDateElementNumber(clickedAnchor));
}
else if (appointmentList[getDateElementNumber(clickedAnchor)]["RolledOut"] == false)
{
showContent(getDateElementNumber(clickedAnchor));
}
else
{
alert("Element not listed");
}
}
BTW: my script isin my html file.
Maybe try using the deviceready event instead of document ready.
https://cordova.apache.org/docs/en/4.0.0/cordova_events_events.md.html
Try this
$(document).on('click', '#anchor0', function(event) {
});
or this
$(document).on('click', 'a', function(event) {
});
okay the Problem is, that Cordova is messing around with normal build/loading oder. to trigger functions, after the side is loaded.
The Cordova Documentary recommends this two solutions:
Put this in your header and bind your events in the onload or dofirst. An do everything you want to be have done, after page is ready, in the do first:
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script src="js/script.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
// Wait for device API libraries to load
//add all Events (click Events)
function onLoad() {
document.addEventListener("deviceready", doFirst(), false);
document.getElementById("anchor").addEventListener("click", clickedFunction, false);
}
// device APIs are available
function onDeviceReady() {
}
//things to put up first
function doFirst() {
}
</script>
or put it in the onDeviceReady function, in the auto created index.js .
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function() {
document.getElementById("anchor0").addEventListener("click", clicked, false);
app.receivedEvent('deviceready');
},
Here the documentary: https://cordova.apache.org/docs/en/4.0.0/cordova_events_events.md.html
And i kicked out jquery and jquery mobile. Jquery was messing around with document ready and jquery mobile prevents the head from beeing loaded again.

asp.net usercontrol won't fire javascript inside updatepanel

I've seen similar issues to this and answers but none seem to fix the issue.
I have a user control inside an update panel. Inside my user control I output javascript.
The javascript will not fire when triggered. If I move the javascript to the parent page outside of the usercontrol/updatepanels then it fires. This doesn't make sense to do this as I can't use this usercontrol on another page without either duplicating code...by either duplicating the entire javascript (different site) or adding references to a .js file in every page it's used on (same site). It's just less portable
I merely want to output the javascript with the control (inside the update panel).
The updatepanel is mentioned for accuracy of what I'm doing. It doesn't work even if I place the usercontrol outside of updatepanels.
Keeping it simple (This does not work for me):
USERCONTROL:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="_location.ascx.cs" Inherits="_location" %>
<script type="text/javascript">
function test() {
alert('Hello World!');
}
</script>
<a href="javascript:void(0);" onclick="javascript:test();">
Find For Me
</a>
PARENT:
<uc1:_location runat="server" ID="_location" />
Debugging in chrome tells me "Uncaught ReferenceError: test is not defined"
If I add the javascript directly to the onclick as below, it works:
onclick="alert('Hello World!');"
And as stated above, moving the function to the parent page ALSO works.
It's as if the browser ignores the script output from the user control.
Any ideas?
When you have an UpdatePanel and that UpdatePanel updates it's content, it treats it's content as simple text/html (not code), it does not have any parser available to run the script and make it available for the page.
So this content,
<script type="text/javascript">
function test() { alert('Hello World!'); }
</script>
<a href="javascript:void(0);" onclick="javascript:test();">
Find For Me
</a>
after client side code of update panel runs and updates content of the page, the script part is not parsed - its simple text/html for the page.
This part however runs
Find For Me
because the parse of the onclick attribute is done when you click on it.
There are following workarounds available:
Move your javascript into external file
Move you script outside of the UpdatePanel
Register the script in the code behind with RegisterClientScriptBlock or alternative functions.
In Addition to the solution that Adam Wood posted, I should say that you must use ScriptManager to register the script when using update panel, at least in .net 4.0 because otherwise it won´t work.
So you can put on the PageLoad event of the usercontrol:
string script = #" alert('this is a test');
alert('it worked')";
ScriptManager.RegisterStartupScript(Page,Page.GetType(),"scriptMelhoria",script,true);
Thanks to Aristos for sending me down the right path... Though his solution works, it did not answer the question of outputting the javascript from inside the usercontrol but instead suggested moving it outside. This was not the desired outcome, as stated, as it's not kept inside the control for easier portability.
Here is my solution that accomplishes this:
CS file:
String script = "<script type=\"text/javascript\">";
script += "function test() {";
script += "alert('Hello World!');";
script += "</script>";
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "locationScript", script);
One might use a stringbuilder if script is longer, but eitherway works.
This keeps the code entirely inside the usercontrol and it works from the onclick event of the a tag.
Try this;
You can find your script elements after udpdate panel callback and evaluate them.
Add a special attribute to your inline script tag to select elements after callback request.
<script type="text/javascript" data-tag='myscript'>
function test() {
alert('Hello World!');
}
</script>
And add this script to your update panel container aspx file.
<script>
if (Sys !== undefined) {
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(endPostbackRequest);
}
function endPostbackRequest(sender, args) {
$("script[data-tag='myscript']:not([data-run])").each(
function () {
eval.apply(window, [$(this).text()]);
$(this).attr('data-run', '1');
});
}
</script>
Preferred way of dealing with javscript code that is bound to DOM elements within UpdatePanel is to subscribe to endRequest event of PageRequestManager and execute your code here. For instance you want to set click event handlers here.
// that is standard way for asp.net to execute JS on page load
// pretty much the same as $(function(){ ...}) with jquery
function pageLoad() {
// find PRM instance and subscribe to endRequest
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest);
}
function endRequest() {
// set all handlers to DOM elements that are within UpdatePanel
$('<%= myButton.ClientID %>').on('click', test)
}
function test(e) {
alert('Hi')
}
Alternative solution will be to use event delegation like so:
function pageLoad() {
// delegate click event on .myButton inside .container
// to the .container DOM element
$('.container').on('click', '.myButton', test)
}
And have div with a class named container around your update panel. In this case your div.container is never removed from DOM so all event handlers on it will hold after partial postbacks.
Same code without jquery and using only asp.net ajax will look like this:
function pageLoad() {
Sys.UI.DomEvent.addHandler($("myContainer"), "click", delegatedTest);
}
function delegatedTest(e) {
// since asp.net ajax does not support event delegation
// you need to check target of the event to be the right button
if (e.target.id == "myButton") test(e)
}
function test(e) {
alert("HI")
}

Change JavaScript and delete old one

In my HTML-head i have this script included:
<script id="mode" type="text/javascript" src="article.js"></script>
With a button click I'd like to change the source of the script to customers.js so that it then looks like this:
<script id="mode" type="text/javascript" src="customers.js"></script>
The point is that I don't want the article.js to be included in my page then anymore, so I can't just use .append().
So, click on the article button -> only article.js included, click on the customers button -> only customers.js included.
I tried to solve this with jQuery this way, but I doesn' seem to work...:
$("#btArticle").click(function(){
$("#mode").attr("src","article.js");
});
$("#btCustomers").click(function(){
$("#mode").attr("src","customers.js");
});
Do you know where my mistake is?
Update: There are methods with the same name in customers.js and article.js. So there's a onSave() method in both of them and when I clicked the customer button before, I want the onSave() method of customers.js to be executed, not the one in articles.js.
The point is that I don't want the article.js to be included in my page then anymore, so I can't just use .append().
Once the script has been downloaded and evaluated, anything it leaves lying around will remain unless explicitly removed; they're not linked to the script element itself and removing it won't have any effect on them.
The only way to get rid of the stuff article.js leaves lying around is to remove or overwrite each and every thing it creates and keeps.
Concrete example:
// article.js
var foo = "bar";
jQuery(function($) {
$(".stuff").click(function() {
alert("You clicked stuff!");
});
});
If the article.js listed above is processed, you can remove the script element that loaded it, and that will have no effect on the foo global variable or the event handler that it hooked up.
If you want to have scripts that you can unload, have them use the module pattern with a single global symbol they add by assigning to a property on window, e.g.:
// article.js
window.articleScript = (function() {
var foo = "bar";
jQuery(function($) {
$(".stuff").bind("click.article", function() {
alert("You clicked stuff!");
});
});
function remove() {
$(".stuff").unbind("click.article");
try {
delete window.articleScript;
}
catch (e) { // Early IEs throw incorrectly on the above
window.articleScript = undefined;
}
}
return {
remove: remove
};
})();
You can then remove it by doing this:
articleScript.remove();
Re your comment on the question:
Maybe I should've mentioned that there are methods in both files with the same name.
If you have global function declarations in customers.js that use the same name as global function declarations in articles.js, when you load customers.js, it will replace those functions.
So if you have this in articles.js:
function foo() {
alert("Articles!");
}
...and this in customers.js:
function foo() {
alert("Customers!");
}
And you have a button:
<input type="button" onclick="foo();" value="Foo">
When you've loaded just articles.js and not customers.js, clicking that button gives you "Articles!". If you then load customers.js, clicking the button will give you "Customers!".
That works because the event handler calls foo(), but the event handler itself is not foo. The onclick attribute creates a hidden event handler for you. The equivalent jQuery would be:
$("input[type='button'][value='Foo']").click(function() {
foo();
});
Note that just doing .click(foo) will do something very different: It will hook up the function that foo points to at that moment as the event handler. Even if you change what foo points to later (by loading customers.js), that won't change the fact that the old function is hooked up as a handler.
FWIW, from the question and your comments, I think I'd recommend sitting back and reviewing your strategy for this page/app. All of this swapping of code in and out and such seems like a design problem.
You are not actually loading and running the respective scripts, you are just changing the source for that tag. Use .getScript() to load and run the appropriate JavaScript file:
http://api.jquery.com/jQuery.getScript/

Categories

Resources