Autohotkey - Using DOM, trigger javascript function - javascript

There are some buttons(actually, links) on a web, and I can click on it menually.
but,
wb:=ComObjCreate("InternetExplorer.Application")
wb.document.getElementById("Status").click()
this script don't work. #critsz said because there is no definition about click.
so, I'm trying to trigger the function after defining "click"
the following is a part of the source.
<ul class="nav nav-pills nav-stacked" id="TabMenu">
<li class="active" id="basic"><i class="fa fa-inbox"></i> Basic
<!-- <span class="label label-primary pull-right">12</span> -->
</li>
<li id="Status"><i class="fa fa-envelope-o"></i> Status</li>
</ul>
function viewPage(Name,Number){
$("#TabMenu li").removeClass("active");
$("#"+Name).addClass("active");
$("#ViewPage").load(
Name+".asp",
{
Number : Number
},
function( response, status, xhr ) {
if ( status == "error" ) {
var msg = "an error: ";
$( "#error" ).html( msg + xhr.status + " " + xhr.statusText );
}
});
}
And I tried this.
wb.document.getElementById("Status").addEventListener("click",viewPage(Status,10000))
but an error occurs : Call to nonexistent function.
Specifically: viewPage(Status,10000)
Does this mean that I need to define the function on my autohotkey script? or Is there any other way to do that?
if i should do, how can I do that?

Try wb.navigate("javascript:viewPage('Status','10010');")

Related

JS innerHTML not displaying

I'm trying to create a dynamic navbar that is different when a user is signed in vs. not signed in.
I have the auth portion working (confirmed with console logs); however, for some reason, the HTML is not getting updated when I use .innerHTML = .... I'm console logging the innerHTML after I update it, and it appears correct in the log but the navbar isn't displaying like it should.
HTML:
...
<ul class="site-menu main-menu js-clone-nav mr-auto d-none d-lg-block">
<li><strong>Home</strong></li>
<li id ="nav-listings">
<strong>Listings</strong>
</li>
<li><strong>Contact</strong></li>
<li class="has-children" id="nav-account">
<strong>Sign-In</strong>
<div id="navDropdown" class="dropdown">
Profile
Sign-Up
</div>
</li>
</ul>
...
js code:
AOS.init({
duration: 800,
easing: 'slide',
once: true
});
jQuery(document).ready(function($) {
"use strict";
$(".loader").delay(1000).fadeOut("slow");
$("#overlayer").delay(1000).fadeOut("slow");
...
firebase.auth().onAuthStateChanged(firebaseUser => {
if (firebaseUser) {
var username = firebaseUser.email;
console.log(`${firebaseUser ? `- User signed in: ${firebaseUser.email} => ${username}` : "No User Signed in"}`);
document.getElementById("nav-listings").className = "has-children";
document.getElementById("nav-listings").innerHTML = "<a href='Search.html' class='nav-link'><strong>Listings</strong></a>" +
"<div id='listDropdown' class='dropdown'>" +
"<a href='AddHouse.html'>Add Listing</a>" +
"<a href='User.html'>Favorites</a>" +
"</div>";
console.log(document.getElementById("nav-listings").innerHTML);
} else {
btnLogin.disabled = false;
}
});
});
EDIT:
It is appearing in the condensed form of the navbar but the main navbar???
See Here for the full code (minus the CSS... which makes the problem hard to see but all the js and HTML are there).
This should work
HTML:
<ul class="site-menu main-menu js-clone-nav mr-auto d-none d-lg-block">
<li><strong>Home</strong></li>
<li id="nav-listings">
<strong>Listings</strong>
</li>
<li><strong>Contact</strong></li>
<li class="has-children" id="nav-account">
<strong>Sign-In</strong>
<div id="navDropdown" class="dropdown">
Profile
Sign-Up
</div>
</li>
</ul>
JavaScript:
firebase.auth().onAuthStateChanged(firebaseUser => {
if (firebaseUser) {
var username = firebaseUser.email;
console.log(`${firebaseUser ? `- User signed in: ${firebaseUser.email} => ${username}` : "No User Signed in"}`); ;
$("#nav-listings").addClass('has-children').html("<a href='Search.html' class='nav-link'><strong>Listings</strong></a><div id='listDropdown' class='dropdown'><a href='AddHouse.html'>Add Listing</a><a href='User.html'>Favorites</a></div>")
console.log($("#nav-listings").html());
} else {
btnLogin.disabled = false;
}
});
When you are setting the innerHTML you are also setting the class for nav-listings to has-children. This removes the existing class of nav-link.
Do you mean to do this? If you want to keep the nav-link class as well then instead of
document.getElementById("nav-listings").className = "has-children";
put a space before the has-children and add the string to the classname. This will then add has-children to the class and wont remove the nav-link.
document.getElementById("nav-listings").className += " has-children";
If you console.log the outerHTML instead of innerHTML you can check whether both nav-link and has-children are there.

