asp.net core page not found - asp.net-mvc

I have error "Page not found" on my website.
This is what i have came up with.
Error occurred to clients few times without me knowing exact moment
When i tested it it ALWAYS happens when i restart my website asp.net server but under some circumstances which i will describe later
It happens in some controllers but in some not
It happens only until i open some controller that will load website, then all other works too.
It happens only on published website and not in my local environment.
So first line is clear and doesn't need explanation.
Second line:
What i have tested to get this error is i shut down my server and then start it again. After it i try going to mywebsite.com/User and error comes.
Third line:
It only happens in controllers /User and /Kalkulator but not in / or /Proizvodi
Forth line:
When i open controller /User and refresh it multiple times it doesn't load but when i go to / and then to /User it loads.
Here are my controllers with their views. I will only provide /User and /Kalkulator since there is easiest to see what happens.
public class UserController : Controller
{
public IActionResult Index()
{
//Debug log are control lines that write to my txt file but they are never reached on first time going to this controller, but when i do fourth step they do reach.
Debug.Log(null, "User/Index pocetak", Debug.Type.CasualChange, Request);
try
{
Debug.Log(null, "User/Index Checking isLogged", Debug.Type.CasualChange, Request);
if (Networking.IsLogged(Request))
{
Debug.Log(null, "User/Index Checking isAdmin", Debug.Type.CasualChange, Request);
if (Networking.IsAdmin(Request))
{
Debug.Log(null, "User/Index Return redirect admin", Debug.Type.CasualChange, Request);
return Redirect("/Admin?select=POR");
}
else
{
Debug.Log(null, "User/Index Return redirect /Proizvodi", Debug.Type.CasualChange, Request);
return Redirect("/Proizvodi");
}
}
Debug.Log(null, "User/Index Creting new user class", Debug.Type.CasualChange, Request);
AR.TDShop.User u = new AR.TDShop.User();
Debug.Log(null, "User/Index Return view with user class", Debug.Type.CasualChange, Request);
return View(u);
}
catch (Exception ex)
{
Debug.Log(null, "User/Index catch error", Debug.Type.CasualChange, Request);
return View("Error", ex.ToString());
}
}
User View
#model AR.TDShop.User
#{
ViewData["Title"] = "Profi kutak";
}
<style>
#Login {
margin: auto;
position: relative;
width: 400px;
text-align: center;
margin-top: 100px;
border-radius: 10px;
border: 1px solid red;
}
#Login input {
margin-top: 10px;
text-align: center;
height: 40px;
font-size: 30px;
width: 60%;
}
#Login button {
margin-top: 20px;
margin-bottom: 20px;
width: 200px;
height: 40px;
font-size: 18px;
border: none;
background-color: #ff0000;
border-radius: 0px 0px 20px 20px;
color: white;
font-weight: bolder;
}
#Login button:hover {
background-color: #ff4d4d;
}
#PostaniClan button:hover {
background-color: lawngreen !important;
color: black !important;
}
</style>
#using (Html.BeginForm("Login", "User", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div id="Login">
<p style="padding-top: 10px; padding-bottom: 10px; border-radius: 10px 10px 0 0; color: white; background-color: red; font-weight: bolder; font-size: x-large">Logovanje</p>
#Html.TextBoxFor(x => x.Name, new { #placeholder = "username" })
<br />
#Html.TextBoxFor(x => x.PW, new { #placeholder = "password", #type = "password" })
<br />
<button type="submit">Potvrdi</button>
</div>
}
<div style="text-align: center; margin-top: 30px; margin-bottom: 30px" id="PostaniClan">
<button onclick="window.location.href='/Majstori/Registracija'" style="background-color: green; color: white; border-radius: 20px; padding: 10px 20px 10px 20px;">Postani član!</button>
</div>
}
As you can see in user controller/view there are few other commands that are not shown here but i think you do not need them and you will get it when you take a look at /Kalkulator controller which also doesn't works and here it is:
public class KalkulatorController : Controller
{
public IActionResult Index()
{
return View();
}
}
and here is the view:
#{
ViewData["Title"] = "Kalkulator";
}
<div class="main-wrapper">
<div class="card bg-info text-center" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">GKP - Plafon</h5>
<p class="card-text">Izracunajte utrosak materijala koji Vam je potreban za izradu spustenog plafona u gips karton sistemu.</p>
Izracunaj!
</div>
</div>
<div class="card bg-info text-center" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">GKP - Zid (oblaganje)</h5>
<p class="card-text">Izracunajte utrosak materijala koji Vam je potreban za oblaganje postojeceg zida.</p>
Izracunaj!
</div>
</div>
<div class="card bg-info text-center" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">GKP - Zid (pregradjivanje)</h5>
<p class="card-text">Izracunajte utrosak materijala koji Vam je potreban za izradu novog pregradnog zida.</p>
Izracunaj!
</div>
</div>
</div>
As you can see it is pure HTML and it doesn't work....
Here is my /Proizvodi controller which works (it has a lot of commands so i will display only index and view)
public IActionResult Index(int? GrupaID, int? PodgrupaID, int? V, string Pretraga)
{
ProizvodiModel pm = new ProizvodiModel(GrupaID, PodgrupaID, V, Request);
pm.Tag = Pretraga;
return View(pm);
}
VIEW:
#model ProizvodiModel
#{
ViewData["Title"] = "Proizvodi";
List<Tuple<int, double>> CeneZaKorisnika = new List<Tuple<int, double>>();
if (Networking.IsLogged(Context.Request))
{
CeneZaKorisnika = AR.TDShop.User.GetVPCene(Model.User.UserID);
CeneZaKorisnika.Sort((x, y) => x.Item1.CompareTo(y.Item1));
}
if (!Model.Majstor)
{
<style>
.proizvod {
margin-bottom: 5px !important;
}
</style>
}
else
{
<style>
.proizvod {
margin-bottom: 103px !important;
}
</style>
}
}
<link rel="stylesheet" type="text/css" href="~/css/ProizvodiIndex.css" />
<div class="main-wrapper">
<div id="left" class="col-sm-3" style=" color: white">
<div style="width: 100%; margin-top: 40px; margin-bottom: 40px; text-align: center">
<img src="~/images/Logo_Long.png" style="width: 90%;" />
</div>
#if (Model.Majstor)
{
Model.User.UcitajPorudzbine(Context.Request);
if (Model.User.Porudzbine.Count > 0)
{
<div style="background-color: red; margin-top: 10px; padding-top: 10px; padding-bottom: 10px">
<h3 style="text-align: center; margin: 0;">Skorašnje porudžbine</h3>
#{
int n = 5;
<table id="PorudzbineTable" style="width: 100%;margin-top: 10px; background-color: #ffbbbb; color: black">
#foreach (AR.TDShop.Porudzbina p in Model.User.Porudzbine)
{
<tr onclick="window.location.href='/Porudzbina?ID=' + #p.PorudzbinaID">
<td style="padding-left: 10px">#p.BrDokKom</td>
#switch (p.Status)
{
case AR.TDShop.Porudzbina.PorudzbinaStatus.NaObradi:
<td>Na obradi!</td>
break;
case AR.TDShop.Porudzbina.PorudzbinaStatus.CekaUplatu:
<td>Čeka uplatu!</td>
break;
case AR.TDShop.Porudzbina.PorudzbinaStatus.ZaPreuzimanje:
<td>Za preuzimanje!</td>
break;
case AR.TDShop.Porudzbina.PorudzbinaStatus.Preuzeto:
<td>Realizovano!</td>
break;
case AR.TDShop.Porudzbina.PorudzbinaStatus.Stornirana:
<td>Stornirano!</td>
break;
}
</tr>
n--;
if (n <= 0)
{
break;
}
}
</table>
<button id="SvePorudzbine" onclick="window.location.href='/User/Porudzbine'" style="text-align: center; margin-top: 10px; background-color: white; color: black">Sve porudzbine</button>
}
</div>
}
<div id="ObjasnjenjeCene">
<p>Cena bez PDV-a je iskazana crvenom bojom!</p>
</div>
}
<div style="padding: 15px; background-color: #5a5cd4; margin-bottom: 40px">
<button class="#if (#Model.ActivateGrupa == null && Model.ActivatePodgrupa == null) { #Html.Raw("activate") }" onclick="GoTo('/Proizvodi')">Svi proizvodi</button>
#foreach (GrupaModel g in Model.Grupe)
{
<button class="#if (Model.ActivateGrupa != null && Model.ActivateGrupa == g.GrupaID)
{
#Html.Raw("activate")
} else if (#Model.ActivatePodgrupa != null)
{
if(PodgrupaModel.GetParent((int)Model.ActivatePodgrupa) == g.GrupaID) { #Html.Raw("activate") }
}"
onclick="GoTo('/Proizvodi?GrupaID=#g.GrupaID')">
#g.Naziv
</button>
}
</div>
<div id="PredloziProizvod" style="border-top: black 2px; color: black;">
<button id="predloziButton" style="width: 100%; text-align: center">Predloži proizvod</button>
<input hidden type="text" placeholder="Naziv proizvoda" />
<input hidden type="text" placeholder="Kataloski broj" />
<input hidden type="text" placeholder="Opis primene" />
<button hidden id="PosaljiPredlogProizvoda">Posalji</button>
</div>
</div>
<div id="right" class="col-sm-9">
<div id="PretragaProizvoda">
<input type="text" placeholder="Pretraga..." value="#Model.Tag" />
<button id="tw" style="float: right" onclick="ToggleView(this)" value="0"><img src="~/images/View2.png" style="width: 25px" /></button>
</div>
<br />
#if (Model.PodGrupe.Count > 0)
{
string cls = "";
if (Model.ActivatePodgrupa == null)
{
cls = "aktivnaPodgrupa";
}
<div id="PodGrupe">
<button class="PodGrupa #cls" onclick="GoTo('/Proizvodi?GrupaID=#PodgrupaModel.GetParent((int)Model.PodGrupe[0].PodgrupaID))'">
<p>Svi proizvodi grupe</p>
</button>
#foreach (PodgrupaModel pgm in Model.PodGrupe)
{
cls = "";
if (pgm.PodgrupaID == Model.ActivatePodgrupa)
{
cls = "aktivnaPodgrupa";
}
<button class="PodGrupa #cls" onclick="GoTo('/Proizvodi?PodgrupaID=#pgm.PodgrupaID')">
<p>#pgm.Naziv</p>
</button>
}
</div>
<hr style="border-bottom: 2px solid black" />
}
#foreach (ProizvodModel p in Model.Proizvodi)
{
if (p.Aktivan)
{
string proizvodStil;
string buttonStil;
if (p.Klasifikacija == 0)
{
proizvodStil = "color: dimgray;";
buttonStil = "background: linear-gradient(to bottom, white, dimgray 20%, dimgray 80%, white 100%);";
}
else if (p.Klasifikacija == 2)
{
proizvodStil = "color: darkorange;";
buttonStil = "background: linear-gradient(to bottom, white, darkorange 20%, darkorange 80%, white 100%);";
}
else
{
proizvodStil = "color: darkgreen;";
buttonStil = "background: linear-gradient(to bottom, white, darkgreen 20%, darkgreen 80%, white 100%);";
}
<div class="proizvod ppppp #if (Model.Majstor) { #Html.Raw("korpa"); } normal"
#Html.Raw("onclick = \"GoToP('" + #p.ROBAID + "')\"") ;
style="#proizvodStil">
<p class="katBr">#p.KatBr</p>
<img src="#p.Slika" />
<p class="nazivProizvoda">#p.Naziv</p>
#if (Model.Majstor)
{
try
{
int NivoZaKorisnika = Model.User.Cenovnik_grupa.Where(x => x.Item1 == p.Cenovnik_GrupaID).Select(t => t.Item2).FirstOrDefault();
double VPCena = CeneZaKorisnika.Where(x => x.Item1 == p.ROBAID).FirstOrDefault().Item2;
double MPCena = VPCena + (VPCena * p.PDV / 100);
if (MPCena > 0)
{
<p class="vpcena">#VPCena.ToString("#,###.00") / #p.JM</p>
<p class="mpcena">#MPCena.ToString("#,###.00") / #p.JM</p>
if (Model.User.Vrsta == UserModel.Tip.Majstor)
{
<button style="#buttonStil" onclick="GoToP(#p.ROBAID); event.stopPropagation();"> KUPI!</button>
}
}
if (Model.User.Vrsta == UserModel.Tip.Administrator)
{
<button style="#buttonStil" onclick="Edit(#p.ROBAID); event.stopPropagation();">Detalji!</button>
}
}
catch (Exception ex)
{
#:alert("#ex.ToString()");
}
}
</div>
}
}
</div>
</div>
<div id="AlertPopUp">
</div>
<script src="~/js/AlertBox.js"></script>
<script>
var alb = new AlertBox($("#AlertPopUp"));
var currRID = -1;
var overwrite = false;
function GoTo(link) {
if ($("#tw").val() == 1) {
if (link.indexOf('?') > -1) {
window.location.href = link + "&V=1";
}
else {
window.location.href = link + "?V=1";
}
}
else {
window.location.href = link;
}
}
function GoToP(link) {
if ($("#tw").val() == 1) {
if (link.indexOf('?') > -1) {
window.location.href = link + "&V=1";
}
else {
window.location.href = link + "?V=1";
}
}
else {
window.location.href = "/Proizvod?ID=" + link;
}
}
function Edit(id) {
GoTo("/Proizvodi/Edit?ID=" + id);
}
function ToggleView(element) {
var curr = $(element).val();
if (curr == 1) {
$(element).val(0);
$(element).children("img").attr("src", "/images/View2.png");
$(".ppppp").removeClass("proizvod1");
$(".ppppp").addClass("block");
$(".ppppp").addClass("proizvod");
$(".korpa button").html("Dodaj u korpu!");
}
else {
$(element).val(1);
$(element).children("img").attr("src", "/images/View1.png");
$(".ppppp").removeClass("proizvod");
$(".ppppp").removeClass("block");
$(".ppppp").addClass("proizvod1");
$(".korpa button").html("<img src='/Images/cart.png' style='height: 50px;width: 50px;border-radius: 10px;padding: 5px;padding-right: 8px;background-color: #2196F3;' />");
}
}
#{
if(Model.View == 1)
{
#:StartOtherView();
}
}
function StartOtherView() {
$("#tw").val(1);
$("#tw").children("img").attr("src", "/images/View1.png");
$(".ppppp").removeClass("proizvod");
$(".ppppp").removeClass("block");
$(".ppppp").addClass("proizvod1");
$(".korpa button").html("<img src='/Images/cart.png' style='height: 50px;width: 50px;border-radius: 10px;padding: 5px;padding-right: 8px;background-color: #2196F3;' />");
}
$(function () {
var PredloziProizvodBlock = false;
$("#predloziButton").click(function () {
$(this).parent().children("input").each(function () {
if (PredloziProizvodBlock == true) {
$(this).hide();
}
else {
$(this).show();
}
});
if (PredloziProizvodBlock == true) {
$("#PosaljiPredlogProizvoda").hide();
}
else {
$("#PosaljiPredlogProizvoda").show();
}
PredloziProizvodBlock = !PredloziProizvodBlock;
})
$("#PosaljiPredlogProizvoda").click(function () {
$.ajax({
type: "GET",
url: "/Proizvodi/PosaljiPredlogProizvoda",
contentType: "application.json; charset-utf-8",
dataType: "json",
async: false,
success: function (data) {
alert(data);
},
error: function (data) {
alert(data);
}
});
})
$("#PretragaProizvoda input").keyup(function () {
var input = $(this).val().toUpperCase();
$(".proizvod").each(function () {
if ($(this).html().toUpperCase().indexOf(input) >= 0 || input.length == 0) {
$(this).show();
}
else {
$(this).hide();
}
});
});
});
</script>
All views use same layout.
Routing option:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});

