How to get all checkbox props with React + ASP.net mvc - asp.net

I am learning React and ASP.net( not core).
I try to create a small project for practice.
I have a number of checkboxes and a submit button.
The idea is when I click on the button I want to create a Jason that will contain a list of the checkboxes text and their states (check \uncheck).
That Jason I want to send to the server.
I mange to create the components and the relevant events.
But fail to create the following
1) Get the state of the checkbox from the submit component and create a Jason out of it.
2) Send that Jason to the server side (ASP.net).
I try to flow the tutorial but didn’t get it, I tried to find solution on the internet but with no lack.
If someone can show me how to do it – or give me some direction that will help
Thanks
the jsk:
var data = [
{ Id: 1, ActionItem: "Action1" },
{ Id: 2, ActionItem: "Action2" },
{ Id: 3, ActionItem: "Action3" }
];
var Checkbox = React.createClass({
getInitialState: function() {
return {
isChecked: false
};
},
toggleChange: function() {
this.setState({
isChecked: !this.state.isChecked
},
function() {
console.log(this.state);
}.bind(this));
},
render: function() {
return (
<label>
<input type="checkbox"
checked={this.state.isChecked}
onChange={this.toggleChange} />{this.props.chkboxlabel}<br />
</label>
);
}
});
var ActionBox = React.createClass({
render: function() {
return (
<div className="actionBox">
<h1>Select Action </h1>
<CheckboxList data={this.props.data} />
<SubmitForm/>
</div>
);
}
});
var CheckboxList = React.createClass({
render: function() {
var actionNodes = this.props.data.map(function(action) {
return (
<Checkbox chkboxlabel={action.ActionItem} key={action.id}>
{action.ActionItem}
</Checkbox>
);
});
return (
<form className="actionList">{actionNodes}
</form>
);
}
});
var SubmitForm = React.createClass({
handleSubmit: function(e) {
//??
},
render: function() {
return (
<form className="actionForm" onSubmit={this.handleSubmit}>
<input type="submit" value="Run" />
</form>
);
}
});
ReactDOM.render(
<ActionBox data={data} />,
document.getElementById('content')
);

I found a solution that works I don’t think it’s the best way but maybe it will help other.
I loop thought the element to get the value- I believe there is a better way of doing it with react.
var data = [
{ Label: "Action 1", IsChecked: false, Name: "a1" },
{ Label: "Action 2", IsChecked: false, Name: "a2" },
{ Label: "Action 3", IsChecked: false, Name: "a3" }
];
handleCommentSubmit: function () {
var data = new FormData();
var inputs = document.getElementsByName('mycheckbox');
for (var i = 0; i < inputs.length; i++) {
var name = inputs.item(i).value;
var ischecked = inputs.item(i).checked;
data.append(name, ischecked);
}
var xhr = new XMLHttpRequest();
xhr.open('post', this.props.submitUrl, true);
xhr.send(data);
},

Related

WordPress with select2 and Toastr get previous selected value destroys select2 behavior