Execute JS function from Code behind (with Parameter)

I'm working on some Code which loads the a page and selects the required nav tab. This works great in the .aspx file, but I don't know how to trigger with the code behind.
Here is the element that I would like to select
<li class="nav-item" runat="server">
<a class="nav-link" id="pills-request-tab" data-toggle="pill" href="#pills-request" role="tab" aria-controls="pills-request" aria-selected="false" onclick="OnTabChange(this)">Request</a>
</li>
JS code
$(document).ready(function () {
debugger;
var tabName = $("#TabName").val() != "" ? $("#TabName").val() : "pills-home";
$('.tab-content div').removeClass('active').removeClass('show');
$('#' + tabName + '-tab').addClass('active');
$('#' + tabName).addClass(' show active');
if ($("#TabName").val() != "" && $("#TabName").val() != "1") {
("#pills-user-tab").addClass(' admin');
("#pills-holiday-tab").addClass(' admin');
("#pills-add-tab").addClass(' admin');
}
});
function OnTabChange(currentTab) {
if (currentTab != null)
console.log(currentTab);
$("#TabName").val(currentTab.id.replace('-tab', ''));
}
Code behind
Page.ClientScript.RegisterStartupScript(this.GetType(), "pills-request-tab", OnTabChange(this), true);
I know that the parameter in Code behind is not OnTabChange(this). I would like to know how I can pass the object from code behind.
You simply call the OnTabChange like this. Only this will not work. You will need to pass a string.
Page.ClientScript.RegisterStartupScript(this.GetType(), "pills-request-tab", "OnTabChange('tabID')", true);
The Solution look like this:
Page.ClientScript.RegisterStartupScript(this.GetType(), "pills-request-tab", "OnTabChange(<a class='nav-link' id='pills-request-tab' data-toggle='pill' href ='#pills-request' role ='tab' aria-controls='pills-request' aria-selected='false' onclick ='OnTabChange(this)' > Request</a>)", true);

if notification count is zero I want what I have right now(box) but if it's not zero I want box to be changed to badge with notification count

