when we implement an web app with knockout JS, we encounter an issue in the page load.
we create an observable object to store an object with observable properties.
self.MyObservable=ko.observable();
self.myObject=new MyObject(){
property1: ko.observable(),
property2: ko.observable(),
property3: ko.observable()
}
self.MyObservable(self.myObject);
in the method.. we have the logic to check the property1 value
then we have to access the property1 with the following code
self.MyObservable().property1()
unfortunately we encounter TypeError:property1 is not a function in chrome debugger
here is the work around to fix the error.
if (ko.isObservable(self.MyObservable().property1)) {
return self.MyObservable().property1();
}
a blog to share Microsoft technologies Azure, DotNet, SharePoint, SQL Server,JavaScript Framework: Node.JS, Angular, React
Showing posts with label Client Side. Show all posts
Showing posts with label Client Side. Show all posts
Thursday, June 13, 2019
Monday, June 10, 2019
how to create a Knockout JS custom handler for duplicate email validation?
In the current Knockout JS web application, we want to validate the user input in the email field to make sure the input does not exist in our system.
i implemented the business logic in the textbox blur event. it means that the validation call to the back end when the cursor leaves the textbox.
here is snippet of code to implement binding handler in Knockout JS
ko.bindingHandlers.validateEmail = {
init: function (element, valueAccessor, allBindingsAccessor, data, context) {
var options = allBindingsAccessor().validateEmailParams || {};
$(element).blur(function () {
var customerId = options.customerID();
var email = options.emailAddress();
var value = valueAccessor();
var dataModel = sci.dataModel;
dataModel.CheckDuplicateEmail(customerId, email).then(function (response) {
if (response != null) {
if (response) {
valueAccessor().setError(loc.DuplicateEmailMySubaruAccount);
}
}
});
});
return ko.bindingHandlers.value.init.apply(this, arguments);
},
update: ko.bindingHandlers.value.update
};
HTML Code
<input autocomplete="off" id="email" class="form-control" type="text" data-bind="value: email,validationElement:email, validateEmail:email, validateEmailParams:{emailAddress: email, customerID:accountNumber}, attr: { placeholder: loc.Email }" />
i implemented the business logic in the textbox blur event. it means that the validation call to the back end when the cursor leaves the textbox.
here is snippet of code to implement binding handler in Knockout JS
ko.bindingHandlers.validateEmail = {
init: function (element, valueAccessor, allBindingsAccessor, data, context) {
var options = allBindingsAccessor().validateEmailParams || {};
$(element).blur(function () {
var customerId = options.customerID();
var email = options.emailAddress();
var value = valueAccessor();
var dataModel = sci.dataModel;
dataModel.CheckDuplicateEmail(customerId, email).then(function (response) {
if (response != null) {
if (response) {
valueAccessor().setError(loc.DuplicateEmailMySubaruAccount);
}
}
});
});
return ko.bindingHandlers.value.init.apply(this, arguments);
},
update: ko.bindingHandlers.value.update
};
HTML Code
<input autocomplete="off" id="email" class="form-control" type="text" data-bind="value: email,validationElement:email, validateEmail:email, validateEmailParams:{emailAddress: email, customerID:accountNumber}, attr: { placeholder: loc.Email }" />
Tuesday, April 25, 2017
How to limited number of Rows in return in Data Loading with SharePoint CSOM?
when we load list item from a large document library, the process will hang due to large volumn of items.
it is quite easy to improve the performance to limited the number of rows return from the query. we just need to set the ViewXml property from teh CamlQuery object.
limitedQuery.ViewXml = "<View><RowLimit>50</RowLimit></View>";
class Program
{
static void Main(string[] args)
{
string siteUrl = "http://SharepointSever";
SP.ClientContext clientContext = new SP.ClientContext(siteUrl);
SP.List oList = clientContext.Web.Lists.GetByTitle("My Documents");
SP.CamlQuery limitedQuery = new SP.CamlQuery();
limitedQuery.ViewXml = "<View><RowLimit>50</RowLimit></View>";
SP.ListItemCollection collListItem = oList.GetItems(limitedQuery);
clientContext.Load(collListItem);
clientContext.ExecuteQuery();
foreach (SP.ListItem oListItem in collListItem)
{
Console.WriteLine("ID: {0} \nTitle: {1}", oListItem.Id, oListItem["Title"]);
}
Console.ReadLine();
}
}
it is quite easy to improve the performance to limited the number of rows return from the query. we just need to set the ViewXml property from teh CamlQuery object.
limitedQuery.ViewXml = "<View><RowLimit>50</RowLimit></View>";
class Program
{
static void Main(string[] args)
{
string siteUrl = "http://SharepointSever";
SP.ClientContext clientContext = new SP.ClientContext(siteUrl);
SP.List oList = clientContext.Web.Lists.GetByTitle("My Documents");
SP.CamlQuery limitedQuery = new SP.CamlQuery();
limitedQuery.ViewXml = "<View><RowLimit>50</RowLimit></View>";
SP.ListItemCollection collListItem = oList.GetItems(limitedQuery);
clientContext.Load(collListItem);
clientContext.ExecuteQuery();
foreach (SP.ListItem oListItem in collListItem)
{
Console.WriteLine("ID: {0} \nTitle: {1}", oListItem.Id, oListItem["Title"]);
}
Console.ReadLine();
}
}
Tuesday, April 11, 2017
Advanced configuration and implementation in enabling Cross-Origin Requests in ASP.NET Web API 2
After we deploy the Web Api or WCF to cloud or in the public network. It means that we already expose the data to any one who know the url of the Web Api or WCF.
I will skip the introduction to setting up the Cross-Origin Requests in ASP.NET Web API 2 here.
For more information about the CORS for Web Api. you can visit MSDN link
Enabling Cross-Origin Requests in ASP.NET Web API 2
i will only focus on the a little bit advance topic on CORS implementation, since i had spend
extend period of time to complete the implementation.
1. control the CORS with custom setting in web.config file.
the configuration setting will allow us to add more domains without any code change and depolyment, we only need system admin to add more domain in the name attribute that separate by
comma.
<configSections>
<section name="CORSSettings" type="MyApp.CORSSettings, MyApp" />
</configSections>
<CORSSettings>
<CorsSupport>
<Domain Name="http://firstdomain,http://seconddomain,http://thirddomain" AllowMethods="*" AllowHeaders="*" AllowCredentials="true">
</Domain>
</CorsSupport>
</CORSSettings>
2. Server Side Implementation
In the WebApiConfig class
added the following code to enable the CORS globally
var cORSSettings = ConfigurationManager.GetSection("CORSSettings") as CORSSettings;
if (cORSSettings == null)
throw new InvalidOperationException("Missing CORS configuration");
var domains = cORSSettings.CorsSupport.OfType<CorsDomain>();
foreach (var domain in domains)
{
var cors = new EnableCorsAttribute(domain.Name, domain.AllowHeaders, domain.AllowMethods);
cors.SupportsCredentials = true;
config.EnableCors(cors);
}
please ensure the CORS object with property SupportsCredentials to be True, if your web api is configured with windows authentication and disable anonymous access. otherwise you will always receive XMLHttpRequest Network Error

