How can I call stored procedure returning 2 tables in a controller in mvc entity framework 4? - asp.net-mvc

I have a stored procedure which returns 2 tables. How can I call this stored procedure from a controller in MVC.
(I'm using Entity Framework 4)
Stored procedure:
create proc [dbo].[sp_list33](#emp dbo.list READONLY )
as
select * from dbo.Items
select * from dbo.dept
Here 'list' is a userdefined table type for passing table valued parameter.
CREATE TYPE [dbo].[list] AS TABLE(
[eid] [int] NULL,
[name] [nvarchar](50) NULL,
[age] [int] NULL
)
In controller:
[HttpPost]
public JsonResult Onclick(int id)
{
using (examemployeeEntities1 eee = new examemployeeEntities1())
{
//Create table value parameter
DataTable dt = new DataTable();
DataRow dr = dt.NewRow();
dt.Columns.Add("eid");
dt.Columns.Add("name");
dt.Columns.Add("age");
dt.Rows.Add(1, "john", 21);
dt.Rows.Add(2, "albert", 22);
dt.Rows.Add(3, "martin", 33);
SqlParameter emp1 = new SqlParameter("#emp", SqlDbType.Structured);
emp1.Value = dt;
emp1.TypeName = "list";
//eee.Database.ExecuteSqlCommand("EXEC sp_list4 #emp",emp1);
var resp = eee.Database.SqlQuery<Item>("exec sp_list33 #emp", emp1);
return Json(resp.ToList());
}
}
In view:
paragraph id is "sdf" and button id is "asd"!!!!!
Script:
$("#asd").click(function () {
var a = 1;
var content = "<table><th>Id</th><th>Name </th><th>Age</th></tr>";
$.ajax({
type: 'POST',
url: '/Home/Onclick/',
data: { 'id': a },
datatype: 'json',
success: function (data) {
$.each(data, function (i, item) {
content += "<tr>";
content += "<td style=\"background-color:White\">" + data[i].eid + "</td>";
content += "<td style=\"background-color:White\">" + data[i].name + "</td>";
content += "<td style=\"background-color:White\">" + data[i].age + "</td>";
content += "</tr>";
});
content += "</table>";
$('#sdf').html(content);
alert("success");
},
error: function () {
}
});
});
Result displays content in the Item table only. How to get two entities from stored procedure? It is only retrieving the first select statement. Can any one help me to solve this..?

Since you are not using EF5, you can't go the easy way
As Microsoft stated in that link:
"Prior to EF5, Entity Framework would allow the stored procedure to be called but would only return the first result set to the calling code."
But there is always a work-around. Follow this steps and you will be able to achieve it. Although is not a very straight forward solution.
Hope this helps

Related

Adding data labels (annotations?) to Google Charts (Visualizations API) drawn from a query

I'm creating a line chart by querying data entered into a Google Sheet, and I need to add data labels, i.e. the little numbers next to the points on the chart. I found plenty of documentation on how to do this with charts drawn from a manually entered data-table, but not from a query to a Google Sheet. Please help.
google.charts.load('current', {'packages':['corechart', 'line']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var query = new google.visualization.Query(
'URL'
);
query.setQuery('SELECT A, B OFFSET 0'); //select specific cells from the table
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
var options = {
title: '',
height : 250,
width : '100%',
}
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
correct, you want to add annotations.
this can be done using an annotation column role.
the annotation column role, should directly follow the series column it represents in the data table.
in this case, since you are getting the data from a query,
we can use a DataView to add the annotation using a calculated column.
first, we create the data view.
var view = new google.visualization.DataView(data);
then we use the setColumns method,
to add the column indexes from the query,
and our calculated column for the annotation.
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}]);
finally, we need to use the view to draw the chart.
chart.draw(view, options);
see following snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(drawChart);
function drawChart() {
var query = new google.visualization.Query(
'URL'
);
query.setQuery('SELECT A, B OFFSET 0'); //select specific cells from the table
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
var options = {
title: '',
height : 250,
width : '100%',
};
// create data view with calculated annotation column
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: 'stringify',
sourceColumn: 1,
type: 'string',
role: 'annotation'
}]);
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(view, options); // <-- use view to draw the chart
}
Note: when using google.visualization.LineChart, you only need the 'corechart' package.
the 'line' package is for their material line chart --> google.charts.Line

