I have a small angular app that makes an api call based on a month/year from a drop down list in asp. It is meant for that api call to be made whenever year or month drop down lists are changed.
The first/original load works just fine. According to the debugger on any change I'm hitting the api on the change, and getting a return. The entire "card-widget"/ChartController div is disappearing (even with css properties commented out).
My ASP code:
<div id="card">
<div>
</div>
<div id="card-widget" ng-app="ChartApp" ng-controller="ChartController" style="width:350px; height: 350px;">
<div>
<asp:DropDownList ID="lstMonth" runat="server" ng-model="month" ng-change="updateChart()"></asp:DropDownList>
<asp:DropDownList ID="lstYear" runat="server" ng-model="year" ng-change="updateChart()"></asp:DropDownList>
</div>
<div>
<canvas id="Chart" height="350" width="350"></canvas>
</div>
</div>
<div id="card-widget-fail" style="width: 350px; height: 100px;">
<label>No chart</label>
</div>
</div>
My Angular code:
var app = angular.module("ChartApp", []);
app.controller('ChartController', function ($scope, $http) {
$scope.updateChart = function () { getChart() };
var dataChart = document.getElementById("Chart").getContext('2d');
var year = document.getElementById("<%=lstYear.ClientID %>");
var month = document.getElementById("<%=lstMonth.ClientID %>");
getChart();
function getChart() {
//api call to load chart data based off month.options[year.selectedIndex].text & year.options[year.selectedIndex].text
}
});
The reason getChart() is not being called is because it's not present on the $scope element. Use $scope.getChart = function() { ... } instead. I recommend reading this documentation page, specifically the part "Scope as Data-Model".
Related
So I have a div, in which I have an a element. I want the other div to Render another page (RenderPage) as soon as the a element in the other div is clicked.
<div id="Left" style="width:29.49%; height:100%; border-style:solid; border-color:darkgray;">
<h1 id="Pages"> Articles </h1><br />
<a OnClick="LoadUE()">UE</a>
<a></a>
<script>
function LoadUnity() {
}
function LoadUE() {
document.getElementById("Body").innerHTML = #{RenderPage("Bottom.cshtml")};
}
</script>
</div>
<div id="Body" style="width:69.49%; height:100%;">
</div>
The RenderPage method only works on the server when the page is first executed. If you want to load partials in ASP.NET Web Pages (which is what you are using) from client script, you should remove the leading underscore from the file name and then create an AJAX request to load it. Here's an example that uses Fetch:
#section scripts{
<script>
function loadUE() {
fetch('/bottom')
.then((response) => {
return response.text();
})
.then((result) => {
document.getElementById('body').innerHTML = result;
});
});
</script>
}
As a side note, the ASP.NET Web Pages framework is pretty much dead. If you are just learning and have a choice, you should use Razor Pages instead: https://www.learnrazorpages.com/
How to call AngularJS function after partial postback (from ascx page) in ASP.Net inside an UpdatePanel. Initially I call angular function on ng-init. But after the partial postback, the function is not called. How could I call the function?
Function name is BindLeadGridHeader. Here is my Angular JS code:
.controller('CtrlSalesNav', ['$scope', '$http', '$location', '$timeout', function ($scope, $http, $location, $timeout) {
//function for Bind Module Name Drop Down Created By :Prashant Kumar OnDate:21.04.2017
var UserId = sessionStorage.CurrentUserId;
var CurrentModuleName = 'Lead';
$scope.AllHeader = '';
//code for bind all header to table
$scope.BindLeadGridHeader = function () {
$http.get(WebApiUrl + "api/GetAllLeadHeader?UserId=" + UserId + "&ModuleName=" + CurrentModuleName).then(function (response) {
alert('Header bind call');
$scope.AllHeader = response.data.Table;
Calling code on ascx page inside UpdatePanel:
<div class="lead_noTopMenu" id="divLeadGrid" ng-controller="CtrlSalesNav" ng-cloak>
<div class="row" style="margin-top: 90px;" data-ng-init="BindLeadGridHeader();">
<!-- Search FORM-->
<div class="row row1" id="search" style="display: none;">
<div class="col-md-12">
<div class="tabbable tabbable-custom">
<ul class="nav nav-tabs">
You probably should be using an angular directive or component. There's a 3rd callback on promises that's rarely used, called notify, that might work for you. It's called while the promise is waiting to be resolved.
I am trying to access the Wikimedia API and display ten results. I have written a function that accesses the API and works on its own.
However, when I try to integrate a Search button to call that function and pass the search string to the function nothing happens in Chrome or Firefox.
(oddly though when I use the snippet function within stackoverflow it works fine!)
I'm wondering why my code doesn't work in the browser - could this have something to do with synchronous/asynchronous behavior and if so what is happening?
I'd really appreciate some insight into what is going on...
Thanks!
$(document).ready(function() {
// Initialize the Global Variables
var api = "http://en.wikipedia.org/w/api.php?callback=?&format=json&action=query&generator=search&gsrnamespace=0&gsrlimit=10&prop=pageimages|extracts&pilimit=max&exintro&explaintext&exsentences=1&exlimit=max&gsrsearch=";
var searchTitle = "";
var searchString = "";
$('#submit').click( function() {
searchTitle = $("input:text").val();
searchString = api + searchTitle;
getWiki(searchString);
});
// the following function works if I call it statically outside of the button click
// for example: getWiki(api + "giraffe");
// but it doesn't work if I call it dynamically from within the button. Why?
function getWiki(val) {
$.getJSON(val, function(json) {
$.each(json.query.pages, function(prop, item) {
var id = "#result" + item.index
$(id).html(item.title + "<br>" + item.extract);
});
});
}
// END Document Ready Function
});
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<body>
<form class="form-wrapper">
<input type="text" id="search" placeholder="Search for..." required>
<input type="submit" value="go" id="submit">
</form>
<div class="container">
<div class="row">
<div class="col-xs-12">
<div id="result1"></div>
<div id="result2"></div>
<div id="result3"></div>
<div id="result4"></div>
<div id="result5"></div>
<div id="result6"></div>
<div id="result7"></div>
<div id="result8"></div>
<div id="result9"></div>
<div id="result10"></div>
</div>
</div>
</div>
</body>
I'm using nervgh's angular-file-upload, https://github.com/nervgh/angular-file-upload/wiki/Module-API.
Is there a way to use the angular-file-upload and allow additional properties to each file when doing a multi-file upload?
I'm using their image sample to start out with: http://nervgh.github.io/pages/angular-file-upload/examples/image-preview/
Trying to add a boolean to each file that the user can set and then I use that on the server side when it's picked up.
You can use formData property shown in Properties section to send to server whatever you need.
formData {Array}: Data to be sent along with the files.
If you're using PHP in server side, I think this post can help you out.
The question is rather old, but as the documentation didn't really help me much, I would like to note down my solution here:
This is how my html looks like (look for "options"):
<div ng-controller="UploadCtrl2" nv-file-drop="" uploader="uploader" filters="customFilter">
<div class="progress progress-xs margin-top-5 margin-bottom-20">
<div class="progress-bar" role="progressbar" ng-style="{ 'width': uploader.progress + '%' }"></div>
</div>
<div class="row">
<div class="col-md-6">
<div ng-show="uploader.isHTML5">
<div class="well my-drop-zone" nv-file-drop="" options="{formData:[{folder:'attachments'}, {recordid:0}]}" uploader="uploader">
Dateien hierher ziehen.
</div>
</div>
</div>
<div class="col-md-6">
<span class="btn btn-primary btn-o btn-file margin-bottom-15"> Dateien auswählen
<input type="file" nv-file-select="" options="{formData:[{folder:'attachments'}, {recordid:0}]}" uploader="uploader" multiple />
</span>
</div>
</div>
</div>
And this is my controller (look for "fileItemOptions"):
app.controller('UploadCtrl2', ['$rootScope', '$scope', 'FileUploader', 'Store',
function ($rootScope, $scope, FileUploader, Store) {
var fileItemOptions = {};
var uploader = $scope.uploader = new FileUploader({
url: $rootScope.app.api.url + '/?c=uploads&a=set&authToken=' + encodeURIComponent(Store.get('X-Xsrf-Token')),
});
// FILTERS
uploader.filters.push({
name: 'customFilter',
fn: function (item/*{File|FileLikeObject}*/, options) {
if(options) fileItemOptions = options;
return this.queue.length < 10;
}
});
uploader.removeAfterUpload = true;
// CALLBACKS
uploader.onAfterAddingFile = function (fileItem, options) {
//console.info('onAfterAddingFile', fileItem);
if(fileItemOptions.formData) {
fileItem.formData = fileItemOptions.formData;
}
};
uploader.onAfterAddingAll = function (addedFileItems) {
setTimeout(function () {
console.log(uploader);
uploader.uploadAll();
}, 500);
};
uploader.onCompleteAll = function () {
$scope.$parent.run.uploadComplete();
fileItemOptions = {}; // cleanup
};
}]);
Whenever a file is added, the custom filter stores the option object in a global variable. The callback "onAfterAddingFile" will read that variable and it to the fileItem object. Quite hacky, but this was the only way I got it running.
I have a standalone html page that contains a dojo DataGrid that works just fine. I am including the relevant code below.
<script type="text/javascript">
var readStore, grid;
var gridLayout = [
new dojox.grid.cells.RowIndex({ name: "Row #", width: 5, styles: "text-align: left;" }),
{
name: "Name",
field: "name",
styles: "text-align:right;",
width:30
},
{
name: "Type",
field: "type",
width:20
}
];
function initGrid()
{
readStore=new dojox.data.QueryReadStore({url:"/EG3/orgUnit/getChildren", requestMethod:"get"});
console.info("readStore initialized");
grid=new dojox.grid.DataGrid({store:readStore,
id:"grid",
delayScroll:true,
structure:gridLayout,
query:{id:2},
loadingMessage:"Loading..."
}, document.createElement('div'));
dojo.byId("gridContainer").appendChild(grid.domNode);
grid.startup();
}
dojo.addOnLoad(initGrid);
</script>
</HEAD>
<BODY class="claro">
<div id="list" class="list">
Table goes here
<div id="gridContainer">
</div>
</div>
Now, the problem happens when I try to include this page as a contentpane within a TabContainer. The TabContainer loads the page markup as is and does not fire the onLoad script of the page that contains the grid.
<div dojoType="dijit.layout.TabContainer" region="center" tabStrip="true" id="orgUnitTabs">
<div dojoType="dojox.layout.ContentPane" title="Info" selected="true" id="orgInfo" jsId="orgInfo">
</div>
<div dojoType="dojox.layout.ContentPane" href="/EG3/app/orgUnit/orgUnitChildren.gsp" executeScripts="true" parseOnLoad="true" extractContent="true" title="Children" id="children" jsId="children">
Children of the selected Org
<script type="javascript" event="onLoad">
initGrid();
</script>
</div>
Any ideas on how the onLoad script of the child page can be fired?
Thanks in advance.
you should check if the param executeScripts set to TRUE, and if you wanna use declarative method, you have to parse the domNode manually, see the detailed dojo.parse method:http://docs.dojocampus.org/dojo/parser
Not sure what the right answer is, but if I were you, I would try doing it all programatically instead of declaratively, trap errors, use console outputs to see what's happening and log events as it loads.