3. Client Side Implementation
Even though you have enable the cors with SupportCredentials, you still will encouter the PreFlight request OPTIONS Error like
"Origin http://YourDomain is not allowed by Access-Control-Allow-Origin"
when you use .ajax the jquery wrappper to execute the client call
$.ajax({
type: 'get',
url: 'http://www.example.com/api/test',
xhrFields: {
withCredentials: true
}
actually we should use this XMLHttpRequest directly to call the web api to solve the preFlight request OPTIONS Error
var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open('GET', sWCFUrl, true);
xmlHttpRequest.withCredentials = true;
xmlHttpRequest.onreadystatechange = processData;
xmlHttpRequest.send();
I hope this post can help solve the headache on CORS implementation especiallly with windows authentication eanble and anonymous access diable.
I will skip the introduction to setting up the Cross-Origin Requests in ASP.NET Web API 2 here.
For more information about the CORS for Web Api. you can visit MSDN link
Enabling Cross-Origin Requests in ASP.NET Web API 2
i will only focus on the a little bit advance topic on CORS implementation, since i had spend
extend period of time to complete the implementation.
1. control the CORS with custom setting in web.config file.
the configuration setting will allow us to add more domains without any code change and depolyment, we only need system admin to add more domain in the name attribute that separate by
comma.
<configSections>
<section name="CORSSettings" type="MyApp.CORSSettings, MyApp" />
</configSections>
<CORSSettings>
<CorsSupport>
<Domain Name="http://firstdomain,http://seconddomain,http://thirddomain" AllowMethods="*" AllowHeaders="*" AllowCredentials="true">
</Domain>
</CorsSupport>
</CORSSettings>
2. Server Side Implementation
In the WebApiConfig class
added the following code to enable the CORS globally
var cORSSettings = ConfigurationManager.GetSection("CORSSettings") as CORSSettings;
if (cORSSettings == null)
throw new InvalidOperationException("Missing CORS configuration");
var domains = cORSSettings.CorsSupport.OfType<CorsDomain>();
foreach (var domain in domains)
{
var cors = new EnableCorsAttribute(domain.Name, domain.AllowHeaders, domain.AllowMethods);
cors.SupportsCredentials = true;
config.EnableCors(cors);
}
please ensure the CORS object with property SupportsCredentials to be True, if your web api is configured with windows authentication and disable anonymous access. otherwise you will always receive XMLHttpRequest Network Error
3. Client Side Implementation
Even though you have enable the cors with SupportCredentials, you still will encouter the PreFlight request OPTIONS Error like
"Origin http://YourDomain is not allowed by Access-Control-Allow-Origin"
when you use .ajax the jquery wrappper to execute the client call
$.ajax({
type: 'get',
url: 'http://www.example.com/api/test',
xhrFields: {
withCredentials: true
}
actually we should use this XMLHttpRequest directly to call the web api to solve the preFlight request OPTIONS Error
var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open('GET', sWCFUrl, true);
xmlHttpRequest.withCredentials = true;
xmlHttpRequest.onreadystatechange = processData;
xmlHttpRequest.send();
I hope this post can help solve the headache on CORS implementation especiallly with windows authentication eanble and anonymous access diable.
How to use JSOM to get the list of documents from SharePoint Document Library
there are so many way to perform a task that iterating the list of document inside the docoumnt library. we can do either with CSOM with C# or JSOM with Javascript.
Here i will show a very simple way to execute this task.
<script type="text/javascript">
function getDocuments(title) {
var context = SP.ClientContext.get_current();
var web = context.get_web();
var docLibrary = web.get_lists().getByTitle();
//here we can use SP.CamlQuery to filter the list if we need to
//load the the document by certain criteria.
var items = docLibrary.getItems(SP.CamlQuery.createAllItemsQuery());
context.load(items,"Include(File)");
context.executeQueryAsync(
function () {
if (items.get_count() > 0) {
var e = items.getEnumerator();
while (e.moveNext()) {
var item = e.get_current();
var file = item.get_file();
var title = file.get_title();
var name = file.get_name();
console.log(title + " " + name );
}
}
},
function (sender, args) {
console.log("Error in Loading Documents: " + args.get_message());
}
);
}
// We will use the delegate function to allow the ExecuteOrDelayUntilScriptLoaded function
//run a function with paramenters and this fucntion will ensure that sp.js is sucessfully loaded
//before running getDocuments function.
$(document).ready(function () {
ExecuteOrDelayUntilScriptLoaded(function() {getDocuments("Sales Documents")}, "sp.js");
});
</script>
For more information please visit the following link from MSDN
How to: Retrieve List Items Using JavaScript
Here i will show a very simple way to execute this task.
<script type="text/javascript">
function getDocuments(title) {
var context = SP.ClientContext.get_current();
var web = context.get_web();
var docLibrary = web.get_lists().getByTitle();
//here we can use SP.CamlQuery to filter the list if we need to
//load the the document by certain criteria.
var items = docLibrary.getItems(SP.CamlQuery.createAllItemsQuery());
context.load(items,"Include(File)");
context.executeQueryAsync(
function () {
if (items.get_count() > 0) {
var e = items.getEnumerator();
while (e.moveNext()) {
var item = e.get_current();
var file = item.get_file();
var title = file.get_title();
var name = file.get_name();
console.log(title + " " + name );
}
}
},
function (sender, args) {
console.log("Error in Loading Documents: " + args.get_message());
}
);
}
// We will use the delegate function to allow the ExecuteOrDelayUntilScriptLoaded function
//run a function with paramenters and this fucntion will ensure that sp.js is sucessfully loaded
//before running getDocuments function.
$(document).ready(function () {
ExecuteOrDelayUntilScriptLoaded(function() {getDocuments("Sales Documents")}, "sp.js");
});
</script>
For more information please visit the following link from MSDN
How to: Retrieve List Items Using JavaScript
Thursday, September 25, 2014
How to fixed Silverlight Control Content always null from Javascript Access
I got a quite tough issue when i try access the siliverlight object from the client side.
the following snippet of client side code
function search() {
try {
var silverLightControl = document.getElementById("silverlightControl");
silverLightControl.Content.Page.SetUser(document.getElementById("txtUser").value);
} catch (e) {
alert(e.description);
}
}
the page with silverlight object embeded
<div id="silverlightControl">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="ClientBin/SLAspxCommunication.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="5.0.61118.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
in the silverlight object class we have registered the page as javascriptable object with following line
HtmlPage.RegisterScriptableObject("Page", this);
public MainPage()
{
InitializeComponent();
_users = GenerateList();
HtmlPage.RegisterScriptableObject("Page", this);
}
the function looks simple that I just want to call the siliverlight function to search the user, unfortunately
this error message always popped up

when i debug the process, it indicate that the control did not contain an Content element. the main cause of
this error is that
var silverLightControl = document.getElementById("silverlightControl");
will load the Div Control instead of the object container that host the silverlight object. after i set the id to be
silverlightControl for the object tag. then search function funtion well and access the SetUser function in the
silverlight object.
<div>
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%" id="silverlightControl">
<param name="source" value="ClientBin/SLAspxCommunication.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="5.0.61118.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
the following snippet of client side code
function search() {
try {
var silverLightControl = document.getElementById("silverlightControl");
silverLightControl.Content.Page.SetUser(document.getElementById("txtUser").value);
} catch (e) {
alert(e.description);
}
}
the page with silverlight object embeded
<div id="silverlightControl">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="ClientBin/SLAspxCommunication.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="5.0.61118.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
in the silverlight object class we have registered the page as javascriptable object with following line
HtmlPage.RegisterScriptableObject("Page", this);
public MainPage()
{
InitializeComponent();
_users = GenerateList();
HtmlPage.RegisterScriptableObject("Page", this);
}
the function looks simple that I just want to call the siliverlight function to search the user, unfortunately
this error message always popped up
when i debug the process, it indicate that the control did not contain an Content element. the main cause of
this error is that
var silverLightControl = document.getElementById("silverlightControl");
will load the Div Control instead of the object container that host the silverlight object. after i set the id to be
silverlightControl for the object tag. then search function funtion well and access the SetUser function in the
silverlight object.
<div>
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%" id="silverlightControl">
<param name="source" value="ClientBin/SLAspxCommunication.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="5.0.61118.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
Subscribe to:
Posts (Atom)