Get term for selected autocomplete when multiple are on one page

I have a page where I am adding jquery-ui autocompletes dynamically
My .autocomplete() code includes a $.getJSON('my_url', my_payload) where, in my_payload,' I am trying to send the request.term (what I typed into the jqueryui textbox) as well as the id of the jquery ui text box.
The problem is, for all the dynamically added textboxes, they were just picking up the term and id of the original autocomplete.
I managed to find a way to get the id of the added (not original) autocomplete by wrapping the autocomplete in a function that has the added field passed in as a parameter, but because the 'term' is in the request, which comes from .autocomplete, I do not know how to get this for the new ones.
https://jsfiddle.net/amchugh89/1L8jvea5/4/
//=======dynamic formset script from https://medium.com/all-about-
django/adding-forms-dynamically-to-a-django-formset-375f1090c2b0======
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+)');
var replacement = prefix + '-' + ndx;
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function cloneMore(selector, prefix) {
var newElement = $(selector).clone(true);
var total = $('#id_' + prefix + '-TOTAL_FORMS').val();
newElement.find(':input:not([type=button]):not([type=submit]):not([type=reset])').each(function() {
if ($(this).attr('name')){
var name = $(this).attr('name').replace('-' + (total-1) + '-', '-' + total + '-');
var id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
if($(this).attr('id').includes('gl')){
console.log($(this).attr('id'))
make_autocomplete($(this))
}
}
});
newElement.find('label').each(function() {
var forValue = $(this).attr('for');
if (forValue) {
forValue = forValue.replace('-' + (total-1) + '-', '-' + total + '-');
$(this).attr({'for': forValue});
}
});
total++;
$('#id_' + prefix + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
var conditionRow = $('.form-row:not(:last)');
conditionRow.find('.btn.add-form-row')
.removeClass('btn-success').addClass('btn-danger')
.removeClass('add-form-row').addClass('remove-form-row')
.html('<span class="glyphicon glyphicon-minus" aria-hidden="true"></span>');
return false;
}
function deleteForm(prefix, btn) {
var total = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
if (total > 1){
btn.closest('.form-row').remove();
var forms = $('.form-row');
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
for (var i=0, formCount=forms.length; i<formCount; i++) {
$(forms.get(i)).find(':input').each(function() {
updateElementIndex(this, prefix, i);
});
}
}
return false;
}
$(document).on('click', '.add-form-row', function(e){
e.preventDefault();
cloneMore('.form-row:last', 'form');
return false;
});
$(document).on('click', '.remove-form-row', function(e){
e.preventDefault();
deleteForm('form', $(this));
return false;
});
//====================
//AUTOCOMPLETE==(that allows for multiple ACs
https://stackoverflow.com/questions/24656589/using-jquery-ui-autocomplete-
with-multiple-input-fields)===================================
function make_autocomplete(ee) {
ee.on("focus", function(){ //.autocomplete({
$(this).autocomplete({
minLength: 2,
source: function( request, response ) {
var term = request.term;
//with the formset, I want to get the row for which I am typing in the
'term'
var this_formset_row_autocomplete_id
=ee.attr('id');//$(this.element).prop("id");//
$(this).attr('id');
console.log(this_formset_row_autocomplete_id);
var corresponding_branch_html_id =
this_formset_row_autocomplete_id.replace('gl_account','branch');
var this_formset_row_branch_sym_id =
$('#'+corresponding_branch_html_id).val();
//console.log(corresponding_branch_html_id, this_formset_row_branch_sym_id)
var appended_data={term:term,
this_formset_row_branch_sym_id:this_formset_row_branch_sym_id};
console.log(appended_data);
$.getJSON( "{% url 'dashapp:account_autocomplete' %}", appended_data,
function( data,
status, xhr ) {
//cache[ term ] = data;
response( data );
});
}
});
});
}//end function make_autocomplete
var ee =$( ".account_autocomplete" )
make_autocomplete(ee)
//===============
You may want to try to make it more simple for testing. Something like:
function make_autocomplete(obj) {
obj.autocomplete({
minLength: 2,
source: function(req, resp) {
var myData = {
term: req.term,
original_form_branch_id: $(this).closest("form").attr("id"),
this_formset_row_branch_sym_id: $(this).closest(".row").find("select").val()
}
$.getJSON("myurl", myData, function(results) {
resp(results);
});
}
});
}
Fiddle: https://jsfiddle.net/Twisty/pywb9nhv/23/
This uses .closest() to gather details from the relative objects. Also I do not see any benefit to initializing Autocomplete on focus event.
If you would like further help, please provide Example Data that can be used in a working example.
Hope that helps a little.

