Button with handler and bound tag attributes - jsviews

I want to define in a jsviews template a button that have both click handler and data bound property.
Assuming I have this data:
var data = {
Enable : true,
DisplayName : "foo",
SomeData : 42
};
This helpers :
var handlers = {
fooClicked : function(data, evt) {
console.log(arguments);
}
};
How to add a button in my template to plumb the event handler and the properties of the button ?
I tried :
<button data-link="{on ~onAvailabilityClick SomeData disabled:^{!Enable}}">
{^{>DisplayName}}
</button>
<button data-link="{on ~onAvailabilityClick SomeData} disabled:^{!Enable}">
{^{>DisplayName}}
</button>
{^{on ~onAvailabilityClick SomeData}}<button data-link="disabled:^{!Enable}">
{^{>DisplayName}}
</button>{{/on}}
But none of these works (either template syntax error or incomplete button, like having no text, or no handler).
I'm using jsViews 0.98.4.
PS: I don't know if it matters, but actually, my template is fed within a for loop, for an deep object structure.

You can find documentation on setting multiple data-link bindings, and other related topics here:
http://www.jsviews.com/#linked-elem-syntax#fullsyntax
http://www.jsviews.com/#link-elemattribs
http://www.jsviews.com/#link-tags
http://www.jsviews.com/#link-events
In your case, you need to write
<button data-link="disabled{:!Enable} {on ~onAvailabilityClick SomeData}">
{^{>DisplayName}}
</button>
or if you prefer:
<button
data-link="disabled{:!Enable} {on ~onAvailabilityClick SomeData} {:DisplayName}">
</button>

I finally made it :
<button data-link="disabled{:!Enable} {on ~onAvailabilityClick SomeData}">
{^{>DisplayName}}
</button>

Related

Vue.js CSS change button onClick to href not working