I have a notification system that works. Right now, when there's no notification or not, the notification appears in a <span class='glyphicon glyphicon-inbox' aria-hidden="true"></span> just like stackoverflow. but my desire is when there's a notification, I want the box to be turned into a
<span class="badge badge-notify" style="red">notification count</span>
again just like a stack overflow.
So I tried removing a particular class that changes the form of the box when if count == 0 and adding the class when count is not zero. I tried setting set interval as well but it just won't work.
Can you please help me?
below is what I have in navbar, I have the notification box and the badge set up.
<li class="dropdown">
<a href="#" class="dropdown-toggle notification-toggle" data-toggle="dropdown" role="button" aria-expanded="false" id="button">
<span class='glyphicon glyphicon-inbox' aria-hidden="true"></span>
<span class="caret"></span>
<span class="badge badge-notify">notification count</span></a>
<ul class="dropdown-menu" role="menu" id='notification_dropdown'>
</ul>
</li>
below is my ajax function to disply notification
<script>
$(document).ready(function(){
$(".notification-toggle").click(function(e){
e.preventDefault();
$.ajax({
type: "POST",
url: "{% url 'get_notifications_ajax' %}",
data: {
csrfmiddlewaretoken: "{{ csrf_token }}",
},
success: function(data){
$("#notification_dropdown").html(' <li role="presentation" class="dropdown-header">alarm</li>');
var count = data.count
console.log(count)
if (count == 0) {
$("#notification_dropdown").removeClass('notification');
var url = '{% url "notifications_all" %}'
$("#notification_dropdown").append("<li><a href='" + url+ "'>view all</a></li>")
} else {
$("#notification_dropdown").addClass('notification');
$(data.notifications).each(function(){
var link = this;
$("#notification_dropdown").append("<li>" + link + "</li>")
})
}
console.log(data.notifications);
},
error: function(rs, e) {
console.log(rs);
console.log(e);
}
})
})
})
</script>
so what I kinda tried was this,
<style>
{% block style %}
#notification_dropdown{
}
#notification_dropdown.notification{
color: red;
}
{% endblock %}
</style>
and
<script>
setTimeout(function(){
$("#notification_dropdown:visible").addClass('notification');
}, 2000);
</script>
maybe I set the id wrong...those did nothing unfortunately.
not sure if this is needed, I'll also add function for notification(ajax)
def get_notifications_ajax(request):
if request.is_ajax() and request.method == "POST":
notifications = Notification.objects.all_for_user(MyProfile.objects.get(user=request.user)).recent()
count = notifications.count()
notes = []
for note in notifications:
notes.append(note.get_link.encode('utf-8'))
data = {
"notifications": notes,
"count": count,
}
print data
json_data = json.dumps(data)
print json_data
return HttpResponse(json_data, content_type='application/json')
else:
raise Http404
So my question)
1) what did I do wrong that the form/color of notification box didn't change when notification is not zero, and how do I achieve what I want which is box to be turned into a
<span class="badge badge-notify" style="red">notification count</span>
2) I'm able to display count of notification in console with console.log(count), how do I display this count in the navbar?
It looks like all the changes you are doing in AJAX success are on #notification_dropdown but in your navbar HTML the <span> elements you want to toggle are never touched. It's the same in your CSS:
<style>
{% block style %}
#notification_dropdown{
}
#notification_dropdown.notification{
color: red;
}
{% endblock %}
</style>
The CSS selectors used (#notification_dropdown) do not apply the CSS properties to the <span> elements which matter.
One of the ways to fix this -
Change your navbar HTML to:
<li class="dropdown">
<a href="#" class="dropdown-toggle notification-toggle" data-toggle="dropdown" role="button" aria-expanded="false" id="button">
<span id="no_notify" class='glyphicon glyphicon-inbox' aria-hidden="true"></span>
<span class="caret"></span>
<span id="notify_count" class="badge badge-notify">notification count</span></a>
<ul class="dropdown-menu" role="menu" id='notification_dropdown'>
</ul>
</li>
Change: added id attribute to both no notify and notify count badge span elements.
And
Change your Ajax script to:
<script>
$(document).ready(function(){
$(".notification-toggle").click(function(e){
e.preventDefault();
$.ajax({
type: "POST",
url: "{% url 'get_notifications_ajax' %}",
data: {
csrfmiddlewaretoken: "{{ csrf_token }}",
},
success: function(data){
$("#notification_dropdown").html(' <li role="presentation" class="dropdown-header">alarm</li>');
var count = data.count
console.log(count)
if (count == 0) {
$("#notify_count").html(count).hide();
$("#no_notify").show();
$("#notification_dropdown").removeClass('notification');
var url = '{% url "notifications_all" %}'
$("#notification_dropdown").append("<li><a href='" + url+ "'>view all</a></li>")
} else {
$("#no_notify").hide();
$("#notify_count").html(count).show();
$("#notification_dropdown").addClass('notification');
$(data.notifications).each(function(){
var link = this;
$("#notification_dropdown").append("<li>" + link + "</li>")
})
}
console.log(data.notifications);
},
error: function(rs, e) {
console.log(rs);
console.log(e);
}
})
})
})
</script>
Change: added $("#no_notify") and $("#notify_count") related lines to show()/hide() those spans based on count
And change your setTimeout to:
<script>
setTimeout(function(){
$(".notification-toggle").click();
}, 2000);
</script>
$(".notification-toggle").click(); triggers a click on <a> in navbar, which does the Ajax call. If the count from Ajax response is zero we hide notify_count span and show no_notify else do the reverse.
Triggering a click on the <a> tag seems like a good idea. If in future you want the count update to happen only on user action (a click on anchor tag) and do not want the call to happen periodically all you have to do is get rid of setTimeout logic.
It is a best practice to add an error callback too for your AJAX call, just in case if the POST call to get_notifications_ajax fails.
One simple way to accomplish this is to use setInterval() to query the server every few seconds for new notifications. The code would look something like this:
HTML
<li class="dropdown">
<a href="#" class="dropdown-toggle notification-toggle" data-toggle="dropdown" role="button" aria-expanded="false" id="button">
<div id='inbox-wrapper'><span class='glyphicon glyphicon-inbox' aria-hidden="true"></span><div>
<span class="caret"></span>
<span class="badge badge-notify">notification count</span></a>
<ul class="dropdown-menu" role="menu" id='notification_dropdown'></ul>
</li>
JS
<script>
setInterval(function(){
$.ajax({
type: "POST",
url: "{% url 'get_notifications_ajax' %}",
data: {
csrfmiddlewaretoken: "{{ csrf_token }}",
},
success: function(data){
$("#notification_dropdown").html(' <li role="presentation" class="dropdown-header">alarm</li>');
var count = data.count
console.log(count)
if (count == 0) {
$("#notification_dropdown").removeClass('notification');
var url = '{% url "notifications_all" %}'
$("#notification_dropdown").append("<li><a href='" + url+ "'>view all</a></li>")
// here we change the inbox appearance
$("#inbox-wrapper").html("<span class='glyphicon glyphicon-inbox' aria-hidden='true'></span>");
} else {
$("#notification_dropdown").addClass('notification');
$(data.notifications).each(function(){
var link = this;
$("#notification_dropdown").append("<li>" + link + "</li>")
// change the inbox appearance
$("#inbox-wrapper").html("<span class='badge badge-notify' style='background-color:red'>" + count + "</span>");
})
}
console.log(data.notifications);
},
error: function(rs, e) {
console.log(rs);
console.log(e);
}
});
}, 5000);
</script>
I made the following changes to your code:
1) I added a div with an id to wrap the inbox, in order to make HTML swapping simpler (as well I fixed the style attribute for the 'active' inbox span)
2) I move the code from the inbox click event to a setInterval function.
That way, you don't have to send the AJAX request when opening the inbox drop-down, because you already have done so, every 5 seconds!
3) I added the notification count to the inbox element