Bind data from Database to dhtmlx scheduler

I use dhtmlx schedule and problem in loading data into scheduler view.
I use databasefirst, so i have a sp to fetch all details to display on scheduler,
public ContentResult Data()
{
var data = new SchedulerAjaxData(
new Entities().tblAppTime.Select(e => new { e.SharedId, e.StartTime, e.Duration}));
return data;}
output from var data (during debugging) :
{[{"SharedId":54,"StartTime":"09/14/2013 10:00","Duration":"09/14/2013 11:20"},{"SharedId":56,"StartTime":"09/14/2013 10:00","Duration":"09/14/2013 10:40"},
{[{"SharedId":10,"StartTime":"09/12/2013 8:50","Duration":"09/12/2013 8:55"},{"SharedId":56,"StartTime":"09/14/2013 10:00","Duration":"09/14/2013 10:40"}]}
still I dont get this binded in scheduler, Please help.
Update:
controller.cs
sched.BeforeInit.Add("customeventbox()");
public ContentResult Data()
{
var scheduler = new DHXScheduler();
scheduler.InitialDate= DateTime.Today ;
var data = new SchedulerAjaxData(new OnlineABEntities().GetAppointmentsDisplay(scheduler.InitialDate).Select(e => new {id= e.ID, e.ResourceID,start_date= e.StartTime,end_date= e.Duration, e.Color,text=""}));
return data;
}
schedscript.js
function customeventbox() {
debugger;
scheduler.attachEvent("onTemplatesReady", function () {
alert("eventbox");
scheduler.templates.event_header = function (start, end, ev) {
alert("eventbox1");
return scheduler.templates.event_date(ev.StartTime) + "-" +
scheduler.templates.event_date(ev.Duration);
};
scheduler.templates.event_text = function (start, end, event) {
alert("eventboxtext");
debugger;
return "<br>" + event.ID + "<br>"+event.Duration +"<br>"+event.StartTime+"<br>"+event.Color+ "sampleready" + "<br>"+ "sampletext" ;
}
});
}
Scheduler have some requirements to the loaded data,
check the article in the docs.
In short, the output data must contain at least four following properties, all case-sensitive - id, start_date, end_date and text
If you fetch data like this, it will be displayed in the scheduler
var data = new SchedulerAjaxData(
new Entities().tblAppTime.Select(e => new { id = e.SharedId, start_date = e.StartTime, end_date = e.Duration, text = ""})
);
Update
on the client data objects will have the same set of properties as objects that has been passed to SchedulerAjaxData. Start and end dates of the event are JS date objects, so they should be converted to string before output.
scheduler.templates.event_text = function (start, end, event) {
var dateToStr = scheduler.date.date_to_str("%H:%i");
return "<br>" + event.id +
"<br>" + dateToStr(event.end_date) +
"<br>" + dateToStr(event.start_date) +
"<br>" + event.Color +
"sampleready" + "<br>"+ "sampletext" ;
}
here is details on date format mask
http://docs.dhtmlx.com/scheduler/settings_format.html

Jstree, get_checked, pass value to div onselect event

i'm using an MVC c# asp.net 4.0 project with Jstree, but i have a small problem i have a jstree that's populated witha a JSON array.
My problem is I need to catch the value of the checkboxes in jstree when checked to a div in my view.
OK, i finally got this working this is the solution i hope it Help's someone :)
first you must bind:
.bind('check_node.jstree', function (e, data) {
$("#listSelectedActives").html(BuildList());
})
.bind('uncheck_node.jstree', function (e, data) {
$("#listSelectedActives").html(BuildList());
then the use this function:
function BuildList() {
var checked = $("#demoTree").jstree("get_checked", null, true);
var output = "";
$(checked).each(function (i, node) {
var id = $(node).attr("ID");
var text = $(node).attr("NodeText");
output += "<p>ID: " + id + " TEXT: " + text + "</p>";
})
return output;
}
If this is too confusing please let'me know :)

Does the iPad have a governor?

I loop through an ajax recordset and insert rows into an html5 database.
In Google Chrome, the program inserts 581 rows, whereas on the iPad, it only inserts between 20 and 80 rows.
I output the commands to the document body just to make sure they are being run, so I know there are 581 insert statements being run on the iPad, but then the table only has a handful.
OK, here's how I do it.
I first drop the table, then when that's done, I create the table.
Then when that's done, I do my ajax call.
When that comes back, I loop through the recordset and insert into the html5 local database.
var DropTableiUsr = function() {
var DropTableDeferred = new $.Deferred();
var CreateTableDeferred = new $.Deferred();
dbo.transaction(function(myTrans) {
myTrans.executeSql(
'drop table iUsr;'
,[]
,DropTableDeferred.resolve()
);
});
DropTableDeferred.done(function() {
dbo.transaction(function(myTrans) {
myTrans.executeSql(
'CREATE TABLE IF NOT EXISTS iUsr'
+ '(UsrID Integer NOT NULL PRIMARY KEY'
+ ',UsrGradeDate Varchar(128)'
+ ');'
,[]
,CreateTableDeferred.resolve()
);
});
});
CreateTableDeferred.done(function() {
var settings = {};
settings.data = {};
settings.data.method = 'View0';
var myPromise = $(this).myAjax('com/Usr.cfc', settings); // 'this' normally points to the DOM element that is the context of what caused the Ajax call.
myPromise.done(function(result) {
if (result.RTN) {
var qryUsr = result.qry.DATA;
qryUsr.RecordCount = result.qry.ROWCOUNT;
// qryUsr.ColumnList = result.qry.COLUMNS;
for (var CurrentRow=0;CurrentRow < qryUsr.RecordCount;CurrentRow++) {
myFunction(CurrentRow);
};
function myFunction(CurrentRow) {
$('body').append('INSERT INTO iUsr(UsrID,UsrGradeDate) VALUES(' + qryUsr.USRID[CurrentRow] + ',' + qryUsr.USRGRADEDATE[CurrentRow] + ')<br>');
dbo.transaction(function(myTrans) {
myTrans.executeSql(
'INSERT INTO iUsr(UsrID,UsrGradeDate) VALUES(?,?)',
[
qryUsr.USRID[CurrentRow],
qryUsr.USRGRADEDATE[CurrentRow]
]
)
});
};
} else {
$('#msg').text(result.MSG);
}
});
myPromise.fail(function(jqXHR, textStatus,C ) {
alert('PopulateiUsr: ' + C);
$('.container').append(jqXHR.responseText);
})
$('body').append('iUsr<br>');
});
};
$('#Reset').click(function() {
DropTableiUsr();
});
If you move the screen around while something is processing, it stops the processing.
Try displaying a countdown on the INSERT INTO callback, and you will see that it stops the countdown if you scroll the screen down.

Resources