Need help Modifying how data is displayed via javascript and jquery - javascript

I have the code below and I need a little help in modifying the code output.
The code below is for a Codeigniter chat application where the user enters their message in the text box (#text) and the message is output, the message is saved in a MySQL database via PHP and then output to the textbox (#received).
I would like to modify the code to include the message sender and also show the messages with differentiation between the sender and recipient like google chat or Text message threads. The data output is via javascript and I am still a novice in the language.
This is the current chat thread output. Current Chat Output. For the full CodeIgniter project code, Click this link. Any help or pointers will be appreciated.
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script>
var time = 0;
var updateTime = function(cb) {
$.getJSON("index.php/chat/time", function(data) {
cb(~~data);
});
};
var sendChat = function(message, cb) {
$.getJSON("index.php/chat/insert_chat?message=" + message, function(data) {
cb();
});
}
var addDataToReceived = function(arrayOfData) {
arrayOfData.forEach(function(data) {
$("#received").val($("#received").val() + "\n" + data[0]);
});
}
var getNewChats = function() {
$.getJSON("index.php/chat/get_chats?time=" + time, function(data) {
addDataToReceived(data);
// reset scroll height
setTimeout(function() {
$('#received').scrollTop($('#received')[0].scrollHeight);
}, 0);
time = data[data.length - 1][3];
});
}
// using JQUERY's ready method to know when all dom elements are rendered
$(document).ready(function() {
// set an on click on the button
$("form").submit(function(evt) {
evt.preventDefault();
var data = $("#text").val();
$("#text").val('');
// get the time if clicked via a ajax get query
sendChat(data, function() {
alert("dane");
});
});
setInterval(function() {
getNewChats(0);
}, 1500);
});
</script>
<textarea id="received" rows="10" cols="50"></textarea>
<form>
<input id="text" type="text" name="user">
<input type="submit" value="Send">
</form>

According to the link it looks like it is impossible to differentiate messages by sender. Your application simply doesn't know who has sent a message.
So, first of all, you have to add a field in DB to store information about a sender. Most likely you'll have to implement some sort of authentication in the application. After that you'll be able to make differentiation on the client side.
On the client side you have to change the #received textbox to a div or some other block element. Doing this you'll be able to apply CSS styles to individual messages. Than you will need to change your addDataToReceived function in this way:
var addDataToReceived = function (arrayOfData) {
arrayOfData.forEach(function (data) {
var message = $('<div>');
message.html(data[0]);
if (data[2] === username) {
// data[2] is a new element, it points to an author of the message
//
// username indentificates a current user
// you'll save it to a variable after authentication somehow
message.addClass('self-message');
} else {
message.addClass('other-message');
}
$("#received").append(message);
});
}
It highly depends on a concrete realization, but all in all something like that.

Related

How to access javascript code from a controller in an Asp.Net Core MVC application

I have an Asp.Net Core MVC application that searches youtube videos and returns a list that is displayed on screen. Each video is placed in a custom component that has a checkbox. Every time a checkbox is selected I access a script that searches all the video components that are on the screen and I store the video id's in a list in my .cshtml page.
At some point I need to get this list of video id's to do a processing. For that I created a javascript method in the same .cshtml page to return this list of ids.
I've already done a research on JSRuntime on Blazor (.razor) pages but that wouldn't be my case.
The fact is that with the click of a button I need to call a controller method, and this method calls my javascript method which returns my list of ids.
How best to do this?
This my javascript code.
#section scripts
{
<script>
var listaDeIds = [];
function Mostrar() {
//document.getElementById("btnplaylist").style.display = 'block';
var videos = document.querySelectorAll('#video');
var count = 0;
var lista = [];
for (var i = 0; i < videos.length; i++) {
//console.log("1 - " + videos.item(i).getAttribute("name"));
var videoID = videos.item(i).getAttribute("name");
//console.log("2 - " + videos.item(i).getAttribute("id"));
const shadow = videos.item(i).shadowRoot;
const childNodes = Array.from(shadow.childNodes);
//console.log("3 - " + childNodes.length);
childNodes.forEach(childNode => {
if (childNode.nodeName === "DIV") {
//console.log("4 - " + childNode.nodeName);
const shadowChilds = Array.from(childNode.childNodes);
//console.log("5 - " + shadowChilds.length);
shadowChilds.forEach(shadowShild => {
if (shadowShild.nodeName === "DIV") {
//console.log("6 - " + shadowShild.nodeName);
const shadowChildsInternas = Array.from(shadowShild.childNodes);
//console.log("7 - " + shadowChildsInternas.length);
shadowChildsInternas.forEach(interna => {
if (interna.nodeName === "INPUT") {
//console.log("8 - Name " + interna.nodeName);
if (interna.checked === true) {
//console.log("9 - Checked: " + interna.checked);
lista[count] = videoID;
count = count + 1;
}
}
});
}
});
}
});
}
if (lista.length > 0) {
document.getElementById("btnplaylist").style.display = 'block';
} else {
document.getElementById("btnplaylist").style.display = 'none';
}
listaDeIds = lista;
}
function RetornaListaDeIds() {
return listaDeIds;
}
</script>
This is my html component code
<custom-iframe id="video" name="#item.Id.VideoId" urlvideo='#Url.Content(item.Url)' onclick="Mostrar()"></custom-iframe>
This is the button that calls my controller.
<div id="btnplaylist" class="right_side hidden">
<button value="Playlist" asp-controller="VideoSearch" asp-action="GravarSelecionados" class="btn green-button button-tamanho-padrao">Playlist</button>
</div>
Code of my control.
I think you might be missing something at a high level here so bear with me.
Your use case is you want users to 'check' videos that you serve to them via a web app, visually altering the page elements around the videos and ultimately sending them off for processing, which I assume means some kind of storage or at least some back-end work.
If I understand your attempted solution to this problem correctly, it is impossible. Even if you did get your backend to run javascript, it wouldn't be aware of the client's state and could not read that list of videos off of it. There's no reason for javascript to run on your server as I see it.
Instead, you need your client-side Javascript to send that list of ids to your server via an API in a JSON format. The flow goes (user checks box -> JS on the browser collects the id of that video and formats a POST request with some json describing what was checked -> that JSON is sent to your server which then reads it an processes it)
The frontend javascript and the server should always communicate with eachother in this way. Again, there's no need for javascript to be run on the server itself.
Moving on to thank everyone who gave suggestions for solving my problem for their support. I followed and tested all the suggestions and the one that fit best to my problem was the use of ajax, suggested by #Andre.Santarosa.
I followed the following article as a reference:http://www.macoratti.net/15/05/mvc_ajax.htm
I installed the package: Microsoft.jQuery.Unobtrusive.Ajax
I added the script reference in my _Layout.cshtml:
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
On the page that lists the videos, the code looks like this:
Button code:
<div id="btnplaylist" class="right_side hidden">
<input type="button" value="Playlist" id="Playlist" class="btn green-button button-tamanho-padrao" />
</div>
Ajax Code:
$('#Playlist').click(function () {
var url = "/VideoSearch/PegarListaDeIds";
var lista = listaDeIds;
$.post(url, { pListaDeIds: lista }, function (data) {
$("#msg").html(data);
});
});

Display results from api after user input

I'm learning JS and I need some help figuring out why my info isn't getting populated in the html. I'm just trying to get the basic functionality to work, so that I can continue to expand on it.
User is supposed to input a 3 digit route value, which will then return all the route information from an api call. I was able to get the route info to display earlier when I got the api call set up, but I'm struggling to figure why it's not displaying now that I tried adding in a feature to allow the user to input the route. See attached pen
HTML
<div class='container'>
<h1 id='header'>Route Info</h1>
<input id="input" type="text" placeholder="Enter 3 digit route ex 005" >
<input type="button" value="Get Route" onclick="getRoute()">
<br>
<p id = 'p'><span id="routeInfo"></span></p>
</div>
Javascript
$(document).ready(function() {
var route = $('#input');
getRoute.click(function() {
var scriptTag = document.createElement('SCRIPT');
scriptTag.src = "https://wsdot.wa.gov/Traffic/api/Bridges/ClearanceREST.svc/GetClearancesAsJson?AccessCode=59a077ad-7ee3-49f8-9966-95a788d7052f&callback=myCallback&Route=" + route;
document.getElementsByTagName('HEAD')[0].appendChild(scriptTag);
var myCallback = function(data) {
var myarray = Array.prototype.slice.call(data);
document.getElementById("routeInfo").innerHTML = JSON.stringify(myarray);
}
});
});
It looks like you are jumping through a lot of hoops you don't need to. As long as you are using Jquery, you should look into getting the api data with an ajax request. It's much easier and more intuitive. Also you have a few problems such as trying to get the input value with var route = $('#input'); which return the actual input element. You are also processing the returned data in a way that won't work.
Here's a basic example to get you going on (IMO) a better track:
function getRoute() {
var route = $('#input').val();
var url = "https://wsdot.wa.gov/Traffic/api/Bridges/ClearanceREST.svc/GetClearancesAsJson?AccessCode=59a077ad-7ee3-49f8-9966-95a788d7052f&Route=" + route;
$.ajax({url: url, success: function(data){
var retValue = "";
var i = 0
for(i; i< data.length; i++) {
retValue += data[i].BridgeName + "<br>"
}
document.getElementById("routeInfo").innerHTML = retValue;
}});
}
If you intend functionality in the getRoute.click callback to run, you need to rewrite that as a method function getRoute(), or get the button element via jQuery and assign that to the variable getRoute. As it stands, you have the click method wired via the markup to a function named getRoute which does not exist. In the JS you are trying to register a click event to a jQuery object named getRoute which does not exist.
getRoute needs to be a global function for it to be called from html :
getRoute = (function() {
Also, myCallback needs to be a global function for it to be called from your loaded script (just remove the var):
myCallback = function(data) {

Trying to pass value from ASP.NET JavaScript script to my C# Code Behind function using Hidden Field

I have a JavaScript script inside my ASP.NET Web site, and i want to get a value from a function in my C# Code Behind, with a argument i pass it from my ASP.NET Hidden Field.
Here is my ASP.NET & JavaScript part, i define a HiddenField and assigns the chatMessage var to it, than assigns a value to the var, and try to send its value to the returnLiClass() function.
(Important part is the first line, and the 13,14,17 lines):
<asp:HiddenField ID="chatMessage" runat="server" />
<script type="text/javascript">
$(function () {
// Declare a proxy to reference the hub.
var chat = $.connection.chatHub;
// Create a function that the hub can call to broadcast messages.
chat.client.broadcastMessage = function (name, message) {
// Html encode display name and message.
var encodedName = $('<div />').text(name).html();
var encodedMsg = $('<div /> ').text(message).html();
var tremp_id = $('<div /> ').text("<%=Request.QueryString["trempid"]%>").html();
var chatMessage = document.getElementById('<%= chatMessage.ClientID %>');
chatMessage.value = 'value from javascript';
// Add the message to the page.
$('#discussion').append('<li class="<%=returnLiClass(chatMessage.Value)%><strong>' + encodedName
+ '</strong>: ' + encodedMsg + "Tremp:" + tremp_id + '</li>');
};
// Get the user name and store it to prepend to messages.
$('#displayname').val('<%=returnName()%>');
// Set initial focus to message input box.
$('#message').focus();
// Start the connection.
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.send($('#displayname').val(), $('#message').val());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
});
</script>
The Code Behind function (When i debug neither the msg nor the chatMessage.Value has values):
protected String returnLiClass(String msg)
{
String test = chatMessage.Value;
return "redChat";
}
I'm not sure what am i doing wrong...
Hope you could help, Thank you!
Try using the jquery val() function.
I also feel that the control isn't being found, which is why it's not setting it.
Try this instead.
$("#<%=chatMessage.ClientID%>").val('value from javascript');

Adding an img HTML tag combined with a call to C# function to an ASP.NET page inside JavaScript script

Yeah, i know the title is a bit confusing but that's what it is...
Here is the piece of JavaScript code i have inside my ASP.NET Web app,
the line that troubles me is the 7th line from the bottom, after chat.server.send.
<script type="text/javascript">
$(function () {
// Declare a proxy to reference the hub.
var chat = $.connection.chatHub;
// Create a function that the hub can call to broadcast messages.
chat.client.broadcastMessage = function (name, message) {
// Html encode display name and message.
var encodedName = $('<div />').text(name).html();
var encodedMsg = $('<div /> ').text(message).html();
var tremp_id = $('<div /> ').text("<%=Request.QueryString["tid"]%>").html();
var chatMessage = document.getElementById('<%= chatMessage.ClientID %>');
chatMessage.value = 'value from javascript';
// Add the message to the page.
$('#discussion').append('<li><strong>' + encodedName
+ '</strong>: ' + encodedMsg + '</li>');
};
// Get the user name and store it to prepend to messages.
$('#displayname').val('<%=returnName()%>');
// Set initial focus to message input box.
$('#message').focus();
// Start the connection.
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.send($('<div /> ').text('<img src="<%=getUserImage(Convert.ToInt32(Request.QueryString["uid"]))%>" height="50" width="50" border="1" bordercolor=black />').html() + $('#displayname').val(), $('#message').val() + $('<div /> ').text(" | Tremp: <%=Request.QueryString["tid"]%>").html());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
});
</script>
As you can see I'm trying to add an image that gets the URL from a function within my C# code behind.
It gets some number from the URL and sends it to the function, that returns an image URL.
It seems alright except it shows the following instead:
What am i doing wrong and how can i fix it?
I'm sure it should be pretty simple.. but i can' find the right way..
Thanks.
You're using jquery Text function which escape the string (intended for text).
What you're looking for it the jquery append function.
chat.server.send($('<div /> ').append(...
In fact, you have the same problem when you broadcast your message (chat.client.broadcastMessage). You're using text instead of append
var encodedMsg = $('<div /> ').append(message).html();
Also make sure that your message variable is not already encoded from the server.

Can not make the settings from the sidebar gadget get applied

OK, I am not an expert at Sidebar Gadgets, but I have this project I will have to make for school. Have tried to solve it on my own but I got really stuck.
I will have to use the Cirip API (Cirip.ro being a kind of Twitter), and for the use of the API I have to input the username. I do so by means of the Settings, but when closing the settings there is no effect.
Here is the code, but it's pretty messy. I am not a web programmer so javascript/html is new to me.
http://www.box.net/shared/7yogevhzrr
EDIT: Ok, so I have narrowed it down a little and optimized my code here but it is still not working. I have made it as simple as possible.
In the main html I have this:
<script language="javascript">
document.write(getUserName());
</script>
In the gadget.js:
var userName;
document.onreadystatechange = function DoInit() {
document.body.style.width = 251;
document.body.style.height= 351;
document.body.style.margin=2;
userName="danieliuhasz";
System.Gadget.settingsUI = "settings.html";
System.Gadget.onSettingsClosing = settingsClosed;
}
function setUserName(userNameSet){
userName = userNameSet;
}
function getUserName(){
return userName;
}
function settingsClosed()
{
var username = System.Gadget.Settings.read("username");
setUserName(username);
}
In the settings.html:
<body>
Username:<br />
<input name="userBox" type="text" maxlength="50" />
</body>
In settings.js:
document.onreadystatechange = function DoInit()
{
if(document.readyState=="complete")
{
var user = System.Gadget.Settings.read("userName");
if(user != "")
{
userBox.value = user;
}
}
}
System.Gadget.onSettingsClosing = function(event)
{
if (event.closeAction == event.Action.commit)
{
var username = userBox.value;
if(username != "")
{
System.Gadget.Settings.write("username", username);
System.Gadget.document.parentWindow.settingsClosed();
}
}
}
I really can't figure it out. The output of this is "undefined".
I don't have a RAR unpacker on this machine so I can't take a look at the file, but I can give you a little bit of advice about saving settings. If you need further help, try pasting the code into your question (see my comment above).
When working with settings, you need to catch the System.Gadget.onSettingsClosing event in your JavaScript code. In this event handler, you can either make the settings temporary, by setting properties in the gadget window, or you can make them semi-permanent, by using System.Gadget.Settings.write to store the settings. Let's say your username/password html looks like this:
<label for="username">Username: </label><input id="username" type="text"><br/>
<label for="password">Password: </label><input id="password" type="password">
Your JavaScript should look something like this:
System.Gadget.onSettingsClosing = function (event) {
// First, we need to make sure the user clicked the OK button to save
if (event.closeAction == event.Action.commit) {
// If they did, we need to store the settings
var username = document.getElementById("username").value,
password = document.getElementById("password").value;
System.Gadget.Settings.write("username", username);
System.Gadget.Settings.write("password", password);
/* Finally, we can call a function defined in the main gadget window's
JavaScript to let it know that the settings have changed */
System.Gadget.document.parentWindow.settingsHaveChanged();
}
}
In your main gadget's JavaScript, settingsHaveChanged might look something like the following function:
function settingsHaveChanged () {
var username = System.Gadget.Settings.read("username"),
password = System.Gadget.Settings.read("password");
sendAPIRequest(username, password);
}

Categories

Resources