I am using WordPress and I have used Select2 and Toastr libraries successfully.
Basically I have a dropdown and if I change, Toastr will ask whether I need to update or not.
If I click on "Yes" then it will update and if I click on "No" then my dropdown should set previous value and nothing will happen.
Currently its selecting previous value but then if I open the same dropdown try to click on it to search then its saying "The results could not be loaded".
Here is my JS code what I have done so far.
var prevSubVarClientId;
jQuery('.mySubscription').select2({
allowClear: true,
placeholder: "",
//minimumInputLength: 3,
ajax: {
type: "POST",
url: '/wp-admin/admin-ajax.php',
dataType: 'json',
delay: 250, // delay in ms while typing when to perform a AJAX search
data: function (params, page) {
return {
action: 'list_posts',
q: params.term,
};
},
processResults: function( data ) {
var options = [];
if ( data ) {
jQuery.each( data, function( index, text ) {
options.push( { id: text['id'], text: text['name'] } );
});
}
return {
results: options
};
},
cache: true
}
});
jQuery('.mySubscription').on('select2:selecting', function (evt) {
prevSubVarClientId = jQuery('select').val();
});
jQuery('.mySubscription').change(function() {
var $this = jQuery(this);
jQuery(this).blur();
alertify.confirm("Are you sure you want to transfer?",
function(e){
var subscriptionId = jQuery($this).data("subscription-id");
var url = jQuery($this).data("ajax-url");
var userId = jQuery($this).val();
jQuery.ajax({
type: "POST",
url: url,
data : {
action : 'update_var_client_user_id',
userId : userId,
subscriptionId : subscriptionId
},
success: function(data)
{
var data = JSON.parse(data);
toastr["success"]("Transferred Successfully." );
}
});
},
function(){
jQuery($this).val(prevSubVarClientId);
jQuery($this).select2().trigger('change');
}).set({title:"Alert!!!"}).set({ labels:{ok:'Yes', cancel: 'No'} });
});
As you can see I have prevSubVarClientId variable and mySubscription dropdown with this class.
jQuery('.mySubscription').change(function() { here you can see I am opening alertify confirm box and if I click on "No" then I am doing below code.
jQuery($this).val(prevSubVarClientId);
jQuery($this).select2().trigger('change');
But then whenever I am trying to open the dropdown again, I am getting the below error.
Can some one guide me, what I am doing wrong here ?
Thanks
"The results could not be loaded". only show when return data is null or not found.
I tested your code below snippet and working fine.
$(".js-data-example-ajax").select2();
jQuery('.js-data-example-ajax').on('select2:selecting', function (evt) {
prevSubVarClientId = jQuery('select').val();
});
jQuery('.js-data-example-ajax').change(function() {
var $this = jQuery(this);
jQuery(this).blur();
alertify.confirm("Are you sure you want to transfer?",
function(e){
console.log('change');
},function(){
console.log('no change');
jQuery($this).val(prevSubVarClientId);
jQuery($this).select2().trigger('change');
}).set({title:"Alert!!!"}).set({ labels:{ok:'Yes', cancel: 'No'} });
});
.select2-container, .select2-container--open .select2-dropdown--below {
width: 200px !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/AlertifyJS/1.13.1/css/alertify.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/AlertifyJS/1.13.1/alertify.min.js"></script>
<select class="js-data-example-ajax">
<option value="abc">ABC</option>
<option value="bca" selected>BCA</option>
<option value="mnp">MNP</option>
<option value="pqr">PQR</option>
</select>

Vue-Full-Calendar refetch-events error

I am having issues refreshing events when I add a new one. The event gets inserted into the database fine, but the call to
this.$refs.calendar.$emit('refetch-events')
Throws the following error:
[Vue warn]: Error in event handler for "refetch-events": "TypeError: $(...).fullCalendar is not a function"
Here is some more of the code to further demonstrate what I am trying to do:
<template>
<div>
<full-calendar ref="calendar" :event-sources="eventSources" #day-click="daySelected" #event-selected="eventSelected" :config="config"></full-calendar>
<!-- Modal Component -->
<b-modal ref="my_modal" title="New Appointment" #ok="submit" #shown="clearModalValues">
<form #submit.stop.prevent="submit">
<label>Client:</label>
<b-form-select v-model="selectedClient" :options="clientOptions" class='mb-3'></b-form-select>
<label>Service:</label>
<b-form-select multiple v-model="selectedService" :options="serviceOptions" class='mb-3'></b-form-select>
<label>Start time:</label>
<time-picker v-model="myTime"></time-picker>
<label>Notes:</label>
<b-form-input textarea v-model="notes" placeholder="Notes"></b-form-input>
</form>
</b-modal>
<!-- /Modal Component -->
</div>
</template>
<script>
export default {
props: {
staff:{
type: Number,
required: true
},
},
data() {
return {
myTime: new Date(),
selectedService: [null],
selectedClient: null,
selectedStartTime: new Date(),
notes: null,
serviceOptions: [],
clientOptions: [],
events: [],
config: {
timeFormat: 'h(:mm)',
eventClick: (event) => {
console.log('Event Clicked: '+event.title);
},
},
selected: {},
};
},
computed: {
eventSources() {
return [
{
events(start, end, timezone, callback) {
axios.get('/getEvents').then(response => {
callback(response.data)
})
}
}
]
}
},
mounted() {
this.myTime = new Date()
axios.get('/getClients').then(response => this.clientOptions = response.data);
axios.get('/getServices').then(response => this.serviceOptions = response.data);
},
methods: {
clearModalValues() {
this.selectedService = [null];
this.selectedClient = null;
this.selectedStartTime = new Date();
this.myTime = new Date();
this.notes = null;
},
submit(e) {
axios.post('/addEvent/',{'selectedService':this.selectedService,'selectedClient':this.selectedClient,'selectedStartTime':this.selectedStartTime,'notes':this.notes}).then(function(response){
//console.log(response.data);
new PNotify({
title: 'Success',
text: 'New event has been created',
icon: 'icon-checkmark3',
type: 'success'
});
this.selectedService = [null];
this.selectedClient = null;
this.selectedStartTime = new Date();
this.notes = null;
this.myTime = new Date();
// ******** I HAVE TRIED THESE CALLS AS PER DOCUMENTATION **********
//this.$refs.calendar.fireMethod('refetch-events')
//this.$refs.calendar.fullCalendar.$emit('refetch-events');
//this.$refs.calendar.$emit('refetch-events');
console.log(this.$refs.calendar);
}.bind(this));
},
eventSelected(event) {
console.log('Event Selected: '+event.title);
},
daySelected(date,event,view){
this.$refs.my_modal.show();
this.selectedStartTime = date.format("YYYY-MM-DD HH:mm:ss");
this.myTime = date.toDate();
},
},
};
</script>
According to the documentation it should be correct. I know its late and I have been at this for a couple hours so I might be overlooking something simple. Again this is vue-full-calendar and not regular full-calendar. I just need to call refetchEvents when I add the new events in the submit method. Thanks!
I have found the issue, thanks to Brock for the help. I had multiple versions of jquery running(the html template I was using was also calling it).

display:none is not freeing up the space in firefox

I am using react.js for displaying some data. I have more than one divs one below other. and each div contain graph, created from chart.js. I have one button in every div to display or hide that particular chart. It is working nicely. But when I hide that graph, my firefox is still not freeing up the space which was taken by chart when it was getting displayed. Like when I am hiding my chart, the space is getting created between two divs. The code is working properly in Microsoft Edge browser.
Here is my code:
var Div= React.createClass({
getInitialState: function () {
return {
displayChart: false
};
},
chartClick: function () {
this.setState({
displayChart: !this.state.displayChart,
});
},
render: function() {
return (
<div>
<p className="text-justify">
{ this.props.detail }
</p>
<button type="button" className="btn btn-link" onClick={ this.chartClick }>Chart</button>
{ this.state.displayChart ?
<ChartGraph id={this.props.id} />
: null }
</div>
);
}
});
Chart Component is :
ChartGraph = React.createClass({
onLoad: function () {
var barChartData = {
labels: [ option1, option2 ],
datasets: [
{
data: [451, 145],
fillColor: "rgba(46,145,202,0.8)",
strokeColor: "rgba(46,145,202,0.8)",
highlightFill: "rgba(46,145,202,1)",
highlightStroke: "rgba(46,145,202,1)"
}
]
};
var ctx = document.getElementById("canvas_poll"+this.props.id).getContext("2d")
new Chart(ctx).HorizontalBar(barChartData, {
scaleGridLineWidth: 1,
scaleShowGridLines: false,
scaleStartValue : 0
});
},
componentDidMount: function() {
this.onLoad();
},
render: function () {
return (
<div className="red">
<canvas id={"canvas_poll"+this.props.id} height="100" width="400"></canvas>
</div>
);
}
});
Any help for this problem?
Thank you..
This should work.
var Div= React.createClass({
getInitialState: function () {
return {
displayChart: false
};
},
chartClick: function () {
this.setState({
displayChart: !this.state.displayChart,
});
},
render: function() {
var hideChart = this.state.displayChart ? false : true;
return (
<div>
<p className="text-justify">
{ this.props.detail }
</p>
<button type="button" className="btn btn-link" onClick={ this.chartClick }>Chart</button>
<ChartGraph id={this.props.id} hide={hideChart} />
</div>
);
}
});
and
ChartGraph = React.createClass({
onLoad: function () {
var barChartData = {
labels: [ option1, option2 ],
datasets: [
{
data: [451, 145],
fillColor: "rgba(46,145,202,0.8)",
strokeColor: "rgba(46,145,202,0.8)",
highlightFill: "rgba(46,145,202,1)",
highlightStroke: "rgba(46,145,202,1)"
}
]
};
var ctx = document.getElementById("canvas_poll"+this.props.id).getContext("2d")
new Chart(ctx).HorizontalBar(barChartData, {
scaleGridLineWidth: 1,
scaleShowGridLines: false,
scaleStartValue : 0
});
},
componentDidMount: function() {
this.onLoad();
},
render: function () {
if (this.props.hide) return null;
return (
<div className="red">
<canvas id={"canvas_poll"+this.props.id} height="100" width="400"></canvas>
</div>
);
}
});

Update function returns an error

This code returns an "Error: $scope.todoItems.update is not a function"
(in markDone function)
As I can see in console, $scope.todoItems has functions like save(), remove() but not an update() function, but as I can see here I writing it right.
Is something that I doing is wrong? More information would be helpful?
TodoItems = new Mongo.Collection('todoItems');
if(Meteor.isClient){
angular.module('todo_am', ['angular-meteor']);
angular.module('todo_am').controller('OutputListCtrl', ['$scope', '$meteor',
function($scope, $meteor){
$scope.todoItems = $meteor.collection(TodoItems);
$scope.remove = function(todoItem){
$scope.todoItems.remove(todoItem);
};
$scope.saveCustom = function(todoItem){
todoItem.isRead = false;
$scope.todoItems.save(todoItem);
};
$scope.markDone = function(todoItem){
console.log('>>> 4', todoItem);
console.log('>>> 5', $scope.todoItems);
$scope.todoItems.update(todoItem._id, { $set: { isRead: true }}); // <<<<<<<<< This line returns error
};
$scope.markUndone = function(todoItem){
todoItem.isRead = true;
$scope.todoItems.update(todoItem);
};
}]);
}
------------------------------ UPDATE --------------------------------
This is working:
if(Meteor.isClient){
angular.module('todo_am', ['angular-meteor']);
angular.module('todo_am').controller('OutputListCtrl', ['$scope', '$meteor',
function($scope, $meteor){
$scope.todoItems = $meteor.collection(TodoItems);
$scope.remove = function(todoItem){
$scope.todoItems.remove(todoItem);
};
$scope.saveCustom = function(todoItem){
todoItem.isRead = false;
$scope.todoItems.save(todoItem);
};
$scope.markDone = function(todoItem){
TodoItems.update({ _id: todoItem._id }, { $set: { isRead: true }});
};
$scope.markUndone = function(todoItem){
TodoItems.update({ _id: todoItem._id }, { $set: { isRead: false }});
};
}]);
}
------------------------------ UPDATE2 --------------------------------
This is whole code. I do not know if it's a right solution or not but it works.
Is there any example for update exists record in DB?
$ meteor --version
Meteor 1.1.0.2
As I can see in .meteor/versions file:
angular:angular#1.3.15_1
urigo:angular#0.8.6
index.html
<body ng-app="todo_am">
<div ng-controller="OutputListCtrl">
<div ng-include="'output-list.ng.html'"></div>
<div ng-include="'insert-new-form.ng.html'"></div>
</div>
</body>
index.ng.html
<p>Nothing</p>
insert-new-form.ng.html
<div>
<input type="text" ng-model="newTodoItem.text" />
<button ng-click="saveCustom(newTodoItem); newTodoItem='';" >Add New</button>
</div>
output-list.ng.html
<div>
<ul>
<li ng-repeat="todoItem in todoItems">
<p>
{{ todoItem.text }}
<span ng-switch on="todoItem.isRead">
<span ng-switch-when="true">
<button ng-click="markUndone(todoItem)">Mark Undone</button>
</span>
<span ng-switch-default>
<button ng-click="markDone(todoItem)">Mark Done</button>
</span>
</span>
<button ng-click="remove(todoItem)">X</button>
</p>
</li>
</ul>
</div>
app.js
TodoItems = new Mongo.Collection('todoItems');
if(Meteor.isClient){
angular.module('todo_am', ['angular-meteor']);
angular.module('todo_am').controller('OutputListCtrl', ['$scope', '$meteor',
function($scope, $meteor){
$scope.todoItems = $meteor.collection(TodoItems);
$scope.remove = function(todoItem){
$scope.todoItems.remove(todoItem);
};
$scope.saveCustom = function(todoItem){
todoItem.isRead = false;
$scope.todoItems.save(todoItem);
};
$scope.markDone = function(todoItem){
TodoItems.update({ _id: todoItem._id }, { $set: { isRead: true }});
};
$scope.markUndone = function(todoItem){
TodoItems.update({ _id: todoItem._id }, { $set: { isRead: false }});
};
}]);
}
if(Meteor.isServer){
Meteor.startup(function(){
/**
* If DB is empty, add some todoItems just for DEV purposes
*/
if (TodoItems.find().count() === 0) {
var todoItems = [
{
'text': 'First todo first todo first todo first todo first todo first todo first todo first todo first todo',
'isRead': true,
'userPosted': 'Vasia'
},
{
'text': 'Second todo item',
'isRead': false,
'userPosted': 'Fedia'
},
{
'text': 'Third todo item',
'isRead': true,
'userPosted': 'Vasia'
}
];
for (var i = 0; i < todoItems.length; i++)
TodoItems.insert({text: todoItems[i].text, isRead: todoItems[i].isRead});
}
});
}
That doesn't look like $scope.todoItems is a Meteor collection. If you look through the documentation you linked (http://docs.meteor.com/#/full/mongo_collection) - there's no reference to Meteor's Mongo Collections having a "save" method.
It looks like you're using an "Angular Meteor Collection" - http://angularjs.meteor.com/api/AngularMeteorCollection
In which case a simple call to ".save" should do it. Perhaps something like this:
$scope.markDone = function(todoItem){
todoItem.isRead = true;
$scope.todoItems.save(todoItem);
};

Meteor.js calling a template.helpers function vs global variable

I am using Reactive-table to display paginated data in my meteor.js app as shown below, yet data displayed in Reactive-table is dependent on on specific user event (Selecting client, project, date range and clicking on the submit button). So I was wondering if it is possible to trigger template.helpers >> myCollection function from the 'submit form' event? OR is it better to define a global variable to store data returned from user query based on the user (client, project, date range selection) then make this global variable the return from the myCollection function?
I have tried researching how to call .helpers function from an template.events event but couldn't find any information. So any help on which approach is better and if calling the .events function is better then how to do that, will be highly appreciated. Thanks.
Below is the code I have in my app:
Template.detailedreport.rendered = function() {
Session.set("dreport_customer", "");
Session.set("dreport_project", "");
Session.set("dreport_startDate", new Date());
Session.set("dreport_endDate", new Date());
$('.set-start-date').datetimepicker({
pickTime: false,
defaultDate: new Date()
});
$('.set-end-date').datetimepicker({
pickTime: false,
defaultDate: new Date()
});
$('.set-start-date').on("dp.change",function (e) {
Session.set("dreport_startDate", $('.set-start-date').data('DateTimePicker').getDate().toLocaleString());
});
$('.set-end-date').on("dp.change",function (e) {
Session.set("dreport_endDate", $('.set-end-date').data('DateTimePicker').getDate().toLocaleString());
});
};
Template.detailedreport.helpers({
customerslist: function() {
return Customers.find({}, {sort:{name: -1}});
},
projectslist: function() {
return Projects.find({customerid: Session.get("dreport_customer")}, {sort:{title: -1}});
},
myCollection: function () {
var now = Session.get("dreport_startDate");
var then = Session.get("dreport_endDate");
var custID = Session.get("dreport_customer");
var projID = Session.get("dreport_project");
Meteor.call('logSummary', now, then, projID, custID, function(error, data){
if(error)
return alert(error.reason);
return data;
});
}
},
settings: function () {
return {
rowsPerPage: 10,
showFilter: true,
showColumnToggles: false,
fields: [
{ key: '0._id.day', label: 'Day' },
{ key: '0.totalhours', label: 'Hours Spent'}
]
};
}
});
Template.detailedreport.events({
'submit form': function(e) {
e.preventDefault();
var now = $('.set-start-date').data('DateTimePicker').getDate().toLocaleString();
var then = $('.set-end-date').data('DateTimePicker').getDate().toLocaleString();
var custID = $(e.target).find('[name=customer]').val();
var projID = $(e.target).find('[name=project]').val();
//Here is the problem as I am not sure how to refresh myCollection function in .helpers
},
'change #customer': function(e){
Session.set("dreport_project", "");
Session.set("dreport_customer", e.currentTarget.value);
},
'change #project': function(e){
Session.set("dreport_project", e.currentTarget.value);
}
});
Template:
<div>
{{> reactiveTable class="table table-bordered table-hover" collection=myCollection settings=settings}}
</div>
Server:
Meteor.methods({
logSummary: function(startDate, endDate, projid, custid){
//Left without filtering based on date, proj, cust for testing only...
return Storylog.find({});
}
});
Template helpers are reactive, meaning that they will be recomputed if their dependencies change. So all you need to do is update their dependencies and then the myCollection helper will be recomputed.
Replace your comment // Here is the problem... with:
Session.set('dreport_endDate', then);
Session.set('dreport_startDate', now);
Session.set('dreport_project', projID);
Session.set('dreport_customer', custID);

Resources