I think your problem with Redirect in you UserController, could your try replace it on RedirectToAction(); It's must be help you.

I found out mistake and it was so easy.
I thought i was checking all my code which is ran when entering some page but i forgot one big part and it is constructor:
private readonly IHostingEnvironment hostingEnvironment;
public ProizvodiController(IHostingEnvironment he)
{
hostingEnvironment = he;
Program.AbsolutePath = hostingEnvironment.WebRootPath;
Debug.FilePath = Path.Combine(Program.AbsolutePath, "Log");
}
public IActionResult Index(int? GrupaID, int? PodgrupaID, int? V, string Pretraga)
{
ProizvodiModel pm = new ProizvodiModel(GrupaID, PodgrupaID, V, Request);
pm.Tag = Pretraga;
return View(pm);
}
I forgot that constructor is accessed each time when you access any page from controller and it sets my AbsolutePath variable which i use later.
When i restart my server he lose all in memory data (which is static variable AbsolutePath) and it is only set when ANY user enter website but since i call it only in 2 controllers, other controllers were not working.
Solution was to add same code to all controllers constructors.

Related

Why does my CSS code renders incorrectly on iOS/MacOS?

We developed a web app on Vue 3 and it displays perfectly on every browser except on iOS and Mac OS devices.
This is worse if you're using Safari, however some issues occur even on Chrome for Mac.
This problem causes forms to always be shown blank, without displaying a placeholder or user input. It also makes several other elements to misalign.
We even tried making a new form and removing all stylesheets, but the problem persists.
Here is the code for one of the forms:
<template>
<div>
<form class="contactus" #submit.prevent="saveMessage">
<div class="row">
<h1 class="titleFormAbout">
{{ $t("contactus.componentForm.text1") }}
</h1>
</div>
<p style="margin-bottom: 30px;">{{ $t("contactus.componentForm.text9") }}</p>
<input type="text" class="form-control formContact" :placeholder="$t('contactus.componentForm.text2')" id="name" required />
<input type="email" class="form-control formContact" :placeholder="$t('contactus.componentForm.text3')" id="email" required />
<vue-tel-input
v-model="phone"
id="phone"
class="formControl formContact"
></vue-tel-input>
<br />
<textarea
class="form-control formContact"
name=""
id="message"
rows="10"
:placeholder="$t('contactus.componentForm.text5')"
required
></textarea>
<br />
<vue-recaptcha
style="margin-bottom: 14px"
#validate="validated"
/>
<div class="row">
<div class="col-6">
<input
class="form-control "
type="Submit"
id="submitButton"
:value="$t('contactus.componentForm.text6')"
disabled
/>
</div>
<div class="col-6">
<button class="form-control clear" #click="clearForm" >
{{ $t("contactus.buttonClear") }}
</button>
</div>
</div>
<br />
<div class="alert" id="Response" role="alert"></div>
</form>
</div>
</template>
<script>
import axios from "axios";
import VueRecaptcha from "../forms/vue-recaptcha.vue";
const hostName = location.port =="" ?location.protocol + "//" + location.host:'http://'+location.hostname+':3000';
export default {
components: {
VueRecaptcha,
},
data() {
return {
config: {
headers: {
//'Content-Type': 'application/x-www-form-urlencoded'
"Content-Type": "multipart/form-data",
},
},
};
},
methods: {
validated(){
const htmlElement=document.getElementById('submitButton');
htmlElement.classList.add('submit');
htmlElement.disabled=false;
},
clearForm() {
document.getElementById("name").value = "";
document.getElementById("email").value = "";
document.getElementsByName("telephone")[0].value = "";
document.getElementById("message").value= "";
},
saveMessage() {
//alert(document.getElementsByClassName("highlighted")[0].getElementsByTagName('span')[0].innerHTML)
const responseBox = document.getElementById("Response");
const params = new FormData();
const countryPhone = document.getElementsByClassName("highlighted");
var countryPhoneid = "+52";
if (countryPhone.length > 0) {
countryPhoneid =
countryPhone[0].getElementsByTagName("span")[0].innerHTML;
}
params.append("name", document.getElementById("name").value);
params.append("email", document.getElementById("email").value);
params.append("phone",countryPhoneid + " " + document.getElementsByName("telephone")[0].value);
params.append("message", document.getElementById("message").value);
axios
.post(hostName + "/api/contact", params, this.config)
.then((response) => {
responseBox.innerHTML = this.$t("contactus.componentForm.text7");
responseBox.classList.add("alert-success");
setTimeout(() => {
responseBox.classList.remove("alert-success");
}, 5000);
console.log(response);
})
.catch((err) => {
responseBox.innerHTML = this.$t("contactus.componentForm.text8");
responseBox.classList.add("alert-danger");
setTimeout(() => {
responseBox.classList.remove("alert-danger");
}, 5000);
console.log(err);
});
responseBox.hidden = false;
setTimeout(() => {
responseBox.hidden = true;
}, 5000);
document.getElementById("name").value = "";
document.getElementById("email").value = "";
document.getElementsByName("telephone")[0].value = "";
document.getElementById("message").value = "";
},
},
mounted() {
document.getElementsByName("telephone")[0].placeholder=this.$t('contactus.componentForm.text10');
const listcountry = document.getElementsByClassName("vti__dropdown-list");
listcountry[0].getElementsByTagName("li")[137].classList.add("highlighted");
document.getElementsByName("telephone")[0].required = true;
document
.getElementsByName("telephone")[0]
.addEventListener("input", (textin) => {
const telephone = document.getElementsByName("telephone")[0];
//console.log(parseInt(textin.data));
//console.log(Number.isInteger(textin.data));<
if (Number.isInteger(parseInt(textin.data))) {
// console.log(telephone.value);
} else {
telephone.value = telephone.value.slice(
0,
telephone.value.length - 1
);
}
});
},
};
</script>
<style>
.contactus .submit {
background: #008b9e;
color: white;
font-weight: bold;
}
.contactus .formContact{
border: 2px solid #BAD1FF;
margin-top: 2vh;
margin-bottom: 2vh;
}
.contactus .clear {
background: rgba(0, 0, 0, 0.25);
font-weight: bold;
}
.contactus .titleFormAbout {
margin-top: 20px;
margin-bottom: 20px;
text-align: left;
color: #00a8c6;
font-weight: bolder;
margin-left: 12px;
text-transform: none;
}
form.contactus {
padding-left: 5vw;
padding-right: 5vw;
}
.contactus form li {
color: black;
}
.contactus .alet {
text-align: center;
}
.contactus .contactus p{
text-align: justify;
}
</style>
Here you can see the type of behaviour we're getting:
On iOS/MacOS:
The same elements on Windows/Android devices:
Can anyone please tell me if this is a common issue and if there's a solution? We have been stuck with this problem for two weeks and we're losing our minds.
Thanks.

