ZK :Show Bind value in Client.showNotification - mvvm

i m working on a ZK project using MVVM aproach , what i m trying to do is to show notification of a #bind(each.info) value but is not seems to work with me , here s what i have done so far.
<div width="59%" style=" float: left !important;" apply="org.zkoss.bind.BindComposer"
viewModel="#id('menu') #init('ma.schlemmer.headerbar.mainMenu')">
<hlayout children="#bind(menu.listMenu)">
<template name="children">
<a iconSclass="#bind(each.icon)" href="#bind(each.link)" autag="#bind(each.info)" onRightClick='Clients.showNotification("#bind(each.info)" ,"warning",this.self,"after_center",1000)'></a>
</template>
</hlayout>
</div>
and thank you

You can do this using ZK commands. You should get the result you want like this:
<div width="59%" style=" float: left !important;" apply="org.zkoss.bind.BindComposer"
viewModel="#id('menu') #init('ma.schlemmer.headerbar.mainMenu')">
<hlayout children="#bind(menu.listMenu)">
<template name="children">
<a iconSclass="#bind(each.icon)" href="#bind(each.link)" autag="#bind(each.info)"
onRightClick="#command('showInfo', obj=each, comp=self)"></a>
</template>
</hlayout>
Then add this command to your View Model:
#Command
public void showInfo(#BindingParam("obj") ListMenu listMenu, #BindingParam("comp") Component comp) {
Clients.showNotification(listMenu.getInfo(),"warning",comp,"after_center",1000);
}
You did not provide enough code, so I can`t test the exact situation, but basically you need to pass the object each (which I guess is something like ListMenu object) and component to the command. Then you can easily show notification.
Best regards,
Osvaldas

Related

Ionic Framework: GridLayout with multiple rows and column on which buttons placed for an arrayItem

On a page, using ng-repeat, I try to place buttons on a grid layout.
Iterating through an array which is defined in a controller $scope.btnNames[]. buttons are place on Total number of buttons equal to array size of $scope.btnNames[]
I would like to put say 4 buttons per row.
As $scope.btnNames[] size is 20, then I like to place 20 buttons on 5 rows,
where each row will have 4 buttons.
1) on Controller :
- I have an array with button names
$scope.btnNames['aa', 'bb', 'cc','dd', 'ee', 'ff'....] whose size is 20.
2) on the page:
- using ng-repeat, iterate throught the
$scope.btnNames[] and put buttons as per follwoing code
<body ng-controller="PopupCtrl">
<div class="row responsive-sm">
<div ng-repeat="btnName in btnNames">
<button id={{$index}} class="button button-dark col" >{{btnName}}</button>
</div>
</div>
Please help me defining class="row" and class="col" and such a way that,
during ng-repate, after 4th button, it should add a new row and place 4 buttons till it reach end of ng-repeat.
Being new to both ionic and angulrJs, I'm not able to define class="row" during ng-repeat ( similar like a for loop, where, put a new class="row", when iterator counter in this case {{index}} greater than 4.
Use flex-wrap
You can get this behavior by using style="flex-wrap: wrap;" + the following CSS classes:
<div class="row" style="flex-wrap: wrap;">
<div class="col col-25" ng-repeat="btnName in btnNames">
<button class="button button-dark" >{{btnName}}</button>
</div>
</div>
http://codepen.io/Jossef/pen/doeJJP
You can find a possible solution here : https://stackoverflow.com/a/23780288/1015046
I have taken the above solution and implemented it for Ionic : http://codepen.io/arvindr21/pen/EaVLRN
<div ng-repeat="btnName in btnNames">
<div ng-if="$index%4==0" class="row">
<div class="col">
<button id={{$index}} class="button button-dark">{{btnNames[$index]}}</button>
<button id={{$index+1}} class="button button-dark">{{btnNames[$index+1]}}</button>
<button id={{$index+2}} class="button button-dark">{{btnNames[$index+2]}}</button>
<button id={{$index+3}} class="button button-dark">{{btnNames[$index+3]}}</button>
</div>
</div>
</div>
If you want the grid to be dynamic, you can take a look at : https://stackoverflow.com/a/27080632/1015046
Thanks.
Ok, So if you want to stack images like me in rows, See how the ng-repeat holds col-50.
<div class="row gallery">
<div class="col col-50" ng-repeat="photo in photos">
<img id="fitWidth" ng-src="{{photo.url}}"/>
</div>
</div>
Then with your css.
.gallery {
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
}
Tested on IOS, Hope that helps :)
I would just like to add to the #Jossef Harush's answer (which, btw, worked).
However, when I tested it in the Ionic View application on iPhone, it didn't work. When I tested it in the Ionic View application on Android it worked as expected (multiple rows).
The solution was to add this as a style:
style="display: -webkit-flex; -webkit-flex-wrap: wrap; display: flex; flex-wrap: wrap;"
because, as you can see here Safari needs a -webkit prefix.
Hope this helps someone who will choose this solution over #Arvind's.
Worked for me as soon as I added flex-wrap: wrap in the styling.
Since i have set col-50 I started getting rows with two columns as intended.
Example:
<div class="row" style="flex-wrap: wrap;">
<div class="col col-50" ng-repeat="picture in pictures">
{{picture.src}}
</div>
</div>
There's a limitTo starting $index in AngularJS,
Maybe that can simplify things
<div class="row" ng-repeat="element in elements" ng-if="$index % 4==0">
<div class="element" ng-repeat="element in elements|limitTo:4:$index">...</div>
</div>
That will make sure that {{ index + 1 }} fall on a non-existent cell ..

Knockout 3.2 applyBindings to new dom node

I have searched, and found old answers to this, and hacks about manually clearing bidnigns, and then calling applybindings... as well as creating a custom viewmodel that isnt directly related to anythign else and applying bindings with that AFTER the new dom nodes appear.
My specific scenario is that a bootstrap3 modal basically re-attaches itself after show is called, and likewise none of the items in the modal actually still bound.
I already have a model that represents state/properties of the dialog, but I'd like the dialogviewmodel to be a child of my pageViewModel.
My question is, at this point in time, whats the most appropriate way to do this? Is there no way to say take this node, attach it to the viewmodel at this property?
I am using the same tools as you (knockout and bootstrap3). This is how I accomplish Modals as an example:
This div exists as the first element of the body in my index.html:
<div class="modal fade" id="BaseModal" tabindex="-1" role="dialog" aria-labelledby="BaseModal" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div id="modalLoading" class="ajax-loader">
<img src="images/working_blue.gif" />
</div>
<div class="modal-dialog modal-lg">
<div id="ModalAnchor" class="modal-content col-lg-4 col-lg-offset-4" data-bind="html: $data.ModalContent"></div>
</div>
</div>
// This is typescript but the javascript should be pretty close to this.
private LoadModalView(viewName: string, viewModel: any): void {
$.get(viewName)
.then((view: any, status: string, jxhr: JQueryXHR) => {
this.ModalContent(''); // ensure there is no content in the modal.
this.ModalContent(view); // Load new HTML
ko.applyBindingsToDescendants(viewModel, this.ModalAnchor[0]); // bind new modal viewmodel
this.BaseModal.modal('show'); // Open the modal
}, (view: any, status: string, jxhr: JQueryXHR) => { /*Do error handling*/ });
}
EDIT: Here is an example of the HTML I load into the modal:
<div class="modal-header">
<h3 data-bind="text: $data.Header"></h3>
</div>
<div class="modal-body">
<h5 data-bind="text: $data.Message"></h5>
</div>
<div class="modal-footer">
<button id="OK" class="btn btn-primary center-block" data-bind="click: OK, text: ButtonText" />
</div>
In the LoadModalView function, the ViewModel parameter is a viewmodel to represent the new data/content/etc of the new modal.
In the Modal Viewmodel, I call 'hide' on the modal when it's purpose is served.
I hope this helps! I don't know if it's the 'correct' or 'proper' way to do this, but this is my pattern.

In JSSOR, how to access the current caption via Javascript?

I would like to pass a value from a slide out of JSSOR to other parts of the DOM.
Markup:
<div class="slide">
<img data-u="image" src="bilder/bild2.jpg" />
<div class="caption" data-u="caption" ><p>Caption text</p></div>
</div>
JS:
jssor_slider1.$On($JssorSlider$.$EVT_PARK,function(slideIndex,fromIndex){
$(".outer-caption").text(currentCaption);
});
The custom JSSOR Event, EVT_PARK, works fine. But what's missing is how to get the caption of the current slide and put it into the variable currentCaption. How to do that?
And if so, where could I have found that out on my own?
Please have a full test of following code,
<div class="slide">
<img data-u="image" src="bilder/bild2.jpg" />
<div class="caption" data-u="caption" id="caption-slide-0"><p>Slide 0 Caption</p></div>
</div>
jssor_slider1.$On($JssorSlider$.$EVT_PARK,function(slideIndex,fromIndex){
$("#outer-caption").text($("#caption-slide-" + slideIndex).text());
});

How do I make a HTML form using <label> <input> and <span>?

I have made a form in HTML using a table and that worked fine, however, my teacher told me that making forms from tables is not the proper way to do it anymore, instead I should use:
<form>
<label></label>
<input>
</form>
but he also mentioned something about using <span></span> and I'll guess it is just about this point where I got a bit confused, because where should I use it - ie. should I put the <label> and the <input> in between <span></span> ?
A few of the reason I ask is:
I don't consider myself very savvy when it comes to HTML
I would just have used a <div></div> to wrap around the <label> and the <input> and then use css to put it where I want it to appear on the webpage.
Regarding the form I want to create then I want it to look like this:
[Firstname] [lastname]
[textfield] [textfield]
[Street] [zip-code] [city]
[textfield] [textfield] [textfield]
[E-mail] [Phone]
[textfield] [textfield]
[message]
[textarea]
I hope the layout of my form makes sense to the majority of you !
Try something like this:
<form action="action.php">
<label for="firstName">First Name</label>
<input type="text" name="fname" id="firstName"><br>
<label for="lastName">First Name</label>
<input type="text" name="lname" id="lastName"><br>
....
</form>
and to line it all up you could use some css like this:
label{
width: 100px;
text-align:left;
}
Although you could use SPAN technically.. as it's an inline element and so are LABEL and INPUT, it doesn't quite sit well. Inline elements aren't really designed to be containers, so using a block level element such as a DIV would be a better way of structuring it.
Beyond this to make it line up, you're moving into the relms of CSS to float your elements.
So something alone the lines of:
<form action="">
<fieldset>
<div class="left">
<label for="FirstName">First Name</label>
<input type="text" name="FirstName" id="FirstName">
</div>
<div class="right">
<label for="LastName">Last Name</label>
<input type="text" name="LastName" id="LastName">
</div>
</fieldset>
</form>
<style type="text/css">
fieldset {
width:500px;
overflow:hidden;
}
fieldset .left {
float:left;
width:50%;
}
fieldset .right {
float:right;
width:50%;
}
fieldset label {
display:block;
}
fieldset block {
display:block;
}
</style>
You teacher probably means that you should wrap each pair of input and label in a span. You are quite right in thinking that you should use div instead of span there. Just tell your teacher to look at the page when style sheets are disabled. On similar grounds, you should prove her/him that he is all wrong about saying that a table should not be used.
To do the exercise of writing a form (that is essentially tabular data) without using table markup, just use your div approach and use tabular layout features of CSS: set display: table on the form, display: table-row on the div elements, and display: table-cell on the input and label elements. Add padding and horizontal alignment as needed. Do not forget to inform your teacher that this will only work on sufficiently modern browsers, whereas the logical approach of using an HTML table works on all browsers.

knockout doesn't update html after get data from ajax

I bind list of data to HTML, in each list has button for get details by ajax. I want to bind callback data to member of model, After ajax call back, object have data, view received ( ko.toJSON(d, null, 2))object. But HTML doesn't update data.
I don't know what is wrong. please help. Thank you.
Html:
<section id="lists">
<article class="todoList">
<script type="text/html" id="person-template">
<!-- <p>Credits: <span data-bind="text: message"></span></p>-->
<p>xxx</p>
</script>
<ul data-bind="foreach: Items">
<li>
<div>
<span class="contentarea" data-bind="text: message"></span>
<button data-bind="click: $parent.evClick.bind($data)">Get details</button>
<button data-bind="click: detail">Ajax-Get</button>
<p>Credits: <span data-bind="text: d.message"></span></p>
<div style="display: block; width: 200px; height: 200px; border: solid 1px #ff6a00;" data-bind="text: ko.toJSON(d, null, 2)"></div>
</div>
</li>
</ul>
</article>
</section>
Full code here.
http://jsfiddle.net/wuttipat/sc8fX/12/
You should use
<div data-bind="with: d">
<span data-bind="text: message"></span>
Because data-bind="with: d" create scope for binding context when you use data-bind="text: message" inside it will reference to parent binding context in this case mean d.
Full code here : http://jsfiddle.net/sc8fX/74/
I think I've figured it out (after cleaning up the fiddle some more). You're binding is
text: d.message
But it should be
text: message
Because d is the context of your binding. So you're actually trying to bind to d.d.message which doesn't exist. Replacing it with text: message seemed to work, no?
See this updated fiddle.
I found the issue posted on knockout document.
http://knockoutjs.com/documentation/with-binding.html