I'm new to Perl and trying to check to see if a series of checkboxs on an HTML page are checked or not. Each checkbox has a different numeric value I want to add to an array in Perl. I keep getting an undef value. I've combed the web for a reason this is not working and finally broken down to ask for help. For now I just want to display the values retrieved in my log. I'm expecting to see (1, 2) in my results when the checkbox is checked. Can anyone see anything wrong with the code below or offer a suggestion as to why I'm getting an "undefined" array? Is there a way to test for connection to the checkbox in question from Perl?
HTML:
<input type="checkbox" name="Shipping" id="checkFXG" value="1" enabled />
<input type="checkbox" name="Shipping" id="checkFX2" value="2" enabled />
PERL:
use CGI;
...
sub updateShipping;
my $p;
my $self = shift;
my $cgi;
my $sIDquery = CGI->new;
my $param = $sIDquery->Vars;
my #sID = $param->{'Shipping'}; # Grab VALUE from checkbox
my $sID;
foreach $sID(#sID) { # Loop through array displaying each Shipping ID
warn "**** sID : [$sID]";
}
}
To get multiple parameters with the same name, don't use the Vars method, do:
my #values = $sIDquery->param('Shipping');
There are very few cases where you'd ever want to use Vars. It is especially unlikely to do what you want for parameters that may not be present (such as checkboxes) or may have more than one value.
Related
Is there a way to remove a number from an attibute array in an update? For example, if I want to update all of an alchy's booze stashes if he runs out of a particular type of booze:
Alchy has_many :stashes
Stash.available_booze_types = [] (filled with booze.ids)
Booze is also a class
#booze.id = 7
if #booze.is_all_gone
#alchy.stashes.update(available_booze_types: "remove #booze.id")
end
update: #booze.id may or may not be present in the available_booze_types array
... so if #booze.id was in any of the Alchy.stash instances (in the available_booze_types attribute array), it would be removed.
I think you can do what you want in the following way:
if #booze.is_all_gone
#alchy.stashes.each do |stash|
stash.available_booze_types.delete(#booze.id)
end
end
However, it looks to me like there are better ways to do what you are trying to do. Rails gives you something like that array by using relations. Also, the data in the array will be lost if you reset the app (if as I understand available_booze_types is an attribute which is not stored in a database). If your application is correctly set up (an stash has many boozes), an scope like the following in Stash class seems to me like the correct approach:
scope :available_boozes, -> { joins(:boozes).where("number > ?", 0) }
You can use it in the following way:
#alchy.stashes.available_boozes
which would only return the ones that are available.
I've been trying to build a form to create and delete Revit print Sets.
I've 2 main issues:
1) I'm able to create a print set but I cannot access its content unless I restart the Form. I get the errors below (depending if I'm defining the view_set variable or not)
List_object_has_no_attribute_Views
Local_variable_referenced_before_assignment
This is the code of the function to display the sheets of the selected Print Set
def DisplaySheetsInSet (self, sender, args):
self.curItem = CurrentSetsListBox.SelectedItem
PrintSetForm_Load
try:
view_set=[]
for i in PrintSetForm.ViewSets:
if i.Name == str(self.curItem):
view_set = i
else:
continue
Sheets=[sheet.Name for sheet in view_set.Views]
SheetsLb.BeginUpdate()
SheetsLb.Items.Clear()
for sheet in Sheets:
SheetsLb.Items.Add(sheet)
SheetsLb.EndUpdate()
except Exception as e:
popup (str(e)
2) I'm able to delete print sets once. If I try do delete another one I get the following error and I need to restart the form ( code for the function that deletes the print sets shown below)
The_referenced_object_is_not_valid
def DelPrintSet(self, sender, args):
self.curItem = CurrentSetsListBox.SelectedItems
t = Transaction (doc, 'Delete printset')
t.Start()
for viewset in PrintSetForm.ViewSets:
if viewset.Name in [str(item) for item in self.curItem]:
doc.Delete(viewset.Id)
doc.Regenerate()
else:
continue
self.Refresh()
UpdateSetNames(CurrentSetsListBox)
t.Commit()
I've tried to build a function to restart/refresh the Form but it doesn't work (code below):
global PrintSetForm_Load
def PrintSetForm_Load(self, sender):
Application.Exit()
Application.Restart()
#self.Refresh()
#self.ResetBindings()
#self.ActiveForm.Close()
sd = PrintSetForm()
sd.ShowDialog()
This gif shows the form in action:
Manage Print Sets
Any ideas or suggestions?
Thank you.
3) If I try to populate the SheetsLb with a DataSource, just the first set clicked is shown.
Sheets=[sheet.Name for sheet in view_set.Views]
SheetNumber=[sheet.get_Parameter(BuiltInParameter.SHEET_NUMBER).AsString() for sheet in view_set.Views]
SheetsLb.BeginUpdate()
SheetsLb.DataSource = None
SheetsLb.Items.Clear()
UpdatedList=[]
for number,name in zip(SheetNumber,Sheets):
UpdatedList.append(number+" - "+ name + " [ ] ")
SheetsLb.DataSource=UpdatedList
SheetsLb.EndUpdate()
1) See if this works:
It would be worth checking that there is something selected in self.viewSetsLb. Ive added a check to the code below
The view_set variable could be initialised as a boolean instead of a list
Using break in the for loop keeps things a little snappier
Ive used the more pythonic for view in PrintSetForm.viewSets rather than for i in PrintSetForm.viewSets - keeping it nice and clear
This code works for me:
self.curItem = self.viewSetsLb.SelectedItem
if not self.viewSetsLb.SelectedItem:
print 'No Printset selected!'
return
view_set = False
for view in PrintSetForm.viewSets:
if view.Name == str(self.curItem):
view_set = view
break
else:
continue
Sheets=[sheet.Name for sheet in view_set.Views]
self.sheetsLb.BeginUpdate()
self.sheetsLb.Items.Clear()
for sheet in Sheets:
self.sheetsLb.Items.Add(sheet)
self.sheetsLb.EndUpdate()
2) Its because the data in your PrintSetForm.ViewSets list is out of date. Every time you change something (ie delete a viewset), repopulate this list:
PrintSetForm.ViewSets = FilteredElementCollector(doc).OfClass(ViewSheetSet).ToElements()
Also, you shouldnt need to build a refresh button, perhaps have a class function that repopulates the Printset list and ListBox, and clears the Sheet ListBox that you call after every action?
Sounds like youre having fun mate!
It sounds as if you have an issue with the scoping and lifetime of variables. For instance, some variables may have a lifetime limited to the form display, and therefore cannot be accessed after the form is closed. You could change the lifetime of these variables, e.g., by making them static class variables instead of local instance variables. I suggest you read up on .net static class variable scope.
I am using selenium to fill a p:calendar field. Instead of using the date picker, I send the keys to the field directly.
webDriver.findElement(By.id("theId").sendKeys("06031984");
Before and after this, I am interacting with various other elements on the page. With each run, I am getting different values appearing in my date input field - and rarely are these the correct ones:
40.60.3198
98.40.6031
06.03.1984 <- Correct
The order of the keys seems to be shifted, probably by the ajax calls in the p:calendar:
<p:calendar id="theId" styleClass="date-input"
binding="#{date}" navigator="true"
value="#{aView.date}"
validator="dateValidator"
yearRange="#{validatorService.dateRange}"
pattern="dd.MM.yyyy" mask="99.99.9999" readonlyInput="false"
readonly="false" required="true" showOn="button"
requiredMessage="#{i18n['aMsg']}"
locale="de">
<p:ajax event="dateSelect"
update="many elements"
oncomplete="updateTabbing();" />
<p:ajax event="change"
update="many elements"
oncomplete="updateTabbing();" />
</p:calendar>
Is there a way to ensure the correct value ends up in the field ?
So far I find working with Selenium (and a JSF page) to be a bit of a hassle.
We can try adding some wait and send tab key
or injecting java script for the value would Solve this problem
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("document.getElementsByid('theId').value = '06.03.1984';");
Please let me know if its solving the problem.
I'm adding a custom attribute that is an enum list to some of my nodes. I can easily do this with addAttr. But I don't see a way to later add a new enum value or change the enum list. Is that possible?
I have found a way to do this but it seems there should be an easier way. For my workaround, if the attribute exists I grab its value and delete the attribute. Then I add the revised attribute back into the node and set its value to the old value. By changing $enumValues I can edit the list of enums. (Note I only plan to add values not delete values) This script demonstrates my workaround:
string $attrName = "MaterialType";
string $enumValues = "Water:Sky:Terrain:Building:Road:";
string $selected[] = `ls -sl`;
if(`size $selected` == 1)
{
string $attrFullName = $selected[0]+"."+$attrName;
$existingValue = 0;
if(attributeExists($attrName, $selected[0]))
{
$existingValue = `getAttr $attrFullName`;
deleteAttr $attrFullName;
}
addAttr -ln $attrName -at "enum" -en $enumValues $selected;
setAttr $attrFullName $existingValue;
}
else
{
print "You must have 1 object and only 1 object selected\n";
};
Worth mentioning, if I run this script it does change the enum's values but these changes don't show up in Maya's interface until I close the file and reopen the file.
Any suggestions on how to do this more gracefully would be appreciated.
I might be a bit late, but you can use the "-edit" flag in addAttr.
addAttr -edit -enumNames "A:B:C" "node.enumAttrName"
However, you still need to refresh manually or with refreshEditorTemplates
Edit:
You might also want to consider optionMenuGrp. You can add menuItems via the -parent flag. You can remove a specific child with the deleteUI command or remove all children with the -deleteAllItems flag in edit mode on the optionsMenuGrp.
What you're doing - deleting the attribute and re-adding -- is unfortunately the only way to do this. Maya enums are pretty lame.
The attribute should be working correctly after the script is done - you may need to deselect and reselect it to properly refresh the attribute editor. You can check it with an listAttr -ud on your object after the script runs - you should see your attribute name in the results, even if the UI has not refreshed.
I am programming a select box in which a user can select from multiple values (up to 72). Im population the select box by using a for each loop to go through the array, like so:
For Each item In myArray
ItemUur = PadDigits(Hour(item),2)
ItemMinuut = PadDigits(Minute(item),2)
ItemTotaal = ItemUur & ":" & ItemMinuut
%>
<OPTION NAME="van" VALUE="<%=ItemTotaal%>"><%=ItemTotaal %></OPTION>
<%
Next
The array are time values (I am using the paddigits function to output the time as 05:00).
This works great. Though I want the select box to start at a default value, which isnt the first array (05:00) but instead the 10th array value (07:30).
I tried accomplishing this like so:
<OPTION NAME="van" VALUE="<%=ItemTotaal%>"><%=ItemTotaal(10) %></OPTION>
This is not working so then I thought I should be using the original array so I tried with item(10) as well, got the same error though..
The error message I am receiving is:
type mismatch 'item' / 'ItemTotaal' (depends on which I am using)
How can I get this to work?
<OPTION NAME="van"><%=myArray(10)%></OPTION>
ItemTotaal in your case -- just variable (not array)
myArray in your case -- array. so need to use it for access items in array
error you get because you are trying to use "Not Array" variable as Array variable
You were trying to use the variable as array.
The format should be as ArrayName(ArrayElementPosition)
<OPTION NAME="van" VALUE="<%=myArray(9) %>"><%=myArray(9) %></OPTION>
Note: to get the 10th element, i have mentioned as myArray(9) instead of myArray(10) as the array starts its position in 0.
Hope this helps.