Click an anchor in a UIWebView with a UIButton - javascript

I have a Javascript function on my webpage that I'm displaying in a UIWebView:
$(document).ready(function() {
// index to reference the next/prev display
var i = 0;
// get the total number of display sections
// where the ID starts with "display_"
var len = $('div[id^="hl"]').length;
// for next, increment the index, or reset to 0, and concatenate
// it to "display_" and set it as the hash
$('#next').click(function() {
++i;
window.location.hash = "hl" + i;
return false;
});
// for prev, if the index is 0, set it to the total length, then decrement
// it, concatenate it to "display_" and set it as the hash
$('#prev').click(function() {
if (i > 1)
--i;
window.location.hash = "hl" + i;
return false;
});
});
So what I need to do is simulate an anchor click when my UIButton is clicked:
- (IBAction)next:(id)sender {
[animalDesciption stringByEvaluatingJavaScriptFromString:#"document.getElementById(\"next\").click();"];
}
But this doesn't work!
It works great on an HTML page, just by clicking the anchor that has an id of "next".
Any ideas why this won't work when clicking the button?
BTW I am able to call a standard javascript function like myFunc() with my current setup, but it won't do anything like this!
Any thoughts would be very appreciated!

You could implement javascript functions for next and previous and call that directly from your UIButton.
var i = 0;
function next() {
++i;
window.location.hash = "hl" + i;
return false;
}
function prev() {
if (i > 1)
--i;
window.location.hash = "hl" + i;
return false;
}
$(document).ready(function() {
// get the total number of display sections
// where the ID starts with "display_"
var len = $('div[id^="hl"]').length;
$('#next').click(function() {
next();
});
$('#prev').click(function() {
prev():
});
});
The call from your UIButton would be:
- (IBAction)next:(id)sender {
[animalDesciption stringByEvaluatingJavaScriptFromString:#"next()"];
}
By the way: I think you forgot to use len in the next() function to avoid stepping over the last display section.

Related

Cordova navigator.app.backHistory button on html different approach

I'm building hybrid app with Intel XDK and I need help with back button and it's function. I have only one index.html file. All "pages" are 's and each one have different id.
I navigate through them using activate_subpage("#uib_page_10");
$(document).on("click", ".firs_div_button", function(evt){
//#uib_page_10 is div with it's content
activate_subpage("#uib_page_10");
var thisPage = 1;
goBackFunction (thisPage); //call function and pass it page number
});
$(document).on("click", ".second_div_button", function(evt){
//#uib_page_20 is div with it's content
activate_subpage("#uib_page_20");
var thisPage = 2;
goBackFunction (thisPage); //call function and pass it page number
});
I have set this EventListener hardware on back button.
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown() {
alert("hello");
navigator.app.backHistory();
}
This is functional but it does not work as it should, in my case and for my app.
When I navigate from one page to another (5 pages / divs) and hit back button, sometimes it does not go back to the first page. It just go "back" to history too deep and close the app, without changing the actual page (view) before closing.
Now, I have an idea, but I need help with this.
I will not use history back, I will use counter and dynamic array for up to 5 elements.
function goBackFunction (getActivePage) {
var active_page = getActivePage;
var counter = 0; // init the counter (max is 5)
var history_list = [counter][active_page]; // empty array
counter = counter + 1;
:
:
:
}
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown() {
//read the array and it's positions then activate:
activate_subpage("#PAGE_FROM_ARRAY");
counter = counter - 1;
if (counter == 0) {
//trigger the app exit when counter get's to 0.
navigator.app.exitApp();
}
}
This is only idea, not tested. I would like to store list of opened pages in Array and when back button is pressed, to activate the pages taken from the Array list, backwards.
I do not know how to do this, I'm not a expert :( There is may be batter way to do this. If someone have any suggestion, I will accept it :D
I save an array in localStorage with all pages navigated and I go back using a pop() on the array. At the moment, it's the best way I got to go back.
This is my code:
// First, create the table "pages"
function init_pages_table()
{
var pages = new localStorageDB("pages", localStorage);
if (!pages.isNew())
{
pages.drop();
pages.commit();
}
var pages = new localStorageDB("pages", localStorage);
pages.createTable("Pages", ["nome"]);
// commit the database to localStorage
// all create/drop/insert/update/delete operations should be committed
pages.commit();
}
// Add a page into the array:
function push_pagename(pagename)
{
var pages = new localStorageDB("pages", localStorage);
if (!pages.tableExists("Pages"))
{
init_pages_table();
pages = new localStorageDB("pages", localStorage);
}
pages.insert("Pages", {nome: pagename});
pages.commit();
}
// Pop a page form the array:
function pop_pagename()
{
var output = '';
var id_page = ''
var pages = new localStorageDB("pages", localStorage);
var last_page = pages.queryAll("Pages", { limit: 1,
sort: [["ID", "DESC"]]
});
$.each(last_page, function(index,value){
output = value.nome;
id_page = value.ID;
return false;
});
var rowdeleted = pages.deleteRows("Pages", {ID: id_page});
pages.commit();
return output;
}
You can also define functions for set, get, read:
function set_backpage(pageurl)
{
push_pagename(pageurl);
}
function get_backpage()
{
return pop_pagename();
}
function read_backpage()
{
var output = '';
var id_page = ''
var pages = new localStorageDB("pages", localStorage);
var last_page = pages.queryAll("Pages", { limit: 1,
sort: [["ID", "DESC"]]
});
$.each(last_page, function(index,value){
output = value.nome;
id_page = value.ID;
return false;
});
return output;
}

Is it possible to make "for" loop in CasperJS?

It is additional question of How to stop a loop when clicking asynchronously in CasperJS
I tried this code
function execOnce(casper, i, max){
// end condition
if (i === max) {
return;
}
casper.wait(3000, function() {
var button = x('//*[#id="content"]/div[3]/a['+i+']');
if (!this.exists(button)) {
this.echo(i + " not available");
return;
}
this.thenClick(button, function (){
console.log('Searching dic');
words = words.concat(this.evaluate(getWords));
// recursive step
execOnce(this, i+1, max);
});
});
};
// start the recursive chain
casper.then(function(){
execOnce(this, 1, 200);
});
But I found that indexes' Xpath of my target web pages has iteration.
When it reached '//*[#id="mArticle"]/div[2]/a['11']' next index's Xpath becomes '//*[#id="mArticle"]/div[2]/a['2'] (back to a['2'])
for example the webpage url is "http://krdic.naver.com/search.nhn?query=%E3%85%8F%E3%85%8F&kind=keyword"
under the page there are [1][2][3][4][5][6][7][8][9][10] [Next Page]
When I click Next page you can see
[Previous Page][11][12][13][14][15][16][17][18][19][20] [Next Page]
but [12] 's Xpath is not //*[#id="content"]/div[3]/a[12] ---> It is
//*[#id="content"]/div[3]/a[2]
So I have to do iteration of function execOnce including code casper.wait(6000, function() {}
because my target website is really sensitive to query so I put "wait" code whenever I can..!
In case of this can I use nested function like this?
function execOnce(casper, i, max){
if (i === max) {
function execOnce(casper, i, max){
return;
}
...
XPath is very expressive. You can for example select the intended page link based on link text instead of link position (//div[#class='paginate']/a[text()='5']), but that alone doesn't help you much in this case.
The problem is of course that the site has a secondary pagination. You need to go to the next pagination page, before you can click of the next pagination links.
casper.wait(3000, function() {
var nextButton = x('//*[#id="content"]/div[3]/a[text()="'+i+'"]');
var lastPageNextButton = '.paginate > strong + a.next';
var button = nextButton;
if (this.exists(lastPageNextButton)) {
button = lastPageNextButton;
} else if (!this.exists(button)) {
this.echo(i + " not available");
return;
}
this.thenClick(button, function (){
console.log('Searching dic');
words = words.concat(this.evaluate(getWords));
// recursive step
execOnce(this, i+1, max);
});
});

How can I traverse through cookie and then upon clicking a button change the url depending on values from cookie

I have a cookie dataid giving data as below
"D_2781467,D_2792290,D_2803725,D_2677313,D_2799569,D_2805134,D_2758142,D_2802506,D_2802509,D_2802508,D_2803726,D_2652515"
And in the body we have valies as below
<body class="mycars" data-listing-id="2792290">
And the URL will be like
http://www.abcd.com/c_f_s/D_2792290/xyz.html
What I want is that in this page upon clicking a button , the user is taken to next url as in
http://www.abcd.com/c_f_s/D_2803725
So basically somehow we need to traverse through the cookie and get the index and on pressing the button change the url with the number received from the cookie
You can do it like,
HTML
Next
SCRIPT
$(function(){
var dataArr = ['D_2781467', 'D_2792290', 'D_2803725', 'D_2677313', 'D_2799569',
'D_2805134', 'D_2758142', 'D_2802506', 'D_2802509','D_2802508',
'D_2803726', 'D_2652515'];
var index = 0;
$.cookie('index', 0);
$('#next').on('click', function (e) {
e.preventDefault();
if (index < dataArr.length-1) { // check index length
index++ ;// increment index
} else {
index = 0; // reset index
}
var currentIndex = $.cookie('index'); // get current cookie index from cookie
$.cookie('index', index);
alert('http://www.abcd.com/c_f_s/' + dataArr[currentIndex]);
});
});
You can use cookie plugin
Live Demo
Here is how I would do it (not tested, but this is the basic idea).
using the getCookie function from:
http://www.w3schools.com/js/js_cookies.asp
$('#button').click(function() {
var cook = getCookie('dataid').split(',')
var myId = $('body').eq(0).attr('data-listing-id')
var index = cook.indexOf('D_'+myId)
if (index == -1 || index == cook.length - 1)
return;
document.location = 'http://www.abcd.com/c_f_s/D_'+cook[index+1]
}

Is there a way to convert this jquery code to javascript?

I'm trying to create a tab menu. And I need this coded in regular javascript, not jquery.
$(document).ready(function() {
//When page loads...
$(".general_info_content").hide(); //Hide all content
$("ul.general_info_tabs li:first").addClass("active").show(); //Activate first tab
$(".general_info_content:first").show(); //Show first tab content
//On Click Event
$("ul.general_info_tabs li").click(function() {
$("ul.general_info_tabs li").removeClass("active"); //Remove any "active" class
$(this).addClass("active"); //Add "active" class to selected tab
$(".general_info_content").hide(); //Hide all tab content
var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
$(activeTab).fadeIn(); //Fade in the active ID content
return false;
});
});
The core of what you want to do is below - I'm sure there are a thousand different ways to do each task:
Remove a CSS class from an element:
var classes = document.getElementById([id]).className.split(" ");
for(var i = 0; i < classes.length; i++)
if(classes[i] == removeClass)
classes[i] = "";
document.getElementById([id]).className = classes.join(" ");
Add a CSS class to an element:
document.getElementById([i]).className += " " + addClassName;
Hide an element:
document.getElementById([i]).style.display = "none";
Fade an element:
// not tested, but based on tested/used code
function fade(el, opacity, fadeInTime) {
if (opacity < 100) {
el.style.opacity = opacity / 100;
el.style.filter = "alpha(opacity=" + opacity + ")";
opacity += 5;
setTimeout(function () { fade(el, opacity, fadeInTime); }, fadeInTime / 5);
}
}
To find all elements by CSS and tag name:
var matches = new Array();
var all = document.getElementByTagName(searchTagName);
for(var i = 0; i < all.length; i++){
if(all[i].className.replace(searchClassName, "") != all[i].className) {
matches.push(all[i].className);
}
}
// do something with (i.e., return or process) matches
And for the record, I find it encouraging, not unreasonable, that a person using the jQuery library wants to know how to do get things done with native JS/DOM.
More functions to complement Brian's post. Good luck.
EDIT: As I mentioned I would change the class=general_info_content to id=general_info_content1.
function attach(el, event, fnc) {
//attach event to the element
if (el.addEventListener) {
el.addEventListener(event, fnc, false);
}
else if (document.attachEvent) {
el["on" + event] = fnc; // Don not use attachEvent as it breaks 'this'
}
}
function ready() {
// put all your code within $(function(){}); here.
}
function init() {
attach(document, "readystatechange", function () {
if (document.readyState == "complete") {
ready();
}
});
}

NEED HELP. Author has abandoned to fix this jQuery plugin!

I am trying to implemented this jQuery news ticker style plugin from http://www.makemineatriple.com/2007/10/bbcnewsticker
Like mentioned in the comments (around May) there is a bug and the author lost its will to give a bug fix.
The bug is:
In Mac browsers (Firefox, Opera and Safari, all OSX) - links (a href) don’t ‘work’ until each list item has finished scrolling/revealing. Basically after this plugin has loaded, all the a href stops working.
Here is the code for the plugin (http://plugins.jquery.com/project/BBCnewsTicker):
/*
News ticker plugin (BBC news style)
Bryan Gullan,2007-2010
version 2.2
updated 2010-04-04
Documentation at http://www.makemineatriple.com/news-ticker-documentation/
Demo at http://www.makemineatriple.com/jquery/?newsTicker
Use and distrubute freely with this header intact.
*/
(function($) {
var name='newsTicker';
function runTicker(settings) {
tickerData = $(settings.newsList).data('newsTicker');
if(tickerData.currentItem > tickerData.newsItemCounter){
// if we've looped to beyond the last item in the list, start over
tickerData.currentItem = 0;
}
else if (tickerData.currentItem < 0) {
// if we've looped back before the first item, move to the last one
tickerData.currentItem = tickerData.newsItemCounter;
}
if(tickerData.currentPosition == 0) {
if(tickerData.newsLinks[tickerData.currentItem].length > 0) {
$(tickerData.newsList).empty().append('<li></li>');
}
else {
$(tickerData.newsList).empty().append('<li></li>');
}
}
//only start the ticker itself if it's defined as animating: otherwise it's paused or under manual advance
if (tickerData.animating) {
if( tickerData.currentPosition % 2 == 0) {
var placeHolder = tickerData.placeHolder1;
}
else {
var placeHolder = tickerData.placeHolder2;
}
if( tickerData.currentPosition < tickerData.newsItems[tickerData.currentItem].length) {
// we haven't completed ticking out the current item
var tickerText = tickerData.newsItems[tickerData.currentItem].substring(0,tickerData.currentPosition);
if(tickerData.newsLinks[tickerData.currentItem].length > 0) {
$(tickerData.newsList + ' li a').text(tickerText + placeHolder);
}
else {
$(tickerData.newsList + ' li').text(tickerText + placeHolder);
}
tickerData.currentPosition ++;
setTimeout(function(){runTicker(settings); settings = null;},tickerData.tickerRate);
}
else {
// we're on the last letter of the current item
if(tickerData.newsLinks[tickerData.currentItem].length > 0) {
$(tickerData.newsList + ' li a').text(tickerData.newsItems[tickerData.currentItem]);
}
else {
$(tickerData.newsList + ' li').text(tickerData.newsItems[tickerData.currentItem]);
}
setTimeout(function(){
if (tickerData.animating) {
tickerData.currentPosition = 0;
tickerData.currentItem ++;
runTicker(settings); settings = null;
}
},tickerData.loopDelay);
}
}
else {// settings.animating == false
// display the full text of the current item
var tickerText = tickerData.newsItems[tickerData.currentItem];
if(tickerData.newsLinks[tickerData.currentItem].length > 0) {
$(tickerData.newsList + ' li a').text(tickerText);
}
else {
$(tickerData.newsList + ' li').text(tickerText);
}
}
}
// Core plugin setup and config
jQuery.fn[name] = function(options) {
// Add or overwrite options onto defaults
var settings = jQuery.extend({}, jQuery.fn.newsTicker.defaults, options);
var newsItems = new Array();
var newsLinks = new Array();
var newsItemCounter = 0;
// Hide the static list items
$(settings.newsList + ' li').hide();
// Store the items and links in arrays for output
$(settings.newsList + ' li').each(function(){
if($(this).children('a').length) {
newsItems[newsItemCounter] = $(this).children('a').text();
newsLinks[newsItemCounter] = $(this).children('a').attr('href');
}
else {
newsItems[newsItemCounter] = $(this).text();
newsLinks[newsItemCounter] = '';
}
newsItemCounter ++;
});
var tickerElement = $(settings.newsList); // for quick reference below
tickerElement.data(name, {
newsList: settings.newsList,
tickerRate: settings.tickerRate,
startDelay: settings.startDelay,
loopDelay: settings.loopDelay,
placeHolder1: settings.placeHolder1,
placeHolder2: settings.placeHolder2,
controls: settings.controls,
ownControls: settings.ownControls,
stopOnHover: settings.stopOnHover,
newsItems: newsItems,
newsLinks: newsLinks,
newsItemCounter: newsItemCounter - 1, // -1 because we've incremented even after the last item (above)
currentItem: 0,
currentPosition: 0,
firstRun:1
})
.bind({
stop: function(event) {
// show remainder of the current item immediately
tickerData = tickerElement.data(name);
if (tickerData.animating) { // only stop if not already stopped
tickerData.animating = false;
}
},
play: function(event) {
// show 1st item with startdelay
tickerData = tickerElement.data(name);
if (!tickerData.animating) { // if already animating, don't start animating again
tickerData.animating = true;
setTimeout(function(){runTicker(tickerData); tickerData = null;},tickerData.startDelay);
}
},
resume: function(event) {
// start from next item, with no delay
tickerData = tickerElement.data(name);
if (!tickerData.animating) { // if already animating, don't start animating again
tickerData.animating = true;
// set the character position as 0 to ensure on resume we start at the right point
tickerData.currentPosition = 0;
tickerData.currentItem ++;
runTicker(tickerData); // no delay when resuming.
}
},
next: function(event) {
// show whole of next item
tickerData = tickerElement.data(name);
// stop (which sets as non-animating), and call runticker
$(tickerData.newsList).trigger("stop");
// set the character position as 0 to ensure on resume we start at the right point
tickerData.currentPosition = 0;
tickerData.currentItem ++;
runTicker(tickerData);
},
previous: function(event) {
// show whole of previous item
tickerData = tickerElement.data(name);
// stop (which sets as non-animating), and call runticker
$(tickerData.newsList).trigger("stop");
// set the character position as 0 to ensure on resume we start at the right point
tickerData.currentPosition = 0;
tickerData.currentItem --;
runTicker(tickerData);
}
});
if (settings.stopOnHover) {
tickerElement.bind({
mouseover: function(event) {
tickerData = tickerElement.data(name);
if (tickerData.animating) { // stop if not already stopped
$(tickerData.newsList).trigger("stop");
if (tickerData.controls) { // ensure that the ticker can be resumed if controls are enabled
$('.stop').hide();
$('.resume').show();
}
}
}
});
}
tickerData = tickerElement.data(name);
// set up control buttons if the option is on
if (tickerData.controls || tickerData.ownControls) {
if (!tickerData.ownControls) {
$('<ul class="ticker-controls"><li class="play">Play</li><li class="resume">Resume</li><li class="stop">Stop</li><li class="previous">Previous</li><li class="next">Next</li></ul>').insertAfter($(tickerData.newsList));
}
$('.play').hide();
$('.resume').hide();
$('.play').click(function(event){
$(tickerData.newsList).trigger("play");
$('.play').hide();
$('.resume').hide();
$('.stop').show();
event.preventDefault();
});
$('.resume').click(function(event){
$(tickerData.newsList).trigger("resume");
$('.play').hide();
$('.resume').hide();
$('.stop').show();
event.preventDefault();
});
$('.stop').click(function(event){
$(tickerData.newsList).trigger("stop");
$('.stop').hide();
$('.resume').show();
event.preventDefault();
});
$('.previous').click(function(event){
$(tickerData.newsList).trigger("previous");
$('.stop').hide();
$('.resume').show();
event.preventDefault();
});
$('.next').click(function(event){
$(tickerData.newsList).trigger("next");
$('.stop').hide();
$('.resume').show();
event.preventDefault();
});
};
// tell it to play
$(tickerData.newsList).trigger("play");
};
// News ticker defaults
jQuery.fn[name].defaults = {
newsList: "#news",
tickerRate: 80,
startDelay: 100,
loopDelay: 3000,
placeHolder1: " |",
placeHolder2: "_",
controls: true,
ownControls: false,
stopOnHover: true
}
})(jQuery);
Any solutions? I am not a programmer so if someone could point out where to patch it greatly appreciated!
UPDATE: it seems only the links with ? mark becomes disabled.
Example: http://url.com/blog/index.html?page=2
I just happened to come across this post. I do still support the ticker, and there have been a few releases since last July.
The way to mitigate this issue was that there's now a "stop on hover" option, which pauses the ticker and completes (immediately) the display of an item when the user hovers over it (including of course being about to click it).
If this is still of relevance to you, if you still have issues with the latest version it'd be worth reading through the thread of comments; please do get in touch if you've still a problem (if one of the comments was yours and I missed it, then sorry!). The "official" way is to post a bug report on the jQuery plugins site, which fully tracks any reported issues, but I do try to respond to anyone who requests support via the blog.
If there are any elements with the ID of news in your document, there might be a collision happening... Might this be the case? I'd search your html document for any occurrences of id="news" and correct them, seeing as though passing the proper parameters into the plugin might require a bit of extra research.

Categories

Resources