How to trigger an onchange event in Firefox::Mechanize? - html

I'm using Firefox::Mechanize to scrape a website. I'm stuck on a dropdown menu which has an onchange event associated with it.
I'm able to select the option I wanted from the pulldown menu, and I'm able to verify this because the pulldown now shows the option I selected. But it doesn't trigger the onchange event associated with it.
I'm thinking I might need a "click" event after selecting my option, but I'm not sure exactly how to incorporate that.
Here is the bit of HTML:
<select class="" id="select20279" name="20279" onchange="selectAction(this, this.options[this.selectedIndex].value, '20279');">
<option value="">please choose</option>
<option value="edit">Edit</option>
<option value="view">View</option>
<option value="delete_now">Delete</option>
</select>
Here is my script:
use WWW::Mechanize::Firefox;
my $mech = WWW::Mechanize::Firefox->new( tab => 'current', autoclose => 0 );
$mech->get('http://www.mywebsite.com/');
$mech->select("20279", "view");
Thanks in advance.

Get the DOM element and then send the change or click event to it:
my $select = $mech->selector('#select20279', only => 1);
$select->__change();
# or
$select->__click();
See also
http://search.cpan.org/~corion/MozRepl-RemoteObject-0.39/lib/MozRepl/RemoteObject.pm

Related

Add an attribute on a condition with angular 2

I have a simple dropdown that is populated from an array.
Users will be editing a record in a form where the priority of the record can be selected from the mentioned dropdown. I'm having difficulty with setting the selected item in that dropdown.
Here's my code for that dropdown:
<select *ngIf="formModel" [(ngModel)]="record.priority" formControlName="priority">
<option value="-1">Select priority</option>
<option *ngFor="let priority of formModel.priorities"
[ngValue]="priority"
[innerHtml]="priority.name"
[selected]="priority.id == record.priority.id"></option>
</select>
The selected priority of the record is however not selected, the resulting HTML shows selected="true".
When I change the code to the following:
[selected]="(priority.id == record.priority.id ? '' : null)"
The result is selected="", but the option is stil NOT selected.
I have already confirmed that that particular option should be selected.
Also when I change the HTML in Firebug to just selected the option is selected.
So my question is: how can I add an attribute on a certain condition so that the attribute is not added to other elements with an empty value?
Using two-way-binding is discouraged in reactive forms. The point is to utilize the form controls instead. Why use reactive form, if you are using two-way-binding? That would mean the model driven form is totally redundant. So if you want to solve this problem using the model-driven form, I'd suggest the following:
Since you are using a separate object (record.priority) it cannot automatically be bound as the pre-selected value, you'd have to somehow create a reference. So when building a form you can do this:
this.myForm = this.fb.group({
priority: [this.formModel.priorities.find(x => x.id == this.record.priority.id)]
});
And the template would look like this:
<form [formGroup]="myForm">
<select *ngIf="formModel" formControlName="priority">
<option value="-1">Select priority</option>
<option *ngFor="let priority of formModel.priorities"
[ngValue]="priority"
[innerHtml]="priority.name"></option>
</select>
</form>
Now the value object you are getting from the form holds this value.
if having the record coming async, you can set a boolean flag to not show the form until the values have been set. Or you can build an empty form initially and then use setValue() for the form control.
DEMO
EDIT: Looking closer, that you want to have the condition to set null if there is no value for record.priority? That can be done well in the form control as well:
priority: [this.record.priority ? this.formModel.priorities.find(x => x.id == this.record.priority.id) : null]
Try this :
<select *ngIf="formModel" [(ngModel)]="record.priority.id" formControlName="priority">
<option value="-1">Select priority</option>
<option *ngFor="let priority of formModel.priorities"
[ngValue]="priority.id"
[innerHtml]="priority.name"></option>
</select>
[ngValue]="priority.id" and [(ngModel)]="record.priority.id" should point to the same value , and it will work automatically ,
There is no need to write [selected]="priority.id == record.priority.id"

how to reset select in angular2

I have tow select lists (select1 and select2) in my form, select2 depends on select2 selection, when select1 selection change options in select2 must be change this work fine but my problem is that on change don't return to default option, it gives me last index of last select2 selection,
i want on change the select2 option change and index of selected option return to 0 or default option
I am using ng-model to deal with select in angular2
this my html code:
<td *ngIf="classificationCheck"><select name="classification_type" [(ngModel)]="message.classification_type"
class="form-control" [disabled]="isReply||isForward">
<option value="" disabled default>تصنيف موضوعي</option>
<option *ngFor= "let subType of classificationTypes">{{subType}}</option>
</select></td>
and this onChange function for select1 witch update select2 options:
classificationChange( event ){
if("غير محدد"==event){
this.classificationCheck=false;
this.message.classification_type=null;
}
else{
for(let classtype of this.classifications){
if(classtype.gen==event){
if(classtype.name)
{
this.classificationTypes=[];
this.classificationCheck=true;
for(let subType of classtype.name){
this.classificationTypes.push(subType);
}
}
}
}
}
}
Put an *ngIf on your select. Set it to true. When you want to reset, set it to false then back to true very quickly.
This was the official approach in RC4 until a proper approach was made available.
If a new approach is now available in the final release of ng2, I don't know.

