Can't handle Button Click in Popup - mvvm

I use CaliburnMicro in my Windows Store App. All works great, but when I put Button in Popup, method in ViewModel doesn't called. If I move Button from Popup to Page - all works like a charm.
Ex. code
.xaml
<Button x:Name="Method1"/>
<Popup Width="400" Height="300" IsOpen="True">
<Button x:Name="Method2"/>
</Popup>
in ViewModel.cs
public void Method1() //this method is called
{
var a = 10;
}
public void Method2() //this method isn't called
{
var a = 10;
}
Need some help.
UPDATE
I also tried to add to my popup
cal:Bind.Model="{Binding}"
And in code I check popup.Datacontext is the nested ViewModel

You could explicitly declare an action message by doing something like this.
<Popup Width="400" Height="300" IsOpen="True">
<Button x:Name="Method2" Content="Popup}"
cal:Message.Attach="Method2"/>
</Popup>
More detail about Action here.

Related

Jquery not working when click ajax button

I use jquery datepicker and it not display after I click ajax button.
Is there any way to show datepicker again after click? I use wicket 8.
BasePage.java
public class BasePage extends WebPage {
...
}
BasePage.html
<body>
...
<script src="/js/jquery.min.js"></script>
<script src="/js/jqueryui.min.js"></script>
<script src="/js/main.js"></script>
</body>
HomePage.java
public class HomePage extends BasePage {
public HomePage() {
SearchForm searchForm = new SearchForm();
Form<SearchForm> form = new Form<>(new CompoundPropertyModel<SearchForm>(searchForm))
AjaxButton btn = new AjaxButton() {
protected void onSubmit(AjaxRequest target) {
// Handle search data
...
target.add(form);
}
};
TextField<String> date = new TextField<>("searchDate");
form.add(date);
form.add(btn);
}
}
HomePage.html
<wicket:extend>
<form wicket:id="form">
<input wicket:id="searchDate" class="datepicker" />
<button wicket:id="btn">Search</button>
</form>
</wicket:extend>
main.js
$(function() {
$(".datepicker").datepicker();
...
});
After click ajax button all script in file main.js not working
Please help me.
when you update form via AJAX you replace each element inside it, which includes the input field you use with datepicker. But doing so you loose the javascript setting done by main.js when page was first loaded.
You can solve this in two ways. First, you could update only those elements that need to be refreshed, for example the component that you use to show search result (I suppose there must be such an element in your code).
The second solution, more heavier and complicated, is to make a custom TextField component that execute the datepicker javascript code each time is rendered.
An example of such solution can be found is in the user guide: https://wicket-guide.herokuapp.com/wicket/bookmarkable/org.wicketTutorial.ajaxdatepicker.HomePage
I would recommend to follow the first solution as it's more natural and simpler and requires less code.
UPDATE:
If you want to refresh the textfield another simple solution is to use target.appendJavaScript​ to reapply the datepicker plugin:
target.add("$('#" + date.getMarkupId() + "').datepicker();");
this should add the datepicker to the fresh new field.

Changing function on a button using detachPress / attachPress

I have a requirement for my app and I need to change the event handler of a common button depending on the status of the workflow.
Basically I need to change the function called when you press the button and vice-versa and was looking to achieve this by using the event handler functions detachPress and attachPress.
https://ui5.sap.com/#/api/sap.m.Button/methods/detachPress
https://ui5.sap.com/#/api/sap.m.Button/methods/attachPress
My Button (XML View):
<Button text="Edit" width="50%" id="_editButtonEmail" press="editPIN"/>
On my controller I want to change the function editPIN by cancelEditPIN.
Some things I've tried:
editPIN: function(oControlEvent) {
//change button
var editButton = this.getView().byId("_editButtonEmail");
//detach this function on press
editButton.detachPress(editButton.mEventRegistry.press[0].fFunction);
editButton.attachPress(this.cancelEditPIN());
}
cancelEditPIN: function() {
//do something else
}
Also
editPIN: function(oControlEvent) {
//change button
var src = oControlEvent.getSource();
src.detachPress(this.editPIN());
src.attachPress(this.cancelEditPIN());
}
None of these seem to work and if I check my console the function editPIN is still attached to my mEventRegistry press event.
There are few things worse than checking your GUI texts to determine what action should be done.
A different approach uses two buttons. Only one is visible at a time
<Button
text="{i18n>editPIN}"
visible="{= ${myModel>/State} === 'show' }"
press="editPIN" />
<Button
text="{i18n>editCancelPIN}"
visible="{= ${myModel>/State} === 'edit' }"
press="cancelEditPIN" />
In this case {myModel>/State} is a local JSON model where the current state of your workflow is stored.
If you really want to use your attach/detach approach: It probably didn't work because you were calling the methods while passing them as a parameter to attach/detach. So for example try src.detachPress(this.editPIN); instead of src.detachPress(this.editPIN());
Following the idea from #Jorg, I created another function checkPIN with an if statement that compares the text in the button and then fires the appropriate function depending on it.
I do have to phrase that I am using my i18n file to provide texts to my view, this way my textID will not change on whatever language the user is using.
My Button:
<Button text="Edit" width="50%" id="_editButtonEmail" press="checkPIN"/>
My Controller:
checkPIN: function(oControlEvent) {
var src = this.getView().byId("_editButtonEmail").getText();
var oBundle = this.getView().getModel("i18n").getResourceBundle();
//call cancelEditPIN
var editCancelPinText = oBundle.getText("editCancelPIN");
//call editPIN
var editPinText = oBundle.getText("editPIN");
//change button
if (src === editPinText) {
this.editPIN(oBundle);
} else if (src === editCancelPinText) {
this.cancelEditPIN(oBundle);
}
},
editPIN: function(oBundle) {
//do stuff here
//change button text
var editButton = this.getView().byId("_editButtonEmail");
editButton.setText(oBundle.getText("editCancelPIN"));
},
cancelEditPIN: function(oBundle) {
//do different stuff here
//change button text
var editButton = this.getView().byId("_editButtonEmail");
editButton.setText(oBundle.getText("editPIN"));
}
Not really the answer I was looking for because I would like to use detachPress and attachPress so if you know what I should have done in order to implement those please let me know.

