How to iterate ViewBag names inside foreach loop? - asp.net-core

I managed to find in SO questions regarding looping through ViewBag objects, but my issue is how to use iteration to name ViewBag inside of it.
But starting from the beginning. Inside of my Razor View I have a code, that triggers scripts depending on passed ViewBag:
#if (ViewBag.TermsChecked == "false")
{
<script type="text/javascript">
document.getElementById("termschecked").style.border = "2px solid #E24941";
</script>
}
else if (ViewBag.TermsChecked == "true")
{
<script type="text/javascript">
document.getElementById("termschecked").style.border = "unset";
</script>
}
#if (ViewBag.LoginCaptchaChecked == "false")
{
<script type="text/javascript">
document.getElementById("logincaptchachecked").style.border = "2px solid #E24941";
</script>
}
else if (ViewBag.LoginCaptchaChecked == "true")
{
<script type="text/javascript">
document.getElementById("logincaptchachecked").style.border = "unset";
</script>
}
#if (ViewBag.RegisterCaptchaChecked == "false")
{
<script type="text/javascript">
document.getElementById("registercaptchachecked").style.border = "2px solid #E24941";
</script>
}
else if (ViewBag.RegisterCaptchaChecked == "true")
{
<script type="text/javascript">
document.getElementById("registercaptchachecked").style.border = "unset";
</script>
}
#if (ViewBag.CaptchaChecked == "false")
{
<script type="text/javascript">
document.getElementById("captchachecked").style.border = "2px solid #E24941";
</script>
}
else if (ViewBag.CaptchaChecked == "true")
{
<script type="text/javascript">
document.getElementById("captchachecked").style.border = "unset";
</script>
}
To keep it DRY I want to create a loop through ViewBag names, but I am not sure how to pass item into ViewBag name in the loop. Until now I tried 2 approaches already, that did not work:
#{string[] viewbags = new string[] { ViewBag.TermsChecked, ViewBag.LoginCaptchaChecked, ViewBag.RegisterCaptchaChecked, ViewBag.CaptchaChecked };}
#foreach (string item in viewbags)
{
if (item == "false")
{
<script type="text/javascript">
document.getElementById("#item.ToLower()").style.border = "2px solid #E24941";
</script>
}
else if (item == "true")
{
<script type="text/javascript">
document.getElementById("#item.ToLower()").style.border = "unset";
</script>
}
}
and
#{string[] viewbags = new string[] { "TermsChecked", "LoginCaptchaChecked", "RegisterCaptchaChecked", "CaptchaChecked" }}
#foreach (string item in viewbags)
{
#if (ViewBag.item == "false")
{
<script type="text/javascript">
document.getElementById("#item.ToLower()").style.border = "2px solid #E24941";
</script>
}
else if (ViewBag.TermsChecked == "true")
{
<script type="text/javascript">
document.getElementById("#item.ToLower()").style.border = "unset";
</script>
}
}
Both are not triggering any script, like they should do.

You can try to modify your Viewbag like :
public IActionResult Index()
{
List<Item> items = new List<Item>();
items.Add(new Item { key = "LoginCaptchaChecked", value = "false" });
items.Add(new Item { key = "RegisterCaptchaChecked", value = "true" });
ViewBag.showHidelist = items;
return View();
}
public class Item {
public string key { get; set; }
public string value { get; set; }
}
And in page you can dynamically set the border with :
#foreach (var item in ViewBag.showHidelist)
{
if (#item.value=="true")
{
<script type="text/javascript">
document.getElementById("#item.key.ToLower()").style.border = "2px solid #E24941";
</script>
}
else
{
<script type="text/javascript">
document.getElementById("#item.key.ToLower()").style.border = "unset";
</script>
}
}

Using for can solve your problem.
Code:
#for (int i = 0; i < ViewBag.showHideList.Count(); i++)
{
Item itm = ViewBag.showHideList[i];
...
}

Related

SurveyJS : How to implement captcha image challenge

I try implement custom widget follow guide https://surveyjs.io/Examples/Library/?id=custom-widget-select2-tagbox
but not show image challenge of captcha
how can i implement captcha image challenge for surveyjs form?
i find the way:
html:
{
type: "html",
name: "info",
html: "<div id='g-recaptcha'></div> <div class='form-group g-recaptcha' data-callback='verifyCaptcha' data-sitekey='" + recaptchaClientKey + "'></div>"
}
ts, js
survey.onCompleting.add(function (sender, options) {
debugger;
var response = grecaptcha.getResponse();
if (response.length == 0) {
document.getElementById('g-recaptcha').innerHTML =
'<span class="form-group text-danger validation-summary-errors" data-valmsg-summary="true"><ul><li>Google reCAPTCHA validation failed</li></ul ></span >';
options.allowComplete = false;
} else {
options.allowComplete = true;
}
});
#section Scripts{
<script type="text/javascript" src="~/js/signup/survey_config.js"></script>
<script src='https://www.google.com/recaptcha/api.js'></script>
<script>
function verifyCaptcha() {
document.getElementById('g-recaptcha').innerHTML = '';
}
</script>
}

