I am doing a project using vuejs latest version. In this project I want to get html5 attribute associating vue on click event.
my button code is
<a href="javascript:" class="btn btn-info btn-xs" #click="editModal"
data_id="{{$staff->id}}">
<i class="fa fa-pencil"></i>
</a>
and my js is
var staffModal = new Vue({
el: '#app',
methods: {
editModal: function(){
console.log(this.data_id);
}
}});
In my console I get undefined. How to get right value.
MouseEvent instance is passed as 1st parameter to click event handler. Use getAttribute function to access attribute. MouseEvent.target will point to <i> and MouseEvent.currentTarget to <a> (element that the event listener is attached to).
Change your editModal method to:
editModal: function(e) {
console.log(e.currentTarget.getAttribute('data_id'));
}
BTW: use - (dash) not _ (underscore) to create data attributes: correct is data-id not data_id
You have some things wrong in your code.
Let's start with HTML code.
When you need to interpolate an attribute, you must use v-bind. So you have two ways to do that. Using v-bind:attribute="expression" or the shorthand :attribute="expression". Using attribute="{{ expression }}" will definitely not work.
Another important thing, to use a custom attribute name, you should use data-custom-attribute-name instead of data_custom-attribute-name.
<div id="app">
<a
href="javascript:"
class="btn btn-info btn-xs"
#click="editModal"
:data-id="staff.id"
:data-my-amazing-custom-attribute="staff.name">
Click me!
</a>
</div>
Now, let's go to JS. From your question I couldn't know where the $staff variable comes from, so I made an adaptation to demonstrate.
new Vue({
el: '#app',
methods: {
editModal: function(event){
// Here you will be able to see all the
// custom attributes in camelCase
console.log(event.target.dataset);
console.log('ID:', event.target.dataset.id);
console.log('Name:', event.target.dataset.myAmazingCustomAttribute);
}
},
data () {
return {
staff: {
id: 'some id',
name: 'Name of my amazing custom attribute'
}
}
}
});
You can check a working version here: https://jsfiddle.net/6v3wyoh6/
Hope it helps!
Getting the id from a data attribute is fine, and will work, but my question would be, why? You're using Vue, so use Vue. You can pass the id directly.
<a class="btn btn-info btn-xs" #click="editModal({{$staff->id}})">
<i class="fa fa-pencil"></i>
</a>
And your Vue code becomes
methods: {
editModal: function(id){
console.log(id);
}
}
Now you don't need to worry about figuring out what the data attribute is. That's DOM manipulation that you should generally avoid when using Vue because it is unnecessary.
Note: I'm assuming here you are using laravel or something similar such that when {{$staff->id}} is rendered it is rendered as your id.
here the link to vue docs. Exactly the right way to emit a value to an eventhandler.
<button v-on:click="$emit('enlarge-text', 0.1)">
Enlarge text
</button>
Related
I am using a package named vue-google-maps for developing an application.
I added a code snippet for adding few button inside the map but when I click on the button then it does not call any method of vue. How may I solve the problem
Here is my code
let search_result = document.createElement('div');
search_result.style.width = '300px';
search_result.style.margin = '10px';
search_result.style.fontSize = '16px';
search_result.style.backgroundColor = '';
search_result.style.cursor = 'pointer';
search_result.innerHTML = ' <button #click="test()" class="btn-primary" id="reset"><i class="fa fa-refresh" aria-hidden="true"></i> Reset </button>
<button #click="handleUndo()" class="btn-primary" id="undo"><i class="fa fa-undo" aria-hidden="true"></i> Undo </button>
<button #click="polygon_redo()" class="btn-primary" id="redo"><i class="fa fa-repeat" aria-hidden="true"></i> Redo </button> ';
this.$refs.gmap.$mapObject.controls[google.maps.ControlPosition.TOP_RIGHT].push(search_result);
drawingManager.setMap(this.$refs.gmap.$mapObject)
Problem: When I click on the undo, redo, reset button then it does not call any method's of vue js.
I need suggestion, how may I add button or any pop up inside the google map who can interact with vue instance properties or methods, it would be two way data binding
Thanks
In Vue, you should never add markup by createElement method (or in any other way directly from script). Generally, markup should be in your <template>. The markup you created is not reactive or accessible by Vue, because it was added outside of the component initialization scope.
Check out Vuejs docs for more detail: https://v2.vuejs.org/v2/guide/syntax.html
To solve you problem in a valid "Vue way", you need to show more content, preferably a full component.
I have my simple Phonegap app, which is based on tabbed layout. On one of these tabs I have list of tags (more than one). All of these have buttons to edit and delete. Its like this:
<div class="tag-buttons" uid="TAG_ID">
<button class="edit-tag btn btn-default btn-sm">Edit</button>
<button id="aaa" class="remove-tag btn btn-danger btn-sm" onclick="removeTag()">Remove</button>
</div>
Now I want do handle this removeTag() function. So I have in my JS file this function:
function removeTag()
{
//controller.removeTag($(this).parent().attr("uid"));
console.log($(this));
}
Console.log and commented line are only samples. I want to know which button was clicked (I need uid value). All of buttons have this same class. $(this) is returning Window object.
Any ideas?
I had made stupid error. Now everything is working.
I had to change onclick="removeTag()" to onclick="removeTag(this)" and then in JS function was quite good. I changed function declaration to use additional argument like this:
function removeTag(button)
{
var id = $(button).parent().parent().attr("uid");
controller.popTag(id);
}
I'm trying to select this button using protractor:
<button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 0)">
<i class="glyphicon glyphicon-chevron-up">
</i>
</button>
the only unique element in this is ng-click="$arrowAction(-1, 0)"
Nothing I have tried works:
element(by.css("//button[#ng-click='$arrowAction(-1, 0)']")).click();
//button[#ng-click='$arrowAction(-1, 0)'] is not a valid CSS selector. It actually looks like this is an XPath expression and you meant to use by.xpath() locator.
You can though use the partial attribute check instead:
$("button[ng-click*=arrowAction]").click();
$ here is a shortcut to element(by.css(...)), *= means "contains".
Or, do an exact match:
$("button[ng-click='$arrowAction(-1, 0)']").click();
I still don't like the location technique used in this case, but, given what we have, it is probably the best we can do. Ideally, if you have control over the application code and templates, add a meaningful id, class or a custom data attribute to uniquely identify the element.
I can't get the enable binding to work in Knockout JS. With the enabled property set to false, the button is not disabled and I can still click it.
see fiddle
<a class="btn btn-xl btn-primary"
href="#"
role="button"
data-bind="enable: enabled, click: clicked, visible: isVisible">
<i class="icon-only icon-ok bigger-130"></i>
</a>
var ViewModel = function(){
var self = this;
self.enabled = ko.observable(false);
self.isVisible = ko.observable(true);
self.clicked = function(){
alert('You clicked the button');
};
};
$(function(){
var model = new ViewModel();
ko.applyBindings(model);
})
Enable binding does not work with anything you want.
This is useful with form elements like input, select, and textarea
It also works with buttons. Like in my example http://jsfiddle.net/5CbnH/1/
But it does not work with your link. You are using twitter bootstrap and they enable/disable their "buttons" with css classes. So you have to use css binding like this:
data-bind="css: { yourClass: enabled }"
Check what class is responsible in bootstrap for showing your "button" and modify your code accordingly with css binding.
Right:
✅ enable✅ disable
Wrong:
❌ enabled❌ disabled
Make sure you use disable instead of disabled and enable instead of enabled.
<input type="text" data-bind="value: foo, enable: isEditing"/> YES!!
<input type="text" data-bind="value: foo, enabled: isEditing"/> NO!
Easy mistake to make :-)
For people who might find this in a search:
I had a problem getting the enable binding to work as well. My problem was trying to use a complex expression without referencing the observables like functions:
<input type="button" data-bind="enable:AreAllStepsVerified && IsFormEnabled, click:SubmitViewModel"/>
Should have been:
<input type="button" data-bind="enable:AreAllStepsVerified() && IsFormEnabled(), click:SubmitViewModel"/>
See: https://stackoverflow.com/a/15307588/4230970
What Salvador said in his answer.
You must understand that the enabled and disabled binding in knockout work by putting a disabled attribute on the target DOM element. Now if you look at the HTML documentation you'd notice that not all HTML element support this attribute.
Actually only form elements (e.g. <button>) do. <a> does not.
I got it to work by changing the anchor tag to a button, not really sure why this makes it work, but it works nonetheless.
Updated fiddle.
<button class="btn btn-xl btn-primary"
role="button"
data-bind="enable: enabled, click: clicked, visible: isVisible">
<i class="icon-only icon-ok bigger-130"></i>
</button>
I am using the following way to use $scope variable ({{func}}() in this case) as function name in ng-click.
<button type="button" ng-click="{{func}}()">Call {{func}}</button></pre>
This works in angularjs-1.2.0rc3. See working plunkr here
Any future version from > 1.2.0rc3 throw this error
What's changed? How can I use the above syntax in current angular version?
Ok first of all I do not recommend such a usage for ng-click because angularjs itself do not support this, but if you still want to use it such a way here is your solution...
<button type="button" ng-click="$eval(functionName)()">...</button>
where
$scope.f1 = function() {
...
};
//name of function as a string
$scope.functionName = "f1";
this is what your are looking for and here is your PLUNKER example...
All I did was append scope to both variables
<form name="angular" ng-controller="Ctrl">
<button type="button" ng-click="{{scope.func}}()">
Call {{func}}
</button>
<label>Status: {{scope.status}}</label>
http://jsfiddle.net/bebold/TmKLY/1/
I wouldn't advise going this route for dynamic variable change, a better choice would be to create a directive and do the binding within the template:
A great explanation can be found HERE.