Html DropDownList not generating events

In my web page I use something like this, but when a option is selected, onchange is not fired. I don't know where I have made a mistake. Actually my requirements is that I need to fetch location details based on the city selected, but it is not working here. Is there any other better way to do so?
#Html.DropDownList("cities", ViewBag.cities as SelectList, new { onselect = "getLoca();"});
<script type="text/javascript">
function getLoca() {
alert("yes");
$.post('#Url.Action("getLocations","Home")', { 'id': $("#cities").val() },
function (data) {
$("#loca").html(data).show();
});
}
</script>
EDIT:
This is the generated HTML code
<select id="cities" name="cities" onselect="getLoca()"><option value="0">--City-- </option>
<option value="1">City1</option>
<option value="2">City2</option>
<option value="3">City3</option>
<option value="4">City4</option>
<option value="5">City5</option>
</select>;
<select id="loca" name="loca" style="width: 170px" ></select>
Use onchange instead of onselect.
jsFiddle Demo
onselect does not do what you expect - it fires when the user selects text (you know, by dragging the mouse or holding shift and using the arrow buttons), so it is not applicable to a select box, which has no selectable text. It works on certain input elements (like text) and textareas, or you can use it on the window.
onchange fires when the value of a form element changes - so this is what you need.
Note: using inline event handlers in your HTML is not a good idea most of the time. If you can, use addEventListener instead.

HTML Select with disabled Option returns wrong selectedIndex in FireFox

I have a Select with a disabled Option wich is the default selected one:
<select name="select" size="1">
<option>0</option>
<option selected disabled>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
</select>
If I get the selected, it returns 1. Everything OK.
But if I open the popup and hover with the cursor over another Option (for Example '4') and Cancel it via ESC or by clicking anywhere else.
The Select input shows the old value 1 but returns on get selected 4.
Example with jsfiddle
It doesn't happen with Chrome only FireFox (4/5)
It appears that the display is not changed when you exit your select this way however firefox is looking for a different selectedValue because it finds the currently selected option as disabled, which in firefox' eyes should be impossible.
The onChange event was not triggered until the onBlur event (which is when the selectedValue would get changed, but this is not what the display is changed to). If we were to reset our value in the onChange event this event might get called again. So by utilising the onBlur event we can provide the following workaround:
onBlur="javascript:document.getElementsByName('select')[0].selectedIndex = document.getElementsByName('select')[0].selectedIndex;"
http://jsfiddle.net/aRMpt/22/
I hope I'm making sense here.
The following code is ugly, but it does exactly what you want (I think). Basically, I am intercepting all onChange events, and only processing them if there is a corresponding onClick event that results in a changed value. ALso note that change events are processed before click events. EDIT: Just relaized this does not work in chrome, so i added some browser detection code so that it only executes in firefox.
NOTE: The current code would not work if the user had tabbed into the select box and made his changes with the error keys, but the method below can be easily adapted to handle that case as well. You'd simply need to process key events like arrow up or arrow down or TAB or ENTER in the same way clicks are processed below, but only when the select box had focus.
NOTE 2: Playing with this more, the behavior is very strange. If you escape out of the select, the onChange event is not triggered, but it is saved up. If at any later time you click anywhere on the screen the onChange event will be triggered for the value you were hovering over when you escaped, even though that value was actually changed as soon as you escaped. So this is getting tricky. I think you may have to handle the 2 cases separately. One case to handle click aways, and one to handle escape outs (which patrick answered).
It's getting hairy and I see no elegant way to code this. How about a note to the user next to the text box saying "Your currently selected option, 1, is no longer available." Then you could have a select box with only the avalable options.
<select name="select" size="1" onChange="handleChange()" onClick="handleClick()" >
<option>0</option>
<option selected disabled>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
</select>
<br />
<script>
var initialValue = document.getElementsByName('select')[0].selectedIndex;
var potentialChange;
var processClick;
function handleClick() {
//ignore this code if not firefox
if (navigator.userAgent.indexOf("Firefox") === -1)
return;
var curVal = document.getElementsByName('select')[0].selectedIndex;
if (!processClick)
return;
// a value change click occured, now we actually process it.
document.getElementsByName('select')[0].value = potentialChange;
}
function handleChange() {
// save the potential change, which will be used if a real click was detected
potentialChange = document.getElementsByName('select')[0].selectedIndex;
processClick = (potentialChange !== initialValue);
// undo the attempted change, in case of an escape or page click
// but only on firefox
if (navigator.userAgent.indexOf("Firefox")!=-1)
document.getElementsByName('select')[0].value = initialValue;
document.getElementsByName('select')[0].value = initialValue;
}
</script>
getSelected
Detect the esc key and reset it, here is an example using jQuery (and a dash of your code)
$('select').keyup(function(e) {
if (e.keyCode == 27) {
document.getElementsByName('select')[0].selectedIndex = 1;
}
});
UPDATE No jQuery Solution
UPDATE 2 Abstracted out finding event and keycode for re-usability.
DEMO: http://wecodesign.com/demos/stackoverflow-6923135.htm
<script type="text/javascript">
function getEvent( event ) {
if ( window.event ) return window.event;
return event;
}
function getKeycode ( event ) {
if ( event.which ) return event.which;
else return event.keyCode;
}
changeToDefaultListener = function( event ) {
theEvent = getEvent( event );
theKeyCode = getKeycode( theEvent );
if( theKeyCode == 27 ) {
document.getElementsByName( 'select' )[0].selectedIndex = 1;
}
};
</script>
<select name="select" size="1">
<option>0</option>
<option selected disabled>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
</select>
getSelected
<script type="text/javascript">
document.getElementsByName('select')[0].onkeyup=changeToDefaultListener;
</script>
The work around I had to use for this is was putting an event listener on the click event of the not selected options in drop down. In the event listener's function I set a global boolean.
var selectChanged = false;
$('#select option:not(:selected)').click(function () {
selectChanged = true;
});
Then in the area of the code where I need the selected value of the drop down, I check the boolean:
if the boolean is true I can then use it's new value
if the boolean is false I can get the value from the Html property (which contains the initial value of the dropdown).
var selectValue = selectChanged ? $('#select').val() : $($('#select').outerHtml()).find('option:selected').val()
This is ugly I know, but this is the only work around I could find.