Mithril: cannot m.redraw with m.render

I have an app where I want to control when to redraw the view.
I can make it work using m.mount and m.redraw:
var count = 0;
var Counter = {
view: function() {
return m('main', [
m('h1', ('Count: ' + count))
])
}
}
m.mount(document.body, Counter);
window.setInterval(function () {
count++;
m.redraw();
}, 200);
<html>
<body>
<script src="https://unpkg.com/mithril/mithril.js"></script>
<script src="index.js"></script>
</body>
</html>
But if i use m.render (because I don't need mithril to autoredraw) it no longer works:
var count = 0;
var Counter = {
view: function() {
return m('main', [
m('h1', ('Count: ' + count))
])
}
}
m.render(document.body, m(Counter)); // <-- The only changed line
window.setInterval(function () {
count++;
m.redraw();
}, 200);
<html>
<body>
<script src="https://unpkg.com/mithril/mithril.js"></script>
<script src="index.js"></script>
</body>
</html>
How can I make mithril redraw when using m.render instead of m.mount?
As stated here in the mithril docs:
Note that m.redraw only works if you used m.mount or m.route. If you rendered via m.render, you should use m.render to redraw.
var count = 0;
var Counter = {
view: function() {
return m('main', [
m('h1', ('Count: ' + count))
])
}
}
m.render(document.body, m(Counter));
window.setInterval(function () {
count++;
m.render(document.body, m(Counter)); // <-- Use m.render here, not m.redraw
}, 200);
<html>
<body>
<script src="https://unpkg.com/mithril/mithril.js"></script>
<script src="index.js"></script>
</body>
</html>

How to disable Inspect Element and f12 click?

I have a PDF which is open in new Window through Iframe, but when I disabled the f12 and inspect Element then it is not working on that PDF, it's working outside of PDF.
<body>
<div id="divPDFView" style="margin: auto;text-align: center;">
</div>
<div style="display:none;" id="divDocument">
#if (Model.MyAccountList.Count > 0)
{
foreach (var items in Model.MyAccountList)
{
<a href="#" onclick="myPdf(this)" id="#items.PdfName">
<div class="sm-video">
///There have some work
</div>
}
}
</body>
<script>
function myPdf(e) {
var filen = e.id;
debugger;
window.open('#Url.Action("pdfshow", "MyAccount")?pdfname=' + filen);
}
</script>
///Here i show PDF From View Which is pdfshow
<body>
<div>
#Html.Raw(TempData["Embed"])
</div>
</body>
This is JavaScript code which I use to disable the F12 and Inspect Element but this is work outside of PDF.
<script>
$(document).ready(function () {
debugger
document.onmousedown = disableclick;
status = "Right Click Disabled";
function disableclick(event) {
if (event.button == 2) {
alert(status);
return false;
}
}
});
</script>
<script type='text/javascript'>
$(document).keydown(function (event) {
debugger
if (event.keyCode == 123) {
return false;
}
else if (event.ctrlKey && event.shiftKey && event.keyCode == 73) {
return false; //Prevent from ctrl+shift+i
}
});
</script>
This is the controller code where PDF is created using Iframe
public ActionResult pdfshow(string pdfname = null)
{
string pdffile ="<iframe src='/Content/TutorialImage/TutorialPdf/" +
pdfname + "#toolbar=0' width='800px' height='600px'
id='myframe' oncontextmenu='return false;' >
</iframe>";
TempData["Embed"] = pdffile;
return View(TempData["Embed"]);
}

cannot remove knockout observableArray item with SingalR

I am struggling with two issues. The first one is that after I pushed a new item into observableArray and try to refresh the accordion. The new item did not show up in the accordion. But the producs().length increased by one.
this.hub.client.productAdded = function (p) {
products.push(new productListViewModel(p.id, p.Name, self));
$("#accordion").accordion("refresh");
//loadAccordion();
};
My second issue is that After SignalR deleted an item in the database and returned with the deleted object I tried to remove the deleted object from the observableArray. I have tried different ways and none of them work.
this.hub.client.productRemoved = function (deleted) {
//var deleted = ko.utils.arrayFilter(products(), function (item) {
// return item.id == deleted.id;
//})[0];
products.remove(function (item) { return item.id == deleted.id; });
//products.remove(deleted);
$("#accordion").accordion("refresh");
};
What do I miss here? Below is the whole page code for reference
#{
ViewBag.Title = "SignalR";
}
<h2>SignalR</h2>
<div id="error"></div>
<h2>Add Product</h2>
<form data-bind="submit: addProduct">
<input data-bind="value: newProductText" class="ui-corner-all" placeholder="New product name?" />
<input type="submit" class="ui-button" value="Add Product" />
</form>
<h2>Our Products</h2>
listed: <b data-bind="text: productCount"></b> product(s)
#*<div id="accordion" data-bind="template: {name: productTemplate, foreach: products }, visible: products.Length > 0"></div>*#
<div id="accordion" data-bind='template: {name: "product-template", foreach: products }'></div>
<script type="text/html" id="product-template">
<h3 data-bind="text: name"></h3>
<div>
<input type="button" class="ui-button" value="Remove Rroduct" data-bind="click: removeProduct" />
</div>
</script>
<span data-bind="visible: productCount() == 0">What? No products?</span>
#section Scripts {
#Scripts.Render("~/bundles/knockout")
#Scripts.Render("~/bundles/signalr")
<script src="/Scripts/jquery.signalR-2.0.1.min.js" type="text/javascript"></script>
<script src="~/signalr/hubs" type="text/javascript"></script>
<script src="/Scripts/jquery.livequery.min.js"></script>
<style>
#accordion {width: 300px;}
#accordion h3 { padding-left: 30px}
</style>
<script>
function productViewModel(id, name, ownerViewModel) {
this.id = ko.observable(id);
this.name = ko.observable(name);
var self = this;
this.removeProduct = function () { ownerViewModel.removeProduct( id); };
this.name.subscribe(function (newValue) {
ownerViewModel.updateProduct(ko.toJS(self));
});
}
function productListViewModel() {
this.hub = $.connection.products;
this.products = ko.observableArray([]);
this.newProductText = ko.observable();
chat = this.hub
var products = this.products;
var self = this;
// Get All
this.init = function () {
this.hub.server.getAll();
}
this.hub.client.productAll = function (allProducts) {
//var mappedProducts = $.map(allProducts, function (item) {
// return new productViewModel(item.id, item.name, self);
//});
//products(mappedProducts);
$.each(allProducts, function (index, item) {
products.push(new productViewModel(item.id, item.Name, self));
});
loadAccordion();
};
this.hub.reportError = function (error) {
$("#error").text(error);
};
$.connection.hub.error(function (error) {
console.log('SignalR error: ' + error)
});
this.hub.client.productAdded = function (p) {
products.push(new productListViewModel(p.id, p.Name, self));
$("#accordion").accordion("refresh");
//loadAccordion();
};
this.hub.client.productRemoved = function (deleted) {
//var deleted = ko.utils.arrayFilter(products(), function (item) {
// return item.id == deleted.id;
//})[0];
products.remove(function (item) { return item.id == deleted.id; });
//products.remove(deleted);
$("#accordion").accordion("refresh");
};
// Commands
this.addProduct = function () {
var p = { "Name": this.newProductText() };
this.hub.server.add(p).done(function () { }).fail(function (e) { alert(e); });
this.newProductText("");
};
this.removeProduct = function (id) {
this.hub.server.remove(id).done(function () { alert("aa"); }).fail(function (e) { alert(e+" aa"); });
};
this.productCount = ko.dependentObservable(function () {
return products().length;
}, this);
}
function loadAccordion() {
$("#accordion").accordion({ event: "mouseover" });
}
$(function () {
var viewModel = new productListViewModel();
ko.applyBindings(viewModel);
// connect SinalR
$.connection.hub.start(function () { viewModel.init(); });
//$.connection.hub.start(function () { chat.server.getAll(); });
});
</script>
}
To solve your add problem: you are creating a new productListViewModel but you need to add a new productViewModel, so you just need to create the correct viewmodel:
this.hub.client.productAdded = function (p) {
products.push(new productViewModel(p.id, p.Name, self));
$("#accordion").accordion("refresh");
};
To solve your delete problem: in your productViewModel the id is a ko.observable so you need to write item.id() to access its value in the remove function:
this.hub.client.productRemoved = function (deleted) {
products.remove(function (item) { return item.id() == deleted.id; });
$("#accordion").accordion("refresh");
};

