I'm having a problem changing a view in my feed reader. When a button in the feed list is clicked, the feed window is supposed to update. Instead, the feed window stays empty. How do you remove and replace a widget in gtk3-ruby?
The problem method:
def feed=(feed)
#feed.destroy()
#title, #count = feed.channel.title, feed.items.size
#label.set_markup "<b>#{#title} (#{#count} articles)</b>"
#feed = FeedItems.new(feed.items, #parent)
self.pack_end(#feed)
#feed.show()
end
The full source is on pastebin:
http://pastebin.com/KPKAfCmx
I should have used show_all and the widget updates.
def feed=(feed)
self.remove(#feed)
#title, #count = feed.channel.title, feed.items.size
#label.set_markup "<b>#{#title} (#{#count} articles)</b>"
#feed = FeedItems.new(feed.items, #parent)
self.pack_end(#feed)
self.show_all
end
Related
Using Shoes 3.3.7
How do I go about grabbing the text typed in an Edit_box and saving it to a file on a button click?
This is what i used. It created the file but it just stays empty...
Shoes.app do
Stack do
flow do
new_box = edit_box "placeholdertext"
end
flow do
button "Save" do
note_save = ask_save_file
File.open("#{note_save}", "a") do |copy|
copy.para "#{new_box.text}"
end
end
end
end
end
Edit : setting code to,
copy.write(new_box.text)
Still creates a file with empty content
I'm pretty new to all this. Any help is appreciated 😊
you have to use instance variables in such cases:
Shoes.app do
stack do
flow do
#new_box = edit_box "placeholdertext"
end
flow do
button "Save" do
note_save = ask_save_file
File.open("#{note_save}", "w") do |file|
file.write #new_box.text
end
end
end
end
end
Best, seba
I am testing a web app with multiple dynamic rows. With nothing to scope and grab in the vicinity. I get to the particular field by grabbing something I can id, and tabbing to the text box or selector I wish to manipulate.
It looks like this...
editor = page.find_by_id('grabbable')
editor.native.send_keys(:tab, :tab, "Hello World")
What I'd like to do is something like...
tab_amount = tabs(2)
editor = page.find_by_id('grabbable')
editor.native.send_keys(tab_amount, "Hello World")
...
def tabs(amount)
tab_object = :tab
while amount > 1
tab_object = tab_object + :tab
amount = amount - 1
end
return tab_amount
end
Is such a dynamic tab possible?
what about something like
def tabs(amount)
tab_object = Array.new(amount, :tab)
end
editor.native.send_keys(*tabs(3), "Hello World")
some info on splat here
http://www.ruby-doc.org/core-2.0/doc/syntax/calling_methods_rdoc.html#label-Array+to+Arguments+Conversion
Here is what I ended up doing...
def autotab(amount)
tab = Array.new
amount.times do
tab << :tab
end
return tab
end
I have a following situation.
In the model I am populating a table, which has a tree-like structure. I have a Graph model that has_many :nodes and Node model that has a "content" column that is populated during by the following:
class Graph < ActiveRecord::Base
def start_collecting
self.content_collection(self.nodes.first)
end
def content_collection(root)
root.children.all(:order => "idx DESC").each do |node|
#Here the function in Node model is called, that populates 'content' column in node's table.
content_array << node.content.to_s
self.children_content = content.array
self.save!
child.collect_content
if !node.children.blank?
self.content_collection(node)
end
end
end
The question is.. I want to have the progress being displayed on the web page (app/views/graphs/show.html.erb). So far I am doing this:
setInterval(function(){
var text = <%= array_or_string_for_javascript(#graph.children_content)%> ;
var pjs = Processing.getInstanceById("graphsketch");
pjs.update(text);
}, 3000);
So that I am just redrawing the content of #graph.children_content on screen every 3 seconds.. I wonder what would be the best way to draw the contents of each #node.content with this timed refresh? Obviously if I just write an .each loop in show.html.erb I will keep getting the content of the last #node in the loop... Basically I wonder how to translate the loop from the above model onto the view and make the progress visible?
Hope this is clear enough, please let me know if I should explain better...
EDIT ::
So following the advice, now I have in graph_controller.rb:
def getstatus
#graph = Graph.find(params[:id])
#graph_so_far = #graph.get_graph
respond_to do |format|
format_js
end
end
in Graph.rb:
def get_graph(root = self.nodes[0], word_ary = [])
#root = root
#root.children.all(:order => "idx DESC").each do |child|
n_node = (child.depth*2).to_s+child.content
word_ary << n_node
child.parent_relation.collect_videos_multiple_cats
if !child.children.blank?
self.get_graph(child, word_ary)
end
end
return word_ary
end
In graphs/show.html.erb :
<script>
$(document).ready(function () {
setInterval(function(){
var idx = "<%= #graph.id %>";
$.get("getstatus/", {idx} )
},1000);
});
</script>
<%= javascript_include_tag "pjs" %>
<canvas id="graphsketch" data-processing-sources="/assets/pjs/graphBuilder2_2.pde"></canvas>
In graphs/getstatus.js.erb
var text = <%= array_or_string_for_javascript(#sentence_so_far)%> ;
var pjs = Processing.getInstanceById("graphsketch");
alert(text);
pjs.update(text);
The alert in getstatus.js.erb never fires.
In routes (of course):
resource :graphs do
collection do
get 'getstatus'
end
end
What am I doing wrong? Thanks a lot for the help again..
Let me make sure I understand, you want to show the graph in it's entirety as it's growing, refreshing every 3 second, correct?
First thing I'd do is create an AJAX action in the GraphController that get's the full content of the graph so far
def getstatus
#graph_so_far = Graph.???
respond_to do |format|
format_js
end
end
Of course you'll have to add a new route
Then in getstatus.js.erb (in the same directory as show.html.erb)
var text = <%= array_or_string_for_javascript(#graph_so_far)%> ;
var pjs = Processing.getInstanceById("graphsketch");
pjs.update(text);
That get's you your first update, now all you have to do set a timer, and kick off the same AJAX call after 3 seconds, I use jquery.timers.js, but whatever, after 3 seconds send another AJAX request to the URL /graph/getstatus, (or whatever you called your route), starting the cycle over again.
I'm trying to use the DOM inspector to find the ID of the "More" button at the bottom of this page that reveals more results.
I'm trying to do something like this example:
require 'watir-webdriver'
b = Watir::Browser.new
b.goto 'svpply.com/editors_pick'
#count products
puts b.elements(:xpath => '//li[#data-class="Product"]').count
#=> 30
#Now click button
show_all = b.button(:id => "btn_all")
show_all.click
sleep 4
#count products again
puts b.elements(:xpath => '//li[#data-class="Product"]').count
#=>60
However, I'm unclear on how to search for that particular id within the DOM structure. Can someone also explain the difference between an attribute, element, id, and node?
To use the DOM Inspector for the More button:
Open the DOM Inspector (Ctrl+Shift+I)
Click the [More] button that you want to inspect
On the right side of the DOM Inspector bar, click the [HTML] button
This should show the HTML for the page, which will include the details of the [More] control. You'll notice that the element is actually a DIV not a button. As well that the ID is in the form "_more".
--> This should show the HTML for the page, which will show the details of the [More] control. You'll notice that the element is actually a DIV not a button. As well that the ID is in the form "_more".
So to do your example with the Quora page, you would do something like:
require 'watir-webdriver'
class QuoraPage
def initialize(browser)
#browser = browser
end
def goto()
#browser.goto 'http://www.quora.com/Startups/best_questions'
wait_questions_loaded
end
def click_more()
#browser.div(:id, /_more/).click
wait_questions_loaded
end
def questions_count()
#browser.links(:class, 'question_link').count{ |x| x.visible? }
end
def wait_questions_loaded()
begin
questions_start_count = questions_count()
sleep(2)
end while questions_start_count != questions_count()
end
end
page = QuoraPage.new(Watir::Browser.new :chrome)
page.goto
puts page.questions_count
page.click_more
puts page.questions_count
Note that I had to put the sleeps in otherwise webdriver hangs like anonygoose mentioned. I tried different wait_untils, but did not manage to find something that worked (other than sleep which is not very robust).
Regarding your question about nodes, elements, etc. I think you are best to look at http://www.w3schools.com/dom/default.asp.
To press the button on svpply you can use simply
b.button(:text => "Show All").click
Counting all the products that appear on the page could potentially be done with
b.lis(:class => "grab large").count
This is all for the svpply site. I can't get quora to automate at all, it just stalls my watir-webdriver indefinitely.
You'll also want to wait before you have watir count the products. This can be done with:
b.wait_until{b.lis(:class => "grab large").count > 30}
Say I have the following sort of app:
Shoes.app do
#i = 0
def add_button
button ("#{#i += 1}")
end
button("0") {add_button}
end
So that each time you click the button it adds a new button with a higher number. Is there any way to code it so that clicking one of the new buttons displays its number? Since self always points to the app, the obvious approach
button ("#{#i += 1}") {alert #i}
Doesn't work, since then clicking any button just displays the current value of #i.
Shoes.app do
#i = 0
def add_button
n = #i+1
button ("#{#i += 1}") {alert n}
end
button("0") {add_button}
end