Ionic2: use getActive() to change button color for the active page

I have a nav component which I am using on 4 pages, I want to be able to change the color of active page's button in the nav component. In Ionic app doc's for nav controller I found getActive() instance, but I can't figure out how to achieve the desired result with it. I'm using the following code to push to a new view.
viewPage2(){
this.navCtrl.push(Page2);
}
<button ion-button (click)="viewPage2()" color="dark" clear full>Page 2</button>
NavController getActive() returns the ViewController of the Active page.
Looking at the API of ViewController you could try using getContentRef():
this.navCtrl.getActive().contentRef().nativeElement.getElementById("button_id")
Once you have the element you could change the color.
Even though getting the html element by its id may work, modifying the DOM directly is not the recommended way to do things in Ionic.
First option:
If that's a custom component, you can always expose a public method in that component, and get the reference by using ViewChild
#Component({...})
export class NavCustomComponent {
public activePage: string = 'page1';
//...
public changeActivePage(pageName: string): void {
this.activePage = pageName;
}
// ...
}
And in your view:
<button ion-button (click)="viewPage2()" [color]="activePage === 'page2' ? 'light' : 'dark'" clear full>Page 2</button>
Then in the page where you're trying to modify the component:
#Component({...})
export class DemoPage {
#ViewChild(NavCustomComponent) navCustomComponent: NavCustomComponent;
}
and then use that reference to call that public method:
this.navCustomComponent.changeActivePage('page2');
Second option:
If that's not a custom component, or you just want to make things even simpler, you can just Events. Whereever you're defining the code of that nav component, (or in your app.component.ts file to make it global for the entire app) subscribe to the event:
public activePage: string = 'page1';
constructor(public events: Events, ...) {
events.subscribe('page:selected', (pageName) => {
this.activePage = pageName;
});
}
Again, in your view:
<button ion-button (click)="viewPage2()" [color]="activePage === 'page2' ? 'light' : 'dark'" clear full>Page 2</button>
And then in the component where you want to change the color, just publish that event:
events.publish('page:selected', 'page2');

How to use Modal Pop up with Material Design Lite?

I recently started using the latest Desktop version of Google Material Design Lite, I figured it doesn't have a modal pop up and the team has not yet implemented it for the next release.
I have tried to include bootstrap model into it, but thats not working infect seems pretty messed, I believe with the classes/styles clashing with each others.
Any Idea what will work good as an replacement ??
Thanks for your help.
I was also looking for a similar plugin and then I found mdl-jquery-modal-dialog
https://github.com/oRRs/mdl-jquery-modal-dialog
I used this because the other one I found was having issue on IE11. This one works fine.
<button id="show-info" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">
Show Info
</button>
Here a JSFiddle: https://jsfiddle.net/w5cpw7yf/
I came up with a pure JavaScript Solution for this
You can use the default bootstrap data attributes for the buttons, and make sure that your buttons and modals have their own unique IDs.
You need to have Material Design Lite's JS included before using this JavaScript
Check out the code. Any reviews are welcomed. :)
// Selecting all Buttons with data-toggle="modal", i.e. the modal triggers on the page
var modalTriggers = document.querySelectorAll('[data-toggle="modal"]');
// Getting the target modal of every button and applying listeners
for (var i = modalTriggers.length - 1; i >= 0; i--) {
var t = modalTriggers[i].getAttribute('data-target');
var id = '#' + modalTriggers[i].getAttribute('id');
modalProcess(t, id);
}
/**
* It applies the listeners to modal and modal triggers
* #param {string} selector [The Dialog ID]
* #param {string} button [The Dialog triggering Button ID]
*/
function modalProcess(selector, button) {
var dialog = document.querySelector(selector);
var showDialogButton = document.querySelector(button);
if (dialog) {
if (!dialog.showModal) {
dialogPolyfill.registerDialog(dialog);
}
showDialogButton.addEventListener('click', function() {
dialog.showModal();
});
dialog.querySelector('.close').addEventListener('click', function() {
dialog.close();
});
}
}
<!-- Button to trigger Modal-->
<button class="mdl-button mdl-js-button" id="show-dialog" data-toggle="modal" data-target="#upload-pic">
Show Modal
</button>
<!-- Modal -->
<dialog id="upload-pic" class="mdl-dialog mdl-typography--text-center">
<span class="close">×</span>
<h4 class="mdl-dialog__title">Hello World</h4>
<div class="mdl-dialog__content">
<p>This is some content</p>
</div>
</dialog>
I use MDL with bootstrap and the modal is displayed correctly after adding the data-backdrop attribute this to the modal element:
<dialog data-backdrop="false">
Hope it helps!

How to call a function from a button click in JSP

I have the following function:
<script>
function assign()
{
String val="";
String val = document.form1.text1.value;
System.out.println(val);
}
</script>
i am trying to call the function in the button click as shown below:
<button type="button" onclick="assign()">Display</button>
When i click on the button nothing happens. I want the string value in the text box to be printed on the console.Please help
First of all, if you are trying to call JavaScript on button click, then your syntax is wrong. See, you are mixing Java with JavaScript (code) in script tag, that is invalid.
Use like this:
<script>
function assign() {
var val = "";
val = document.form1.text1.value;
alert(val); or console.log(val);
}
</script>
and
<button type="button" onclick="javascript:assign();">Display</button>