jQuery Droppable: Only allow element to drop, if there is no other element in that dropzone

I'm writing a puzzle, where you have to drag an item into the correct dropzone.
Problem: I want that you can only drag an item into a dropzone, if that dropzone does not contain any other items. How can I check, whether there are no other items in that dropzone?
Here is a gif of my current puzzle:
Here is a gif which shows the problem:
As you can see, I can drag multiple items into the same dropzone.
If a dropzone already contains an item, the user should not be able to drop another item into that dropzone. How do I achieve that?
My script so far:
$( ".draggable" ).draggable({ revert: 'invalid', snap: ".dropfield", snapTolerance: 30, snapMode: "inner"});
$( ".dropfield" ).droppable({
accept: ".dropling",
drop: function( event, ui ) {
if(some-condition){ // if correct word got dragged into the correct dropzone
var id = ui.draggable.attr('id');
$("#" + id).draggable( 'disable' );
$(this).droppable( 'disable' );
$("#" + id).css( "background-color", "#7FFF00");
}
});
Html-excerpt:
<div id="liebe" class="dropling draggable text-center">
Liebe
</div>
<span class="dropfield" value="scheitern">
</span>
PS: There are already several topics on Stack-Overflow with the same question. However, I'm not intelligent enough to apply the suggested answers to my case. Please help me.
Edit1
Here is a gif which shows my preferred behavior:
I dragged a wrong word into a dropzone. But as long that dropzone is occupied by a word, no other words should be able to be dropped into that dropzone.
My current code:
if(some-condition){ //correct word
$("#" + id).draggable( 'disable' );
$(this).droppable( 'disable' );
$("#" + id).css( "background-color", "#7FFF00");
}
} else { //wrong word
console.log("wrong word dropped");
$(this).droppable( 'disable' );
}
As soon as I drag the wrong word out of the dropzone, the dropzone should become enabled again. But how can I achieve that?
I would advise breaking this into their own functions. This way you can enable and disable drop repeatedly. Not sure what you want to trigger the item to become draggable and droppable again based on the example you have supplied. Based on what you have supplied, I can offer this the following example.
$(function() {
function enableDrop($target) {
console.log("Enabled Drop");
$target.droppable({
accept: ".dropling",
classes: {
"ui-droppable-hover": "drop-target"
},
drop: function(event, ui) {
var $that = $(this),
dragWord = ui.draggable.text().trim(),
$item = ui.draggable;
if (checkWord(dragWord)) {
console.log("Accepted: " + $item.attr("id"));
$item.
removeClass("draggable")
.draggable('disable')
.attr("style", "")
.appendTo($that);
disableDrop($that);
$that.css("background-color", "#7FFF00");
} else {
return false;
}
}
});
}
function disableDrop($target) {
console.log("Disabling Drop on " + $target.attr("class"));
$target.droppable("destroy");
}
function checkWord(w) {
var result = false;
console.log("Checked Word: " + w);
if (w == "Liebe") {
result = true;
}
return result;
}
$(".draggable").draggable({
revert: 'valid',
snap: ".dropfield",
snapTolerance: 30,
snapMode: "inner"
});
enableDrop($(".dropfield"));
});
p .dropfield {
border: 1px solid #ccc;
border-radius: 3px;
display: inline-block;
width: 4em;
height: 1.5em;
margin-bottom: -.25em
}
p .drop-target {
border: 1px dashed #ccc;
background-color: #ccc;
}
.text-center {
text-align: center;
}
.draggable {
border: 1px solid #ccc;
border-radius: 3px;
display: inline-block;
width: 4em;
height: 1em;
padding: .25em 0;
margin-bottom: -.25em
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<p>Diese Schlussfolgerung ist <span class="dropfield" value="scheitern"></span>: Ee kann doch nicht sein, dass es gut ist, </p>
<div id="liebe" class="dropling draggable text-center">Liebe</div>
<div id="absurd" class="dropling draggable text-center">absurd</div>
The easiest way here is probably to solve the whole thing in a more generic way. For this I would add an attribute to the respective Dom element (data-count) and then check how many characters are contained and how many are still allowed:
See /** ADDED **/ for the things i did:
$(function() {
function textWrapper(str, sp, btn) {
if (sp == undefined) {
sp = [0, 0];
}
var txt = "";
if (btn) {
txt = "<span class='w b'>" + str + "</span>";
} else {
txt = "<span class='w'>" + str + "</span>";
}
if (sp[0]) {
txt = " " + txt;
}
if (sp[1]) {
txt = txt + " ";
}
return txt;
}
function chunkWords(p) {
var words = p.split(" ");
words[0] = textWrapper(words[0], [0, 1]);
var i;
for (i = 1; i < words.length; i++) {
var re = /\[.+\]/;
if (re.test(words[i])) {
var b = makeTextBox(words[i].slice(1, -1));
words[i] = " " + b.prop("outerHTML") + " ";
} else {
if (words[0].indexOf(".")) {
words[i] = textWrapper(words[i], [1, 0]);
} else {
words[i] = textWrapper(words[i], [1, 1]);
}
}
}
return words.join("");
}
function unChunkWords(tObj) {
var words = "";
$(tObj).contents().each(function(i, el) {
if ($(el).hasClass("b")) {
words += "[" + $(el).text() + "]";
} else {
words += $(el).text();
}
});
return words.replace(/\s+/g, " ").trim();
}
function makeBtn(tObj) {
var btn = $("<span>", {
class: "ui-icon ui-icon-close"
}).appendTo(tObj);
}
function makeTextBox(txt) {
var sp = $("<span>", {
class: "w b"
}).html(txt);
makeBtn(sp);
return sp;
}
function makeDropText(obj) {
return obj.droppable({
drop: function(e, ui) {
var txt = ui.draggable.text();
var newSpan = textWrapper(txt, [1, 0], 1);
$(this).after(newSpan);
makeBtn($(this).next("span.w"));
makeDropText($(this).next("span.w"));
$("span.w.ui-state-highlight").removeClass("ui-state-highlight");
update()
},
over: function(e, ui) {
$(this).add($(this).next("span.w")).addClass("ui-state-highlight");
},
out: function() {
$(this).add($(this).next("span.w")).removeClass("ui-state-highlight");
}
});
}
$("p.given").html(chunkWords($("p.given").text()));
$("p.given").on("click", ".b > .ui-icon", function() {
$(this).parent().remove();
});
$("p.given").blur(function() {
var w = unChunkWords($(this));
$(this).html(chunkWords(w));
makeDropText($("p.given span.w"));
});
$("span.given").draggable({
helper: "clone",
revert: "invalid"
});
makeDropText($("p.given span.w"));
/** ADDED **/
// update at beginning
update();
// register update events
$("p.given").on('click keydown keyup drag drop', update);
function update(e) {
var templateText = unChunkWords($("p.given"));
var templateTextWithoutParameters = templateText.replace(/\[(.+?)\]/g, "");
var templateTextWithoutParametersLenght = templateTextWithoutParameters.length;
// calc total length
var totalLength = templateTextWithoutParametersLenght;
// since 'helper: clone' we have to ignore it!
$("[data-count]:not(.ui-draggable-dragging)").each(function(index, item) {
var count = $(item).attr("data-count")
var text = "[" + $(item).text() + "]";
var length = templateText.split(text).length - 1;
totalLength += count * length;
});
// 46,8 keycodes for delete & backspace
var maxLength = 200;
if (totalLength >= maxLength && e && e.keyCode !== 46 && e.keyCode !== 8) {
e.preventDefault();
}
// disable data counts
var remaining = maxLength - totalLength;
$("[data-count]:not(.ui-draggable-dragging)").each(function(index, item) {
var count = $(item).attr("data-count");
if (parseInt(count) > remaining) {
$(item).attr("disabled", true);
$(item).draggable().draggable('disable');
} else {
$(item).attr("disabled", false);
$(item).draggable().draggable('enable');
}
})
$(".output").text(totalLength);
}
});
p.given {
display: flex;
flex-wrap: wrap;
}
p.given span.w span.ui-icon {
cursor: pointer;
}
div.blanks {
display: inline-block;
min-width: 50px;
border-bottom: 2px solid #000000;
color: #000000;
}
div.blanks.ui-droppable-active {
min-height: 20px;
}
span.answers>b {
border-bottom: 2px solid #000000;
}
span.given {
margin: 5px;
}
/** ADDED **/
[disabled] {
color: grey
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="row">
<p class="given" contenteditable="true">Lorem Ipsum is [Test] Ipsum has been the industry's [America] standard dummy text ever since the 1500s, </p>
</div>
<div class="divider"></div>
<div class="section">
<section>
<div class="card blue-grey ">
<div class="card-content white-text">
<div class="row">
<div class="col s12">
<span class="given btn-flat white-text red lighten-1" rel="1" data-count="50">Test</span>
<span class="given btn-flat white-text red lighten-1" rel="2" data-count="30">America</span>
<span class="given btn-flat white-text red lighten-1" rel="3" data-count="20">Qatar</span>
<span class="given btn-flat white-text red lighten-1" rel="4" data-count="10">Philippines</span>
</div>
</div>
</div>
</div>
</section>
</div>
<div class="divider"></div>
Count: <span class="output"></span>

calculateDistances() function doesn't work taking start/end value from a select

I'd like to calculate the distance between 2 points, taking coordinates for each point from a select. The following is the code so far
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Calcola il tuo itinerario</title>
<style>
html, body, #map-canvas {
height: 100%;
margin: 0;
padding: 0;
}
#panel {
position: absolute;
top: 5px;
left: 20%;
margin-left: -180px;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
width: 300px;
}
/*
Provide the following styles for both ID and class,
where ID represents an actual existing "panel" with
JS bound to its name, and the class is just non-map
content that may already have a different ID with
JS bound to its name.
*/
#panel, .panel {
font-family: 'Roboto','sans-serif';
line-height: 30px;
padding-left: 10px;
}
#panel select, #panel input, .panel select, .panel input {
font-size: 15px;
}
#panel select, .panel select {
width: 100%;
}
#panel i, .panel i {
font-size: 12px;
}<br>
#outputDiv {
font-size: 11px;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<script>
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var chiesamadre = new google.maps.LatLng(37.485558, 13.987883);
var mapOptions = {
zoom:17,
center: chiesamadre
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
directionsDisplay.setMap(map);
}
function calcRoute() {
var start = document.getElementById('start').value;
var end = document.getElementById('end').value;
var request = {
origin:start,
destination:end,
travelMode: google.maps.TravelMode.WALKING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
function calculateDistances() {
var start = new google.maps.Map(document.getElementById('start').value);
var end = new google.maps.Map(document.getElementById('end').value);
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origin:start,
destination:end,
travelMode: google.maps.TravelMode.WALKING,
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, callback);
}
function callback(response, status) {
if (status != google.maps.DistanceMatrixStatus.OK) {
alert('Error was: ' + status);
} else {
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
var outputDiv = document.getElementById('outputDiv');
outputDiv.innerHTML = '';
deleteOverlays();
for (var i = 0; i < origins.length; i++) {
var results = response.rows[i].elements;
addMarker(origins[i], false);
for (var j = 0; j < results.length; j++) {
addMarker(destinations[j], true);
outputDiv.innerHTML += origins[i] + ' to ' + destinations[j]
+ ': ' + results[j].distance.text + ' in '
+ results[j].duration.text + '<br>';
}
}
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="panel">
<b>Partenza: </b>
<select id="start" onChange="calcRoute();">
<option value="37.485558, 13.987883">Chiesa Madre</option>
<option value="37.484813, 13.983602">Calvario</option>
<option value="37.484474, 13.986312">Torre civica con orologi</option>
<option value="37.485703, 13.986480">Chiesa di San Giuseppe</option>
<option value="37.491049, 13.988843">Torre Con Orologi Cristo re</option>
<option value="37.484507, 13.989363">Chiesa Santa Maria del Rosario</option>
<option value="37.472353, 13.945771">Vassallaggi</option>
</select>
<b>Arrivo: </b>
<select id="end" onChange="calcRoute();">
<option value="37.485558, 13.987883">Chiesa Madre</option>
<option value="37.484813, 13.983602">Calvario</option>
<option value="37.484474, 13.986312">Torre civica con orologi</option>
<option value="37.485703, 13.986480">Chiesa di San Giuseppe</option>
<option value="37.491049, 13.988843">Torre Con Orologi Cristo re</option>
<option value="37.484507, 13.989363">Chiesa Santa Maria del Rosario</option>
<option value="37.472353, 13.945771">Vassallaggi</option>
</select>
<b>Distanza: </b>
<p><button type="button" onClick="calculateDistances();">Calculate
distances</button></p>
<p> <div id="outputDiv"></div></p>
</div>
<div id="map-canvas"></div>
</body>
</html>
calcRoute() function works fine but calculateDistances() function doesn't work, in fact if I click on the "Calculate distances" button after selecting start and end, no text is showed in the white space on the button, where is the div with the expected result of calculated distance. Maybe I did something wrong with the start and end variables of calculateDistances() function. I added this JSfiddle: https://jsfiddle.net/Lnq91j0c/
and this is the link of the page online: http://turismosancataldo.it/calcolo-itinerario-piedi-dist.html
How to fix the function? Thank You for any help.

Bootstrap 3 column class interfering with jquery-ui droppable div

I'm using jQuery-UI v1.11.2 in order to create some draggable and droppable divs, and Boostrap 3.1.1 as well.
I'd like to know why a Boostrap column class is interfering with the draggable "hint".
In other words, as I drag an image from my Gallery div to my Dashboard div, the Dashboard div comes in FRONT of the image hint. Then once I DROP my image on the Dashboard div, the image re-appears.
If I remove the col-md-8 class from the Dashboard div, this problem goes away.
Here are two screen shots to demonstrate:
1) WITHOUT the Bootstrap column class on the right div (image hint looks good)
2) With the Bootstrap column class on the right div (image hint disappears)
Here's the HTML code :
<section id="gadgets-view" class="mainbar" data-ng-controller="gadgets">
<div class="container-fluid">
<div class="row-fluid">
<!-- based on http://jqueryui.com/droppable/#photo-manager -->
<div class="ui-widget ui-helper-clearfix col-md-4"> <-- GALLERY OF WIDGETS -->
<ul id="gallery" class="gallery ui-helper-reset ui-helper-clearfix">
<li class="ui-widget-content ui-corner-tr">
<h5 class="ui-widget-header">Tree Grid</h5>
<img src="images/treegrid.jpg" alt="Hierarchy Grid" width="96" height="72">
</li>
<li class="ui-widget-content ui-corner-tr">
<h5 class="ui-widget-header">Area Chart</h5>
<img src="images/chart_area.jpg" alt="Area Chart" width="96" height="72">
</li>
<li class="ui-widget-content ui-corner-tr">
<h5 class="ui-widget-header">Bar Chart</h5>
<img src="images/chart_bar.png" alt="Bar Chart" width="96" height="72">
</li>
<li class="ui-widget-content ui-corner-tr">
<h5 class="ui-widget-header">Column Chart</h5>
<img src="images/chart_column.png" alt="Column Chart" width="96" height="72">
</li>
<li class="ui-widget-content ui-corner-tr">
<h5 class="ui-widget-header">Line Chart</h5>
<img src="images/chart_line.png" alt="Line Chart" width="96" height="72">
</li>
</ul>
</div>
<div class="col-md-8">
<div id="dashboard" class="ui-widget-content ui-state-default "> <-- DROPPABLE DASHBOARD -->
<h4 class=""><span class="ui-icon ui-icon-image"></span>Dashboard</h4>
</div>
<div>
</div>
</div>
</section>
The CSS :
<style>
.ui-widget-header{
font-size: 65%;
font-family: "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif";
}
.ui-state-highlight {
border: 2px dashed #d3d3d3; /* override to show dashed border when dragging */
}
#gallery {
float: left;
width: 75%;
min-height: 12em;
}
.gallery.custom-state-active {
background: #eee;
}
.gallery li {
list-style: none;
float: left;
width: 96px;
padding: 0.4em;
margin: 0 0.4em 0.4em 0;
text-align: center;
}
.gallery li h5 {
margin: 0 0 0.4em;
cursor: move;
}
.gallery li a {
float: right;
}
.gallery li a.ui-icon-zoomin {
float: left;
}
.gallery li img {
width: 100%;
cursor: move;
}
#dashboard {
float: left;
width: 45%;
height:500px;
padding: 1%;
}
#dashboard h4 {
line-height: 25px;
margin: 0 0 0.4em;
}
#dashboard h4 .ui-icon {
float: left;
}
#dashboard .gallery h5 {
display: none;
}
The JavaScript to create drag/drop areas :
<script>
$(function () {
// there's the gallery and the dashboard
var $gallery = $("#gallery"),
$dashboard = $("#dashboard");
// let the gallery items be draggable
$("li", $gallery).draggable({
cancel: "a.ui-icon", // clicking an icon won't initiate dragging
revert: "invalid", // when not dropped, the item will revert back to its initial position
containment: "document",
helper: "clone",
cursor: "move"
});
// let the dashboard be droppable, accepting the gallery items
$dashboard.droppable({
accept: "#gallery > li",
activeClass: "ui-state-highlight",
drop: function (event, ui) {
debugger;
deleteImage(ui.draggable);
}
});
// let the gallery be droppable as well, accepting items from the dashboard
$gallery.droppable({
accept: "#dashboard li",
activeClass: "custom-state-active",
drop: function (event, ui) {
recycleImage(ui.draggable);
}
});
// image deletion function
var recycle_icon = "<a href='link/to/recycle/script/when/we/have/js/off' title='Remove gadget' class='ui-icon ui-icon-minus'></a>";
function deleteImage($item) {
$item.fadeOut(function () {
var $list = $("ul", $dashboard).length ?
$("ul", $dashboard) :
$("<ul class='gallery ui-helper-reset'/>").appendTo($dashboard);
//$item.find("a.ui-icon-dashboard").remove(); // DO NOT REMOVE ORIGINAL WIDGET ICON - 11/19/2014 BM:
$item.append(recycle_icon).appendTo($list).fadeIn(function () {
//$item.animate({ width: "48px" }).find("img").animate({ height: "36px" });
$item.animate().find("img").animate();
});
});
}
// image recycle function
var dashboard_icon = "<a href='link/to/dashboard/script/when/we/have/js/off' title='Add this gadget' class='ui-icon ui-icon-plus'</a>";
function recycleImage($item) {
$item.fadeOut(function () {
$item
.find("a.ui-icon-refresh")
.remove()
.end()
.css("width", "96px")
.append(dashboard_icon)
.find("img")
.css("height", "72px")
.end()
.appendTo($gallery)
.fadeIn();
});
}
// image preview function, demonstrating the ui.dialog used as a modal window
function viewLargerImage($link) {
var src = $link.attr("href"),
title = $link.siblings("img").attr("alt"),
$modal = $("img[src$='" + src + "']");
if ($modal.length) {
$modal.dialog("open");
} else {
var img = $("<img alt='" + title + "' width='384' height='288' style='display: none; padding: 8px;' />")
.attr("src", src).appendTo("body");
setTimeout(function () {
img.dialog({
title: title,
width: 400,
modal: true
});
}, 1);
}
}
// resolve the icons behavior with event delegation
$("ul.gallery > li").click(function (event) {
var $item = $(this),
$target = $(event.target);
if ($target.is("a.ui-icon-dashboard")) {
deleteImage($item);
} else if ($target.is("a.ui-icon-zoomin")) {
viewLargerImage($target);
} else if ($target.is("a.ui-icon-refresh")) {
recycleImage($item);
}
return false;
});
});
I found the problem you describe (but i did not found a relation with the Bootstrap Grid Classes).
For my the problem seems to be related to the z-index and can be solved by adding the following style rules at the end of your CSS code:
.ui-draggable-handle {
z-index: 1;
}

