How to convert csv to array - javascript

I am trying to convert csv to array on angular 1.5+ionic on hebrew.
I am using ng-csv.
What I done till now:
Html:
<ng-csv-import
class="import"
content="csv.content"
header="csv.header"
header-visible="csv.headerVisible"
separator="csv.separator"
separator-visible="csv.separatorVisible"
result="csv.result"
encoding="csv.encoding"
encoding-visible="csv.encodingVisible"></ng-csv-import>
my controller is :
.controller('SettingsCtrl', function ($scope,$parse) {
$scope.csv = {
content: null,
header: true,
headerVisible: true,
separator: ',',
separatorVisible: true,
result: null,
encoding: 'Windows-1255',
encodingVisible: true
};
what else should be done to get the object as array.

Modify the code in your controller as
$scope.csv = {
content: null,
header: true,
headerVisible: true,
separator: ',',
separatorVisible: true,
result: null,
encoding: 'ISO-8859-1',
encodingVisible: true,
accept:".csv"
};
and your in your html
<ng-csv-import content="csv.content"
header="csv.header"
separator="csv.separator"
result="csv.result"
accept="csv.accept">
</ng-csv-import>
$scope.csv.result will now be an array of objects

$scope.csv.result will contain the result array from conversion. After the user selects a CSV file from the browse button, it will be populated. So, if you just wanted to do a data dump to the screen:
<div ng-if="csv.content">
{{csv.content}}
</div>
Chances are good you want to do more than that when it gets populated, so you can set up a watch on it
// (in controller)
$scope.$watch(
function() { return $scope.csv.content; },
function(newValue, oldValue) {
// do something on change
}
);

Related

how to solve Trying to get property 'bids' of non-object error

I want to display data from bid table in a form of datatable. But I get this error
"Trying to get property 'bids' of non-object" if it doesn't have bids.The bids model is connected to auction model and the auction model is connected to media site model. How to make it display blank record if it doesn't have data.
Here is my controller:
<?php
namespace App\Http\Controllers;
use App\Auction;
use App\Bid;
use App\User;
use App\Media;
use App\MediaSite;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class MediaSiteController extends Controller
{
public function show(MediaSite $mediaSite)
{
$auction = $mediaSite->auction;
$bids = $auction->bids;
return view('admin.media-site.show', ['mediaSite' => $mediaSite,'auction' => $auction], compact('auction'));
}
My view:
<body>
<div id="datatable-bid"></div>
</body>
<script>
$(document).ready(function () {
var datatableBid = $('#datatable-bid').mDatatable({
// datasource definition
data: {
type: 'local',
source: {!! json_encode($auction->bids) !!},
pageSize: 10
},
// layout definition
layout: {
theme: 'default', // datatable theme
class: '', // custom wrapper class
scroll: false,
footer: false // display/hide footer
},
// column sorting
sortable: true,
pagination: true,
search: {
input: $('#panel-search')
},
// columns definition
columns: [
{
field: "price",
title: "Price",
}, {
field: "month",
title: "Month",
},{
field: "user_id",
title: "User Id",
}
]
});
</script>
Here is my error:
Trying to get property 'bids' of non-object
place following after $auction = $mediaSite->auction;
if($auction){
$bids = $auction->bids;
}else{
//put following line or whatever you need to do if there is no data comes
$auction = [];
}
In the show() function make these changes
$auction = $mediaSite->auction;
if($auction) {
$bids = $auction->bids;
} else {
$bids = [];
}
// now send $bids to view along with $auction
// may be like this
// return view(..., compact($auction, $bids));
Then, in your view make this change
// datasource definition
data: {
type: 'local',
source: {!! json_encode($bids) !!},
pageSize: 10
},
See if this helps.

Knockout Validation on Nested View Model

I am looking to use a combination of the KnockoutJS libarary, the Knockout.Mapping plugin, and the Knockout-Validation plugin to display some data that the user can manipulate.
My data is coming over as a nested object from an AJAX call, and I run that data through the mapping plugin to create a Knockout view model, customizing the validation rules with the mapping options object in ko.mapping.fromJS.
I have been successful in getting objects at the first layer (name in the Fiddle below) to show a message if the field is empty, however objects that are nested (IntroData.PlanName) do not show the validation message. Do I need to setup the mapping object differently for these nested objects?
ViewModel (sample of what is coming in my AJAX call):
var stuff = {
IntroData: {
PlanName: 'Test'
},
name: 'tes2s3t'
};
Mapping:
var validationMapping = {
IntroData: {
PlanName: {
create: function (options) {
return ko.observable(options.data).extend({
required: true
});
}
}
},
name: {
create: function (options) {
return ko.observable(options.data).extend({
required: true
});
}
}
};
Hookup:
ko.validation.init({
registerExtenders: true,
messagesOnModified: true,
insertMessages: true,
parseInputAttributes: true,
messageTemplate: null,
grouping: {
deep: true
}
}, true);
window.viewModel = ko.validatedObservable(ko.mapping.fromJS(stuff, validationMapping));
ko.applyBindings(window.viewModel);
Fiddle: http://jsfiddle.net/odxv53g9/5/
Thanks!
The documentation is not clear on this, but apparently ko.mapping.fromJS() ignores nested mappings, so the "create" method for PlanName never gets called.
You could add an explicit mapping for IntroData instead:
IntroData: {
create: function (options) {
var nestedMapping = {
PlanName: {
create: function (options) {
return ko.observable(options.data).extend({
required: true
});
}
}
}
return ko.mapping.fromJS(options.data, nestedMapping);
}
}
Here is a working fiddle: http://jsfiddle.net/odxv53g9/6/

Controls in Angular break when configuration options come from service

I have a service that will return my some config options for an ng-grid. The getGridOptions function takes the name of the controller it's used on and returns the correct set of options (only one shown here for brevity).
service for ng-grid options:
angular.module('services').service('GridOptionsService',function(){
var documents = {
data: 'myData',
enablePaging: true,
showFooter:true,
totalServerItems: 'totalServerItems',
pagingOptions: {
pageSizes: [50,100,200],
pageSize: 50,
currentPage: 1
},
filterOptions: {
filterText: '',
useExternalFilter: false
},
enableCellEdit: false,
enableColumnReordering: true,
enablePinning: false,
showGroupPanel: false,
groupsCollapsedByDefault: true,
enableColumnResize: true,
showSelectionCheckbox: true,
selectWithCheckboxOnly: true,
columnDefs: [
{field:'docId', displayName:'Document ID', cellTemplate: NgGridDomUtil.toLink('#/documents/{{row.getProperty(col.field)}}')},
{field:'docTags', displayName:'Tags'},
{field:'lastSaveDate', displayName:'Last saved'},
{field:'documentVersion', displayName:'Version', width: 120},
{field:'busDocId', displayName:'Customer Doc ID'},
{field:'markedForDelete', displayName:'Deleted', width: 120, cellTemplate: NgGridDomUtil.toCheckbox('{{row.getProperty(col.field)}}')}]
};
var gridOptionManager = {
documents: documents
}
return {
getGridOptions: function(controllerName){
return gridOptionManager[controllerName];
}
}
})
The NgGridDomUtil class just makes it easier to style things on the grid:
var NgGridDomUtil = (function(){
var toLink = function(href){
var html = '<div class="ngCellText" ng-class="col.colIndex()"><a ng-href= "'+href+'" class="ngCellLink"><span ng-cell-text>{{row.getProperty(col.field)}}</span></a></div>'
return html;
}
var toCheckbox = function(_selected){
var html = '<div class="ngCellText" ng-class="col.colIndex()"><input type="checkbox" ng-change="console.log('+"TEST"+')" ng-model="COL_FIELD" ng-input="COL_FIELD"' + (_selected ? 'selected' : '') + ' /></div>'
return html
}
return {
toLink: toLink,
toCheckbox: toCheckbox
}
})();
My problem is what when I use the GridOptionsService to retrieve the data, the data is still presented to the grid correctly, but the text filtering no longer works and the paging is broken. However, the selectedFilterOption still works.
controller:
angular.module('controllers').controller('Repository', ['$scope', 'DataContext','GridOptionsService','$http', function($scope, DataContext,GridOptionsService,$http) {
$scope.filterOptions = {
filterText: '',
useExternalFilter: false
};
$scope.totalServerItems =0;
$scope.pagingOptions ={
pageSizes: [5,10,100],
pageSize: 5,
currentPage: 1
}
//filter!
$scope.dropdownOptions = [{
name: 'Show all'
},{
name: 'Show active'
},{
name: 'Show trash'
}];
//default choice for filtering is 'show active'
$scope.selectedFilterOption = $scope.dropdownOptions[1];
//three stage bool filter
$scope.customFilter = function(data){
var tempData = [];
angular.forEach(data,function(item){
if($scope.selectedFilterOption.name === 'Show all'){
tempData.push(item);
}
else if($scope.selectedFilterOption.name ==='Show active' && !item.markedForDelete){
tempData.push(item);
}
else if($scope.selectedFilterOption.name ==='Show trash' && item.markedForDelete){
tempData.push(item);
}
});
return tempData;
}
//grabbing data
$scope.getPagedDataAsync = function(pageSize, page, searchText){
var data;
if(searchText){
var ft = searchText.toLowerCase();
DataContext.getDocuments().success(function(largeLoad){
//filter the data when searching
data = $scope.customFilter(largeLoad).filter(function(item){
return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;
})
$scope.setPagingData($scope.customFilter(data),page,pageSize);
})
}
else{
DataContext.getDocuments().success(function(largeLoad){
var testLargeLoad = $scope.customFilter(largeLoad);
//filter the data on initial page load when no search text has been entered
$scope.setPagingData(testLargeLoad,page,pageSize);
})
}
};
//paging
$scope.setPagingData = function(data, page, pageSize){
var pagedData = data.slice((page -1) * pageSize, page * pageSize);
//filter the data for paging
$scope.myData = $scope.customFilter(pagedData);
$scope.myData = pagedData;
$scope.totalServerItems = data.length;
// if(!$scope.$$phase){
// $scope.$apply();
// }
}
//watch for filter option change, set the data property of gridOptions to the newly filtered data
$scope.$watch('selectedFilterOption',function(){
var data = $scope.customFilter($scope.myData);
$scope.myData = data;
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
$scope.setPagingData($scope.myData,$scope.pagingOptions.currentPage,$scope.pagingOptions.pageSize);
})
$scope.$watch('pagingOptions',function(newVal, oldVal){
$scope.getPagedDataAsync($scope.pagingOptions.pageSize,$scope.pagingOptions.currentPage,$scope.filterOptions.filterText);
$scope.setPagingData($scope.myData,$scope.pagingOptions.currentPage,$scope.pagingOptions.pageSize);
},true)
$scope.message ="This is a message";
$scope.gridOptions = {
data: 'myData',
enablePaging: true,
showFooter:true,
totalServerItems: 'totalServerItems',
pagingOptions: $scope.pagingOptions,
filterOptions: $scope.filterOptions,
enableCellEdit: true,
enableColumnReordering: true,
enablePinning: true,
showGroupPanel: true,
groupsCollapsedByDefault: true,
enableColumnResize: true
}
$scope.gridOptions = GridOptionsService.getGridOptions('documents');
//get the data on page load
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
}]);
The grid options that I have hard coded into the controller are the same as the ones returned from the service. What I don't understand is why the grid renders, the dropdown filter works, but the paging is broken, only when the options for the grid come from a service? But it works as expected if it's hard coded into the controller.
EDIT: If someone can more eloquently state my problem, feel free to edit the title.
I don't really know how the ngGrid is implemented, but a common pitfall I do know that exist in many directives, is they expect their configurations to be ready as soon as they're initialized. Meaning that instead of watching the configuration object, they assume it exists and use it directly in the link\controller functions which runs as soon as they're created.
If this is indeed the case, a quick workaround to the problem is initializing the directive only when you have the configuration object. Let's say you pass on the configuration object through the variable 'options' on your scope, you'll then write something like:
<!-- If options exists on your scope, it means you fetched it from the server -->
<div ng-if="options">
<div ng-grid ng-grid-options="options"></div>
</div>
Again, I'm not familiar with ngGrid or its usage, this is just an educated guess, take the conclusions and apply them on the correct API.
I haven't tested this, but one possible issue is that you are overwriting an object that is on the $scope. This can break the two way binding. For a quick test try
$scope.grid = {
Options: {
data: 'myData',
enablePaging: true,
showFooter:true,
totalServerItems: 'totalServerItems',
pagingOptions: $scope.pagingOptions,
filterOptions: $scope.filterOptions,
enableCellEdit: true,
enableColumnReordering: true,
enablePinning: true,
showGroupPanel: true,
groupsCollapsedByDefault: true,
enableColumnResize: true
}
}
$scope.grid.Options = GridOptionsService.getGridOptions('documents');
You would need to update the grid options in the directives attribute as well of course.
The problem is that the controller functions for filtering and paging use the options defined on the controller $scope, but the ng-grid UI is not bound to those objects.
The controller methods for filtering and paging use $scope.pagingOptions as the data source. However, the ng-grid UI is bound to $scope.gridOptions.pagingOptions. When you create the $scope.gridOptions explicitly in the controller, $scope.gridOptions.pagingOptions refers to the same object as $scope.gridOptions, so making changes in the UI will change the value used in the controller functions.
However, when $scope.gridOptions is assigned using the service, the service is creating new pagingOptions, so there is no connection between $scope.gridOptions.pagingOptions and $scope.pagingOptions. Making changes in the UI will not change the values used in the controller functions.
The same is true for filterOptions.
One way to resolve the issue is
$scope.gridOptions = GridOptionsService.getGridOptions('documents');
$scope.pagingOptions = $scope.gridOptions.pagingOptions
$scope.filterOptions = $scope.gridOptions.filterOptions

Fullcalendar - Can we add custom data to our event Json Data?

I want to send a type in my Event Json Response.
Here is my code:
$('#calendar').fullCalendar({
eventSources: [
{"id":"46_l","title":"CustomEvent-Chargement","start":"2013-12-02","end":"2013-12-03","className":"customEventsClass","type":1},
{"id":"46_d","title":"Custom Event-Livraison","start":"2013-12-11","end":"2013-12-12","className":"customEventsClass","type":2}
]
});
You see I send a type in JSON Response array, is this possible? What parameter can we use for sending our custom data?
As per the documentation:
Non-standard Fields
In addition to the fields above, you may also include your own non-standard fields in each Event Object. FullCalendar will not modify or delete these fields. For example, developers often include a description field for use in callbacks such as eventRender.
Example:
$('#calendar').fullCalendar({
events: [
{
title: 'My Event',
start: '2010-01-01',
type: 1 // Custom field
}
],
eventRender: function(event, element) {
console.log(event.type); // Writes "1"
}
});
Try It with events: instead of eventSources:
$('#calendar').fullCalendar({
events: [
{"id":"46_l","title":"CustomEvent-Chargement","start":"2013-12-02","end":"2013-12-03","className":"customEventsClass","type":1},
{"id":"46_d","title":"Custom Event-Livraison","start":"2013-12-11","end":"2013-12-12","className":"customEventsClass","type":2}
]
});
In the new version you should do this:
eventRender: function (info) {
info.el.firstChild.innerHTML = info.event.extendedProps.type + " " + info.event.extendedProps.customEventsClass;
}
In version 4 custom data is in extendedProps.
In short e.event.extendedProps
You can also pass url endpoint to events as long as the url returns json response
cId.fullCalendar({
header: {
right: '',
center: 'prev, title, next',
left: ''
},
theme: true, //Do not remove this as it ruin the design
selectable: true,
selectHelper: true,
editable: true,
//it will load data from this url
events: "{{ url('api/events') }}",
// events: getData(),
//Add Events
});
and in your controller or function
$events = $request->user()->events()->select('title','color','date')->get();
// dd($even,$events)
$eventsResponse = [];
// created_at->format('Y-m-d')
foreach ($events as $event)
{
$eventsResponse[] = [
'title'=>$event->title,
'color'=>$event->color,
'start'=> Carbon::parse($event->date)->toDateTimeString(),
];
}
return $eventsResponse;

kendoui: How to display foreign key from remote datasource in grid

i have a kendoui grid which list claims. one of the columns is lenders which is a foreign key reference to the lenders table. what i want is to be able to display the lender name in the grid instead of its id reference.
ive setup the lenders datasource as follows
var dsLenders = new kendo.data.DataSource({
transport: {
read: {
url: "../data/lenders/",
dataType: "jsonp"
},
parameterMap: function(options, operation) {
if (operation === "read") {
return options;
}
}
}
});
and the grid looks like this
$("#gridClaims").kendoGrid({
dataSource: claimData,
autoSync:true,
batch: true,
pageable: {
refresh: true,
pageSizes: true
},
filterable: true,
sortable: true,
selectable: "true",
editable: {
mode: "popup",
confirmation: "Are you sure you want to delete this record?",
template: $("#claimFormPopup").html()
},
navigable: true, // enables keyboard navigation in the grid
toolbar: ["create"], // adds insert buttons
columns: [
{ field:"id_clm", title:"Ref", width: "80px;" },
{ field:"status_clm", title:"Status", width: "80px;" },
{ field:"idldr_clm", title:"Lender", values: dsLenders },
{ field:"type_clm", title:"Claim Type"},
{ field:"value_clm", title:"Value", width: "80px;", format:"{0:c2}", attributes:{style:"text-align:right;"}},
{ field:"created", title:"Created", width: "80px;", format: "{0:dd/MM/yyyy}"},
{ field:"updated", title:"Updated", width: "80px;", format: "{0:dd/MM/yyyy}"},
{ field:"user", title:"User" , width: "100px;"},
{ command: [
{text: "Details", className: "claim-details"},
"destroy"
],
title: " ",
width: "160px"
}
]
});
however its still displaying the id in the lenders column. Ive tried creating a local datasource and that works fine so i now is something to do with me using a remote datasource.
any help would be great
thanks
Short answer is that you can't. Not directly anyway. See here and here.
You can (as the response in the above linked post mentions) pre-load the data into a var, which can then be used as data for the column definition.
I use something like this:-
function getLookupData(type, callback) {
return $.ajax({
dataType: 'json',
url: '/lookup/' + type,
success: function (data) {
callback(data);
}
});
}
Which I then use like this:-
var countryLookupData;
getLookupData('country', function (data) { countryLookupData = data; });
I use it in a JQuery deferred to ensure that all my lookups are loaded before I bind to the grid:-
$.when(
getLookupData('country', function (data) { countryLookupData = data; }),
getLookupData('state', function (data) { stateLookupData = data; }),
getLookupData('company', function (data) { companyLookupData = data; })
)
.then(function () {
bindGrid();
}).fail(function () {
alert('Error loading lookup data');
});
You can then use countryLookupData for your values.
You could also use a custom grid editor, however you'll probably find that you still need to load the data into a var (as opposed to using a datasource with a DropDownList) and ensure that the data is loaded before the grid, because you'll most likely need to have a lookup for a column template so that you're newly selected value is displayed in the grid.
I couldn't quite get ForeignKey working in any useful way, so I ended up using custom editors as you have much more control over them.
One more gotcha: make sure you have loaded your lookup data BEFORE you define the column. I was using a column array that was defined in a variable I was then attaching to the grid definition... even if the lookup data is loaded before you use the grid, if it's defined after the column definition it will not work.
Although this post past 2 years, I still share my solution
1) Assume the api url (http://localhost/api/term) will return:
{
"odata.metadata":"http://localhost/api/$metadata#term","value":[
{
"value":2,"text":"2016-2020"
},{
"value":1,"text":"2012-2016"
}
]
}
please note that the attribute name must be "text" and "value"
2) show term name (text) from the foreign table instead of term_id (value).
See the grid column "term_id", the dropdownlist will be created if added "values: data_term"
<script>
$.when($.getJSON("http://localhost/api/term")).then(function () {
bind_grid(arguments[0].value);
});
function bind_grid(data_term) {
$("#grid").kendoGrid({
dataSource: ds_proposer,
filterable: true,
sortable: true,
pageable: true,
selectable: "row",
columns: [
{ field: "user_type", title: "User type" },
{ field: "user_name", title: "User name" },
{ field: "term_id", title: "Term", values: data_term }
],
editable: {
mode: "popup",
}
});
}
</script>
For those stumbling across this now, this functionality is supported:
https://demos.telerik.com/aspnet-mvc/grid/foreignkeycolumnbinding

Categories

Resources