MooTools - How to use getSelected()

I'm trying to learn MooTools and am a TOTAL javascript noobie so please be gentle with me.
What I'm tying to do is to change the state of a disabled input field (type is text) when a particular option is selected. The html looks a bit like tis:
<select class="wide" id="selectBox" name="option>
<optgroup label="Common">
<option value="one">One<option>
<option value="two">Two<option>
<option value="three">Three<option>
</optgroup>
<optgroup label="Less Common">
<option value="other">Other<option>
</optgroup>
</select>
<input id="other" type="text" disabled="disabled" />
This is what I was HOPING would give me the value to be checked in an if statement that would then change the input disabled to enabled:
window.addEvent('domready', function(){
$$('#selectBox').addEvent('change',function(){
var selection = $$('#selectBox').getSelected();
alert(selection);
});
});
When the code us run (i.e. I select another value in the option box) all I get is [object HTMLOptionElement].
The documentation on mootools for this method is SPARSE and only says:
Element Method: getSelected
Returns the selected options of a
select element.
Returns:
* (array) An array of the selected elements.
Examples:
HTML
<select id="country-select" name="country">
<option value="US">United States</option
<option value ="IT">Italy</option>
</select>
JavaScript
$('country-select').getSelected(); //Returns whatever the user selected.
Note:
This method returns an array, regardless of the multiple attribute of the select element. If the select is single, it will return an array with only one item.
Totally confusing!
Someone please tell me what I'm missing. I've also tried:
var selection = $$('#selectBox').getSelected().value; //and
var selection = $$('#selectBox').getSelected('value'); //and
//a WHOLE bunch of other wild ideas including
var selection = $$('#selectBox').getSelected();
alert(selection[0]);
Nothing comes out properly. In some cases I get undefined and in other cases I get the same [object HTMLOptionElement].
so many things wrong, not sure where to begin.
$$() is a collection operator (alias for document.getElements() which returns multiples based upon a selector) - not appropriate to use for an id.
you want document.id("idhere") or $("idhere")
for mootools 1.2+
document.id('selectBox').addEvent('change',function() {
alert(this.get("value")); // get value
alert(this.getSelected().get("value")); // gets the option that's selected and then it's value
});
make sure you check your markup - you don't close the options, you have a missing " from name="option> as well.
getSelected is there as a method as some selects use multiple selection so doing selectEl.get("value") will not report anything meaningful. any other case, .get("value") is fine.
check it working:
http://www.jsfiddle.net/dimitar/SmShF/
have fun and read the manual :)
late reply but I was facing the same issue and solved it in this (simple) way in Mootools:
$('selectBox').getSelected().get('text')
So Complex!
You don't need to do such a complex thing, this would suffice:
var selection = document.getElementById("selectBox").value;
alert(selection);
That should get you the selected text.
But if you wanted to use mootools, I guess that this would work (I'm not going to try it)
var selection = $('selectBox').getSelected();
alert(selection[0].value);
Also this has some problems:
<select class="wide" id="selectBox" name="option>
You don't need the name attribute, as it is basically the same as id. Also if you do have both, then they should probably be the same. I.e. id="selectBox" and name="selectBox
Your name tag should be closed.
Also in your sample, you had a lot of <option>...<option> which should be <option>...</option>
All you need to do is:
$('country-select').getSelected().get('value')[0];
Quick, hackish way:
alert($('selectBox').value)
Verbose, recommended way:
var selectBox = document.id('selectBox');
alert(selectBox.get('value'));
.getSelected() returns an array. See the docs: http://mootools.net/docs/core/Element/Element#Element:getSelected .
My Code is :
var $obj=$$('#id').getSelected()[0];
alert( $obj.get('text') );
alert( $obj.get('value') );