Is there a way to pass parameters via the addTarget call as it calls another function?
I've also tried the sender method - but that seems to break as well. What's the correct way to pass the parameters without creating global variables?
#my_button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
#my_button.frame = [[110,180],[100,37]]
#my_button.setTitle("Press Me", forState:UIControlStateNormal)
#my_button.setTitle("Impressive!", forState:UIControlStateHighlighted)
# events
newtext = "hello world"
#my_button.addTarget(self, action:'buttonIsPressed(newtext)', forControlEvents:UIControlEventTouchDown)
view.addSubview(#my_button)
def buttonIsPressed (passText)
message = "Button was pressed down - " + passText.to_s
NSLog(message)
end
Update:
OK, here's a method with an instance variable that worked.
#my_button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
#my_button.frame = [[110,180],[100,37]]
#my_button.setTitle("Press Me", forState:UIControlStateNormal)
#my_button.setTitle("Impressive!", forState:UIControlStateHighlighted)
# events
#newtext = "hello world"
#my_button.addTarget(self, action:'buttonIsPressed', forControlEvents:UIControlEventTouchDown)
view.addSubview(#my_button)
def buttonIsPressed
message = "Button was pressed down - " + #newtext
NSLog(message)
end
The easiest way of attaching "parameters" to a rubymotion UIButton call is through the use of tags.
First set up a button with a tag attribute. This tag is the parameter you want to pass to the target function.
#button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
#button.setTitle "MyButton", forState:UIControlStateNormal
#button.frame =[[0,0],[100,50]]
#button.tag = 1
#button.addTarget(self, action: "buttonClicked:", forControlEvents:UIControlEventTouchUpInside)
Now create a method that accepts sender as a parameter:
def buttonClicked(sender)
mytag = sender.tag
#Do Magical Stuff Here
end
Forewarning: As far as I know, the tag attribute only accepts integer values. You could get around this by putting your logic into the target function like this:
def buttonClicked(sender)
mytag = sender.tag
if mytag == 1
string = "Foo"
else
string = "Bar"
end
end
Initially I tried setting the action with action: :buttonClicked which worked but did not allow for using the sender method.
Yes, you usually create instance variables in your Controller class, and then just call methods on them from any method.
According to the documentation using setTitle is the general way to set a title of a UIButton instance. So you're doing it right.
Related
I have a little problem with my outlook interface.
I'm using <outlook\msoutl.tlh> to create and fill an e-mail item automatically.
But now I want to display my signature too.
I noticed that if I don't set the mail body, the signature is added automatically. But as soon as I want to set the mail body, the signature is not shown. It seems that it will be overwritten. So I tried the following :
string standardText = "Hello Outlook"
string signature = IMailItemPtr->Body;
IMailItemPtr->Body = standardText + signature
So first the signature has to be cached and then appended to the standard text for the body.
But here I noticed that the body is empty until set (which is logical).
But now I wonder where my signature is stored and how I can get it?
Here is the important part of my code:
string standardText = "Hello Outlook"
Outlook::_ApplicationPtr spOutlook(__uuidof(Outlook::Application));
// Get the MAPI namespace
Outlook::_NameSpacePtr pMAPI = spOutlook->GetNamespace("MAPI");
// Initiate a new Outlook-session
pMAPI->Logon("", "", false, true); // Log on by using the default profile or existing session (no dialog box).
// Query the MailItem interface
Outlook::_MailItemPtr IMailItemPtr = spOutlook->CreateItem(Outlook::olMailItem);
IMailItemPtr->Subject = mailSubject;
IMailItemPtr->Body = standardText.c_str();
So, in my method A in the controller ServicioComunitario I send this to the GSP:
tg = ServicioComunitario.findAll("from ServicioComunitario as b where "+query)
[servicioComunitarioInstanceList: tg, params: params]
Then in the GSP I call another method (generarDocDeReporte) of ServicioComunitarioController:
<g:set var="b" value="${'xls'}"/>
<g:set var="a" value="${'excel'}"/>
<g:set var="servicioLista" value="${servicioComunitarioInstanceList}"/>
<g:link controller="ServicioComunitario" action="generarDocDeReporte"
params="${[exportFormat:a, extesion:b, tg: servicioLista] }"
update="mainContent">Excel</g:link><br/>
Then, in the new method "generarDocDeReporte" I have:
println params.exportFormat+"-"+params.extesion
if(params.tg)
println "Not empty"
exportFormat and extension work as expected, but the params.tg doesn't seem to behave normal.
I am trying to use this new params.tg where it was a ServicioComunitario.list(params):
exportService.export(params.exportFormat, response.outputStream, ServicioComunitario.list(params), fields, labels, formatters, parameters)
And here is where I get the error:
exportService.export(params.exportFormat, response.outputStream, params.tg, fields, labels, formatters, parameters)
When I receive the params.tg, do I need to cast it? or what do you think is the error?
Thank you very much in advance
You can't just pass a list of instances like that in a link. You can however collect the ids into a list as a parameter and then use it to populate it later. For example:
<g:link controller="ServicioComunitario" action="generarDocDeReporte"
params="${[exportFormat:a, extesion:b, tgids: servicioLista.collect{it.id}.join(',')] }"
update="mainContent">Excel</g:link><br/>
And then in your controller where you need to get the list again:
def tg = ServicioComunitario.getAll(params?.tgids?.tokenize(","))
Also, you don't need to assign params to params when returning your model. parameters are already exposed in the GSP by convention.
[servicioComunitarioInstanceList: tg]
Is it somehow possible to add the sub-group of a cetrain group the address is assigned to the html output?
In the template I have ###MAINGROUP### and ###GROUPLIST###. I can't use maingroup, cause it's not the case that the group I need is always the maingroup. And with the grouplist I can't say which group is the sub-group of the one group.
Anyone have an idea how I could do it?
And in addition to that I also need the value of a self created field in the tt_address table.
Edit:
I try it like #lorenz say. What I have so far:
ext_localconf.php:
<?php
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['tt_address']['extraItemMarkerHook'][]
='EXT:txnextaddresssort/class.tx_next_address_sort_addmarkers.php:tx_next_address_sort_addmarkers';
class.tx_next_address_sort_addmarkers.php:
<?php
class tx_next_address_sort_addmarkers {
function extraItemMarkerProcessor(&$markerArray, &$address, &$lConf,
&$pObj) {
$lcObj = t3lib_div::makeInstance('tslib_cObj');
$lcObj->data = $address;
$markerArray['###SORTBEREICH###'] =
$lcObj->stdWrap($address['tx_nextaddresssort_sort_bereich'],
$lConf['tx_nextaddresssort_sort_bereich.']);
}
}
Extentionkey: next_address_sort
All I get is a blank screen, but no errors in apache log
No, there is no possibility to do that.
Yet you can write a custom extension that integrates the extraItemMarkerProcessorhook in tt_address. In ext_localconf.php, add:
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['tt_address']['extraItemMarkerHook'][] ='EXT:myextension/class.tx_myextension_filename.php:tx_myextension_classname';
Then add a file class.tx_myextension_filename.php to your extension.:
class tx_myextension_classname {
public function extraItemMarkerProcessor(&$markerArray, &$address, &$lConf, &$pObj) {
$lcObj = t3lib_div::makeInstance('tslib_cObj');
$lcObj->data = $address;
$markerArray['###MYFIELD###'] = $lcObj->stdWrap($address['myfieldlikeindatabase'], $lConf['myfieldlikeindatabase.']);
return $markerArray;
}
}
This would be an example for getting a field that is in the tt_address table and adding it to the markers so they can be used in a template. It is also stdWrap enabled.
Now, instead of getting a field, you should replace $address['myfieldlikeindatabase'] with a variable that contains the information you need. To receive the data, you can use the TYPO3 database API functions ($GLOBALS['TYPO3_DB']).
I have a method in a custom taglib like so:
def deleteAction = {attrs ->
def id = attrs['id']
def type = attrs['type']
def clazz = attrs['class']
def html = new MarkupBuilder(out)
html.span(class: "${clazz} ui-icon ui-icon-trash {id:'${id}'}")
}
I have a controller that uses this method and I'm trying to stub it out for a unit test, so I have the following:
def mockMyTagLib = mockFor(MyTagLib)
mockMyTagLib.demand.deleteAction(1) {id, type, clazz ->
def html = new MarkupBuilder(new StringWriter())
html.span(class: "${clazz} ui-icon ui-icon-trash {id:'${id}'}")
}
controller.metaClass.mn = mockMyTagLib.createMock()
But I keep getting the following:
No more calls to 'deleteAction'
expected at this point. End of
demands.
Am I doing something wrong here? Here is it's actual usage in the controller:
"${mn.deleteAction(id: it.id, type: 'bookProduct', 'class': 'del-book-product')}"
The following is from Testing - Reference Documentation
... You then specify the name of the
method that you want to mock with an
optional range as its argument. This
range determines how many times you
expect the method to be called, so if
the number of invocations falls
outside of that range (either too few
or too many) then an assertion error
will be thrown. If no range is
specified, a default of "1..1" is
assumed, i.e. that the method must be
called exactly once.
You've specified demand.deleteAction(1) which means that the method must be called once and only once.
Also, if you want, you can always set your mock to be loose by specifying it as the second parameter in mockFor (defaults to strict)
mockFor(class, loose = false)
I am trying to pass a mocked domain instance called event to the controllers' show() method, but show() cannot find the Event in question and thus returns null.
Note that the following snippet is still work in progress.
def "trying to show an event containing malicous code"() {
given: "An event named with malicous code"
mockDomain(Event)
def event = Mock(Event)
event.title >> "<script type=\"text/javascript\">alert(\"XSS\");</script>"
event.id >> 1
// Do I have to actually create a full-blown event considering all
// constraints here?
when: "I try to show that event"
controller.params.id = 1
def result = controller.show()
then: "The resulting title will be encoded HTML"
result.eventInstance.title == event.title.encodeAsHTML()
}
This is the beginning of the controllers' show() method:
def show = {
def eventInstance = Event.get(params.id)
// The event exists
if (eventInstance) {
// some processing here
return [eventInstance: eventInstance, isSubscribed: sub ? true:false, sidebar: 'sidebar']
}
Is there a simple solution or will I have to actually create a full-blown event taking care of all constraints?
If I have to create a full event, where would I place the according method? (We're using a createEvent() method in BootStrap.groovy at the moment for initial setup, thus it wouldn't be DRY to repeat the function here).
Try mocking the Event object in the following way:
def event = new Event()
event.title = "<script type=\"text/javascript\">alert(\"XSS\");</script>"
event.id = 1 // optional
mockDomain Event, [event]
Unless you add an instance of event to the mockDomain call, you won't be able to retrieve it with get