I am trying to my migrate my website to angular but slowly. Current scenario is i am having a plain HTML login page in which there is a link to open a forget password popup. I have migrated the Forget password page to Angular. So what i am doing is when the user clicks on the link, i load the angular library, controller and application through $.getscript and then do a AJAX call to load the ForgetPassword page content in the popup. I can see in console evrything has loaded prioperly but error comes when i try to bootstrap. Please find below my JS code.The error i am getting in console is "ReferenceError: angular is not defined angular.bootstrap(document, ['myApp']);"
$(document).ready(function () {
$("#complementary-nav ul li a#popup").bind("click", function () {
loadfiles(function () {
OpenPopup();
angular.bootstrap(document, ['myApp']);
});
});
});
// Code to open in pop up
function loadfiles(callback) {
var scripts = ['/js/angular.min.1.2.9.js', '/js/Controller.js', '/js/application.js'];
for (var i = 0; i < scripts.length; i++) {
$.getScript(scripts[i], function () {});
}
if (typeof callback === "function") {
callback();
}
}
function OpenPopup() {
var url = "/dev/Forgot-Password.aspx";
$.ajax({
type: "GET",
async: false,
contentType: "charset=UTF-8",
url: url,
success: function (data) {
$("#common-popup").html("").append($(data));
$("#common-popup_overlay").fadeIn(500);
},
error: function () {
console.log("error")
}
});
}
The Forgot Password HTML looks like this
<div ng-controller="ForgotPasswordController" id="lostPasswwordOverlayContent" class="overlayContent">
<p>
<label>E-Mail<span class="mandatory">*</span></label>
<input type="email" ng-class="{'input-error':(_ServerForm.email.$dirty && _ServerForm.email.$error.emailValidate) || (blankSubmit && _ServerForm.email.$invalid)}" ng-model="user.email" email-validate required name="email" placeholder="" maxlength="100" id="EmailAddress" />
<span class="ui-state-error h5-message" ng-show="(_ServerForm.email.$dirty && _ServerForm.email.$error.emailValidate) || (blankSubmit && _ServerForm.email.$invalid)">
<span class="h5-arrow"></span>
<span class="h5-content">Invalid Email</span>
</span>
</p>
<div class="button buttonSimple buttonRight greenbutton forgotpassword">
<a name="fgtpassword" id="fgtpassword" href="#" class="" ng-click="submitform($event)"><span>Submit<span class="visual"></span></span></a>
</div>
I have tested the functionality seperately for this page and it works fine if opened an independent HTML page whereas when i try to make changes and open it as a popup, i am getting error
I never used $.getScript() but according to the documentation you can provide a callback when the scripts have arrived and have been executed. Why don't you call your own callback then?
function loadfiles(callback) {
var scripts = ['/js/angular.min.1.2.9.js', '/js/Controller.js', '/js/application.js'];
var scriptsAlreadyFetched = scripts.length;
for (var i = 0; i < scripts.length; i++) {
$.getScript(scripts[i], function () {
scriptsAlreadyFetched--;
if (typeof callback === "function" && scriptsAlreadyFetched== 0) {
callback();
}
});
}
}
#meilke Yes the solution worked for me. But i found an alternative for doing it .
I am using the modernizr approach for the loading the JS files. With this approach i am also able to load CSS files together with the JS files
$("#complementary-nav ul li a#popup").bind("click", function () {
loadfiles(function () {
angular.bootstrap(document, ['myApp']);
});
});
function loadfiles(callback) {
var modernizrLoad = [{ load: ['//code.angularjs.org/1.2.8/angular.min.js', '/js/application.js', '/js/Controller.js', '/css/Styles_v2.css', '/css/tyles.css'], complete: function () { OpenPopup(callback); } }];
Modernizr.load(modernizrLoad);
}
Related
I'm working in a net core app, i made a HttpPost function to know if an user marked like.
This is the function code:
var likesCancion = (from likesCanc in _context.table
where likesCanc.SongId == idCancion && likesCanc.UserId == idUser
select likesCanc.Likes).FirstOrDefault();
if (likesCancion == 1)
{
return 1;
}
else
{
return 0;
}
I have this:
<div class="col-3 col-sm-2 col-md-2">
<i class="far fa-heart" id="heart" data-idAudio = #song.Id>
<span class="badge" >#song.Likes</span>
</i>
</div>
This is the <div> that I want to change at the start of the page if the user liked it or not.
The #song.Likes its data filled from the database.
I made an ajax request inside a for loop and get the respond of my HttpPost function:
const iconosCorazon = document.querySelectorAll('#heart');
setTimeout(function () {
let idUser = $('#inputidUsuario').val();
function makeRequest(i)
{
$.ajax({
type: "POST",
url: "checkHeart",
data: { idCancion: i, idUser: idUser },
dataType: "text",
success: function (msg) {
console.log(msg);
**if (msg == 1) {
$('.fa-heart').removeClass("far text-dark");
$('.fa-heart').addClass("fa text-danger");
}
else
{
$('.fa-heart').removeClass("fa text-danger");
$('.fa-heart').addClass("far fa-heart");
}**
},
error: function (req, status, error) {
console.log(msg);
}
});
}
for (var i=0;i<iconosCorazon.length;i++) {
let idCancion = iconosCorazon[i].getAttribute('data-idAudio');
makeRequest(idCancion);
}
I want to assign the css class to the correct element coming from the function result.
The issue here its that ajax execute all the elements at once and change the classes only with the last lopped element. So the question is how can i assign the rigth class to each div element. eg: If result == 1 paint red, if result == 0 paint other color.
Sorry for my bad english
Im trying to make this code works
You should use $(".fa-heart:eq(index)") to locate the each element with same class name. Sample code below:
$(".div_test:eq(0)").css("border","2px solid yellow");
Test Result:
I have a problem changing items after searching.
I looked at similar threads but found no solution there :(
It looks like the first time the page loads well - the first time the entire Index.cshtml page is loaded which contains a collection of books in the selected category.
There is a search engine on the page - after searching for "manual" - ajax correctly replaces elements with those containing "manual" in the name.
Then when I enter something into the search engine a second time (for example "exercises") - the content of the page does not change any more.
I tried to debug and I see that new items are correctly downloaded from the database - the condition "if (Request.IsAjaxRequest ())" is true and the items are passed to partial view - there the "foreach" loop goes through them. Unfortunately, after _Partial, nothing happens.
I can't find a mistake - the strangest thing is that the first ajax call works fine - only the second (and subsequent) bad.
CatalogController.cs
public ActionResult Index(string categoryName = null, string searchQuery = null)
{
if (categoryName == null)
categoryName = (db.Categories.Find(1)).Name;
var category = db.Categories.Include("Books").Where(x => x.Name.ToLower() == categoryName).Single();
var books = category.Books.Where(x => (searchQuery == null || x.Title.ToLower().Contains(searchQuery.ToLower()) || x.SubTitle.ToLower().Contains(searchQuery.ToLower()) || x.Level.ToLower().Contains(searchQuery.ToLower())) && !x.Inaccessible);
if (Request.IsAjaxRequest())
return PartialView("_PartialBooksList", books);
else
return View(books);
}
Index.cshtml
<form class="o-search-form" id="search-form" method="get" data-ajax="true" data-ajax-target="#booksList">
<input class="o-search-input" id="search-filter" type="search" name="searchQuery" data-autocomplete-source="#Url.Action("SearchTips")" placeholder="Search" />
<input class="o-search-submit" type="submit" value="" />
</form>
<div class="row" id="booksList">
#Html.Partial("_PartialBooksList")
</div>
#section Scripts
{
<script src="~/Scripts/jquery-3.5.0.js"></script>
<script src="~/Scripts/jquery-ui-1.12.1.js"></script>
<script>
$(function () {
var setupAutoComplete = function () {
var $input = $(this);
var options =
{
source: $input.attr("data-autocomplete-source"),
select: function (event, ui) {
$input = $(this);
$input.val(ui.item.label);
var $form = $input.parents("form:first");
$form.submit();
}
};
$input.autocomplete(options);
};
var ajaxSubmit = function () {
var $form = $(this);
var settings = {
data: $(this).serialize(),
url: $(this).attr("action"),
type: $(this).attr("method")
};
$.ajax(settings).done(function (result) {
var $targetElement = $($form.data("ajax-target"));
var $newContent = $(result);
$($targetElement).replaceWith($newContent);
$newContent.effect("slide");
});
return false;
};
$("#search-filter").each(setupAutoComplete);
$("#search-form").submit(ajaxSubmit);
});
</script>
}
_PartialBooksList
#model IEnumerable<ImpressDev.Models.Book>
#using ImpressDev.Infrastructure
<div class="row">
#foreach (var book in Model)
{
<div class="col-12 col-xl-4">
<a class="o-shop-link" href="#Url.Action("Details", "Catalog", new { bookId = book.BookId })">
<div class="o-shop-item">
<img class="o-shop-img" src="#Url.BookPhotoSourcePath(book.PhotoSource)" />
<div class="o-shop-text">
<h2>#book.Title</h2>
<h6>#book.SubTitle - #book.Level - <b>#book.Price zł.</b></h6>
+ Add to cart
</div>
</div>
</a>
</div>
}
</div>
Please help
I am not sure if this is the case, but try to change this code:
$($targetElement).replaceWith($newContent);
To this:
$($targetElement).html($newContent);
I think the problem is the div element with id="booksList" is replaced after first search. So you don't have this element in the second search.
I looked through the code step by step and found a solution to my problem.
In the first search, replace id="booksList"
<div class="row" id="booksList">
#Html.Partial("_PartialBooksList")
</div>
partial view in which there was only without id = booksLists.
In the next search there was no ID in this place and there was nothing to replace.
I'be been using modals as a means to communicate to users in my apps for some time now via several different front end frameworks. The logic is usually the same, defining the modal's html then rendering it via some click event.
As my applications grow, so do the number of modals I use for a user prompt or confirmation - these modals can have anything from text inputs to forms to dropdowns and so on.
My current method is to write out each separate modal in a single html file and simply call them by their IDs but I feel this is inefficient as there is plenty of duplicate boilerplate code, so I'm wondering the best way would be to create modals dynamically while keeping the code as light andclean as possible?
I've been thinking of something like a "modal factory" where you pass the content of the modal along with the height, width, styling, etc. would this be a good approach?
Thanks for any input!
Well what I do for Forms/HTML Content loaded from the server - is create a div with an ID - PartialViewDialog at the end of my page -(I load Partial Views inside a Dialog)
This one is Bootstrap 3.* based - (HTML structure based on Frontend framework
So the HTML is like this:
<body>
<!-- Other page content -->
<div class="modal fade" id="PartialViewDialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" data-modal="title"></h4>
</div>
<div class="modal-body" data-modal="content">
</div>
<div class="modal-footer" data-modal="footer">
</div>
</div>
</div>
</div>
</body>
Then in JS, I create a dialog Manager:
var MyApp = MyApp || {};
MyApp.UIHelper = MyApp.UIHelper || {};
MyApp.UIHelper.DialogManager = (function () {
"use strict";
var self = {};
self.divId = null;
self.dialog = null;
self.dialogBody = null;
self.dialogTitle = null;
self.dialogFooter = null;
self.actionUrl = "";
self.modalObject = null;
self.options = {};
function Initilize(divId, options) {
self.options = $.extend({ buttons: [] }, options);
self.divId = divId;
self.dialog = $(self.divId);
self.dialogBody = self.dialog.find('*[data-modal="content"]');
self.dialogTitle = self.dialog.find('*[data-modal="title"]');
self.dialogFooter = self.dialog.find('*[data-modal="footer"]');
self.BootgridObject = null;
};
function OpenPartialViewDialog(url, title, preprocessingFunction, postProcessingFunction) {
// Create the buttons
var options = self.GetPartialViewButtons(url, preprocessingFunction, postProcessingFunction);
// Initialise the PartialViewDialog with Buttons
Initilize('#PartialViewDialog', options);
// Set the URL for Ajax content load and Form Post
self.actionUrl = url;
// Set Dialog Title
self.dialogTitle.html(title);
// Open the PartialViewDialog
self.OpenModel();
};
// This Method creates the buttons for the Form dialog
// e.g Save, Cancel, Ok buttons
self.GetPartialViewButtons = function (url, preprocessingFunction, postProcessingFunction) {
// I only need Save and Cancel buttons always so I create them here
var buttons = {
buttons: {
// I create a save button which Posts back the Form in the Dialog
Save: {
Text: "Save",
css: "btn btn-success",
click: function () {
// Call a function before sending the Ajax request to submit form
if (preprocessingFunction) { preprocessingFunction(); }
$.ajax({
type: "POST",
url: url,
// This Dialog has a Form - which is Post back to server
data: self.dialogBody.find("form").serialize(),
success: function (response) {
// TODO: Check if response is success -
// Apply your own logic here
if (response.hasOwnProperty("IsSuccess")) {
if (response.IsSuccess) {
self.dialogBody.html("");
self.dialog.modal("hide");
// TODO: Show Success Message
// You can call another function if you want
if (postProcessingFunction) {
postProcessingFunction();
}
} else {
// If failure show Error Message
}
}
},
error: function (response) {
// If failure show Error Message
}
});
}
},
Cancel: {
Text: "Cancel",
css: "btn btn-danger",
click: function () {
self.dialogBody.html("");
self.dialogFooter.html("");
self.dialogTitle.html("");
self.dialog.modal("hide");
}
}
}
};
return buttons;
};
// dynamic creating the button objects
self.CreateButtonsHtml = function () {
var htmlButtons = [];
$.each(self.options.buttons, function (name, props) {
var tempBtn = $("<button/>", {
text: props.Text,
id: "btn_" + props.Text,
"class": props.css + "",
click: props.click
}).attr({ "style": "margin-right: 5px;" });
htmlButtons.push(tempBtn);
});
return htmlButtons;
};
// This method will load the content/form from server and assign the modal body - it will assign the buttons to the Modal Footer and Open the Dialog for user
self.OpenModel = function () {
$.ajax({
url: self.actionUrl,
type: "GET",
success: function (response) {
// Handle response from server -
// I send JSON object if there is Error in loading the content - otherwise the result is HTML
if (response.hasOwnProperty("HasErrors")) {
// Means some error has occured loading the content - you will have to apply your own logic
} else {
//Server return HTML - assign to the modal body HTML
self.dialogBody.html(response);
self.modalObject = self.dialog.modal();
// show modal
self.modalObject.show();
}
}
});
// Create the buttons in the Dialog footer
var buttons = self.CreateButtonsHtml();
self.dialogFooter.html('');
for (var i = 0; i < buttons.length; i++) {
self.dialogFooter.append(buttons[i]);
}
};
return {
OpenPartialViewDialog: OpenPartialViewDialog,
};
})();
Then whenever I need to open a dialog from the server I can call it like this:
MyApp.UIHelper.DialogManager
.OpenPartialViewDialog('/Content/Load', "My Title",
function(){alert('pre-process')},
function(){alert('post-process')}
);
Note: The PreProcess + PostProcess are called when the Save button is clicked
Here is a working/demo example which shows what the above JS does - Hope it helps
In the demo I load Dummy HTML from a div id="dummycontent"
Fiddle: https://jsfiddle.net/1L0eLazf/
Button Fiddle: https://jsfiddle.net/1L0eLazf/1/
Im running into a really weird error in 3.4 Phonegap/Cordova.
I have tested the service call through fiddler on the web as well as used WEINRE.
Over the browser it runs without any errors, when compiled to run on build.phonegap.com it hangs up on the first service.
The html
<!-- Page 1 -->
<div data-role="page" id="keyword" class="page">
<div class="bg"></div>
<div class="page-wrapper">
<div class="logo"><img src="images/logo.png" alt="" width="325" height="105"/></div>
<div class="text1">Enter Code</div>
<div class="input">
<input type="text" name="keyword" placeholder="code" id="keyword-value" />
</div>
<div class="button" id="keyword-submit" >Submit</div>
<div class="text2">
If you do not have a<br>
code, click continue
</div>
<div class="button" id="keyword-continue">Continue</div>
</div>
Im running into issues when running the keyword-submit function, it doesn't navigate through it though it does in the browser.
app.js
$("#keyword").live("pageinit",
function()
{
$("#keyword-continue").click(
function()
{
$.mobile.changePage("#zip-code");
});
$("#keyword-submit").click(
function()
{
alert("Entered Keyword Submit");
var keyword = $("#keyword-value").val();
if($.trim(keyword) == '')
{
navigator.notification.alert('Please Enter code');
return false;
}
service.getListByKeyword(keyword,
function(response)
{
$.mobile.showPageLoadingMsg("loading");
var check = JSON.parse(response).responsecollection.Response.rss.rs;
if(check.isvalid == 0)
{
if (check.msg!=null)
{
navigator.notification.alert(check.msg);
$.mobile.hidePageLoadingMsg();
}
}
else
{
window.localStorage.setItem("email",check.email);
alert("storing email");
service.resellerId = check.rsid;
localStorage.resellerId = service.resellerId;
alert("set reseller Id");
service.getResellerSetting(
function(response)
{
alert("entered merchant");
service.resellerEmail = JSON.parse(response).responsecollection.Response.rts.rt.mlid;
localStorage.resellerEmail = service.resellerEmail;
var telefloraStatus = JSON.parse(response).responsecollection.Response.rts.rt.UseTeleflora;
window.localStorage.setItem("floraStatus",floraStatus);
});
alert("Navigating to new page");
$.mobile.changePage("#keyword-list?keyword="+keyword);
//window.open("#keyword-list?keyword="+keyword,keywordPage);
}
});
alert();
$.mobile.hidePageLoadingMsg();
});
});
I have set up alerts to see where its navigating in the browser and getting caught in the mobile side.
Last set of code is the index.js
getListByKeyword: function (keyword, result) {
service.sendRequest("Reseller", "IsValid", function(args) {
args.rscode = keyword;
}, result);
alert("Inside the service call *END*");
}
I really cant seem to wrap my head around why it would work in the broswer and not on the android build.
//please follow these steps to check your phonegap project is ready to perform action or not.
//1)include cordova js or phonegap file reference
<script type="text/javascript" src="cordova.js"></script>
//2)check phonegap is ready or not
<script type="text/javascript">
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
alert('ready');
}
</script>
after that perform any action
Hello i have the following code with problems, i'm trying to make it when you click on the output to insert it into the input field. Can you help me please, been trying for hours without any luck.
<script type="text/javascript">
var input = $('#CompanyName');
var output = $('#output');
var timer;
input.on('keyup', function() {
delaySearch(this.value);
});
function delaySearch(keywords) {
clearTimeout(timer);
timer = setTimeout(function() {
performSearch(keywords);
}, 1000);
}
function performSearch(keywords) {
$.ajax({
type: "POST",
url: "/print/order/search",
data: { query: keywords },
cache: false,
dataType: "json",
async: true,
success: function(data) {
for(var key in data) {
output.append('<li onclick="fill('+ data[key].ClientName +')">' + data[key].ClientName) + '</li>';
}
}
});
}
function fill(thisValue) {
input.val(thisValue);
clearTimeout(timer);
}
</script>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="CompanyName">Firma</label>
<div class="col-md-5">
<input id="CompanyName" onblur="fill();" name="CompanyName" type="text" placeholder="Firma" class="form-control input-md">
<ul id="output"></ul>
<span class="help-block"></span>
</div>
</div>
Uncaught ReferenceError: somevalue is not defined
Update:
After adding jquery ready function i noticed some errors around and fixed them here is an update on the code
<div class="form-group">
<label class="col-md-4 control-label" for="CompanyName">Firma</label>
<div class="col-md-5">
<input id="CompanyName" name="CompanyName" type="text" placeholder="Firma" class="form-control input-md">
<ul id="output"><li onclick="fill(Ionut)">Ionut</li></ul>
<span class="help-block">Nume Firma</span>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
var input = $('#CompanyName');
var output = $('#output');
var timer;
input.on('keyup', function() {
delaySearch(this.value);
});
function delaySearch(keywords) {
clearTimeout(timer);
timer = setTimeout(function() {
performSearch(keywords);
}, 1000);
}
function fill(thisValue) {
input.val(thisValue);
}
function performSearch(keywords) {
$.ajax({
type: "POST",
url: "/print/order/search",
data: { query: keywords },
cache: false,
dataType: "json",
async: true,
success: function(data) {
for(var key in data) {
output.append('<li onclick="fill(' + data[key].ClientName + ')">' + data[key].ClientName) + '</li>';
}
}
});
}
});
</script>
onclick the error persists
Uncaught ReferenceError: fill is not defined
realseanp is onto the correct answer. I'll try to explain it a little better for you. When a browser starts processing and rendering a page, it loads top down. So your javascript scripts are being ran and evaluated before the DOM is created.
So your jquery selectors: var input = $('#CompanyName'); if you were to inspect them are going to be an empty array. They cannot find the #CompanyName element because it has not yet been rendered.
If you use jQuery's $(document).ready() function, then you can be assured that your code will not run until the dom is finished rendering, and therefore will find the elements as you intend them to. So in the end, your code will need to change to this:
$(document).ready(function(){
//Put your code in here.
//It will then fire once the dom is ready.
});
UPDATE:
Additionally, with your update. I'm noticing that the error is that 'fill' is not defined. fill being your onclick method. You have your js script evaluating after the dom is rendered. So at the time that the dom is rendered, and the tag with the onclick is rendered, no fill method yet exists. Two solutions:
Move the script above the dom, and place a var fill; outside of the $(document).ready so essentially this:
var fill;
$(document.ready(function(){
//your code
});
Don't use the onclick dom attribute, and instead use jquery to bind the event. So change
Ionut
to this:
<ul id="output"><li>Ionut</li></ul>
and inside the document.ready, add:
$('#output li').click(function(e) {
fill(/*your value/*)
});
You need to put your script below your HTML. That or wrap it in the jQuery Document ready function. And make sure you have jQuery loaded on the page, before your script