Function not able to access observableArray in knockout

I keep getting this error when I try to update an observableArray:
'Unable to get property 'removeAll' of undefined or null reference'
Here is my code:
var agilityFirmViewModel = {
test: ko.computed(function () {
return Pairs[0].Pairs;
}),
currentLocation: ko.observableArray(Pairs[0].Pairs[0].Location);
//function to update values in currentLocation
ChangeLocation: function (practiceGroup) {
if (practiceGroup === undefined) {
practiceGroup = '(All Practice Groups)';
}
for (var i = 0; i <= Pairs[0].Pairs.length; i++) {
if (practiceGroup.Department === Pairs[0].Pairs[i].Department) {
this.currentLocation.removeAll();
this.currentLocation.push(practiceGroup.Location[i]);
return root.currentLocation;
}
}
},
}
$(document).ready(function () {
ko.applyBindings(agilityFirmViewModel);
});
Assuming that it goes through the if statement inside the for loop everytime,
whenever it gets to
this.currentLocation.removeAll();
I get the error above saying that currentLocation is undefined. I know that currentLocation has data in it, so would could be causing this issue. It's probably something simple, but I can't seem to figure it out. Thank you.
Where i call ChangeLocation():
<li class="nav-sidebar-GreenMenu">
<a href="javascript:;" class="draggable-panel" draggable="true">
<i id="CategoryIcon" class="glyphicon glyphicon-user"></i>
<span class="sidebarTabName"><b>Practice Group</b></span><br />
<!--For some reason, changing the margin-left below will change the width of the entire sidebar-->
<span id="CurrentItem_TPG" class="currentItem" #*style="margin-left:64px;"*#>(All Practice Groups)</span>
<span id="DefaultItem_TPG" style="display:none;">(All Practice Groups)</span>
<i class="fa fa-chevron-left pull-right hidden-xs" data-bind=""></i>
<span class="arrow open" style="margin-top:-30px;"></span>
</a>
<ul class="sub-menu">
<!--ko foreach: test()-->
<li>
</li>
<!-- /ko -->
</ul>
</li>
The problem is the way you're using bind. The actual signature for bind is:
fun.bind(thisArg[, arg1[, arg2[, ...]]])
Meaning, the first argument determines what this means in the function and the rest sets the arguments to use when it's called. Instead, try changing your click handler to this:
$parent.ChangeLocation.bind($parent, $data);
This ensures that ChangeLocation is called with $parent === this and $data === practiceGroup

jQuery click function for <ul><li> elements

I have a unordered list looking like this:
<ul id="frozen" data-name="nameOfSelect" class="tagit">
<li class="tagit-choice" tagvalue="2" style="padding-right: 4px;" id="tag-2">
<div class="tagit-label" data-value="2">kázeň</div>
</li>
<li class="tagit-choice" tagvalue="1" style="padding-right: 4px;" id="tag-1">
<div class="tagit-label" data-value="1">žalmxxxx</div>
</li>
</ul>
I need to bind an click function to all of them and get the data of the id="tag-1" to be used in the function.
I have tried this:
$('#[id|="tag"]').each(function(){
var tag = this.attr('id');
var tagID = tag.replace('tag-','');
this.click(function (){
alert('index.php?s=taglist&tag=' + tagID);
//window.location = string;
});
});
However, for some reason it seems that this approach is wrong for the <li> element as I am having problems with the selector (it seems). Maybe I am also missing something stupid... Any ideas?
No need for a loop, jQuery does this internally, and this is a native DOM element, which has an id property, but no attr() method :
$('[id^="tag-"]').on('click', function() {
var tag = this.id,
tagID = tag.replace('tag-', '');
alert('index.php?s=taglist&tag=' + tagID);
});

Categories