localStorage and updateView + windows 8

I have some items and I mark them as favorite by pressing a button, here is the code:
function AddToFavorites() {
//called when a shop is added as as a favorite one.
//first we check if already is favorite
var favoritesArray = getStoreArray();
var alreadyExists = exists();
if (!alreadyExists) {
favoritesArray.push(itemHolder);
var storage = window.localStorage;
storage.shopsFavorites = JSON.stringify(favoritesArray);
}
}
function exists() {
var alreadyExists = false;
var favoritesArray = getStoreArray();
for (var key in favoritesArray) {
if (favoritesArray[key].title == itemHolder.title) {
//already exists
alreadyExists = true;
}
}
return alreadyExists;
}
function getStoreArray() {
//restores our favorites array if any or creates one
var storage = window.localStorage;
var favoritesArray = storage.shopsFavorites;
if (favoritesArray == null || favoritesArray == "") {
//if first time
favoritesArray = new Array();
} else {
//if there are already favorites
favoritesArray = JSON.parse(favoritesArray);
}
return favoritesArray;
}
And I have a favorites.html to present those as a list.
The problem I have is that the list doesn't update automaticly every time I add or remove items.
Here is my code for that:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Αγαπημένα</title>
<!-- WinJS references -->
<link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
<link href="favoritesDetails.css" rel="stylesheet" />
<script src="favoritesDetails.js"></script>
</head>
<body>
<div class="favoritesDetails fragment">
<header aria-label="Header content" role="banner">
<button class="win-backbutton" aria-label="Back" disabled type="button"></button>
<h1 class="titlearea win-type-ellipsis">
<span class="pagetitle">Αγαπημένα</span>
</h1>
</header>
<section aria-label="Main content" role="main">
<div id="mediumListIconTextTemplate" data-win-control="WinJS.Binding.Template" style="display: none">
<div class="mediumListIconTextItem">
<img src="#" class="mediumListIconTextItem-Image" data-win-bind="src: picture" />
<div class="mediumListIconTextItem-Detail">
<h4 data-win-bind="innerText: title"></h4>
<h6 data-win-bind="innerText: text"></h6>
</div>
</div>
</div>
<div id="basicListView" data-win-control="WinJS.UI.ListView"
data-win-options="{itemDataSource : DataExample.itemList.dataSource,
itemTemplate: select('#mediumListIconTextTemplate')}">
</div>
</section>
</div>
</body>
</html>
And here is the JavaScript code:
// For an introduction to the Page Control template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232511
var dataArray = [], shopsArray = [];
(function () {
"use strict";
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var nav = WinJS.Navigation;
var ui = WinJS.UI;
shopsArray = getStoreArray();
if (shopsArray) {
for (var key in shopsArray) {
var group = { title: shopsArray[key].title, text: shopsArray[key].subtitle, picture: shopsArray[key].backgroundImage, description: shopsArray[key].description, phoneNumbers: shopsArray[key].content };
dataArray.push(group);
}
var dataList = new WinJS.Binding.List(dataArray);
// Create a namespace to make the data publicly
// accessible.
var publicMembers =
{
itemList: dataList
};
WinJS.Namespace.define("DataExample", publicMembers);
}
WinJS.UI.Pages.define("/pages/favoritesDetails/favoritesDetails.html", {
// This function is called whenever a user navigates to this page. It
// populates the page elements with the app's data.
ready: function (element, options) {
},
unload: function () {
},
updateLayout: function (element, viewState, lastViewState) {
}
});
})();
function getStoreArray() {
//restores our favorites array if any or creates one
var storage = window.localStorage;
var favoritesArray = storage.shopsFavorites;
if (favoritesArray == null || favoritesArray == "") {
//if first time
favoritesArray = new Array();
} else {
//if there are already favorites
favoritesArray = JSON.parse(favoritesArray);
}
return favoritesArray;
}
So how can I update the favorites HTML page when new favorites are stored/removed in the localDB? can i add event listeners there?
Is the code that stores favorites a part of the same app?
If so, I would consider adding the favorite to the underlying WinJS.Binding.list that you're using to bind to the ListView, and then store the updated list info in the DB, rather than trying to react to changes in the DB from the ListView.
Have a look at the following sample, which shows how to update a ListView dynamically:
http://code.msdn.microsoft.com/windowsapps/ListView-custom-data-4dcfb128/sourcecode?fileId=50893&pathId=1976562066
Hope that helps!