First I should say, I just want to solve this as logic, not my real code is jQuery or JavaScript, because I learning reactjs I trying to solve this logic with jQ or JS then do it in React. So I don't want a solution like $.param and also don't want to replace last & with something, I looking for to make a URL Builder function, What I trying to do is add URL parameter (Query String) What I tried so far is:
let obj = {}
let array = []
let url = 'http://www.example.com/foo';
function buildUrl(base, key, value) {
var sep = (base.indexOf('?') > -1) ? '&' : '?';
return base + sep + key + '=' + value;
}
$('#btn1').click(function() {
obj = {
name: 'province',
value: 11
}
array.push(obj)
console.log('param 1 added!')
});
$('#btn2').click(function() {
obj = {
name: 'city',
value: 2
}
array.push(obj)
console.log('param 2 added!')
});
$('#build').click(function() {
$.each(array, function(i, v) {
url = buildUrl(url, v.name, v.value);
});
console.log(url)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="btn1">1. Click this</button>
<kbd>-></kbd>
<button id="btn2">2. Then click this</button>
<kbd>=</kbd>
<button id="build">Make URL</button>
Somehow, it add province twice, I don't how to make this function to avoid duplicate parameters, any idea?
side note: I have many btn to build parameter, so I can't detect value each time!
It is all here and here
let url = new URL('http://www.example.com/foo');
let params = url.searchParams;
document.getElementById("buts").addEventListener('click', (e) => {
const tgt = e.target;
if (tgt.classList.contains('add')) {
params.set(tgt.id, tgt.getAttribute('data-value'));
console.log('param ' + tgt.id + ' added!', params.toString())
}
});
document.getElementById("build").addEventListener('click', (e) => console.log(url));
<div id="buts">
<button class="add" id="province" data-value="11">1. Click this</button>
<kbd>-></kbd>
<button class="add" id="city" data-value="2">2. Then click this</button>
<kbd>=</kbd>
<button id="build">Make URL</button>
</div>
Related
I have this code below, it works as expected, but I need to pass the id of each one to work.
How can I turn it into a function to use the onKeyPress event:
document.getElementById('inp').addEventListener('input', e => {
const val = e.target.value.replace(/\D/g, '').replace(/^0*/, '').padStart(3, '0')
e.target.value = val.slice(0, -2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1.') + ',' + val.slice(-2)
})
I would like to turn to use as a: function Mask(){ // code }
<input asp-for="Frete" name="Frete" onKeyPress="return(Mask(this,'.',',',event))" class="form-control" />
To be able to use the function, so I would need to create one by one by id
Here you go you could use event object like :
document.getElementById('inp1').addEventListener('input', (e) => { Mask(e, 'inp1'); });
document.getElementById('inp2').addEventListener('input', (e) => { Mask(e, 'inp2'); });
document.getElementById('inp3').addEventListener('input', (e) => { Mask(e, 'inp3'); });
function Mask(e, id) {
const target = document.getElementById(id);
const val = target.value.replace(/\D/g, '').replace(/^0*/, '').padStart(3, '0');
target.value = val.slice(0, -2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1.') + ',' + val.slice(-2);
}
<input id="inp1">
<input id="inp2">
<input id="inp3">
I have the following code, I'm trying to determine which button a user presses.
function Navigation(navigating, timed) {
if (navigating == general) {
if (timed) {
window.location.replace('general.html?timed=' + timed);
} else {
window.location.replace('general.html');
}
} else if (navigating == sport) {
if (timed) {
window.location.replace('sport.html?timed=' + timed);
} else {
window.location.replace('sport.html');
}
} else if (navigating == music) {
if (timed) {
window.location.replace('music.html?timed=' + timed);
} else {
window.location.replace('music.html');
}
}
}
<button type="button" id="general" onclick="Navigation(general, null)">General Knowledge</button>
<button type="button" id="sport" onclick="Navigation(sport, null)">Sport</button>
<button type="button" id="music" onclick="Navigation(music, null)">Music</button>
<button type="button" id="generalTimer" onclick="Navigation(general, 'true')">Timed General Knowledge</button>
<button type="button" id="sportTimer" onclick="Navigation(sport, 'true')">Timed Sport</button>
<button type="button" id="musicTimer" onclick="Navigation(music, 'true')">Timed Music</button>
It actually works, however when I get to the next page, I don't know how to get the timed variable to affect the page.
function getQueryVariable(variable)
{
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
Usage
Example URL:
http://www.example.com/index.php?id=1&image=awesome.jpg
Calling getQueryVariable("id") - would return "1".
Calling getQueryVariable("image") - would return "awesome.jpg".
Source: CSS-TRICKS
You can get the url params from window.location.search. This function will parse the values, and allow you to get them all or just a single value.
unfortunately it's not working in the debug window due to the ristrictions of the iframe.
function urlParams(key) {
const search = location.search.slice(1)
.split(/\=|\&/)
.filter(val => val !== '')
const obj = {}
for (let ii = 0; ii < search.length; ii+=2) {
obj[search[ii]] = search[ii + 1]
}
return key
? obj[key]
: obj
}
console.log(
urlParams('testing'), // get specific param
urlParams() // get all params
)
you can use localstorage
for example:
first save the value that has been choosen to localstorage by code like this
localStorage.nav = navigating;
and then
for nextpages and whereever you want call the value with
document.getElementById("result").innerHTML=localStorage.nav;
for example write down it with
i want to build mini webchat - When view site i set show 5 messages and if view more, you can click button. All things are fine but when i remove 1 node, firebase auto add last node into, how can i prevent it?
Ex: I have node A,B,C,D,E,F,G. I had loaded list C,D,E,F,G but when i delete 1 in all, it auto add B into list.
<div id="messgesDiv">
<center><h3>Message</h3></center>
</div>
<div style="margin-top: 20px;">
<input type="text" id="nameInput" placeholder="Name">
<input type="text" id="messageInput" placeholder="Message" data-id="">
<input type="text" id="idproject" placeholder="ID Project">
</div>
<button id="delete">Delete Test</button>
<button id="edit">Edit</button>
<button id="loadmore">Load more</button>
<button id="showlastkey">Show last key</button>
My javascript
$('#loadmore').click(function() {
i = 0; old = first;
myDataRef.orderByKey().endAt(first).limitToLast(6).on('child_added', function (snapshot){
if( i == 0)
first = snapshot.key();
var message = snapshot.val();
if(snapshot.key() != old)
displayChatMessage(message.name, message.text, message.idproject, 'old');
i++;
console.log('myDataRef.orderByKey().endAt(first).limitToLast(6)');
});
});
$("#messageInput").keypress(function (e){
if(e.keyCode == 13){ //Enter
var name = $("#nameInput").val();
var text = $("#messageInput").val();
var idproject = $("#idproject").val();
if($("#messageInput").data("id")=='')
{
myDataRef.push({name: name, text: text, idproject: idproject});
}
else
{
myDataRef.child(key).update({name: name, text: text, idproject: idproject});
$('#messageInput').attr('data-id', '');
}
$("#messageInput").val("");
}
});
myDataRef.limitToLast(5).on('child_added', function (snapshot){
if( i == 0)
first = snapshot.key();
var message = snapshot.val();
displayChatMessage(snapshot.key(), message.name, message.text, message.idproject, 'new');
i++;
console.log(snapshot.key());
console.log(' myDataRef.limitToLast(5)');
});
function displayChatMessage(key, name, text, idproject, status){
//console.log(name + " -- " + text + " -- " +idproject);
if( status == 'new')
{
$('<div/>', { 'data-id': key , 'class' : 'test'}).text(text + " - ").prepend($('<em/>').text(name+": " )).append("IdProject: "+idproject).appendTo($("#messgesDiv"));
$("#messgesDiv")[0].scrollTop = $("#messgesDiv")[0].scrollHeight;
}
else
{
$('<div/>', { 'data-id': key , 'class' : 'test'}).text(text + " - ").prepend($('<em/>').text(name+": " )).append("IdProject: "+idproject).insertAfter($("center"));
$("#messgesDiv")[0].scrollTop = $("#messgesDiv")[0].scrollHeight;
}
}
$('#delete').click(function() {
myDataRef.child(key).remove();
$('#messgesDiv').filter('[data-id="'+key+'"]').remove();
});
Firebase limit queries act like a view on top of the data. So if you create a query for the 5 most recent messages, the Firebase client will ensure that you always have the 5 most recent messages.
Say you start with these messages:
message1
message2
message3
message4
message5
Now if you add a message6, you will get:
child_removed message1
child_added message6
So that your total local view becomes:
message2
message3
message4
message5
message6
Conversely when you remove message 6 again, you get these events:
child_removed message6
child_added message1 (before message2)
So that you can update the UI and end up with the correct list again.
There is no way to change this behavior of the API. So if you want to handle the situation differently, you will have to do this in your client-side code.
Your code currently only handles child_added. If you have add a handler for child_removed you'll see that you can easily keep the user interface in sync with the data.
Alternatively you can detect that the message is already in your UI by comparing the key of the message you're adding to the ones already present in the DOM:
function displayChatMessage(key, name, text, idproject, status){
var exists = $("div[data-id='" + key + "']").length;
if (status == 'new' && !exists) {
$('<div/>', { 'data-id': key , 'class' : 'test'}).text(text + " - ").prepend($('<em/>').text(name+": " )).append("IdProject: "+idproject).appendTo($("#messgesDiv"));
$("#messgesDiv")[0].scrollTop = $("#messgesDiv")[0].scrollHeight;
}
else {
$('<div/>', { 'data-id': key , 'class' : 'test'}).text(text + " - ").prepend($('<em/>').text(name+": " )).append("IdProject: "+idproject).insertAfter($("center"));
$("#messgesDiv")[0].scrollTop = $("#messgesDiv")[0].scrollHeight;
}
}
Am struggling hard to bind an array object with list of span values using watcher in Angularjs.
It is partially working, when i input span elements, an array automatically gets created for each span and when I remove any span element -> respective row from the existing array gets deleted and all the other rows gets realigned correctly(without disturbing the value and name).
The problem is when I remove a span element and reenter it using my input text, it is not getting added to my array. So, after removing one span element, and enter any new element - these new values are not getting appended to my array.
DemoCode fiddle link
What am I missing in my code?
How can I get reinserted spans to be appended to the existing array object without disturbing the values of leftover rows (name and values of array)?
Please note that values will get changed any time as per a chart.
This is the code am using:
<script>
function rdCtrl($scope) {
$scope.dataset_v1 = {};
$scope.dataset_wc = {};
$scope.$watch('dataset_wc', function (newVal) {
//alert('columns changed :: ' + JSON.stringify($scope.dataset_wc, null, 2));
$('#status').html(JSON.stringify($scope.dataset_wc));
}, true);
$(function () {
$('#tags input').on('focusout', function () {
var txt = this.value.replace(/[^a-zA-Z0-9\+\-\.\#]/g, ''); // allowed characters
if (txt) {
//alert(txt);
$(this).before('<span class="tag">' + txt.toLowerCase() + '</span>');
var div = $("#tags");
var spans = div.find("span");
spans.each(function (i, elem) { // loop over each spans
$scope.dataset_v1["d" + i] = { // add the key for each object results in "d0, d1..n"
id: i, // gives the id as "0,1,2.....n"
name: $(elem).text(), // push the text of the span in the loop
value: 3
}
});
$("#assign").click();
}
this.value = "";
}).on('keyup', function (e) {
// if: comma,enter (delimit more keyCodes with | pipe)
if (/(188|13)/.test(e.which)) $(this).focusout();
if ($('#tags span').length == 7) {
document.getElementById('inptags').style.display = 'none';
}
});
$('#tags').on('click', '.tag', function () {
var tagrm = this.innerHTML;
sk1 = $scope.dataset_wc;
removeparent(sk1);
filter($scope.dataset_v1, tagrm, 0);
$(this).remove();
document.getElementById('inptags').style.display = 'block';
$("#assign").click();
});
});
$scope.assign = function () {
$scope.dataset_wc = $scope.dataset_v1;
};
function filter(arr, m, i) {
if (i < arr.length) {
if (arr[i].name === m) {
arr.splice(i, 1);
arr.forEach(function (val, index) {
val.id = index
});
return arr
} else {
return filter(arr, m, i + 1)
}
} else {
return m + " not found in array"
}
}
function removeparent(d1)
{
dataset = d1;
d_sk = [];
Object.keys(dataset).forEach(function (key) {
// Get the value from the object
var value = dataset[key].value;
d_sk.push(dataset[key]);
});
$scope.dataset_v1 = d_sk;
}
}
</script>
Am giving another try, checking my luck on SO... I tried using another object to track the data while appending, but found difficult.
You should be using the scope as a way to bridge the full array and the tags. use ng-repeat to show the tags, and use the input model to push it into the main array that's showing the tags. I got it started for you here: http://jsfiddle.net/d5ah88mh/9/
function rdCtrl($scope){
$scope.dataset = [];
$scope.inputVal = "";
$scope.removeData = function(index){
$scope.dataset.splice(index, 1);
redoIndexes($scope.dataset);
}
$scope.addToData = function(){
$scope.dataset.push(
{"id": $scope.dataset.length+1,
"name": $scope.inputVal,
"value": 3}
);
$scope.inputVal = "";
redoIndexes($scope.dataset);
}
function redoIndexes(dataset){
for(i=0; i<dataset.length; i++){
$scope.dataset[i].id = i;
}
}
}
<div ng-app>
<div ng-controller="rdCtrl">
<div id="tags" style="border:none;width:370px;margin-left:300px;">
<span class="tag" style="padding:10px;background-color:#808080;margin-left:10px;margin-right:10px;" ng-repeat="data in dataset" id="4" ng-click="removeData($index)">{{data.name}}</span>
<div>
<input type="text" style="margin-left:-5px;" id="inptags" value="" placeholder="Add ur 5 main categories (enter ,)" ng-model="inputVal" />
<button type="submit" ng-click="addToData()">Submit</button>
<img src="../../../static/app/img/accept.png" ng-click="assign()" id="assign" style="cursor:pointer;display:none" />
</div>
</div>
<div id="status" style="margin-top:100px;"></div>
</div>
</div>
I am having some trouble trying to get params from my GSP to my controller from a Javascript click handler that looks like this:
$('#save').click(function () {
var uniqueId = "${recordToEdit.uniqueId}";
var secondaryId = "${recordToEdit.secondaryId}";
console.log(removedYellowIssues);
<g:remoteFunction controller="customer"
action="saveModifiedIndividualRecord"
params='{uniqueId: uniqueId,
secondaryId: secondaryId,
yellowIssuesRemoved: removedYellowIssues,
redIssuesRemoved: removedRedIssues}'/>
});
When the "save" button is pressed this is what I see in the javascript console:
["No address provided."]
so you can see the the 'removedYellowIssues' list is NOT empty. It's a Javascript list containing one string. However, here is what my controller thinks:
<><><> Parameters ***:
<><><> uniqueId: 239400B
<><><> secondaryId: 1
<><><> Red issues removed: null
<><><> Yellow issues removed: null
Here is the controller action:
def saveModifiedIndividualRecord() {
println "<><><> Parameters ***: "
println "<><><> uniqueId: " + params.uniqueId
println "<><><> secondaryId: " + params.secondaryId
println "<><><> Red issues removed: " + params.redIssuesRemoved
println "<><><> Yellow issues removed: " + params.yellowIssuesRemoved
}
Here is more of the Javascript code containing the above save button snippet.
var currentYellowIndex = 0;
var allYellowIssues = $('#allYellowIssues'); // The unordered list 'ul'
var removedYellowIssues = []; // An array to keep track of issues removed
if (allYellowIssues.length) { // If there are issues to be displayed
var yellowElements = document.getElementsByName('yellowIssue');
var yellowListSize = yellowElements.length;
yellowElements[currentYellowIndex].className = "display";
$('#yellowStartIndex').html(currentYellowIndex + 1);
$('#yellowSizeIndex').html(yellowListSize);
$('#nextYellowIssue').click(function () {
if (currentYellowIndex < yellowListSize-1) {
yellowElements[currentYellowIndex++].className = "display-none";
yellowElements[currentYellowIndex].className = "display";
$('#yellowStartIndex').html(currentYellowIndex + 1);
}
});
$('#previousYellowIssue').click(function () {
if (currentYellowIndex > 0) {
yellowElements[currentYellowIndex--].className = "display-none";
yellowElements[currentYellowIndex].className = "display";
$('#yellowStartIndex').html(currentYellowIndex + 1);
}
});
$('#clearYellowFlag').click(function () {
removedYellowIssues.push(yellowElements[currentYellowIndex].innerHTML);
yellowElements[currentYellowIndex].className = "display-none";
yellowElements[currentYellowIndex].remove();
yellowListSize = yellowElements.length;
if (yellowListSize == 0)
$('#yellowIssues').hide();
else {
currentYellowIndex = 0;
yellowElements[currentYellowIndex].className = "display";
$('#yellowStartIndex').html(currentYellowIndex + 1);
$('#yellowSizeIndex').html(yellowListSize);
}
});
}
$('#save').click(function () {
var uniqueId = "${recordToEdit.uniqueId}";
var secondaryId = "${recordToEdit.secondaryId}";
console.log(removedYellowIssues);
<g:remoteFunction controller="customer"
action="saveModifiedIndividualRecord"
params='{uniqueId: uniqueId,
secondaryId: secondaryId,
yellowIssuesRemoved: removedYellowIssues,
redIssuesRemoved: removedRedIssues}'/>
});
The last part of the GSP is where the save button itself is defined as follows:
<br>
<button id="save"> Save </button>   
<button id="cancel" class="close" type="button"> Cancel </button>
I feel like the { } in the params should be [ ] instead. The g:remoteFunction is a GSP tag and the params should be a map.
<g:remoteFunction controller="customer"
action="saveModifiedIndividualRecord"
params='[uniqueId: uniqueId,
secondaryId: secondaryId,
yellowIssuesRemoved: removedYellowIssues,
redIssuesRemoved: removedRedIssues]'/>
However, you really shouldn't use that tag (I think it is deprecated in the latest versions). You should just do an a post via jQuery:
$.post("${g.createLink(action: 'saveModifiedIndividualRecord')", {uniqueId: uniqueId, ...}, function(result) {
...
});