Ajax ModalPopupExtender with an edit form in ASP.NET MVC

I have an events calendar and on each event in the calendar there is an edit link which open up ajax ModalPopupExtender for editing the event information. The issue that I am facing right now is that the edit has to be in a form so it can update the information on the server..
How do I deal with this? And what would be the best way of doing this ?
You can use jQuery to accomplish the same functionality. I had to do this recently for a project because I didn't like the way the ModalPopupExtender was handling it. Unfortunately though I didn't build the drag click-and-drag functionality.
Here's the code for the ASP.NET and XHTML:
Somewhere on the page, you put trigger button:
<input type="button" value="Trigger Action" class="popup-trigger-delete" />
Panel Code:
<div class="popup-wrapper popup-wrapper-delete">
<div class="popup-top"></div>
<div class="popup-middle">
<div class="content">Are you sure you want to delete this from your project?</div>
<div class="controls">
<asp:Button ID="btnDelete_Yes" runat="server" CssClass="left" OnClick="btnDelete_Yes_OnClick" />
<input type="button" value="Cancel" class="right popup-background-delete-cancel" />
</div>
</div>
<div class="popup-bottom"></div>
</div>
<div class="popup-background popup-background-delete-track"></div>
Javascript / jQuery
var fadeInTime = 400;
var popupStatus = 0;
function loadPopup(wrapper){
//loads popup only if it is disabled
if(popupStatus==0){
$(wrapper).fadeIn(fadeInTime);
popupStatus = 1;
}
}
function disablePopup(wrapper, background){
if(popupStatus==1){
$(background).fadeOut(fadeInTime);
$(wrapper).fadeOut(fadeInTime);
popupStatus = 0;
}
}
function centerPopup(wrapper, background){
//request data for centering
var windowWidth = document.documentElement.clientWidth;
var windowHeight = document.documentElement.clientHeight;
var popupHeight = $(wrapper).height();
var popupWidth = $(wrapper).width();
//centering
$(wrapper).css({
"position": "fixed",
"top": (windowHeight/2-100)-popupHeight/2,
"left": windowWidth/2-popupWidth/2,
"z-index" : "10000"
});
$(background).css({ "height": windowHeight });
}
//event handlers
var trigger = "input.popup-trigger-delete";
var wrapper = "div.popup-wrapper-delete";
var background = "div.popup-background-delete";
var dtpbc = "input.popup-background-delete-cancel";
$(document).ready(function(){
$(trigger).click(function(){ centerPopup(wrapper,background); loadPopup(wrapper); });
$(dtpbc).click(function(){ disablePopup(wrapper, background); });
$(document).keypress(function(e){ if(e.keyCode==27 && popupStatus==1){ disablePopup(wrapper,background); } });
});
CSS
div.popup-background-delete { display:none; }
div.popup-wrapper-delete { display:none; }
div.popup-wrapper { position:relative; display:none; display:block; width:350px; height:245px; padding:0; margin:0; z-index:5000; }
div.popup-top { position:relative; display:block; background-color:#ffffff; width:350px; height:40px; padding:0; margin:0; z-index:5000; }
div.popup-middle { position:relative; display:block; background-color:#ffffff; width:350px; min-height:165px; padding:0; margin:0; z-index:5000; }
div.popup-middle .content { position:relative; display:block; margin:0 auto; padding-top:20px; padding-bottom:10px; width:255px; z-index:5000; }
div.popup-middle .controls .left { position:absolute; top:0; left:80px; z-index:5000; }
div.popup-middle .controls .right { position:absolute; top:0; right:80px; z-index:5000;}
div.popup-bottom { position:relative; display:block; background-color:#ffffff; width:350px; height:40px; padding:0; margin:0; z-index:5000; }
div.popup-background { position:absolute; top:0; left:0; width:100%; height:100%; z-index:5000; background-color:#cbcbcb; opacity:0.2; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=20)"; filter: alpha(opacity=20); -moz-opacity:0.2; }
In order to get above sample working (sorry, can't comment), do this:
Change asp button to html button
Change "popup-background-delete-track" to "popup-background-delete"
In centerPopup, replace $(background).css({ "height": windowHeight }); with $(background).css({ "display": 'block' });
Remove all references to display:block in the CSS.

Resources