checkbox in vuejs and laravel - laravel-5

I want to generate checkbox using v-for and use v-model. But i am having difficult time trying the get the value of checkbox. Here is what i am doing. My view looks like this:
<div class="checkbox" v-for="role in userRole">
<label>
<input v-model="newUser.urole" type="checkbox"
value="#{{role.roName}}">#{{role.roName}}</label>
</div>
Here is my Vue Js:
var emailRe = /^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*#([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i
var vm = new Vue({
el: '#userMgt',
data: {
newUser:{
fname: '',
mname: '',
lname: '',
email: '',
username: '',
password: '',
conpassword: '',
utype: '',
urole:''
},
},
methods: {
fetchUser: function () {
this.$http.get('../api/users', function (data) {
this.$set('users', data)
});
},
fetchUserType: function () {
this.$http.get('../api/usertype', function (data) {
this.$set('userType', data);
});
},
fetchUserRole: function () {
this.$http.get('../api/role', function (data) {
this.$set('userRole', data);
});
},
AddNewUser: function(){
//user input
var user = this.newUser;
alert(user.urole) ///not alerting right info
//clear form input
this.newUser = {fname:'',mname:'',lname:'',email:'',username:'',password:'',conpassword:'',utype:'',urole:''};
this.$http.post('../api/users', user);
;
},
selectAll: function(){
}
},
computed: {
},
ready: function () {
this.fetchUser();
this.fetchUserType();
this.fetchUserRole();
}
});
I am not able to get the selected value in newUser.urole and more over all my checkbox gets selected when i click one. How can i do this?. Thanks

Related

How to SUM cells from DataTables when checked?