In a SinglePageApp, I need to use a <button> tag rather than an <a> tag 5 I am using UKit
the <a> tag would be :
<a type="button" class="uk-button uk-button-link" href="#events"><events</a>
But writing the tag this way , does not work
<button #click="location.href='{{ url('events') }}'" class="uk-button uk-button-link">EVENTS</button>
note : I see an ESLint error .. [js] ';' expected
#webnoob answer is correct , however it seems that it's not working in a single page application : I get a scopelocation undefined error..
SO I am using a method :
<button #click="goToEvents()" class="uk-button uk-button-link">EVENTS</button>
and
methods: {
goToEvents: function () {
location.href='#events'
}
},
To do an onclick with Vue, you would do it like this:
<button v-on:click="location.href=url('events')" class="uk-button uk-button-link">EVENTS</button>
You can also use #click="location.href=url('events')"
Take a look at Vue Event Binding for more information.
If you're within a form and don't want the form to be posted as well, you would need to also add in .prevent so it would become v-on:click.prevent="url('events')"
You only use {{ }} (mustache's) when you're rendering content i.e text. When you're within an attribute which you want to use dynamic values in, you would prefix the attribute with : so, for instance, if you wanted to add some dynamic text in a data attribute, it would become :data-something="myDataProp"

knockout.js How to get values from form and get additional data ASP.NET MVC

What i got is:
var post = function(id, message, username, date) {
this.id = id;
this.message = message;
this.username = username;
this.date = date;
this.comments = ko.observableArray([]);
this.addComment = function(context) {
var comment = $('input[name="comment"]', context).val();
if (comment.length > 0) {
$.connection.boardHub.server.addComment(this.id, comment, vm.username())
.done(function() {
$('input[name="comment"]', context).val('');
});
}
};
And View:
<form class="add-comment" data-bind="submit: addComment">
<div class="row">
<div class="col-md-9">
<input type="text" class="form-control" name="comment" placeholder="" />
</div>
<div class="col-md-3">
<button class="btn btn-default" type="submit">Answer</button>
</div>
And the question is how can i pass to addComment extra value without missing context?
Like:
<form data-bind="submit: function(){ writePost(<context>, '#ViewBag.UserN'); }">
As I mentioned in my comment, you are not using knockout correctly. Therefore I'll provide you with a generic example of how you should handle form submits using knockout.
First, you should define a viewmodel which wraps your UI data and connects to services to do any actual logic. In simple cases, many people just write the logic, such as API calls right into the viewmodel instead of a service. For simplicity, I'll just do that, because extracting it into its own 'class' should be simple enough. You should give your viewmodel a more descriptive name than post. Here is an example:
var commentViewModel = function(id, userName) {
var self = this;
this.commentText = ko.observable('');
this.addComment = function() {
var txt = self.commentText();
if (txt) {
$.connection.boardHub.server.addComment(id, txt, userName)
.done(function() {
self.commentText('');
});
}
};
};
var commentVM = new commentViewModel('#ViewBag.Id', '#ViewBag.UserN');
$(function() { ko.applyBindings(commentVM); });
HTML:
<form class="add-comment" data-bind="submit: addComment">
<div class="row">
<div class="col-md-9">
<input type="text" class="form-control" data-bind="textInput: commentText" />
</div>
<div class="col-md-3">
<button class="btn btn-default" type="submit">Answer</button>
</div>
</div>
</form>
Explaination:
The commentVM object contains a commentText member. This is a KO observable, so by exposing it by assigning it to this, you can bind to it. Then you can read the value of it by utilizing the KO binding mechanism instead of mixing jQuery and KO. Bindings exist to simplify your life not to be mixed with plain jQuery stuff, so you should use them wherever you can.
You should also expose an observable array to hold the actual comments, but since that wasn't part of your question I didn't want to introduce it to exclude any additional noise which is not related to what you asked.
In your HTML, you used the submit binding correctly. By binding the submit event to the addComment method, this method will get invoked correctly. But what's different compared to your code is that you read the comment text from the observable you've just defined, and avoid using jQuery. Since the VM itself is the context, you don't have to care about how to pass it -- that is, anything that you intend do use from within the submit method should generally be included in the viewmodel.
If, for whatever reason, you need to pass any extra parameter - such as dynamic content generated by Razor, for example, you can use the bind method. You can read more about it here, it is written just above Note 3. I'd like to note that even though it is documented in the click binding page, you can use it with submit as well (in fact, with any binding that binds to a method). Just for clarity, I'll include the relevant part here as well:
<button data-bind="click: myFunction.bind($data, 'param1', 'param2')">
Click me
</button>
So all you have to do is to specify the function to which you want to bind, and append a .bind($data, parameter1, parameter2,....) expression to it. Note that here, $data is the context; you should always include it in the .bind call. However, this will not be passed to any method parameter, it is necessary for KO to do its magic, so if you had a function like this:
function a(x,y,z)
then x would be passed param1, y would be passed param2 and z wouldn't be passed anything. If you want to force passing $data, you should include it twice in the bind call as such: .bind($data, $data, ....more params).

How Do I Access a Property of bound Object Instance with Knockout

I am unable to figure out how to get to a property of a bound item. The following does not work when the .name() is there.
<span data-bind='text: selectedMenuSection().name()'></span>
Seems you can't access a property of a bound object in the data-bind. The same syntax works in a model function, MenuViewModel.showSelection(). I've tried every conceivable syntax with no success. Below is an excerpt of my code.
Html
MenuSections: <select data-bind="options: leftMenu, optionsText: 'name', value: selectedMenuSection, optionsCaption: 'Pick...'"> </select>
Selected: <span data-bind='text: selectedMenuSection().name()'></span>
<button data-bind="click: showSelection">Show Selected Info</button>
javascript
function MenuViewModel (menu) {
var self = this;
self.leftMenu = ko.observableArray(menu);
//Bound to Select
self.selectedMenuSection = ko.observable();
self.showSelection = function(){
alert(self.selectedMenuSection().name());
};
};
Is it not possible to get to a databound object property or have I just not figured out how to do it?
Can you try the following:
<span data-bind="with: selectedMenuSection">
<span data-bind="text: name"></span>
</span>
The first line makes sure that the inner span only exists if selectedMenuSection is not null or undefined (when you create self.selectedMenuSection, its value is undefined which can cause an error while trying to access the name property). The second line is your original binding. You don't need the () at the end, because you bind against the observable (you only need () to access the current value of the observable, or if you bind against a complex statement instead of directly to an observable).
What does a MenuSection look like? I'm assuming that it has a name property that is not an observable. Hans's answer is the correct way to solve your problem. Understand the javascript object and understanding what 'context' you are in when you write your knockout html is very important.
The with binding changes the context from the root element ( the object you passed into your ko.applyBindings) to the context of the selectedMenuSection. So inside of that 'with' your context ( $data in all cases ) is a MenuSection. If you are every curious about what object is in the context you can do something like this:
<div data-bind="with: selectMenuSection">
<pre data-bind="text: ko.toJSON($data)></pre>
<span data-bind="text: name"></span>
</div>
This will print out the current object context that you are in. You will then be able to see that you have a 'name' property available to you and whatever else is attached to a MenuSection.

set a click event dynamically to dojo button

I m trying to set a on click event dynamically to a dijit/form/Button.
But, the method I m trying doesn't seem to work.
<button id = "newActButton" data-dojo-type="dijit/form/Button"
type = "button"
data-dojo-props="iconClass: 'newActButtonIcon', label: 'New Act'"></button>
dijit.byId("newActButton").set("onClick", newActButtonOnClick());
I have a function newActButtonOnClick(), which I want to fire.
You may try something like this:
require(["dojo/on", "dojo/dom", "dojo/domReady!"],
function(on, dom) {
var newActButton = dom.byId("newActButton");
on(newActButton, "click", newActButtonOnClick);
});
Here's tutorial
jsfiddle
It doesn't work because you have an error in your code (by.Id VERSUS byId):
dijit.by.Id("newActButton").set("onClick", newActButtonOnClick());
should be
dijit.byId("newActButton").set("onClick", newActButtonOnClick());
EDIT
Try this:
require(["dojo/parser", "dijit/form/Button"]);
<button data-dojo-type="dijit/form/Button" type="button">Click me too!
<script type="dojo/on" data-dojo-event="click" data-dojo-args="evt">
require(["dojo/dom"], function(dom){
dom.byId("result2").innerHTML += "Thank you! ";
});
</script>
</button>
<div id="result2"></div>

submit button can't send action with <a class [duplicate]

i want a anchor should act like and input type submit button.
i am using a jquery plugin library that actually uses input type submit but i have styled my buttons on anchors. i dont want to use
<input type="button">
or
<input type="submit">
i want to use anchors such as
<a href="javascript to submit the form" ></a>
and here is my jquery code where i want to use
{
var submit = $('<button type="submit" />');
submit.html(settings.submit);
}
$(this).append(submit);
}
if (settings.cancel) {
/* if given html string use that */
if (settings.cancel.match(/>$/)) {
var cancel = $(settings.cancel);
/* otherwise use button with given string as text */
} else {
var cancel = $('<button type="cancel" />');
how to use anchors instead of button.
If you want an anchor tag to act like a button just do this
<!--YOUR FORM-->
<form id="submit_this">.....</form>
<a id="fakeanchor" href="#"></a>
<script>
$("a#fakeanchor").click(function()
{
$("#submit_this").submit();
return false;
});
</script>
Since you're using jQuery, just use $() to select the form element, and call submit on it; hook all this up to the anchor via $() to find the anchor and click to hook up the handler:
$("selector_for_the_anchor").click(function() {
$("selector_for_the_form").submit();
return false;
});
Probably best to return false; to cancel the click on the anchor.
Off-topic: But note that this makes your page completely unusable without JavaScript, as well as making it confusing even for JavaScript-enabled browsers employed by users requiring assistive technologies (screenreaders, etc.). It makes the markup completely un-semantic. But since you'd said quite clearly that this was what you wanted to do...
<a id='anchor' href="javascript to submit the form" ></a>
now you can use jquery to add an event handler
$('#anchor').click(function (e) {
// do some work
// prevent the default anchor behaviour
e.preventDefault();
})
now you can style your anchor as you wish and it will act as a regular button
And what about:
<form id="formOne">
...
link here
</form>
you can use input of type image (it works as a submit button for a form) or in jquery:
$("a").click(function(event){
event.preventDefault();
$('form').submit();
})

Resources