Java script drop down menu access Watir-web driver - watir

I am having problems trying to access some a link in a drop down menu In a web site. When you put your cursor over the button, as shown in the first picture, the menu drops down. Below that is a picture of the webpage script. What i want to do is click the search specifications button inn the drop down menu.
the like of code would go something like this :
e.frame(:name => "content").frame(:name => "main").a(:index => 0).click.a(:index => 10).click
However, that is not a valid peace of code, i just don't know the right way of doing it.
< e.frame(:name => "content").frame(:name => "main")
=> #<Watir::Frame:0x7f74b4d4 located=false selector={:name=>"main"}>
irb(main):064:0> my_frame.a(:text => 'Operations').click
Watir::Exception::UnknownObjectException: unable to locate element, using {:text
=>"Operations", :tag_name=>"a"}
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-webdriver-0.6.1/lib/watir
-webdriver/elements/element.rb:365:in `assert_exists'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-webdriver-0.6.1/lib/watir
-webdriver/elements/element.rb:95:in `click'
from (irb):64
from C:/Ruby193/bin/irb:12:in `<main>'
irb(main):065:0>

The dropdown menu does not appear to be in the HTML part that you posted. It is likely further down in the HTML.
Instead of trying to locate by index, which can easily change, you could locate by text. Try:
my_frame = e.frame(:name => "content").frame(:name => "main")
my_frame.a(:text => 'Operations').click
my_frame.a(:text => 'Search Specifications').click
This assumes that the 'Search Specifications' link is also in the same frame as the 'Operations' link.

Try this:
myframe.a(:text, 'Operations').fire_event 'mouseover'
myframe.a(:text, 'Search Specifications').click
Not sure if this is perfect, but the idea is that you make the link in the drop down menu present after you select the drop down. Play around with other elements. The fire_event method is the best way I know to make the drop down menu present.

Related

Tabulator. How to enable and disable editing from js

I'm using tabulator (fantastic thing), which has a built in, in line editing functionality.
The thing is though, it's either on or off by having the editor tag on a column basis.
You can disable the editor for a given cell as well.
What I'm trying to do is to have the table displayed as read only so to say.
Then click on a 'edit' button (which is in my table and I capture the click). That would in turn enable the inline, built-in editor functionality for that raw only.
Then I click a save button, write the updated data back to my DB and make the row read-only again.
So, with tabulator 4.2, I'd be looking for something like
var usrtable = new Tabulator("#usrtable", {
ajaxURL:"/account/cgi-bin/getallusers.php",
resizableColumns:false,
tooltips:true,
history:true,
pagination:"local",
paginationSize:10,
paginationSizeSelector:true,
reactiveData:true,
selectable:true,
initialSort:[{column:"username", dir:"asc"},],
columns:[
{ formatter: editIcon, width: 40, sortable: false, align: "center", cellClick: function (e, cell) {
var id = cell.getRow().getData().id;
row(id).editable=true;
/\/\/\/\/\/\/\/\/\/\/\
}
},
{title:"Id", field:"id", visible:false},
{title:"Username", field:"username", width:80, editor:"input"},
{title:"Password", field:"password", width:70, editor:"input"},
{title:"Role", field:"role", width:70, align:"center", formatter:"plaintext", editor:"select", editorParams:{values:["user","admin"]}},
{title:"Change passwd", field:"changepasswd", width:90, align:"center", formatter:"tickCross", sorter:"boolean", editor:true},
],
});
Is that somehow possible or do I have to re-invent the wheel? i.e. create a model to edit the data outside the table?
What I have tried.....
Once rendered, a cell looks like this:
<div class="tabulator-cell" role="gridcell" tabulator-field="username" tabindex="0" title="test" style="width: 80px; height: 29px;">test</div>
And when you click on the cell, it becomes editable and the class 'tabulator-editing' is added to the div.
So..... I though I could 'just' catch the click event and do something like this:
$(".tabulator-cell").on("click",function(){
($this).removeClass("tabulator-editing");
});
that didn't work so tried this:
$(".tabulator-cell").on("click",function(e){
e.preventDefault();
});
that didn't work either.
When doing this:
$(".tabulator-cell").on("click",function(){
alert("cell clicked");
});
it actually never fires... :-(
Either I'm doing something wrong or really do not know where to go from here....
This can be achieved with Tabulator's Optional Editing:
// column definition
{ title:"Name", field:"name", editor:"input", editable:editCheck }
var editCheck = function (cell) {
var isEditable = cell.getRow().getElement().classList.contains('isEditable');
return isEditable;
}
With this logic in place, you simply need to toggle isEditable class on the appropriate Tabulator Row.
In the documentation under Column Setup, there is a Data Manipulation option called editable.
http://tabulator.info/docs/4.2/columns#definition
editable - callback to check if the cell is editable (see Manipulating Data for more details)
I haven't experimented with it myself, but it appears as if this is only called when initially rendering the table, so you may have to force a re-render with table.redraw(true) when the user clicks the Edit and Save buttons.
You could also just use your cellClick event and call cell.edit().
So, I also got feedback from Oli who is the developer for Tabulator.
The short answer is that there is no option to enable editing at the row lever as I feared.
Furthermore, the option will not be added due to multiple factors.
In other words, what I'm trying to do is not available out of the box and the editing is to be done at the cell level.
There is no option for this in the tabulator. But if you want to disable a cell from editing, you can simply remove all the tabulator applied classes for the particular cell. For eg., if you want to make the last row edit disabled, you can use something like this,
$(".tabulator-row:last .tabulator-cell").removeAttr("role tabulator-field tabindex title");
I know this is a old question but my answer can be useful for visitors come here (like me) in future..
We have also a similar requirements, and we ended up by this solution. We have added "editor" in every column with another attribute "editable". In "editable", we are checking whether the row is selected or not, if row is selected then field can be editable otherwise not editable.
Other than that we have also used a "rowSelected" and "rowDeselected" to show/hide save button and on "rowSelected", we are checking that only 1 row is selected at a time.

Chrome Bookmarklet which open in new tab with specific action

I want to make a Chrome Bookmarklet which open a new tab with specific action.
To be more exact I want to have a fixed URL like "https://www.blablabla.com/search=" inside the bookmarklet and when I press it, I want a popup window to appear with an input field.
When I type something in the input field and press enter or OK/submit it should "run" the whole link plus my query.
For example, I press the bookmarklet, the input field appears and input the word "test" (without the quotes).
When I press submit the query, a new tab will open with the address of https://www.blablabla.com/search=test as the URL.
How do I do that?
I tried with prompt function but I can't get it work...
My question is a bit similar to How do I get JavaScript code in a bookmarklet to execute after I open a new webpage in a new tab?.
Although it remains unclear what exact issue you encounter, try the following bookmarklet:
javascript:(function() {
var targetUrl = "http://www.blablabla.com/search=";
new Promise (
(setQuery) => {var input = window.prompt("ENTER YOUR QUERY:"); if (input) setQuery(input);}
)
.then (
(query) => window.open(targetUrl + query)
);
})();
If it doesn't work, you should provide the problem description in more detail.
#Shugar's answer is mostly correct, but you don't need the promise.
javascript:(function() {
var targetUrl = "http://www.blablabla.com/search=";
var input = window.prompt("ENTER YOUR QUERY:");
if (input)
window.open(targetUrl + input)
})();
javascript:void(window.open('http://www.URL.com/'+prompt ('Enter your Query:')));
I hope this helps. Works for me and is much simpler code than I see above. (as long as we reach the end result, that is all that matters right?)

Telerik MVC Grid Filter

I was using Telerik MVC Grid in my project. I just wanted to change the dropdown value orders a bit. I googled for the requirement and found the filter dropdown options are handled by **telerik.grid.min.js file. But, I dont know how can i change the order from
Options by Default
Is Equal to
Is not equal to
Starts with
Contains
Does not contain
Ends with
Change to the below format
Contains
Does not contain
Starts with
Ends with
Is Equal to
Is not equal to
Can anybody tell me the possibilities that i can change the order of filter dropdown box ..
Thanks,
You can do it by JQuery simply by some codes like this :
$('#GRIDID').find(".t-filter").click(function () {
setTimeout(function () {
$(".t-filter-operator").html('<option value="substringof">Contains</option><option value="notsubstringof">Does not contain</option>');
});
});
NOTE : the above code is a sample, you should do a process to check what operators you have and then repopulate the items in desired order. You can find all allowed "option" tags by inspecting the rendered grid.
The easy way (if you're using MVC razor syntax)
#Html.Kendo().Grid<Model>().Columns(columns =>
{
columns.Bound(x => x.variableName);
})
.Filterable(filterable => filterable
.Extra(false)
.Operators(operators => operators
.ForString(str => str.Clear()
.Contains("Contains").DoesNotContain("DoesNotContain").WhateverYouNeed)
.ForEnums( dat => dat.Clear()
.IsEqualTo("Is Equal To"))
))
Here, the Clear() empties the options in the filter and then you can add the ones you want or even create your own custom ones there, simply place them there in the order that you want.
Have fun!

ActiveAdmin - Filter with default value

Would like to know is that possible to have filter with default value with active admin? This will be helpful for preloading the data for the admin user.
filter :country, :default=>'US'
You can do it by defining before_filter
before_filter :only => [:index] do
if params['commit'].blank?
#country_contains or country_eq .. or depending of your filter type
params['q'] = {:country_eq => 'US'}
end
end
UPD:
in some cases you need to set filter if params[:q] is empty or params[:scope] empty
so this might work better
before_filter :only => [:index] do
if params['commit'].blank? && params['q'].blank? && params[:scope].blank?
#country_contains or country_eq .. or depending of your filter type
params['q'] = {:country_eq => 'US'}
end
end
Adapted Fivells answer to work correctly with scopes and downloads. Feels hacky but seems to do the job. Annotated intention in comments.
before_filter only: :index do
# when arriving through top navigation
if params.keys == ["controller", "action"]
extra_params = {"q" => {"country_eq" => "US"}}
# make sure data is filtered and filters show correctly
params.merge! extra_params
# make sure downloads and scopes use the default filter
request.query_parameters.merge! extra_params
end
end
Fixing issue with "Clear Filters" button breaking, updated answer building on previous answers:
Rails now uses before_action instead of before_filter. It belongs in the controller like so:
ActiveAdmin.register User do
controller do
before_action :set_filter, only: [:index]
def set_filter
# when arriving through top navigation
if params.keys == ["controller", "action"]
extra_params = {"q" => {"country_eq" => "US"}}
# make sure data is filtered and filters show correctly
params.merge! extra_params
# make sure downloads and scopes use the default filter
request.query_parameters.merge! extra_params
end
end
params.delete("clear_filters") #removes "clear_filters" if it exists to clear it out when not needed
end
end
Note, ActiveAdmin uses ransack for queries (ex. {"q" => {"country_eq" => "US"}}), check out https://activerecord-hackery.github.io/ransack/getting-started/search-matches for more matches if you need something more complex than "_eq".
Also, previous answers leave the "Clear Filters" button broken. It doesn't clear the filters, the filters set here are simply re-applied.
To fix the "Clear Filters" button, I used this post as a guide How to keep parameters after clicking clear filters in ActiveAdmin.
#app/assets/javascripts/active_admin.js
# Making clear filter button work even on pages with default filters
$ ->
$('.clear_filters_btn').click ->
if !location.search.includes("clear_filters=true")
location.search = "clear_filters=true"
This removes all search params (ie filters) and adds "clear_filters=true" so the controller can tell the request came from the "Clear Filters" button.
before_action only: [:index] do
if params['commit'].blank?
extra_params = {"country_eq" => "US"}
params['q'] = {} if params['q'].blank?
params['q'].merge! extra_params
request.query_parameters.merge! extra_params
end
end

magento exclude bundled items from search results

Currently, when one searches for an item, the quick search also brings up any bundles that contain items that fit the search criteria. How would I stop this?
A solution that filters out all bundled items from search results all together would be fine too.
UPDATE
I don't want the items to show in either the catalogue or search, but am using them as upsell items. This seems to leave two options:
I could amend the search results controller to omit bundled items (the method I was asking about), or
I could change the Upsell.php script to include "Don't show individually" items.
The second is perhaps easier? Currently the filter applied is:
Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($this->_itemCollection);
How would I change this so it shows don't show individually items?
Apologies for the incomplete initial question.
Second Update:
Ok, I've added
->setVisibility(null)
and it already has
->addStoreFilter()
But there is no change.
Essentially, if I don't have either of:
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($this->_itemCollection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($this->_itemCollection);
Then I get the following error:
SELECT 1 AS status, e.entity_id, e.type_id, e.attribute_set_id, price_index.price, price_index.tax_class_id, price_index.final_price, IF(price_index.tier_price IS NOT NULL, LEAST(price_index.min_price, price_index.tier_price), price_index.min_price) AS minimal_price, price_index.min_price, price_index.max_price, price_index.tier_price, e.name, e.short_description, e.sku, e.price, e.special_price, e.special_from_date, e.special_to_date, e.manufacturer, e.manufacturer_value, e.small_image, e.thumbnail, e.news_from_date, e.news_to_date, e.tax_class_id, e.url_key, e.required_options, e.image_label, e.small_image_label, e.thumbnail_label, e.price_type, e.weight_type, e.price_view, e.shipment_type, e.links_purchased_separately, e.links_exist, e.is_imported, e.rc_manufacturer, e.rc_manufacturer_value, e.rc_vehicle, e.rc_vehicle_value, e.rc_assembly_type, e.rc_assembly_type_value, e.surface_type, e.surface_type_value, e.rc_drive, e.rc_drive_value, e.rc_scale, e.rc_scale_value, e.rc_motor_type, e.rc_motor_type_value, e.rc_engine_start_type, e.rc_engine_start_type_value, e.rc_engine_size, e.rc_engine_size_value, e.rc_form_factor, e.rc_form_factor_value, e.rc_frequency, e.rc_frequency_value, e.rc_gear_material, e.rc_gear_material_value, e.rc_operation, e.rc_operation_value, e.rc_torque_6v, e.rc_torque_6v_value, e.rc_speed_6v, e.rc_speed_6v_value, e.rc_bearing_type, e.rc_bearing_type_value, e.rc_waterproofing, e.rc_waterproofing_value, e.rc_battery_application, e.rc_battery_application_value, e.rc_input_supply, e.rc_input_supply_value, e.rc_power_output_amps, e.rc_power_output_amps_value, e.rc_power_output_watts, e.rc_power_output_watts_value, e.rc_lead_connector_type, e.rc_lead_connector_type_value, e.rc_gear_pitch, e.rc_gear_pitch_value, e.rc_nitro_content, e.rc_nitro_content_value, e.rc_exhaust_type, e.rc_exhaust_type_value, e.rc_engine_starter_type, e.rc_engine_starter_type_value, e.rc_head_fitting, e.rc_head_fitting_value, e.rc_temperature_rating, e.rc_temperature_rating_value, e.rc_oil_type, e.rc_oil_type_value, e.rc_container_size, e.rc_container_size_value, e.rc_class, e.rc_class_value, e.rc_paint_application, e.rc_paint_application_value, e.rc_size, e.rc_size_value, e.rc_colour, e.rc_colour_value, e.rc_pack_contents, e.rc_pack_contents_value, e.rc_spare_part_type, e.rc_spare_part_type_value, e.rc_oil_weight, e.rc_oil_weight_value, e.rc_glue_type, e.rc_glue_type_value, e.rc_usage, e.rc_usage_value, e.rc_tool_type, e.rc_tool_type_value, e.rc_engine_spare_type, e.rc_engine_spare_type_value, e.rc_tune_up_type, e.rc_tune_up_type_value, e.rc_bearing_pack_type, e.rc_bearing_pack_type_value, e.rc_driver_type, e.rc_driver_type_value, e.rc_nut_type, e.rc_nut_type_value, e.rc_plane_type, e.rc_plane_type_value, e.rc_boat_type, e.rc_boat_type_value, e.pre_order, e.pre_order_value, e.msrp_enabled, e.msrp_display_actual_price_type, e.msrp, links.link_id, link_attribute_position_int.value AS position FROM catalog_product_flat_1 AS e
INNER JOIN catalog_product_index_price AS price_index ON price_index.entity_id = e.entity_id AND price_index.website_id = '1' AND price_index.customer_group_id = 0
INNER JOIN catalog_product_link AS links ON links.linked_product_id = e.entity_id AND links.link_type_id = 4
LEFT JOIN catalog_product_link_attribute_int AS link_attribute_position_int ON link_attribute_position_int.link_id = links
I've also tried the following, but get the error:
Mage::getSingleton('catalog/product_status')->addSaleableFilterToCollection($this->_itemCollection);
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($this->_itemCollection);
Thanks for the help.
Based on your updated question:
If you are not using Enterprise Edition TargetRule or some other module which automates upsells (i.e. the upsells are defined explicitly by the admin), then likely the simplest approach is that which you've specified - rewrite the Upsell block to not add the visibility filter. As a guess, to be optimal you may want to call setVisibility(null) and addStoreFilter() on the collection to trigger normal limiting behavior.
EDIT: Original answer below
Admin > Catalog > Manage Products grid
Choose "Bundle Product" from the filters area at the top, click "Search"
Click "Select All"
Select "Update Attributes" from the mass action block's "Action" dropdown, click "Submit"
Change the "Visibility" attribute to "Catalog"
I solved it by modifying the custom module so that I didn't need to worry about this. It may be of some use as it involved using:
$collection->addAttributeToFilter('type_id', array('neq' => 'bundle'));
Which just excludes all bundle items from a collection.

Resources