I want to SUM values from cells when I check then. Like:
I´ve found how on DataTables website but it is not quite like I need.
Will be a lot of data on this table, and I want to SUM their values when the checkbox is checked, the save the total on a variable to pass to a controller.
P.S.: I forgot to say that I am using VueJS. Let´s see some code.
#section('scripts')
<script type="text/javascript"
src="https://cdn.datatables.net/v/dt/jszip-2.5.0/dt-1.10.16/af-2.2.2/b-1.5.1/b-colvis-1.5.1/b-flash-1.5.1/b-html5-1.5.1/b-print-1.5.1/cr-1.4.1/fh-3.1.3/kt-2.3.2/rg-1.0.2/rr-1.2.3/sl-1.2.5/datatables.min.js">
</script>
<script type="text/javascript" src="{{ asset('js/moment-with-locales.min.js') }}"></script>
<script>
var vue = new Vue({
el: '#app',
data: {
isLoading: false,
cliente: '{{ $contemplado->id }}',
checked : false,
nrocpfCnpj: "{!! $contemplado->cpfCnpj !!}",
porte: '{!! $contemplado->porte !!}',
natureza_juridica: '{!! $contemplado->natureza_juridica !!}',
idERP: '{!! $contrato->idERP !!}',
originalSegmento: '{!! $contrato->originalSegmento !!}',
novoSegmento: '{!! $contrato->novoSegmento !!}',
isLoading: false,
grupo: '{!! $contrato->grupo !!}',
cota: '{!! $contrato->cota !!}',
},
mounted() {
const vm = this
var tabela = $('#example').dataTable({
"language": {
'url': '//cdn.datatables.net/plug-ins/1.10.16/i18n/Portuguese-Brasil.json'
},
'scrollX': true,
'scrollY': false,
'autoWidth': true,
responsive: true,
processing: true,
"ajax": {
"url": "montaTabelaMultiCota",
"data": {
"nrocpfCnpj": vm.nrocpfCnpj
}
},
columns: [
{ data: null,
fnCreatedCell: function (nTd, sData, oData, iRow, iCol) {
$(nTd).html("<div class='form-check'><input class='form-check-input' type='checkbox' name='cota"+oData['NUMERO-COTA']+"' value='"+oData['VALOR-BEM']+"'></div>")
}
},
{ data: 'CODIGO-GRUPO'},
{ data: 'NUMERO-COTA',
fnCreatedCell: function (nTd, sData, oData, iRow, iCol) {
$(nTd).html(oData['NUMERO-COTA'])
}
},
{ data: 'DESCRICAO-BEM'},
{ data: 'VALOR-BEM',
fnCreatedCell: function (nTd, sData, oData, iRow, iCol) {
$(nTd).html("R$ "+oData['VALOR-BEM']+",00")
}
},
{ data: 'NUMERO-CONTRATO'},
{ data: 'DATA-CONTEMPLACAO',
fnCreatedCell: function (nTd, sData, oData, iRow, iCol) {
moment.locale('pt-br');
var data = oData['DATA-CONTEMPLACAO'];
let criado = moment(data, 'YYYYMMDD').fromNow();
$(nTd).html(criado);
}
},
{ data: 'DATA-ENTREGA',
fnCreatedCell: function (nTd, sData, oData, iRow, iCol) {
moment.locale('pt-br');
var data = oData['DATA-ENTREGA'];
let criado = moment(data, 'YYYYMMDD').fromNow();
$(nTd).html(criado);
}
}
]
});
// Adds the values and updates the readonly input.
function updateTotal(){
$('input#total').val($('input.selected:checked').toArray().reduce(function(last, current){
return last + parseInt($(current).attr('data-value'));
}, 0));
}
// init the total value and bind updateTotal function to the change event on the checkboxes.
function dt_init(){
updateTotal();
$('.selected').off('change').on('change', function(e) {
updateTotal();
});
}
var dt = $('#dt_container').DataTable({
// Add the checkboxes and set the values in a data-* attribute for later
rowCallback: function(row, data){
let value = parseInt($('td:eq(4)', row).html().substring(3))
// $('td:eq(4)', row).html() : 'R$ 12975.00'
// 'R$ 12975.00'.substring(3) : '12975.00'
// parseInt('12975.00') : 12975
$('td:eq(0)', row).html(`<input class="selected" type="checkbox" data-value=${value}>`)
},
// If you need to redraw your table (sort, search, page), then you need to redo some things, that's why dt_init is called upon every time.
initComplete: function(settings, json, param){
// show the footer after the DataTable is done
$(dt.table().footer()).css('display', '');
dt_init();
},
drawCallback: function(settings){
dt_init();
}
});
},
});
</script>
#endsection
Any helps?
Thanks a lot!
You can use a footer in your datatable. Just make it initially invisible and add some boilerplate to show some results.
<table id="dt_container">
<tfoot style="display: none;">
<tr>
<th>Total:</th>
<th><input id="total" type="text" name="total" value="" readonly></th>
</tr>
</tfoot>
</table>
Next, in the javascript init the DataTable but add some callbacks
// Adds the values and updates the readonly input.
function updateTotal(){
$('input#total').val($('input.selected:checked').toArray().reduce(function(last, current){
return last + parseInt($(current).attr('data-value'));
}, 0);
}
// init the total value and bind updateTotal function to the change event on the checkboxes.
function dt_init(){
updateTotal();
$('.selected').off('change').on('change', function(e){
updateTotal();
});
}
var dt = $('#dt_container').DataTable({
// Add the checkboxes and set the values in a data-* attribute for later
rowCallback: function(row, data){
let value = parseInt($('td:eq(4)', row).html().substring(3))
// $('td:eq(4)', row).html() : 'R$ 12975.00'
// 'R$ 12975.00'.substring(3) : '12975.00'
// parseInt('12975.00') : 12975
$('td:eq(0)', row).html(`<input class="selected" type="checkbox" data-value=${value}>`)
},
// If you need to redraw your table (sort, search, page), then you need to redo some things, that's why dt_init is called upon every time.
initComplete: function(settings, json, param){
// show the footer after the DataTable is done
$(dt.table().footer()).css('display', '');
dt_init();
},
drawCallback: function(settings){
dt_init();
}
});

Vue.js add class on specific element

So im creating a basic tasklist where i want to set them done, when the <li>is clicked. When it's clicked i want that a class is added to the <li> thats clicked. i could not figure this out with the docs so i hope someone could help me out :D
The code i already have:
<transition-group name="list">
<li class="list-item list-group-item" v-for="(task, index) in list" :key="task.id" v-on:click="finishTask(task.id)" >
#{{ task.text }}
<button #click="removeTask(task.id)" class="btn btn-danger btn-xs pull-right">Delete</button>
</li>
</transition-group>
</ul>
</div>
// get the csrf token from the meta
var csrf_token = $('meta[name="csrf-token"]').attr('content');
export default {
data() {
return {
list: [],
taskInput: {
id: '',
text: ''
}
};
},
// So the tasks will show when the page is loaded
created() {
this.allTasks();
},
methods: {
// get all the existing tasks
allTasks() {
axios.get('tasks').then((response) => {
this.list = response.data;
});
},
// create a new task
createTask() {
axios({
method: 'post',
url: '/tasks',
data: {
_token: csrf_token,
text: this.taskInput.text,
},
}).then(response => {
this.taskInput.text = '';
this.allTasks();
});
},
// remove the tasks
removeTask(id) {
axios.get('tasks/' + id).then((response) => {
this.allTasks();
});
},
finishTask(id) {
axios({
method: 'post',
url: 'tasks/done/' + id,
data: {
_token: csrf_token,
data: this.taskInput,
},
}).then(response => {
this.allTasks();
});
}
}
}
I know how i should do this with jquery but not with vue js, i hope this aint a to stupid question :D
You can bind css classes and styles, add a Boolean done property to your note object with default value of false, when you click the note change its done property to true. here is an example
new Vue({
el:"#app",
data:{
notes: [
{ text: "First note", done:false },
{ text: "Second note", done:false },
{ text: "Third note", done:false },
{ text: "Fourth note", done:false },
{ text: "Fifth note", done:false }
]
},
methods:{
finishNote(note){
// send your api request
// then update your note
note.done = true
}
}
})
.done{
background-color:green;
}
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.13/dist/vue.min.js"></script>
<div id="app">
<ul>
<li v-for="note in notes" :class="{done:note.done}" #click="finishNote(note)">{{note.text}}</li>
</ul>
</div>
You can use the event argument. Which is automatically provided on your on click method.
onListClicked(event) {
event.target.className += " myClass";
}
Here I did a demo for you: https://jsfiddle.net/6wpbp70g/

React Tutorial - Page Refreshing after Comments Added

I'm working through the official React tutorial and having a little trouble. When I add a comment I expect the comment to appear in the view, and for a split second it does, but then the page refreshes and the comment's gone.
On a related matter (and really just a request for a little FYI as I'm still learning AJAX), the code is supposed to add the comment to the JSON. I'm presuming that this wouldn't work on the Plunker but is there enough code there to actually update a JSON if the page is live?
Thanks for any help! Plunker link and code follows:
https://plnkr.co/edit/p76jB1W4Pizo0rDFYIwq?p=preview
<script type="text/babel">
// To get started with this tutorial running your own code, simply remove
// the script tag loading scripts/example.js and start writing code here.
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
handleCommentSubmit: function(comment) {
var comments = this.state.data;
// Optimistically set an id on the new comment. It will be replaced by an
// id generated by the server. In a production application you would likely
// not use Date.now() for this and would have a more robust system in place.
comment.id = Date.now();
var newComments = comments.concat([comment]);
this.setState({data: newComments});
$.ajax({
url: this.props.url,
dataType: 'json',
type: 'POST',
data: comment,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
this.setState({data: comments});
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
getInitialState: function() {
return {data: []};
},
componentDidMount: function() {
this.loadCommentsFromServer();
setInterval(this.loadCommentsFromServer, this.props.pollInterval);
},
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm onCommentSubmit={this.handleCommentSubmit} />
</div>
);
}
});
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function(comment) {
return (
<Comment author={comment.author} key={comment.id}>
{comment.text}
</Comment>
);
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
var CommentForm = React.createClass({
getInitialState: function() {
return {author: '', text: ''};
},
handleAuthorChange: function(e) {
this.setState({author: e.target.value});
},
handleTextChange: function(e) {
this.setState({text: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
var author = this.state.author.trim();
var text = this.state.text.trim();
if (!text || !author) {
return;
}
this.props.onCommentSubmit({author: author, text: text});
this.setState({author: '', text: ''});
},
render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input
type="text"
placeholder="Your name"
value={this.state.author}
onChange={this.handleAuthorChange}
/>
<input
type="text"
placeholder="Say something..."
value={this.state.text}
onChange={this.handleTextChange}
/>
<input type="submit" value="Post" />
</form>
);
}
});
var Comment = React.createClass({
rawMarkup: function() {
var md = new Remarkable();
var rawMarkup = md.render(this.props.children.toString());
return { __html: rawMarkup };
},
render: function() {
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
<span dangerouslySetInnerHTML={this.rawMarkup()} />
</div>
);
}
});
ReactDOM.render(
<CommentBox url="comments.json" pollInterval={2000} />,
document.getElementById('content')
);
</script>
As you said, your problem is that the information in the json file is static (see last paragraph), so every time the comments are refreshed, you lose the new one. The way you could handle it is using the json file during the first load and then just prevent refreshing them, just adding the new ones to the comment box state (after all this is just a example and you just want to see some eye candy, don't you?).
Checking the browser's console you can see that your AJAX request to store the new file is failing, you cannot update it on Plunker, that file is immutable.

Updating state with React

I am creating a blog using React, MongoDB, Express and Node. I have three components: App, List, and Item. The item is a blog post; the list is a list of the blog posts, and the app includes a place to enter text and submit it. I will eventually add more functionality, but I want to determine if I am adhering to best practices for React (I doubt I am).
So in App, I getInitialState with an array of posts (posts) and a string of text for the input (postbody). I used the componentDidMount to make an AJAX GET request to my database, so the user can see all the posts.
To handle entering text I just made a simple handleChange function which updates the state of postbody.
I also have a handleClick function, which grabs this.state.postbody and then POSTs it database. However the same function also makes a separate GET request of the database to update the state of the posts array. This doesn't seem right! Shouldn't that be handled some other way and updated automatically? * This is the primary question I have. *
Also, please let me know if I need to break the components down further, or if I am violating best practices using React (e.g. changing state in the wrong place, or using props incorrectly).
var React = require('react');
var Item = React.createClass({
render: function() {
return (
<div>
<h2>{this.props.postbody}</h2>
</div>
)
}
})
var List = React.createClass({
render: function() {
return (
<div>
{this.props.array.map(function(post) {
return (
<Item postbody={post.postbody}></Item>
)
})}
</div>
)
}
})
var App = React.createClass({
getInitialState: function() {
return {
posts: [],
postbody: ''
}
},
componentDidMount: function() {
$.ajax({
type: 'GET',
url: '/api/blogPosts',
success: function(data) {
this.setState({posts: data});
}.bind(this)
})
},
handleClick: function() {
event.preventDefault();
var blogPost = this.state.postbody;
$.ajax({
type: 'POST',
url: '/api/blogPosts',
data: { postbody: blogPost }
});
$.ajax({
type: 'GET',
url: '/api/blogPosts',
success: function(data) {
this.setState({posts: data});
}.bind(this)
})
},
handleChange: function(event) {
this.setState({ postbody: event.target.value})
},
render: function() {
return (
<div>
<form action="/api/blogPosts" method="post">
<input onChange={this.handleChange} type="text" name="postbody"></input>
<button type="button" onClick={this.handleClick}>Submit</button>
</form>
<List array={this.state.posts} />
</div>
)
}
})
Well, actually since you only have an Add api call, you could do this. You just push a blogPost to the array of posts in a post request. Also, you might want to use the form's onSubmit.
var React = require('react');
var Item = React.createClass({
render: function() {
return (
<div>
<h2>{this.props.postbody}</h2>
</div>
)
}
})
var List = React.createClass({
render: function() {
return (
<div>
{this.props.array.map(function(post) {
return (
<Item postbody={post.postbody}></Item>
)
})}
</div>
)
}
})
var App = React.createClass({
getInitialState: function() {
return {
posts: [],
postbody: ''
}
},
componentDidMount: function() {
$.ajax({
type: 'GET',
url: '/api/blogPosts',
success: function(data) {
this.setState({posts: data});
}.bind(this)
})
},
handleSubmit: function() {
event.preventDefault();
var blogPost = this.state.postbody;
$.ajax({
type: 'POST',
url: '/api/blogPosts',
data: { postbody: blogPost },
success:function(){
this.setState({posts: Object.assign([],this.state.posts.push({postbody:postbody}))});
}.bind(this)
});
},
handleChange: function(event) {
this.setState({ postbody: event.target.value})
},
render: function() {
return (
<div>
<form action="/api/blogPosts" method="post" onSubmit={this.handleSubmit}>
<input onChange={this.handleChange} type="text" name="postbody"></input>
<input type="submit" value="Submit" >Submit</button>
</form>
<List array={this.state.posts} />
</div>
)
}
})
The idea is that you maintain a store, which exists outside of the components and you manage the store through various events/actions. In this case, the app is relatively simple, so we can afford to have the "store" as a state prop and change it through the POST XHR.
However, as your app logic keeps increasing, have the posts data in a store. And have actions CRUD data into the store. And add a listener on the store to publish updates to the React component and update it, using a state variable.
Whenever something changes in the store, change the state variable from within the store using a listener(which passes data to and fro between stores,components and api calls) and your component updates. This is how Flux works. There are other ways to do this. Just a start.

Access dropdown selected value from jquery to mvc3 action

I am trying to fill auto complete textbox based on dropdown selected value,
But unable to pass selected dropdown value as parameter to autocomplete url.Action()
Here is the code which I am using..
Dictionary<string, string> searchlist = new Dictionary<string, string>();
searchlist.Add("option1", "1");
searchlist.Add("option2", "2");
searchlist.Add("option3", "3");
searchlist.Add("option4", "4");
SelectList list = new SelectList(searchlist, "value", "key");
#Html.DropDownListFor(m => m.SearchType, list, new {#id="category", #class = "select" })
<script type="text/javascript">
$(document).ready(function () {
$("#category").change(function () {
var selectedVal = $("#category option:selected").text();
alert("You selected :" + selectedVal);
});
});
</script>
<input type="text" id="searchField" name="searchField" data-autocomplete-url="#Url.Action("Autocomplete", "Home", new { lang = Model.Language, cattype = selectedVal })" class="select" value="Search" onBlur="if(this.value == '') this.value = 'Search';" onFocus="if(this.value == 'Search') this.value = '';" />
<img src="#Url.Content("~/Content/images/magnifier.png")" alt="Search" title="Search" />
Please help me where am I going wrong.
Thanks in advance.
You should fire autocomplete when DDL change:
$(document).ready(function () {
$("#category").change(function () {
var selectedVal = $("#category option:selected").text();
//fire autocomlete
$('*[data-autocomplete-url]').each(function () {
$(this).autocomplete(
{
source: function (request, response) {
$.ajax({
url: $(this).attr('data-action'),
dataType: "json",
data: { lang : '#Model.Language', cattype : selectedVal },
success: function (data) {
response($.map(data, function (item) {
return {
label: item.Label,
value: item.Label,
realValue: item.Value
};
}));
},
});
},
minLength: 2,
select: function (event, ui) {
//do something
},
change: function (event, ui) {
if (!ui.item) {
this.value = '';
} else {
}
}
});
});
});
});

Resources